Skip to content

Commit 98f0bcb

Browse files
committedMay 7, 2021
Add fill/brush symbol support to embedded symbol renderer
1 parent 8651055 commit 98f0bcb

File tree

10 files changed

+530
-7
lines changed

10 files changed

+530
-7
lines changed
 

‎src/core/qgsogrutils.cpp

Lines changed: 157 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "qgspolygon.h"
2727
#include "qgsmultipolygon.h"
2828
#include "qgsmapinfosymbolconverter.h"
29+
#include "qgsfillsymbollayer.h"
30+
#include "qgssymbollayerutils.h"
2931

3032
#include <QTextCodec>
3133
#include <QUuid>
@@ -1234,6 +1236,9 @@ std::unique_ptr<QgsSymbol> QgsOgrUtils::symbolFromStyleString( const QString &st
12341236

12351237
auto convertColor = []( const QString & string ) -> QColor
12361238
{
1239+
if ( string.isEmpty() )
1240+
return QColor();
1241+
12371242
const thread_local QRegularExpression sColorWithAlphaRx = QRegularExpression( QStringLiteral( "^#([0-9a-fA-F]{6})([0-9a-fA-F]{2})$" ) );
12381243
const QRegularExpressionMatch match = sColorWithAlphaRx.match( string );
12391244
if ( match.hasMatch() )
@@ -1247,10 +1252,8 @@ std::unique_ptr<QgsSymbol> QgsOgrUtils::symbolFromStyleString( const QString &st
12471252
}
12481253
};
12491254

1250-
if ( type == QgsSymbol::Line && styles.contains( QStringLiteral( "pen" ) ) )
1255+
auto convertPen = [&convertColor, &convertSize, string]( const QVariantMap & lineStyle ) -> std::unique_ptr< QgsSymbol >
12511256
{
1252-
// line symbol type
1253-
const QVariantMap lineStyle = styles.value( QStringLiteral( "pen" ) ).toMap();
12541257
QColor color = convertColor( lineStyle.value( QStringLiteral( "c" ), QStringLiteral( "#000000" ) ).toString() );
12551258

12561259
double lineWidth = DEFAULT_SIMPLELINE_WIDTH;
@@ -1347,6 +1350,157 @@ std::unique_ptr<QgsSymbol> QgsOgrUtils::symbolFromStyleString( const QString &st
13471350
simpleLine->setRenderingPass( priority.toInt() );
13481351
}
13491352
return std::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << simpleLine.release() );
1353+
};
1354+
1355+
auto convertBrush = [&convertColor]( const QVariantMap & brushStyle ) -> std::unique_ptr< QgsSymbol >
1356+
{
1357+
const QColor foreColor = convertColor( brushStyle.value( QStringLiteral( "fc" ), QStringLiteral( "#000000" ) ).toString() );
1358+
const QColor backColor = convertColor( brushStyle.value( QStringLiteral( "bc" ), QString() ).toString() );
1359+
1360+
const QString id = brushStyle.value( QStringLiteral( "id" ) ).toString();
1361+
1362+
// if the pen is a mapinfo brush, use dedicated converter for more accurate results
1363+
const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral( "mapinfo-brush-(\\d+)" ) );
1364+
const QRegularExpressionMatch match = sMapInfoId.match( id );
1365+
if ( match.hasMatch() )
1366+
{
1367+
const int brushId = match.captured( 1 ).toInt();
1368+
QgsMapInfoSymbolConversionContext context;
1369+
std::unique_ptr<QgsSymbol> res( QgsMapInfoSymbolConverter::convertFillSymbol( brushId, context, foreColor, backColor ) );
1370+
if ( res )
1371+
return res;
1372+
}
1373+
1374+
const thread_local QRegularExpression sOgrId = QRegularExpression( QStringLiteral( "ogr-brush-(\\d+)" ) );
1375+
const QRegularExpressionMatch ogrMatch = sOgrId.match( id );
1376+
1377+
Qt::BrushStyle style = Qt::SolidPattern;
1378+
if ( ogrMatch.hasMatch() )
1379+
{
1380+
const int brushId = ogrMatch.captured( 1 ).toInt();
1381+
switch ( brushId )
1382+
{
1383+
case 0:
1384+
style = Qt::SolidPattern;
1385+
break;
1386+
1387+
case 1:
1388+
style = Qt::NoBrush;
1389+
break;
1390+
1391+
case 2:
1392+
style = Qt::HorPattern;
1393+
break;
1394+
1395+
case 3:
1396+
style = Qt::VerPattern;
1397+
break;
1398+
1399+
case 4:
1400+
style = Qt::FDiagPattern;
1401+
break;
1402+
1403+
case 5:
1404+
style = Qt::BDiagPattern;
1405+
break;
1406+
1407+
case 6:
1408+
style = Qt::CrossPattern;
1409+
break;
1410+
1411+
case 7:
1412+
style = Qt::DiagCrossPattern;
1413+
break;
1414+
}
1415+
}
1416+
1417+
QgsSymbolLayerList layers;
1418+
if ( backColor.isValid() && style != Qt::SolidPattern && style != Qt::NoBrush )
1419+
{
1420+
std::unique_ptr< QgsSimpleFillSymbolLayer > backgroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( backColor );
1421+
backgroundFill->setLocked( true );
1422+
backgroundFill->setStrokeStyle( Qt::NoPen );
1423+
layers << backgroundFill.release();
1424+
}
1425+
1426+
std::unique_ptr< QgsSimpleFillSymbolLayer > foregroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( foreColor );
1427+
foregroundFill->setBrushStyle( style );
1428+
foregroundFill->setStrokeStyle( Qt::NoPen );
1429+
1430+
const QString priority = brushStyle.value( QStringLiteral( "l" ) ).toString();
1431+
if ( !priority.isEmpty() )
1432+
{
1433+
foregroundFill->setRenderingPass( priority.toInt() );
1434+
}
1435+
layers << foregroundFill.release();
1436+
return std::make_unique< QgsFillSymbol >( layers );
1437+
};
1438+
1439+
switch ( type )
1440+
{
1441+
case QgsSymbol::Marker:
1442+
break;
1443+
1444+
case QgsSymbol::Line:
1445+
if ( styles.contains( QStringLiteral( "pen" ) ) )
1446+
{
1447+
// line symbol type
1448+
const QVariantMap lineStyle = styles.value( QStringLiteral( "pen" ) ).toMap();
1449+
return convertPen( lineStyle );
1450+
}
1451+
else
1452+
{
1453+
return nullptr;
1454+
}
1455+
1456+
case QgsSymbol::Fill:
1457+
{
1458+
std::unique_ptr< QgsSymbol > fillSymbol = std::make_unique< QgsFillSymbol >();
1459+
if ( styles.contains( QStringLiteral( "brush" ) ) )
1460+
{
1461+
const QVariantMap brushStyle = styles.value( QStringLiteral( "brush" ) ).toMap();
1462+
fillSymbol = convertBrush( brushStyle );
1463+
}
1464+
else
1465+
{
1466+
std::unique_ptr< QgsSimpleFillSymbolLayer > emptyFill = std::make_unique< QgsSimpleFillSymbolLayer >();
1467+
emptyFill->setBrushStyle( Qt::NoBrush );
1468+
fillSymbol = std::make_unique< QgsFillSymbol >( QgsSymbolLayerList() << emptyFill.release() );
1469+
}
1470+
1471+
std::unique_ptr< QgsSymbol > penSymbol;
1472+
if ( styles.contains( QStringLiteral( "pen" ) ) )
1473+
{
1474+
const QVariantMap lineStyle = styles.value( QStringLiteral( "pen" ) ).toMap();
1475+
penSymbol = convertPen( lineStyle );
1476+
}
1477+
1478+
if ( penSymbol )
1479+
{
1480+
const int count = penSymbol->symbolLayerCount();
1481+
1482+
if ( count == 1 )
1483+
{
1484+
// if only one pen symbol layer, let's try and combine it with the topmost brush layer, so that the resultant QGIS symbol is simpler
1485+
if ( QgsSymbolLayerUtils::condenseFillAndOutline( dynamic_cast< QgsFillSymbolLayer * >( fillSymbol->symbolLayer( fillSymbol->symbolLayerCount() - 1 ) ),
1486+
dynamic_cast< QgsLineSymbolLayer * >( penSymbol->symbolLayer( 0 ) ) ) )
1487+
return fillSymbol;
1488+
}
1489+
1490+
for ( int i = 0; i < count; ++i )
1491+
{
1492+
std::unique_ptr< QgsSymbolLayer > layer( penSymbol->takeSymbolLayer( 0 ) );
1493+
layer->setLocked( true );
1494+
fillSymbol->appendSymbolLayer( layer.release() );
1495+
}
1496+
}
1497+
1498+
return fillSymbol;
1499+
}
1500+
1501+
case QgsSymbol::Hybrid:
1502+
break;
13501503
}
1504+
13511505
return nullptr;
13521506
}

‎src/core/symbology/qgsmapinfosymbolconverter.cpp

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "qgslogger.h"
1818
#include "qgslinesymbollayer.h"
1919
#include "qgsmarkersymbollayer.h"
20+
#include "qgsfillsymbollayer.h"
2021

2122
//
2223
// QgsMapInfoSymbolConversionContext
@@ -1094,3 +1095,294 @@ QgsLineSymbol *QgsMapInfoSymbolConverter::convertLineSymbol( int identifier, Qgs
10941095

10951096
return symbol.release();
10961097
}
1098+
1099+
QgsFillSymbol *QgsMapInfoSymbolConverter::convertFillSymbol( int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &foreColor, const QColor &backColor )
1100+
{
1101+
Qt::BrushStyle style = Qt::SolidPattern;
1102+
1103+
bool useLineFill = false;
1104+
bool crossFill = false;
1105+
double lineAngle = 0;
1106+
double lineWidth = 0;
1107+
double lineSpacing = 1;
1108+
switch ( identifier )
1109+
{
1110+
case 0:
1111+
case 1:
1112+
style = Qt::NoBrush;
1113+
break;
1114+
1115+
case 2:
1116+
style = Qt::SolidPattern;
1117+
break;
1118+
1119+
case 3:
1120+
case 19:
1121+
style = Qt::HorPattern;
1122+
break;
1123+
1124+
case 4:
1125+
case 24:
1126+
style = Qt::VerPattern;
1127+
break;
1128+
1129+
case 5:
1130+
case 34:
1131+
style = Qt::FDiagPattern;
1132+
break;
1133+
1134+
case 6:
1135+
case 29:
1136+
style = Qt::BDiagPattern;
1137+
break;
1138+
1139+
case 7:
1140+
case 39:
1141+
style = Qt::CrossPattern;
1142+
break;
1143+
1144+
case 8:
1145+
case 44:
1146+
style = Qt::DiagCrossPattern;
1147+
break;
1148+
1149+
case 12:
1150+
style = Qt::Dense1Pattern;
1151+
break;
1152+
1153+
case 13:
1154+
style = Qt::Dense2Pattern;
1155+
break;
1156+
1157+
case 14:
1158+
style = Qt::Dense3Pattern;
1159+
break;
1160+
1161+
case 15:
1162+
style = Qt::Dense4Pattern;
1163+
break;
1164+
1165+
case 16:
1166+
style = Qt::Dense5Pattern;
1167+
break;
1168+
1169+
case 17:
1170+
style = Qt::Dense6Pattern;
1171+
break;
1172+
1173+
case 18:
1174+
style = Qt::Dense7Pattern;
1175+
break;
1176+
1177+
case 20:
1178+
useLineFill = true;
1179+
lineAngle = 0;
1180+
lineSpacing = 6;
1181+
lineWidth = 1.2;
1182+
break;
1183+
1184+
case 21:
1185+
useLineFill = true;
1186+
lineAngle = 0;
1187+
lineSpacing = 4;
1188+
lineWidth = 0.8;
1189+
break;
1190+
1191+
case 22:
1192+
useLineFill = true;
1193+
lineAngle = 0;
1194+
lineSpacing = 3.4;
1195+
lineWidth = 1.2;
1196+
break;
1197+
1198+
case 23:
1199+
useLineFill = true;
1200+
lineAngle = 0;
1201+
lineSpacing = 3.0;
1202+
lineWidth = 1.0;
1203+
break;
1204+
1205+
case 25:
1206+
useLineFill = true;
1207+
lineAngle = 90;
1208+
lineSpacing = 6;
1209+
lineWidth = 1.2;
1210+
break;
1211+
1212+
case 26:
1213+
useLineFill = true;
1214+
lineAngle = 90;
1215+
lineSpacing = 4;
1216+
lineWidth = 0.8;
1217+
break;
1218+
1219+
case 27:
1220+
useLineFill = true;
1221+
lineAngle = 90;
1222+
lineSpacing = 3.4;
1223+
lineWidth = 1.2;
1224+
break;
1225+
1226+
case 28:
1227+
useLineFill = true;
1228+
lineAngle = 90;
1229+
lineSpacing = 3.0;
1230+
lineWidth = 1.0;
1231+
break;
1232+
1233+
case 30:
1234+
useLineFill = true;
1235+
lineAngle = 45;
1236+
lineSpacing = 6;
1237+
lineWidth = 1.2;
1238+
break;
1239+
1240+
case 31:
1241+
useLineFill = true;
1242+
lineAngle = 45;
1243+
lineSpacing = 4;
1244+
lineWidth = 0.8;
1245+
break;
1246+
1247+
case 32:
1248+
useLineFill = true;
1249+
lineAngle = 45;
1250+
lineSpacing = 3.4;
1251+
lineWidth = 1.2;
1252+
break;
1253+
1254+
case 33:
1255+
useLineFill = true;
1256+
lineAngle = 45;
1257+
lineSpacing = 3.0;
1258+
lineWidth = 1.0;
1259+
break;
1260+
1261+
case 35:
1262+
useLineFill = true;
1263+
lineAngle = 135;
1264+
lineSpacing = 6;
1265+
lineWidth = 1.2;
1266+
break;
1267+
1268+
case 36:
1269+
useLineFill = true;
1270+
lineAngle = 135;
1271+
lineSpacing = 4;
1272+
lineWidth = 0.8;
1273+
break;
1274+
1275+
case 37:
1276+
useLineFill = true;
1277+
lineAngle = 135;
1278+
lineSpacing = 3.4;
1279+
lineWidth = 1.2;
1280+
break;
1281+
1282+
case 38:
1283+
useLineFill = true;
1284+
lineAngle = 135;
1285+
lineSpacing = 3.0;
1286+
lineWidth = 1.0;
1287+
break;
1288+
1289+
case 40:
1290+
useLineFill = true;
1291+
crossFill = true;
1292+
lineAngle = 0;
1293+
lineSpacing = 6;
1294+
lineWidth = 1.2;
1295+
break;
1296+
1297+
case 41:
1298+
useLineFill = true;
1299+
crossFill = true;
1300+
lineAngle = 0;
1301+
lineSpacing = 4;
1302+
lineWidth = 0.8;
1303+
break;
1304+
1305+
case 42:
1306+
useLineFill = true;
1307+
crossFill = true;
1308+
lineAngle = 0;
1309+
lineSpacing = 3.4;
1310+
lineWidth = 1.2;
1311+
break;
1312+
1313+
case 43:
1314+
useLineFill = true;
1315+
crossFill = true;
1316+
lineAngle = 0;
1317+
lineSpacing = 3.0;
1318+
lineWidth = 1.0;
1319+
break;
1320+
1321+
case 45:
1322+
useLineFill = true;
1323+
crossFill = true;
1324+
lineAngle = 45;
1325+
lineSpacing = 6;
1326+
lineWidth = 1.2;
1327+
break;
1328+
1329+
case 46:
1330+
useLineFill = true;
1331+
crossFill = true;
1332+
lineAngle = 45;
1333+
lineSpacing = 4;
1334+
lineWidth = 0.8;
1335+
break;
1336+
1337+
case 47:
1338+
useLineFill = true;
1339+
crossFill = true;
1340+
lineAngle = 45;
1341+
lineSpacing = 3.4;
1342+
lineWidth = 1.2;
1343+
break;
1344+
1345+
default:
1346+
context.pushWarning( QObject::tr( "The brush style is not supported in QGIS" ) );
1347+
return nullptr;
1348+
}
1349+
1350+
QgsSymbolLayerList layers;
1351+
if ( backColor.isValid() && style != Qt::SolidPattern && ( useLineFill || style != Qt::NoBrush ) )
1352+
{
1353+
std::unique_ptr< QgsSimpleFillSymbolLayer > backgroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( backColor );
1354+
backgroundFill->setLocked( true );
1355+
backgroundFill->setStrokeStyle( Qt::NoPen );
1356+
layers << backgroundFill.release();
1357+
}
1358+
1359+
if ( !useLineFill )
1360+
{
1361+
std::unique_ptr< QgsSimpleFillSymbolLayer > foregroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( foreColor );
1362+
foregroundFill->setBrushStyle( style );
1363+
foregroundFill->setStrokeStyle( Qt::NoPen );
1364+
layers << foregroundFill.release();
1365+
}
1366+
else
1367+
{
1368+
std::unique_ptr< QgsLinePatternFillSymbolLayer > lineFill = std::make_unique< QgsLinePatternFillSymbolLayer >();
1369+
1370+
std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( foreColor, lineWidth );
1371+
simpleLine->setWidthUnit( QgsUnitTypes::RenderPoints );
1372+
lineFill->setSubSymbol( new QgsLineSymbol( QgsSymbolLayerList() << simpleLine.release() ) );
1373+
1374+
lineFill->setDistance( lineSpacing );
1375+
lineFill->setDistanceUnit( QgsUnitTypes::RenderPoints );
1376+
lineFill->setLineAngle( lineAngle );
1377+
1378+
if ( crossFill )
1379+
{
1380+
std::unique_ptr< QgsLinePatternFillSymbolLayer > lineFill2( lineFill->clone() );
1381+
lineFill2->setLineAngle( lineFill->lineAngle() + 90 );
1382+
layers << lineFill2.release();
1383+
}
1384+
1385+
layers << lineFill.release();
1386+
}
1387+
return new QgsFillSymbol( layers );
1388+
}

‎src/core/symbology/qgsmapinfosymbolconverter.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
#include "qgis_sip.h"
2121
#include "qgsunittypes.h"
2222
#include <QStringList>
23+
#include <QColor>
2324

2425
class QgsLineSymbol;
26+
class QgsFillSymbol;
2527

2628
/**
2729
* Context for a MapInfo symbol conversion operation.
@@ -71,6 +73,13 @@ class CORE_EXPORT QgsMapInfoSymbolConverter
7173
*/
7274
static QgsLineSymbol *convertLineSymbol( int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &foreColor, double size, QgsUnitTypes::RenderUnit sizeUnit, bool interleaved = false ) SIP_FACTORY;
7375

76+
/**
77+
* Converts the MapInfo fill symbol with the specified \a identifier to a QgsFillSymbol.
78+
*
79+
* The caller takes ownership of the returned symbol.
80+
*/
81+
static QgsFillSymbol *convertFillSymbol( int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &foreColor, const QColor &backColor = QColor() ) SIP_FACTORY;
82+
7483
};
7584

7685
#endif // QGSMAPINFOSYMBOLCONVERTER_H

‎tests/src/core/testqgsogrutils.cpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "qgspoint.h"
3030
#include "qgsogrproxytextcodec.h"
3131
#include "qgslinesymbollayer.h"
32+
#include "qgsfillsymbollayer.h"
3233

3334
class TestQgsOgrUtils: public QObject
3435
{
@@ -591,10 +592,49 @@ void TestQgsOgrUtils::convertStyleString()
591592
symbol = QgsOgrUtils::symbolFromStyleString( QStringLiteral( R"""(PEN(c:#FFFF007F,w:4.000000pt);BRUSH(fc:#00FF007F))""" ), QgsSymbol::Line );
592593
QVERIFY( symbol );
593594
QCOMPARE( symbol->symbolLayerCount(), 1 );
594-
QCOMPARE( dynamic_cast<QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().name(), QStringLiteral( "#ffff00" ) );
595-
QCOMPARE( dynamic_cast<QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().alpha(), 127 );
596-
QCOMPARE( dynamic_cast<QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->width(), 4.0 );
597-
QCOMPARE( dynamic_cast<QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->widthUnit(), QgsUnitTypes::RenderPoints );
595+
QCOMPARE( qgis::down_cast<QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().name(), QStringLiteral( "#ffff00" ) );
596+
QCOMPARE( qgis::down_cast<QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().alpha(), 127 );
597+
QCOMPARE( qgis::down_cast<QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->width(), 4.0 );
598+
QCOMPARE( qgis::down_cast<QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->widthUnit(), QgsUnitTypes::RenderPoints );
599+
600+
// brush
601+
symbol = QgsOgrUtils::symbolFromStyleString( QStringLiteral( R"""(BRUSH(fc:#00FF007F))""" ), QgsSymbol::Fill );
602+
QVERIFY( symbol );
603+
QCOMPARE( symbol->symbolLayerCount(), 1 );
604+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().name(), QStringLiteral( "#00ff00" ) );
605+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().alpha(), 127 );
606+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->brushStyle(), Qt::SolidPattern );
607+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->strokeStyle(), Qt::NoPen );
608+
609+
symbol = QgsOgrUtils::symbolFromStyleString( QStringLiteral( R"""(BRUSH(fc:#00FF007F,bc:#00000087,id:ogr-brush-6))""" ), QgsSymbol::Fill );
610+
QVERIFY( symbol );
611+
QCOMPARE( symbol->symbolLayerCount(), 2 );
612+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().name(), QStringLiteral( "#000000" ) );
613+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().alpha(), 135 );
614+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->brushStyle(), Qt::SolidPattern );
615+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->strokeStyle(), Qt::NoPen );
616+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 1 ) )->color().name(), QStringLiteral( "#00ff00" ) );
617+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 1 ) )->color().alpha(), 127 );
618+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 1 ) )->brushStyle(), Qt::CrossPattern );
619+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 1 ) )->strokeStyle(), Qt::NoPen );
620+
621+
// brush with pen
622+
symbol = QgsOgrUtils::symbolFromStyleString( QStringLiteral( R"""(PEN(c:#FFFF007F,w:4.000000pt);BRUSH(fc:#00FF007F))""" ), QgsSymbol::Fill );
623+
QVERIFY( symbol );
624+
QCOMPARE( symbol->symbolLayerCount(), 1 );
625+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().name(), QStringLiteral( "#00ff00" ) );
626+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->color().alpha(), 127 );
627+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->brushStyle(), Qt::SolidPattern );
628+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->strokeStyle(), Qt::SolidLine );
629+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->strokeColor().name(), QStringLiteral( "#ffff00" ) );
630+
631+
// no brush, but need fill symbol
632+
symbol = QgsOgrUtils::symbolFromStyleString( QStringLiteral( R"""(PEN(c:#FFFF007F,w:4.000000pt))""" ), QgsSymbol::Fill );
633+
QVERIFY( symbol );
634+
QCOMPARE( symbol->symbolLayerCount(), 1 );
635+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->brushStyle(), Qt::NoBrush );
636+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->strokeStyle(), Qt::SolidLine );
637+
QCOMPARE( qgis::down_cast<QgsSimpleFillSymbolLayer * >( symbol->symbolLayer( 0 ) )->strokeColor().name(), QStringLiteral( "#ffff00" ) );
598638
}
599639

600640
QGSTEST_MAIN( TestQgsOgrUtils )

‎tests/src/python/test_qgsembeddedsymbolrenderer.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,26 @@ def testMapInfoLineSymbolConversion(self):
174174
renderchecker.setControlName('expected_embedded_mapinfo_lines')
175175
self.assertTrue(renderchecker.runTest('embedded_mapinfo_lines'))
176176

177+
def testMapFillLineSymbolConversion(self):
178+
line_layer = QgsVectorLayer(TEST_DATA_DIR + '/mapinfo/fill_styles.TAB', 'Fills', 'ogr')
179+
180+
renderer = QgsEmbeddedSymbolRenderer(defaultSymbol=QgsLineSymbol.createSimple({}))
181+
line_layer.setRenderer(renderer)
182+
183+
mapsettings = QgsMapSettings()
184+
mapsettings.setOutputSize(QSize(2000, 4000))
185+
mapsettings.setOutputDpi(96)
186+
mapsettings.setMagnificationFactor(2)
187+
mapsettings.setExtent(line_layer.extent().buffered(0.1))
188+
189+
mapsettings.setLayers([line_layer])
190+
191+
renderchecker = QgsMultiRenderChecker()
192+
renderchecker.setMapSettings(mapsettings)
193+
renderchecker.setControlPathPrefix('embedded')
194+
renderchecker.setControlName('expected_embedded_mapinfo_fills')
195+
self.assertTrue(renderchecker.runTest('embedded_mapinfo_fills'))
196+
177197

178198
if __name__ == '__main__':
179199
unittest.main()
605 Bytes
Binary file not shown.

‎tests/testdata/mapinfo/fill_styles.ID

196 Bytes
Binary file not shown.
4.5 KB
Binary file not shown.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
!table
2+
!version 450
3+
!charset WindowsLatin1
4+
5+
Definition Table
6+
Type NATIVE Charset "WindowsLatin1"
7+
Fields 1
8+
Field1 Char (10) ;

0 commit comments

Comments
 (0)
Please sign in to comment.