33 #include <QSvgRenderer> 
   36 #include <QDomDocument> 
   37 #include <QDomElement> 
   44 static constexpr 
int MAX_FONT_CHARACTER_SIZE_IN_PIXELS = 500;
 
   46 static void _fixQPictureDPI( QPainter *p )
 
   52   p->scale( 
static_cast< double >( 
qt_defaultDpiX() ) / p->device()->logicalDpiX(),
 
   53             static_cast< double >( 
qt_defaultDpiY() ) / p->device()->logicalDpiY() );
 
   66   QList< Shape > shapes;
 
  165   QTransform transform;
 
  168   if ( !hasDataDefinedSize )
 
  178     double half = scaledSize / 2.0;
 
  179     transform.scale( half, half );
 
  185     transform.rotate( 
mAngle );
 
  212   bool hasDataDefinedSize = 
false;
 
  213   double scaledSize = 
calculateSize( context, hasDataDefinedSize );
 
  215   bool hasDataDefinedRotation = 
false;
 
  221   bool createdNewPath = 
false;
 
  228     if ( !exprVal.isNull() )
 
  239         createdNewPath = 
true;
 
  248   QTransform transform;
 
  251   transform.translate( point.x() + 
offset.x(), point.y() + 
offset.y() );
 
  254   if ( hasDataDefinedSize || createdNewPath )
 
  263     double half = s / 2.0;
 
  264     transform.scale( half, half );
 
  269     transform.rotate( 
angle );
 
  278     polygon = transform.map( 
mPolygon );
 
  282     path = transform.map( 
mPath );
 
  284   draw( context, symbol, polygon, path );
 
  289   bool hasDataDefinedSize = 
false;
 
  290   double scaledSize = 
calculateSize( context, hasDataDefinedSize );
 
  292   bool hasDataDefinedRotation = 
false;
 
  299   QTransform transform;
 
  302   transform.translate( point.x() + 
offset.x(), point.y() + 
offset.y() );
 
  305     transform.rotate( 
angle );
 
  307   return transform.mapRect( QRectF( -scaledSize / 2.0,
 
  317   QString cleaned = name.toLower().trimmed();
 
  319   if ( cleaned == QLatin1String( 
"square" ) || cleaned == QLatin1String( 
"rectangle" ) )
 
  321   else if ( cleaned == QLatin1String( 
"square_with_corners" ) )
 
  323   else if ( cleaned == QLatin1String( 
"diamond" ) )
 
  325   else if ( cleaned == QLatin1String( 
"pentagon" ) )
 
  327   else if ( cleaned == QLatin1String( 
"hexagon" ) )
 
  329   else if ( cleaned == QLatin1String( 
"octagon" ) )
 
  331   else if ( cleaned == QLatin1String( 
"triangle" ) )
 
  333   else if ( cleaned == QLatin1String( 
"equilateral_triangle" ) )
 
  335   else if ( cleaned == QLatin1String( 
"star" ) || cleaned == QLatin1String( 
"regular_star" ) )
 
  337   else if ( cleaned == QLatin1String( 
"arrow" ) )
 
  339   else if ( cleaned == QLatin1String( 
"circle" ) )
 
  341   else if ( cleaned == QLatin1String( 
"cross" ) )
 
  343   else if ( cleaned == QLatin1String( 
"cross_fill" ) )
 
  345   else if ( cleaned == QLatin1String( 
"cross2" ) || cleaned == QLatin1String( 
"x" ) )
 
  347   else if ( cleaned == QLatin1String( 
"line" ) )
 
  349   else if ( cleaned == QLatin1String( 
"arrowhead" ) )
 
  351   else if ( cleaned == QLatin1String( 
"filled_arrowhead" ) )
 
  353   else if ( cleaned == QLatin1String( 
"semi_circle" ) )
 
  355   else if ( cleaned == QLatin1String( 
"third_circle" ) )
 
  357   else if ( cleaned == QLatin1String( 
"quarter_circle" ) )
 
  359   else if ( cleaned == QLatin1String( 
"quarter_square" ) )
 
  361   else if ( cleaned == QLatin1String( 
"half_square" ) )
 
  363   else if ( cleaned == QLatin1String( 
"diagonal_half_square" ) )
 
  365   else if ( cleaned == QLatin1String( 
"right_half_triangle" ) )
 
  367   else if ( cleaned == QLatin1String( 
"left_half_triangle" ) )
 
  369   else if ( cleaned == QLatin1String( 
"asterisk_fill" ) )
 
  371   else if ( cleaned == QLatin1String( 
"half_arc" ) )
 
  373   else if ( cleaned == QLatin1String( 
"third_arc" ) )
 
  375   else if ( cleaned == QLatin1String( 
"quarter_arc" ) )
 
  388       return QStringLiteral( 
"square" );
 
  390       return QStringLiteral( 
"quarter_square" );
 
  392       return QStringLiteral( 
"half_square" );
 
  394       return QStringLiteral( 
"diagonal_half_square" );
 
  396       return QStringLiteral( 
"diamond" );
 
  398       return QStringLiteral( 
"pentagon" );
 
  400       return QStringLiteral( 
"hexagon" );
 
  402       return QStringLiteral( 
"octagon" );
 
  404       return QStringLiteral( 
"square_with_corners" );
 
  406       return QStringLiteral( 
"triangle" );
 
  408       return QStringLiteral( 
"equilateral_triangle" );
 
  410       return QStringLiteral( 
"left_half_triangle" );
 
  412       return QStringLiteral( 
"right_half_triangle" );
 
  414       return QStringLiteral( 
"star" );
 
  416       return QStringLiteral( 
"arrow" );
 
  418       return QStringLiteral( 
"filled_arrowhead" );
 
  420       return QStringLiteral( 
"cross_fill" );
 
  422       return QStringLiteral( 
"circle" );
 
  424       return QStringLiteral( 
"cross" );
 
  426       return QStringLiteral( 
"cross2" );
 
  428       return QStringLiteral( 
"line" );
 
  430       return QStringLiteral( 
"arrowhead" );
 
  432       return QStringLiteral( 
"semi_circle" );
 
  434       return QStringLiteral( 
"third_circle" );
 
  436       return QStringLiteral( 
"quarter_circle" );
 
  438       return QStringLiteral( 
"asterisk_fill" );
 
  440       return QStringLiteral( 
"half_arc" );
 
  442       return QStringLiteral( 
"third_arc" );
 
  444       return QStringLiteral( 
"quarter_arc" );
 
  461       polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
 
  466       static constexpr 
double VERTEX_OFFSET_FROM_ORIGIN = 0.6072;
 
  468       polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
 
  469               << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
 
  470               << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
 
  471               << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
 
  472               << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
 
  473               << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
 
  474               << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
 
  475               << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
 
  476               << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
 
  481       polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 0 ) ) );
 
  485       polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 1 ) ) );
 
  489       polygon << QPointF( -1, -1 ) << QPointF( 1, 1 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
 
  493       polygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
 
  494               << QPointF( 1, 0 ) << QPointF( 0, -1 ) << QPointF( -1, 0 );
 
  504       polygon << QPointF( -0.9511, -0.3090 )
 
  505               << QPointF( -0.5878, 0.8090 )
 
  506               << QPointF( 0.5878, 0.8090 )
 
  507               << QPointF( 0.9511, -0.3090 )
 
  509               << QPointF( -0.9511, -0.3090 );
 
  520       polygon << QPointF( -0.8660, -0.5 )
 
  521               << QPointF( -0.8660, 0.5 )
 
  523               << QPointF( 0.8660, 0.5 )
 
  524               << QPointF( 0.8660, -0.5 )
 
  526               << QPointF( -0.8660, -0.5 );
 
  531       static constexpr 
double VERTEX_OFFSET_FROM_ORIGIN = 1.0 / ( 1 + M_SQRT2 );
 
  533       polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
 
  534               << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
 
  535               << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
 
  536               << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
 
  537               << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
 
  538               << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
 
  539               << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
 
  540               << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
 
  541               << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
 
  546       polygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
 
  554       polygon << QPointF( -0.8660, 0.5 )
 
  555               << QPointF( 0.8660, 0.5 )
 
  557               << QPointF( -0.8660, 0.5 );
 
  561       polygon << QPointF( 0, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( 0, 1 );
 
  565       polygon << QPointF( -1, 1 ) << QPointF( 0, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
 
  570       double inner_r = std::cos( 
DEG2RAD( 72.0 ) ) / std::cos( 
DEG2RAD( 36.0 ) );
 
  572       polygon << QPointF( inner_r * std::sin( 
DEG2RAD( 324.0 ) ), - inner_r * std::cos( 
DEG2RAD( 324.0 ) ) )  
 
  573               << QPointF( std::sin( 
DEG2RAD( 288.0 ) ), - std::cos( 
DEG2RAD( 288 ) ) )    
 
  574               << QPointF( inner_r * std::sin( 
DEG2RAD( 252.0 ) ), - inner_r * std::cos( 
DEG2RAD( 252.0 ) ) )   
 
  575               << QPointF( std::sin( 
DEG2RAD( 216.0 ) ), - std::cos( 
DEG2RAD( 216.0 ) ) )   
 
  576               << QPointF( 0, inner_r )         
 
  577               << QPointF( std::sin( 
DEG2RAD( 144.0 ) ), - std::cos( 
DEG2RAD( 144.0 ) ) )   
 
  578               << QPointF( inner_r * std::sin( 
DEG2RAD( 108.0 ) ), - inner_r * std::cos( 
DEG2RAD( 108.0 ) ) )   
 
  579               << QPointF( std::sin( 
DEG2RAD( 72.0 ) ), - std::cos( 
DEG2RAD( 72.0 ) ) )    
 
  580               << QPointF( inner_r * std::sin( 
DEG2RAD( 36.0 ) ), - inner_r * std::cos( 
DEG2RAD( 36.0 ) ) )   
 
  582               << QPointF( inner_r * std::sin( 
DEG2RAD( 324.0 ) ), - inner_r * std::cos( 
DEG2RAD( 324.0 ) ) );  
 
  587       polygon << QPointF( 0, -1 )
 
  588               << QPointF( 0.5,  -0.5 )
 
  589               << QPointF( 0.25, -0.5 )
 
  590               << QPointF( 0.25,  1 )
 
  591               << QPointF( -0.25,  1 )
 
  592               << QPointF( -0.25, -0.5 )
 
  593               << QPointF( -0.5,  -0.5 )
 
  598       polygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 ) << QPointF( 0, 0 );
 
  602       polygon << QPointF( -1, -0.2 )
 
  603               << QPointF( -1, -0.2 )
 
  604               << QPointF( -1, 0.2 )
 
  605               << QPointF( -0.2, 0.2 )
 
  606               << QPointF( -0.2, 1 )
 
  608               << QPointF( 0.2, 0.2 )
 
  610               << QPointF( 1, -0.2 )
 
  611               << QPointF( 0.2, -0.2 )
 
  612               << QPointF( 0.2, -1 )
 
  613               << QPointF( -0.2, -1 )
 
  614               << QPointF( -0.2, -0.2 )
 
  615               << QPointF( -1, -0.2 );
 
  620       static constexpr 
double THICKNESS = 0.3;
 
  621       static constexpr 
double HALF_THICKNESS = THICKNESS / 2.0;
 
  622       static constexpr 
double INTERSECTION_POINT = THICKNESS / M_SQRT2;
 
  623       static constexpr 
double DIAGONAL1 = M_SQRT1_2 - INTERSECTION_POINT * 0.5;
 
  624       static constexpr 
double DIAGONAL2 = M_SQRT1_2 + INTERSECTION_POINT * 0.5;
 
  626       polygon << QPointF( -HALF_THICKNESS, -1 )
 
  627               << QPointF( HALF_THICKNESS, -1 )
 
  628               << QPointF( HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
 
  629               << QPointF( DIAGONAL1, -DIAGONAL2 )
 
  630               << QPointF( DIAGONAL2, -DIAGONAL1 )
 
  631               << QPointF( HALF_THICKNESS + INTERSECTION_POINT, -HALF_THICKNESS )
 
  632               << QPointF( 1, -HALF_THICKNESS )
 
  633               << QPointF( 1, HALF_THICKNESS )
 
  634               << QPointF( HALF_THICKNESS + INTERSECTION_POINT, HALF_THICKNESS )
 
  635               << QPointF( DIAGONAL2, DIAGONAL1 )
 
  636               << QPointF( DIAGONAL1, DIAGONAL2 )
 
  637               << QPointF( HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
 
  638               << QPointF( HALF_THICKNESS, 1 )
 
  639               << QPointF( -HALF_THICKNESS, 1 )
 
  640               << QPointF( -HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
 
  641               << QPointF( -DIAGONAL1, DIAGONAL2 )
 
  642               << QPointF( -DIAGONAL2, DIAGONAL1 )
 
  643               << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, HALF_THICKNESS )
 
  644               << QPointF( -1, HALF_THICKNESS )
 
  645               << QPointF( -1, -HALF_THICKNESS )
 
  646               << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, -HALF_THICKNESS )
 
  647               << QPointF( -DIAGONAL2, -DIAGONAL1 )
 
  648               << QPointF( -DIAGONAL1, -DIAGONAL2 )
 
  649               << QPointF( -HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
 
  650               << QPointF( -HALF_THICKNESS, -1 );
 
  673   mPath = QPainterPath();
 
  679       mPath.addEllipse( QRectF( -1, -1, 2, 2 ) ); 
 
  683       mPath.arcTo( -1, -1, 2, 2, 0, 180 );
 
  684       mPath.lineTo( 0, 0 );
 
  688       mPath.arcTo( -1, -1, 2, 2, 90, 120 );
 
  689       mPath.lineTo( 0, 0 );
 
  693       mPath.arcTo( -1, -1, 2, 2, 90, 90 );
 
  694       mPath.lineTo( 0, 0 );
 
  698       mPath.moveTo( 1, 0 );
 
  699       mPath.arcTo( -1, -1, 2, 2, 0, 180 );
 
  703       mPath.moveTo( 0, -1 );
 
  704       mPath.arcTo( -1, -1, 2, 2, 90, 120 );
 
  708       mPath.moveTo( 0, -1 );
 
  709       mPath.arcTo( -1, -1, 2, 2, 90, 90 );
 
  713       mPath.moveTo( -1, 0 );
 
  714       mPath.lineTo( 1, 0 ); 
 
  715       mPath.moveTo( 0, -1 );
 
  716       mPath.lineTo( 0, 1 ); 
 
  720       mPath.moveTo( -1, -1 );
 
  721       mPath.lineTo( 1, 1 );
 
  722       mPath.moveTo( 1, -1 );
 
  723       mPath.lineTo( -1, 1 );
 
  727       mPath.moveTo( 0, -1 );
 
  728       mPath.lineTo( 0, 1 ); 
 
  732       mPath.moveTo( -1, -1 );
 
  733       mPath.lineTo( 0, 0 );
 
  734       mPath.lineTo( -1, 1 );
 
  762   double scaledSize = 
mSize;
 
  766   if ( hasDataDefinedSize )
 
  773   if ( hasDataDefinedSize && ok )
 
  778         scaledSize = std::sqrt( scaledSize );
 
  793   markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
 
  794   offset = QPointF( offsetX, offsetY );
 
  796   hasDataDefinedRotation = 
false;
 
  809     hasDataDefinedRotation = 
true;
 
  814   if ( hasDataDefinedRotation )
 
  843   , mStrokeColor( strokeColor )
 
  844   , mPenJoinStyle( penJoinStyle )
 
  861   if ( props.contains( QStringLiteral( 
"name" ) ) )
 
  865   if ( props.contains( QStringLiteral( 
"color" ) ) )
 
  867   if ( props.contains( QStringLiteral( 
"color_border" ) ) )
 
  872   else if ( props.contains( QStringLiteral( 
"outline_color" ) ) )
 
  876   else if ( props.contains( QStringLiteral( 
"line_color" ) ) )
 
  880   if ( props.contains( QStringLiteral( 
"joinstyle" ) ) )
 
  884   if ( props.contains( QStringLiteral( 
"size" ) ) )
 
  885     size = props[QStringLiteral( 
"size" )].toDouble();
 
  886   if ( props.contains( QStringLiteral( 
"angle" ) ) )
 
  887     angle = props[QStringLiteral( 
"angle" )].toDouble();
 
  888   if ( props.contains( QStringLiteral( 
"scale_method" ) ) )
 
  892   if ( props.contains( QStringLiteral( 
"offset" ) ) )
 
  894   if ( props.contains( QStringLiteral( 
"offset_unit" ) ) )
 
  896   if ( props.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
  898   if ( props.contains( QStringLiteral( 
"size_unit" ) ) )
 
  900   if ( props.contains( QStringLiteral( 
"size_map_unit_scale" ) ) )
 
  903   if ( props.contains( QStringLiteral( 
"outline_style" ) ) )
 
  907   else if ( props.contains( QStringLiteral( 
"line_style" ) ) )
 
  911   if ( props.contains( QStringLiteral( 
"outline_width" ) ) )
 
  913     m->
setStrokeWidth( props[QStringLiteral( 
"outline_width" )].toDouble() );
 
  915   else if ( props.contains( QStringLiteral( 
"line_width" ) ) )
 
  917     m->
setStrokeWidth( props[QStringLiteral( 
"line_width" )].toDouble() );
 
  919   if ( props.contains( QStringLiteral( 
"outline_width_unit" ) ) )
 
  923   if ( props.contains( QStringLiteral( 
"line_width_unit" ) ) )
 
  927   if ( props.contains( QStringLiteral( 
"outline_width_map_unit_scale" ) ) )
 
  932   if ( props.contains( QStringLiteral( 
"horizontal_anchor_point" ) ) )
 
  936   if ( props.contains( QStringLiteral( 
"vertical_anchor_point" ) ) )
 
  941   if ( props.contains( QStringLiteral( 
"cap_style" ) ) )
 
  954   return QStringLiteral( 
"SimpleMarker" );
 
  961   QColor brushColor = 
mColor;
 
  967   mBrush = QBrush( brushColor );
 
  968   mPen = QPen( penColor );
 
  978     selBrushColor.setAlphaF( context.
opacity() );
 
  979     selPenColor.setAlphaF( context.
opacity() );
 
  998     mCachedOpacity = context.
opacity();
 
 1004     mSelPen.setColor( selBrushColor );
 
 1036     scaledSize = ( std::abs( std::sin( 
mAngle * M_PI / 180 ) ) + std::abs( std::cos( 
mAngle * M_PI / 180 ) ) ) * scaledSize;
 
 1039   double pw = 
static_cast< int >( std::round( ( ( 
qgsDoubleNear( 
mPen.widthF(), 0.0 ) ? 1 : 
mPen.widthF() * 4 ) + 1 ) ) ) / 2 * 2; 
 
 1040   int imageSize = ( 
static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1; 
 
 1041   double center = imageSize / 2.0;
 
 1047   mCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
 
 1054   p.setRenderHint( QPainter::Antialiasing );
 
 1055   p.setBrush( needsBrush ? 
mBrush : Qt::NoBrush );
 
 1057   p.translate( QPointF( center, center ) );
 
 1065   mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
 
 1069   p.setRenderHint( QPainter::Antialiasing );
 
 1070   p.setBrush( needsBrush ? 
mSelBrush : Qt::NoBrush );
 
 1072   p.translate( QPointF( center, center ) );
 
 1083     p.setRenderHint( QPainter::Antialiasing );
 
 1084     p.fillRect( 0, 0, imageSize, imageSize, selColor );
 
 1085     p.setBrush( needsBrush ? 
mBrush : Qt::NoBrush );
 
 1087     p.translate( QPointF( center, center ) );
 
 1106   QColor brushColor = 
mColor;
 
 1107   brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
 
 1108   mBrush.setColor( brushColor );
 
 1111   penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
 
 1112   mPen.setColor( penColor );
 
 1121       c.setAlphaF( 
c.alphaF() * context.
opacity() );
 
 1131       c.setAlphaF( 
c.alphaF() * context.
opacity() );
 
 1183     p->setBrush( Qt::NoBrush );
 
 1187   if ( !polygon.isEmpty() )
 
 1188     p->drawPolygon( polygon );
 
 1190     p->drawPath( path );
 
 1207     double s = img.width();
 
 1209     bool hasDataDefinedSize = 
false;
 
 1210     double scaledSize = 
calculateSize( context, hasDataDefinedSize );
 
 1212     bool hasDataDefinedRotation = 
false;
 
 1217     p->drawImage( QRectF( point.x() - s / 2.0 + 
offset.x(),
 
 1218                           point.y() - s / 2.0 + 
offset.y(),
 
 1233   map[QStringLiteral( 
"size" )] = QString::number( 
mSize );
 
 1236   map[QStringLiteral( 
"angle" )] = QString::number( 
mAngle );
 
 1242   map[QStringLiteral( 
"outline_width" )] = QString::number( 
mStrokeWidth );
 
 1275   QDomElement graphicElem = doc.createElement( QStringLiteral( 
"se:Graphic" ) );
 
 1276   element.appendChild( graphicElem );
 
 1285   double angle = props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toDouble( &ok );
 
 1288     angleFunc = QStringLiteral( 
"%1 + %2" ).arg( props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toString() ).arg( 
mAngle );
 
 1303   Q_UNUSED( mmScaleFactor )
 
 1304   Q_UNUSED( mapUnitScaleFactor )
 
 1306   QString ogrType = 
"3"; 
 
 1307   if ( mName == 
"square" )
 
 1311   else if ( mName == 
"triangle" )
 
 1315   else if ( mName == 
"star" )
 
 1319   else if ( mName == 
"circle" )
 
 1323   else if ( mName == 
"cross" )
 
 1327   else if ( mName == 
"x" || mName == 
"cross2" )
 
 1331   else if ( mName == 
"line" )
 
 1337   ogrString.append( 
"SYMBOL(" );
 
 1338   ogrString.append( 
"id:" );
 
 1339   ogrString.append( 
'\"' );
 
 1340   ogrString.append( 
"ogr-sym-" );
 
 1341   ogrString.append( ogrType );
 
 1342   ogrString.append( 
'\"' );
 
 1343   ogrString.append( 
",c:" );
 
 1344   ogrString.append( 
mColor.name() );
 
 1345   ogrString.append( 
",o:" );
 
 1347   ogrString.append( QString( 
",s:%1mm" ).arg( 
mSize ) );
 
 1348   ogrString.append( 
')' );
 
 1353   ogrString.append( 
"PEN(" );
 
 1354   ogrString.append( 
"c:" );
 
 1355   ogrString.append( 
mColor.name() );
 
 1356   ogrString.append( 
",w:" );
 
 1357   ogrString.append( QString::number( 
mSize ) );
 
 1358   ogrString.append( 
"mm" );
 
 1359   ogrString.append( 
")" );
 
 1367   QDomElement graphicElem = element.firstChildElement( QStringLiteral( 
"Graphic" ) );
 
 1368   if ( graphicElem.isNull() )
 
 1371   QString name = QStringLiteral( 
"square" );
 
 1384     double d = angleFunc.toDouble( &ok );
 
 1394   QString uom = element.attribute( QStringLiteral( 
"uom" ) );
 
 1420     p->drawPath( 
mPath );
 
 1433   if ( hasDataDefinedSize )
 
 1454     size *= mmMapUnitScaleFactor;
 
 1461   double halfSize = 
size / 2.0;
 
 1478   QColor pc = 
mPen.color();
 
 1479   QColor bc = 
mBrush.color();
 
 1499   QPointF off( offsetX, offsetY );
 
 1528   t.translate( shift.x() + off.x(), shift.y() - off.y() );
 
 1536     t.scale( halfSize, -halfSize );
 
 1538     polygon = t.map( polygon );
 
 1541     p.reserve( polygon.size() );
 
 1542     for ( 
int i = 0; i < polygon.size(); i++ )
 
 1547     if ( 
mBrush.style() != Qt::NoBrush )
 
 1549     if ( 
mPen.style() != Qt::NoPen )
 
 1554     shift += QPointF( off.x(), -off.y() );
 
 1555     if ( 
mBrush.style() != Qt::NoBrush )
 
 1557     if ( 
mPen.style() != Qt::NoPen )
 
 1562     QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
 
 1563     QPointF pt2 = t.map( QPointF( 0, halfSize ) );
 
 1565     if ( 
mPen.style() != Qt::NoPen )
 
 1570     if ( 
mPen.style() != Qt::NoPen )
 
 1572       QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
 
 1573       QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
 
 1574       QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
 
 1575       QPointF pt4 = t.map( QPointF( 0, halfSize ) );
 
 1583     if ( 
mPen.style() != Qt::NoPen )
 
 1585       QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
 
 1586       QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
 
 1587       QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
 
 1588       QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
 
 1596     if ( 
mPen.style() != Qt::NoPen )
 
 1598       QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
 
 1599       QPointF pt2 = t.map( QPointF( 0, 0 ) );
 
 1600       QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
 
 1686   symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
 
 1687                        penWidth / 2.0, penWidth / 2.0 );
 
 1689   return symbolBounds;
 
 1738   if ( props.contains( QStringLiteral( 
"name" ) ) )
 
 1739     name = props[QStringLiteral( 
"name" )].toString();
 
 1740   if ( props.contains( QStringLiteral( 
"size" ) ) )
 
 1741     size = props[QStringLiteral( 
"size" )].toDouble();
 
 1742   if ( props.contains( QStringLiteral( 
"angle" ) ) )
 
 1743     angle = props[QStringLiteral( 
"angle" )].toDouble();
 
 1744   if ( props.contains( QStringLiteral( 
"scale_method" ) ) )
 
 1748   if ( props.contains( QStringLiteral( 
"offset" ) ) )
 
 1750   if ( props.contains( QStringLiteral( 
"offset_unit" ) ) )
 
 1752   if ( props.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
 1754   if ( props.contains( QStringLiteral( 
"size_unit" ) ) )
 
 1756   if ( props.contains( QStringLiteral( 
"size_map_unit_scale" ) ) )
 
 1758   if ( props.contains( QStringLiteral( 
"horizontal_anchor_point" ) ) )
 
 1762   if ( props.contains( QStringLiteral( 
"vertical_anchor_point" ) ) )
 
 1776   return QStringLiteral( 
"FilledMarker" );
 
 1801   map[QStringLiteral( 
"size" )] = QString::number( 
mSize );
 
 1804   map[QStringLiteral( 
"angle" )] = QString::number( 
mAngle );
 
 1860     attr.unite( mFill->usedAttributes( context ) );
 
 1868   if ( mFill && mFill->hasDataDefinedProperties() )
 
 1877     mFill->setColor( 
c );
 
 1882   return mFill ?  mFill->color() : 
mColor;
 
 1889          || ( mFill && mFill->usesMapUnits() );
 
 1903   const double prevOpacity = mFill->opacity();
 
 1904   mFill->setOpacity( mFill->opacity() * context.
opacity() );
 
 1908     p->setBrush( Qt::red );
 
 1912     p->setBrush( Qt::NoBrush );
 
 1914   p->setPen( Qt::black );
 
 1916   if ( !polygon.isEmpty() )
 
 1922     QPolygonF poly = path.toFillPolygon();
 
 1926   mFill->setOpacity( prevOpacity );
 
 1941   mColor = QColor( 35, 35, 35 );
 
 1955   if ( props.contains( QStringLiteral( 
"name" ) ) )
 
 1956     name = props[QStringLiteral( 
"name" )].toString();
 
 1957   if ( props.contains( QStringLiteral( 
"size" ) ) )
 
 1958     size = props[QStringLiteral( 
"size" )].toDouble();
 
 1959   if ( props.contains( QStringLiteral( 
"angle" ) ) )
 
 1960     angle = props[QStringLiteral( 
"angle" )].toDouble();
 
 1961   if ( props.contains( QStringLiteral( 
"scale_method" ) ) )
 
 1966   if ( props.contains( QStringLiteral( 
"size_unit" ) ) )
 
 1968   if ( props.contains( QStringLiteral( 
"size_map_unit_scale" ) ) )
 
 1970   if ( props.contains( QStringLiteral( 
"fixedAspectRatio" ) ) )
 
 1972   if ( props.contains( QStringLiteral( 
"offset" ) ) )
 
 1974   if ( props.contains( QStringLiteral( 
"offset_unit" ) ) )
 
 1976   if ( props.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
 1978   if ( props.contains( QStringLiteral( 
"fill" ) ) )
 
 1983   else if ( props.contains( QStringLiteral( 
"color" ) ) )
 
 1987   if ( props.contains( QStringLiteral( 
"outline" ) ) )
 
 1992   else if ( props.contains( QStringLiteral( 
"outline_color" ) ) )
 
 1996   else if ( props.contains( QStringLiteral( 
"line_color" ) ) )
 
 2001   if ( props.contains( QStringLiteral( 
"outline-width" ) ) )
 
 2004     m->
setStrokeWidth( props[QStringLiteral( 
"outline-width" )].toDouble() );
 
 2006   else if ( props.contains( QStringLiteral( 
"outline_width" ) ) )
 
 2008     m->
setStrokeWidth( props[QStringLiteral( 
"outline_width" )].toDouble() );
 
 2010   else if ( props.contains( QStringLiteral( 
"line_width" ) ) )
 
 2012     m->
setStrokeWidth( props[QStringLiteral( 
"line_width" )].toDouble() );
 
 2015   if ( props.contains( QStringLiteral( 
"outline_width_unit" ) ) )
 
 2019   else if ( props.contains( QStringLiteral( 
"line_width_unit" ) ) )
 
 2023   if ( props.contains( QStringLiteral( 
"outline_width_map_unit_scale" ) ) )
 
 2026   if ( props.contains( QStringLiteral( 
"horizontal_anchor_point" ) ) )
 
 2030   if ( props.contains( QStringLiteral( 
"vertical_anchor_point" ) ) )
 
 2039   if ( props.contains( QStringLiteral( 
"parameters" ) ) )
 
 2041     const QVariantMap 
parameters = props[QStringLiteral( 
"parameters" )].toMap();
 
 2050   QVariantMap::iterator it = 
properties.find( QStringLiteral( 
"name" ) );
 
 2069   QColor defaultFillColor, defaultStrokeColor;
 
 2071   bool hasFillOpacityParam = 
false, hasStrokeParam = 
false, hasStrokeWidthParam = 
false, hasStrokeOpacityParam = 
false;
 
 2072   bool hasDefaultFillColor = 
false, hasDefaultFillOpacity = 
false, hasDefaultStrokeColor = 
false, hasDefaultStrokeWidth = 
false, hasDefaultStrokeOpacity = 
false;
 
 2074       hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
 
 2075       hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
 
 2076       hasStrokeWidthParam, hasDefaultStrokeWidth, 
strokeWidth,
 
 2077       hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
 
 2079   double newFillOpacity = hasFillOpacityParam ? 
fillColor().alphaF() : 1.0;
 
 2080   double newStrokeOpacity = hasStrokeOpacityParam ? 
strokeColor().alphaF() : 1.0;
 
 2082   if ( hasDefaultFillColor )
 
 2084     defaultFillColor.setAlphaF( newFillOpacity );
 
 2087   if ( hasDefaultFillOpacity )
 
 2090     c.setAlphaF( fillOpacity );
 
 2093   if ( hasDefaultStrokeColor )
 
 2095     defaultStrokeColor.setAlphaF( newStrokeOpacity );
 
 2098   if ( hasDefaultStrokeWidth )
 
 2102   if ( hasDefaultStrokeOpacity )
 
 2105     c.setAlphaF( strokeOpacity );
 
 2119     double widthScaleFactor = 3.465;
 
 2122     mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
 
 2130   if ( aPreservedAspectRatio && !par )
 
 2134   else if ( !aPreservedAspectRatio && par )
 
 2149   return QStringLiteral( 
"SvgMarker" );
 
 2169   bool hasDataDefinedSize = 
false;
 
 2170   double scaledWidth = calculateSize( context, hasDataDefinedSize );
 
 2174   if ( 
static_cast< int >( width ) < 1 || 10000.0 < width )
 
 2181   bool hasDataDefinedAspectRatio = 
false;
 
 2225       scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
 
 2229   QPointF outputOffset;
 
 2231   calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset, 
angle );
 
 2233   p->translate( point + outputOffset );
 
 2239   bool fitsInCache = 
true;
 
 2240   bool usePict = 
true;
 
 2247     if ( fitsInCache && img.width() > 1 )
 
 2257         QImage transparentImage = img.copy();
 
 2259         p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
 
 2263         p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
 
 2268   if ( usePict || !fitsInCache )
 
 2270     p->setOpacity( context.
opacity() );
 
 2274     if ( pct.width() > 1 )
 
 2277       _fixQPictureDPI( p );
 
 2278       p->drawPicture( 0, 0, pct );
 
 2286 double QgsSvgMarkerSymbolLayer::calculateSize( 
QgsSymbolRenderContext &context, 
bool &hasDataDefinedSize )
 const 
 2288   double scaledSize = 
mSize;
 
 2292   if ( hasDataDefinedSize )
 
 2300     if ( hasDataDefinedSize )
 
 2307   if ( hasDataDefinedSize && ok )
 
 2312         scaledSize = std::sqrt( scaledSize );
 
 2325   if ( !hasDataDefinedAspectRatio )
 
 2335   double defaultHeight = 
mSize * scaledAspectRatio;
 
 2336   scaledAspectRatio = defaultHeight / scaledSize;
 
 2339   double scaledHeight = scaledSize * scaledAspectRatio;
 
 2346   if ( hasDataDefinedAspectRatio && ok )
 
 2351         scaledHeight = sqrt( scaledHeight );
 
 2358   scaledAspectRatio = scaledHeight / scaledSize;
 
 2360   return scaledAspectRatio;
 
 2363 void QgsSvgMarkerSymbolLayer::calculateOffsetAndRotation( 
QgsSymbolRenderContext &context, 
double scaledWidth, 
double scaledHeight, QPointF &offset, 
double &
angle )
 const 
 2368   markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
 
 2369   offset = QPointF( offsetX, offsetY );
 
 2379   if ( hasDataDefinedRotation )
 
 2405   map[QStringLiteral( 
"name" )] = 
mPath;
 
 2406   map[QStringLiteral( 
"size" )] = QString::number( 
mSize );
 
 2409   map[QStringLiteral( 
"fixedAspectRatio" )] = QString::number( 
mFixedAspectRatio );
 
 2410   map[QStringLiteral( 
"angle" )] = QString::number( 
mAngle );
 
 2417   map[QStringLiteral( 
"outline_width" )] = QString::number( 
mStrokeWidth );
 
 2492   QDomElement graphicElem = doc.createElement( QStringLiteral( 
"se:Graphic" ) );
 
 2493   element.appendChild( graphicElem );
 
 2503   double angle = props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toDouble( &ok );
 
 2506     angleFunc = QStringLiteral( 
"%1 + %2" ).arg( props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toString() ).arg( 
mAngle );
 
 2524   QDomElement graphicElem = element.firstChildElement( QStringLiteral( 
"Graphic" ) );
 
 2525   if ( graphicElem.isNull() )
 
 2528   QString 
path, mimeType;
 
 2535   QString uom = element.attribute( QStringLiteral( 
"uom" ) );
 
 2538   if ( mimeType != QLatin1String( 
"image/svg+xml" ) )
 
 2546     double d = angleFunc.toDouble( &ok );
 
 2572   if ( hasDataDefinedSize )
 
 2578   if ( hasDataDefinedSize && ok )
 
 2592     size *= mmMapUnitScaleFactor;
 
 2606   double offsetX = 
offset.x();
 
 2607   double offsetY = 
offset.y();
 
 2609   QPointF outputOffset( offsetX, offsetY );
 
 2659   QSvgRenderer r( svgContent );
 
 2666   QSizeF outSize( r.defaultSize() );
 
 2667   outSize.scale( 
size, 
size, Qt::KeepAspectRatio );
 
 2673     p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
 
 2675     p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
 
 2677   pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
 
 2678   pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
 
 2687   bool hasDataDefinedSize = 
false;
 
 2688   double scaledWidth = calculateSize( context, hasDataDefinedSize );
 
 2690   bool hasDataDefinedAspectRatio = 
false;
 
 2698   if ( 
static_cast< int >( scaledWidth ) < 1 || 10000.0 < scaledWidth )
 
 2703   QPointF outputOffset;
 
 2705   calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset, 
angle );
 
 2744       scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
 
 2748   QTransform transform;
 
 2750   transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
 
 2753     transform.rotate( 
angle );
 
 2758   QRectF symbolBounds = transform.mapRect( QRectF( -scaledWidth / 2.0,
 
 2759                         -scaledHeight / 2.0,
 
 2767   return symbolBounds;
 
 2791   if ( props.contains( QStringLiteral( 
"imageFile" ) ) )
 
 2792     path = props[QStringLiteral( 
"imageFile" )].toString();
 
 2793   if ( props.contains( QStringLiteral( 
"size" ) ) )
 
 2794     size = props[QStringLiteral( 
"size" )].toDouble();
 
 2795   if ( props.contains( QStringLiteral( 
"angle" ) ) )
 
 2796     angle = props[QStringLiteral( 
"angle" )].toDouble();
 
 2797   if ( props.contains( QStringLiteral( 
"scale_method" ) ) )
 
 2802   if ( props.contains( QStringLiteral( 
"alpha" ) ) )
 
 2804     m->
setOpacity( props[QStringLiteral( 
"alpha" )].toDouble() );
 
 2807   if ( props.contains( QStringLiteral( 
"size_unit" ) ) )
 
 2809   if ( props.contains( QStringLiteral( 
"size_map_unit_scale" ) ) )
 
 2811   if ( props.contains( QStringLiteral( 
"fixedAspectRatio" ) ) )
 
 2814   if ( props.contains( QStringLiteral( 
"offset" ) ) )
 
 2816   if ( props.contains( QStringLiteral( 
"offset_unit" ) ) )
 
 2818   if ( props.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
 2821   if ( props.contains( QStringLiteral( 
"horizontal_anchor_point" ) ) )
 
 2825   if ( props.contains( QStringLiteral( 
"vertical_anchor_point" ) ) )
 
 2838   QVariantMap::iterator it = 
properties.find( QStringLiteral( 
"name" ) );
 
 2839   if ( it != 
properties.end() && it.value().type() == QVariant::String )
 
 2857   if ( aPreservedAspectRatio && !par )
 
 2861   else if ( !aPreservedAspectRatio && par )
 
 2880   return QStringLiteral( 
"RasterMarker" );
 
 2896   if ( 
path.isEmpty() )
 
 2900   double height = 0.0;
 
 2902   bool hasDataDefinedSize = 
false;
 
 2903   double scaledSize = calculateSize( context, hasDataDefinedSize );
 
 2905   bool hasDataDefinedAspectRatio = 
false;
 
 2908   QPointF outputOffset;
 
 2915     if ( 
size.isEmpty() )
 
 2918     width = ( scaledSize * 
static_cast< double >( 
size.width() ) ) / 100.0;
 
 2919     height = ( scaledSize * 
static_cast< double >( 
size.height() ) ) / 100.0;
 
 2922     if ( 
static_cast< int >( width ) < 1 || 10000.0 < width || 
static_cast< int >( height ) < 1 || 10000.0 < height )
 
 2925     calculateOffsetAndRotation( context, width, height, outputOffset, 
angle );
 
 2935       if ( !
size.isNull() && 
size.isValid() && 
size.width() > 0 )
 
 2937         height = width * ( 
static_cast< double >( 
size.height() ) / 
static_cast< double >( 
size.width() ) );
 
 2942     if ( 
static_cast< int >( width ) < 1 || 10000.0 < width )
 
 2945     calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset, 
angle );
 
 2949   p->translate( point + outputOffset );
 
 2965   if ( !img.isNull() )
 
 2970     p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
 
 2974 double QgsRasterMarkerSymbolLayer::calculateSize( 
QgsSymbolRenderContext &context, 
bool &hasDataDefinedSize )
 const 
 2976   double scaledSize = 
mSize;
 
 2980   if ( hasDataDefinedSize )
 
 2988     if ( hasDataDefinedSize )
 
 2995   if ( hasDataDefinedSize && ok )
 
 3000         scaledSize = std::sqrt( scaledSize );
 
 3013   if ( !hasDataDefinedAspectRatio )
 
 3023   double defaultHeight = 
mSize * scaledAspectRatio;
 
 3024   scaledAspectRatio = defaultHeight / scaledSize;
 
 3027   double scaledHeight = scaledSize * scaledAspectRatio;
 
 3034   if ( hasDataDefinedAspectRatio && ok )
 
 3039         scaledHeight = sqrt( scaledHeight );
 
 3046   scaledAspectRatio = scaledHeight / scaledSize;
 
 3048   return scaledAspectRatio;
 
 3051 void QgsRasterMarkerSymbolLayer::calculateOffsetAndRotation( 
QgsSymbolRenderContext &context, 
double scaledWidth, 
double scaledHeight, QPointF &offset, 
double &
angle )
 const 
 3056   markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
 
 3057   offset = QPointF( offsetX, offsetY );
 
 3067   if ( hasDataDefinedRotation )
 
 3088   map[QStringLiteral( 
"imageFile" )] = 
mPath;
 
 3089   map[QStringLiteral( 
"size" )] = QString::number( 
mSize );
 
 3092   map[QStringLiteral( 
"fixedAspectRatio" )] = QString::number( 
mFixedAspectRatio );
 
 3093   map[QStringLiteral( 
"angle" )] = QString::number( 
mAngle );
 
 3094   map[QStringLiteral( 
"alpha" )] = QString::number( 
mOpacity );
 
 3139   bool hasDataDefinedSize = 
false;
 
 3140   double scaledSize = calculateSize( context, hasDataDefinedSize );
 
 3142   bool hasDataDefinedAspectRatio = 
false;
 
 3147   if ( 
static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
 
 3152   QPointF outputOffset;
 
 3154   calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset, 
angle );
 
 3156   QTransform transform;
 
 3159   transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
 
 3162     transform.rotate( 
angle );
 
 3164   QRectF symbolBounds = transform.mapRect( QRectF( -width / 2.0,
 
 3169   return symbolBounds;
 
 3181   mOrigSize = pointSize;
 
 3202   if ( props.contains( QStringLiteral( 
"font" ) ) )
 
 3203     fontFamily = props[QStringLiteral( 
"font" )].toString();
 
 3204   if ( props.contains( QStringLiteral( 
"chr" ) ) && props[QStringLiteral( 
"chr" )].toString().length() > 0 )
 
 3205     string = props[QStringLiteral( 
"chr" )].toString();
 
 3206   if ( props.contains( QStringLiteral( 
"size" ) ) )
 
 3207     pointSize = props[QStringLiteral( 
"size" )].toDouble();
 
 3208   if ( props.contains( QStringLiteral( 
"color" ) ) )
 
 3210   if ( props.contains( QStringLiteral( 
"angle" ) ) )
 
 3211     angle = props[QStringLiteral( 
"angle" )].toDouble();
 
 3215   if ( props.contains( QStringLiteral( 
"font_style" ) ) )
 
 3216     m->
setFontStyle( props[QStringLiteral( 
"font_style" )].toString() );
 
 3217   if ( props.contains( QStringLiteral( 
"outline_color" ) ) )
 
 3219   if ( props.contains( QStringLiteral( 
"outline_width" ) ) )
 
 3220     m->
setStrokeWidth( props[QStringLiteral( 
"outline_width" )].toDouble() );
 
 3221   if ( props.contains( QStringLiteral( 
"offset" ) ) )
 
 3223   if ( props.contains( QStringLiteral( 
"offset_unit" ) ) )
 
 3225   if ( props.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
 3227   if ( props.contains( QStringLiteral( 
"size_unit" ) ) )
 
 3229   if ( props.contains( QStringLiteral( 
"size_map_unit_scale" ) ) )
 
 3231   if ( props.contains( QStringLiteral( 
"outline_width_unit" ) ) )
 
 3233   if ( props.contains( QStringLiteral( 
"outline_width_map_unit_scale" ) ) )
 
 3235   if ( props.contains( QStringLiteral( 
"joinstyle" ) ) )
 
 3237   if ( props.contains( QStringLiteral( 
"horizontal_anchor_point" ) ) )
 
 3239   if ( props.contains( QStringLiteral( 
"vertical_anchor_point" ) ) )
 
 3249   return QStringLiteral( 
"FontMarker" );
 
 3254   QColor brushColor = 
mColor;
 
 3255   QColor penColor = mStrokeColor;
 
 3257   brushColor.setAlphaF( 
mColor.alphaF() * context.
opacity() );
 
 3258   penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
 
 3260   mBrush = QBrush( brushColor );
 
 3261   mPen = QPen( penColor );
 
 3262   mPen.setJoinStyle( mPenJoinStyle );
 
 3265   mFont = QFont( mFontFamily );
 
 3266   if ( !mFontStyle.isEmpty() )
 
 3274   if ( mNonZeroFontSize && sizePixels > MAX_FONT_CHARACTER_SIZE_IN_PIXELS )
 
 3279     mFontSizeScale = sizePixels / MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
 
 3280     sizePixels = MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
 
 3283     mFontSizeScale = 1.0;
 
 3287   mFont.setPixelSize( std::max( 2, 
static_cast< int >( std::round( sizePixels ) ) ) );
 
 3288   mFontMetrics.reset( 
new QFontMetrics( mFont ) );
 
 3289   mChrWidth = mFontMetrics->horizontalAdvance( mString );
 
 3290   mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
 
 3297   if ( mUseCachedPath )
 
 3299     QPointF chrOffset = mChrOffset;
 
 3301     QString charToRender = characterToRender( context, chrOffset, chrWidth );
 
 3302     mCachedPath = QPainterPath();
 
 3303     mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
 
 3312 QString QgsFontMarkerSymbolLayer::characterToRender( 
QgsSymbolRenderContext &context, QPointF &charOffset, 
double &charWidth )
 
 3314   charOffset = mChrOffset;
 
 3315   QString stringToRender = mString;
 
 3320     if ( stringToRender != mString )
 
 3322       charWidth = mFontMetrics->horizontalAdvance( stringToRender );
 
 3323       charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
 
 3326   return stringToRender;
 
 3331     bool &hasDataDefinedRotation,
 
 3333     double &
angle )
 const 
 3338   markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
 
 3339   offset = QPointF( offsetX, offsetY );
 
 3355   if ( hasDataDefinedRotation )
 
 3379   double scaledSize = 
mSize;
 
 3383   if ( hasDataDefinedSize )
 
 3389   if ( hasDataDefinedSize && ok )
 
 3394         scaledSize = std::sqrt( scaledSize );
 
 3406   if ( !p || !mNonZeroFontSize )
 
 3409   QTransform transform;
 
 3412   QColor brushColor = 
mColor;
 
 3421     brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
 
 3423   mBrush.setColor( brushColor );
 
 3425   QColor penColor = mStrokeColor;
 
 3431   penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
 
 3455   p->setBrush( mBrush );
 
 3458     mPen.setColor( penColor );
 
 3459     mPen.setWidthF( penWidth );
 
 3464     p->setPen( Qt::NoPen );
 
 3471     mFont.setFamily( ok ? 
fontFamily : mFontFamily );
 
 3481     mFontMetrics.reset( 
new QFontMetrics( mFont ) );
 
 3484   QPointF chrOffset = mChrOffset;
 
 3486   QString charToRender = characterToRender( context, chrOffset, chrWidth );
 
 3488   double sizeToRender = calculateSize( context );
 
 3490   bool hasDataDefinedRotation = 
false;
 
 3493   calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation, 
offset, 
angle );
 
 3495   p->translate( point.x() + 
offset.x(), point.y() + 
offset.y() );
 
 3498     transform.rotate( 
angle );
 
 3502     double s = sizeToRender / mOrigSize;
 
 3503     transform.scale( s, s );
 
 3507     transform.scale( mFontSizeScale, mFontSizeScale );
 
 3509   if ( mUseCachedPath )
 
 3511     p->drawPath( transform.map( mCachedPath ) );
 
 3516     path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
 
 3517     p->drawPath( transform.map( path ) );
 
 3524   props[QStringLiteral( 
"font" )] = mFontFamily;
 
 3525   props[QStringLiteral( 
"font_style" )] = mFontStyle;
 
 3526   props[QStringLiteral( 
"chr" )] = mString;
 
 3527   props[QStringLiteral( 
"size" )] = QString::number( 
mSize );
 
 3532   props[QStringLiteral( 
"outline_width" )] = QString::number( mStrokeWidth );
 
 3536   props[QStringLiteral( 
"angle" )] = QString::number( 
mAngle );
 
 3569   QDomElement graphicElem = doc.createElement( QStringLiteral( 
"se:Graphic" ) );
 
 3570   element.appendChild( graphicElem );
 
 3572   QString fontPath = QStringLiteral( 
"ttf://%1" ).arg( mFontFamily );
 
 3573   int markIndex = !mString.isEmpty() ? mString.at( 0 ).unicode() : 0;
 
 3580   double angle = props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toDouble( &ok );
 
 3583     angleFunc = QStringLiteral( 
"%1 + %2" ).arg( props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toString() ).arg( 
mAngle );
 
 3605   QPointF chrOffset = mChrOffset;
 
 3606   double chrWidth = mChrWidth;
 
 3608   ( void )characterToRender( context, chrOffset, chrWidth );
 
 3610   if ( !mFontMetrics )
 
 3611     mFontMetrics.reset( 
new QFontMetrics( mFont ) );
 
 3613   double scaledSize = calculateSize( context );
 
 3616     chrWidth *= scaledSize / mOrigSize;
 
 3618   chrWidth *= mFontSizeScale;
 
 3620   bool hasDataDefinedRotation = 
false;
 
 3623   calculateOffsetAndRotation( context, scaledSize, hasDataDefinedRotation, 
offset, 
angle );
 
 3626   QTransform transform;
 
 3629   transform.translate( point.x() + 
offset.x(), point.y() + 
offset.y() );
 
 3632     transform.rotate( 
angle );
 
 3634   QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
 
 3638   return symbolBounds;
 
 3645   QDomElement graphicElem = element.firstChildElement( QStringLiteral( 
"Graphic" ) );
 
 3646   if ( graphicElem.isNull() )
 
 3649   QString name, format;
 
 3657   if ( !name.startsWith( QLatin1String( 
"ttf://" ) ) || format != QLatin1String( 
"ttf" ) )
 
 3667     double d = angleFunc.toDouble( &ok );
 
 3675   QString uom = element.attribute( QStringLiteral( 
"uom" ) );
 
 3698   QMap<QString, QgsProperty>::iterator it = 
mParameters.begin();
 
 3710   QMap<QString, QgsProperty>::const_iterator it = 
mParameters.constBegin();
 
 3713     attrs.unite( it.value().referencedFields( context.
expressionContext(), 
true ) );
 
@ DynamicRotation
Rotation of symbol may be changed during rendering and symbol should not be cached.
ScaleMethod
Scale methods.
@ ScaleDiameter
Calculate scale by the diameter.
@ ScaleArea
Calculate scale by the area.
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
Exports QGIS layers to the DXF format.
void writeFilledCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius)
Write filled circle (as hatch)
void writeCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius, const QString &lineStyleName, double width)
Write circle (as polyline)
void writeLine(const QgsPoint &pt1, const QgsPoint &pt2, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Write line (as a polyline)
static double mapUnitScaleFactor(double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
void writePolygon(const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color)
Draw dxf filled polygon (HATCH)
double symbologyScale() const
Returns the reference scale for output.
void clipValueToMapUnitScale(double &value, const QgsMapUnitScale &scale, double pixelToMMFactor) const
Clips value to scale minimum/maximum.
void writePolyline(const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Draw dxf primitives (LWPOLYLINE)
A paint device for drawing into dxf files.
void setShift(QPointF shift)
void setLayer(const QString &layer)
void setOutputSize(const QRectF &r)
void setDrawingSize(QSizeF size)
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool hasGeometry() const
Returns true if the feature has an associated geometry.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbol.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QColor color() const override
The fill color.
QgsFilledMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
~QgsFilledMarkerSymbolLayer() override
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColor(const QColor &c) override
The fill color.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFilledMarkerSymbolLayer.
QgsFilledMarkerSymbolLayer(QgsSimpleMarkerSymbolLayerBase::Shape shape=Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsFilledMarkerSymbolLayer.
~QgsFontMarkerSymbolLayer() override
void setStrokeColor(const QColor &color) override
Set stroke color.
QgsFontMarkerSymbolLayer(const QString &fontFamily=DEFAULT_FONTMARKER_FONT, QString chr=DEFAULT_FONTMARKER_CHR, double pointSize=DEFAULT_FONTMARKER_SIZE, const QColor &color=DEFAULT_FONTMARKER_COLOR, double angle=DEFAULT_FONTMARKER_ANGLE)
Constructs a font marker symbol layer.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the stroke width map unit scale.
double strokeWidth() const
Returns the marker's stroke width.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void setFontStyle(const QString &style)
Sets the font style for the font which will be used to render the point.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QString fontStyle() const
Returns the font style for the associated font which will be used to render the point.
QString fontFamily() const
Returns the font family name for the associated font which will be used to render the point.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the stroke width unit.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
void setStrokeWidth(double width)
Set's the marker's stroke width.
static void resolveFonts(const QVariantMap &properties, const QgsReadWriteContext &context)
Resolves fonts from a properties map, raising warnings in the specified context if the required fonts...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the stroke join style.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsFontMarkerSymbolLayer from an SLD XML element.
QgsFontMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFontMarkerSymbolLayer from a property map (see properties())
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=nullptr, bool *match=nullptr)
Check whether font family is on system.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
QgsWkbTypes::GeometryType type
QSize originalSize(const QString &path, bool blocking=false) const
Returns the original size (in pixels) of the image at the specified path.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
static void adjustHueSaturation(QImage &image, double saturation, const QColor &colorizeColor=QColor(), double colorizeStrength=1.0)
Alter the hue or saturation of a QImage.
Perform transforms between map coordinates and device coordinates.
double mapUnitsPerPixel() const
Returns current map units per pixel.
double mapRotation() const
Returns current map rotation in degrees (clockwise)
Struct for storing maximum and minimum scales for measurements in map units.
Abstract base class for marker symbol layers.
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
double mLineAngle
Line rotation angle (see setLineAngle() for details)
HorizontalAnchorPoint
Symbol horizontal anchor points.
void setAngle(double angle)
Sets the rotation angle for the marker.
Qgis::ScaleMethod scaleMethod() const
Returns the method to use for scaling the marker's size.
QgsUnitTypes::RenderUnit mOffsetUnit
Offset units.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's size.
void setVerticalAnchorPoint(VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QPointF mOffset
Marker offset.
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
QgsMapUnitScale mapUnitScale() const override
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's size.
double size() const
Returns the symbol size.
QgsMapUnitScale mOffsetMapUnitScale
Offset map unit scale.
HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
Qgis::ScaleMethod mScaleMethod
Marker size scaling method.
QgsMapUnitScale mSizeMapUnitScale
Marker size map unit scale.
VerticalAnchorPoint
Symbol vertical anchor points.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's offset.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's offset.
double mAngle
Marker rotation angle, in degrees clockwise from north.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
void setMapUnitScale(const QgsMapUnitScale &scale) override
Resolves relative paths into absolute paths and vice versa.
Point geometry type, with support for z-dimension and m-values.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
Raster marker symbol layer class.
double mFixedAspectRatio
The marker fixed aspect ratio.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsMapUnitScale mapUnitScale() const override
void setOpacity(double opacity)
Set the marker opacity.
QString path() const
Returns the marker raster image path.
double calculateAspectRatio(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedAspectRatio) const
Calculates the marker aspect ratio between width and height.
QgsRasterMarkerSymbolLayer(const QString &path=QString(), double size=DEFAULT_SVGMARKER_SIZE, double angle=DEFAULT_SVGMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructs raster marker symbol layer with picture from given absolute path to a raster image file.
void setPath(const QString &path)
Set the marker raster image path.
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsRasterMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
~QgsRasterMarkerSymbolLayer() override
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a raster marker symbol layer from a string map of properties.
double mOpacity
The marker default opacity.
double updateDefaultAspectRatio()
Calculates the default marker aspect ratio between width and height.
double mDefaultAspectRatio
The marker default aspect ratio.
bool setPreservedAspectRatio(bool par)
Set preserved the marker aspect ratio between width and height.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QString layerType() const override
Returns a string that represents this layer type.
double opacity() const
Returns the marker opacity.
The class is used as a container of context for various read/write operations on other objects.
void pushMessage(const QString &message, Qgis::MessageLevel level=Qgis::MessageLevel::Warning) const
Append a message to the context.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
bool forceVectorOutput() const
Returns true if rendering operations should use vector operations instead of any faster raster shortc...
QColor selectionColor() const
Returns the color to use when rendering selected features.
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
Flags flags() const
Returns combination of flags used for rendering.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
Scoped object for saving and restoring a QPainter object's state.
Abstract base class for simple marker symbol layers.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
Shape mShape
Symbol shape.
void calculateOffsetAndRotation(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedRotation, QPointF &offset, double &angle) const
Calculates the marker offset and rotation.
bool prepareMarkerShape(Shape shape)
Prepares the layer for drawing the specified shape (QPolygonF version)
QPainterPath mPath
Painter path representing shape. If mPolygon is empty then the shape is stored in mPath.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
static bool shapeIsFilled(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Returns true if a symbol shape has a fill.
static QList< QgsSimpleMarkerSymbolLayerBase::Shape > availableShapes()
Returns a list of all available shape types.
QgsSimpleMarkerSymbolLayerBase::Shape shape() const
Returns the shape for the rendered marker symbol.
~QgsSimpleMarkerSymbolLayerBase() override
bool shapeToPolygon(Shape shape, QPolygonF &polygon) const
Creates a polygon representing the specified shape.
bool prepareMarkerPath(Shape symbol)
Prepares the layer for drawing the specified shape (QPainterPath version)
QPolygonF mPolygon
Polygon of points in shape. If polygon is empty then shape is using mPath.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
QgsSimpleMarkerSymbolLayerBase(QgsSimpleMarkerSymbolLayerBase::Shape shape=Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsSimpleMarkerSymbolLayerBase.
static QgsSimpleMarkerSymbolLayerBase::Shape decodeShape(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a shape name to the corresponding shape.
static QString encodeShape(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Encodes a shape to its string representation.
double calculateSize(QgsSymbolRenderContext &context, bool &hasDataDefinedSize) const
Calculates the desired size of the marker, considering data defined size overrides.
Shape
Marker symbol shapes.
@ ArrowHead
Right facing arrow head (unfilled, lines only)
@ QuarterArc
A line-only one quarter arc (since QGIS 3.20)
@ Octagon
Octagon (since QGIS 3.18)
@ ThirdCircle
One third circle (top left third)
@ CrossFill
Solid filled cross.
@ RightHalfTriangle
Right half of triangle.
@ SquareWithCorners
A square with diagonal corners (since QGIS 3.18)
@ LeftHalfTriangle
Left half of triangle.
@ QuarterSquare
Quarter square (top left quarter)
@ ArrowHeadFilled
Right facing filled arrow head.
@ Cross2
Rotated cross (lines only), "x" shape.
@ Cross
Cross (lines only)
@ EquilateralTriangle
Equilateral triangle.
@ HalfSquare
Half square (left half)
@ ThirdArc
A line-only one third arc (since QGIS 3.20)
@ QuarterCircle
Quarter circle (top left quarter)
@ SemiCircle
Semi circle (top half)
@ DiagonalHalfSquare
Diagonal half square (bottom left half)
@ AsteriskFill
A filled asterisk shape (since QGIS 3.18)
@ HalfArc
A line-only half arc (since QGIS 3.20)
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke.
QPen mSelPen
QPen to use as stroke of selected symbols.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit u)
Sets the unit for the width of the marker's stroke.
void setColor(const QColor &color) override
The fill color.
QColor mStrokeColor
Stroke color.
QImage mSelCache
Cached image of selected marker, if using cached version.
QImage mCache
Cached image of marker, if using cached version.
QBrush mSelBrush
QBrush to use as fill of selected symbols.
void setFillColor(const QColor &color) override
Set fill color.
Qt::PenJoinStyle penJoinStyle() const
Returns the marker's stroke join style (e.g., miter, bevel, etc).
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void drawMarker(QPainter *p, QgsSymbolRenderContext &context)
Draws the marker shape in the specified painter.
QPen mPen
QPen corresponding to marker's stroke style.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleMarkerSymbolLayer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void setMapUnitScale(const QgsMapUnitScale &scale) override
QColor color() const override
The fill color.
QgsMapUnitScale mapUnitScale() const override
Qt::PenStyle mStrokeStyle
Stroke style.
QgsSimpleMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSimpleMarkerSymbolLayer from an SLD XML element.
QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayerBase::Shape shape=Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD, const QColor &color=DEFAULT_SIMPLEMARKER_COLOR, const QColor &strokeColor=DEFAULT_SIMPLEMARKER_BORDERCOLOR, Qt::PenJoinStyle penJoinStyle=DEFAULT_SIMPLEMARKER_JOINSTYLE)
Constructor for QgsSimpleMarkerSymbolLayer.
~QgsSimpleMarkerSymbolLayer() override
Qt::PenCapStyle mPenCapStyle
Stroke pen cap style.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QString layerType() const override
Returns a string that represents this layer type.
double mStrokeWidth
Stroke width.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the width of the marker's stroke.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setStrokeStyle(Qt::PenStyle strokeStyle)
Sets the marker's stroke style (e.g., solid, dashed, etc)
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QColor fillColor() const override
Gets fill color.
QColor strokeColor() const override
Returns the marker's stroke color.
QBrush mBrush
QBrush corresponding to marker's fill style.
void setStrokeWidth(double w)
Sets the width of the marker's stroke.
void setStrokeColor(const QColor &color) override
Sets the marker's stroke color.
Qt::PenStyle strokeStyle() const
Returns the marker's stroke style (e.g., solid, dashed, etc)
QgsUnitTypes::RenderUnit mStrokeWidthUnit
Stroke width units.
bool mUsingCache
true if using cached images of markers for drawing.
void setPenCapStyle(Qt::PenCapStyle style)
Sets the marker's stroke cap style (e.g., flat, round, etc).
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
static const int MAXIMUM_CACHE_WIDTH
Maximum width/height of cache image.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
bool prepareCache(QgsSymbolRenderContext &context)
Prepares cache image.
QgsMapUnitScale mStrokeWidthMapUnitScale
Stroke width map unit scale.
double strokeWidth() const
Returns the width of the marker's stroke.
Qt::PenJoinStyle mPenJoinStyle
Stroke pen join style.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
QSizeF svgViewboxSize(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Calculates the viewbox size of a (possibly cached) SVG file.
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QPicture.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QImage.
QByteArray svgContent(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >(), bool *isMissingImage=nullptr)
Gets the SVG content corresponding to the given path.
QgsSvgMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QColor fillColor() const override
Gets fill color.
QgsMapUnitScale mapUnitScale() const override
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates the symbol.
double mDefaultAspectRatio
The marker default aspect ratio.
QgsUnitTypes::RenderUnit mStrokeWidthUnit
QString layerType() const override
Returns a string that represents this layer type.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QString path() const
Returns the marker SVG path.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
void setStrokeWidth(double w)
void prepareExpressions(const QgsSymbolRenderContext &context) override
Prepares all data defined property expressions for evaluation.
QMap< QString, QgsProperty > mParameters
bool setPreservedAspectRatio(bool par)
Set preserved the marker aspect ratio between width and height.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the stroke width.
double calculateAspectRatio(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedAspectRatio) const
Calculates the marker aspect ratio between width and height.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
static QgsSymbolLayer * createFromSld(QDomElement &element)
void setStrokeColor(const QColor &c) override
Set stroke color.
void setMapUnitScale(const QgsMapUnitScale &scale) override
double updateDefaultAspectRatio()
Calculates the default marker aspect ratio between width and height.
QColor strokeColor() const override
Gets stroke color.
void setFillColor(const QColor &color) override
Set fill color.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
double strokeWidth() const
QMap< QString, QgsProperty > parameters() const
Returns the dynamic SVG parameters.
QgsSvgMarkerSymbolLayer(const QString &path, double size=DEFAULT_SVGMARKER_SIZE, double angle=DEFAULT_SVGMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructs SVG marker symbol layer with picture from given absolute path to a SVG file.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
~QgsSvgMarkerSymbolLayer() override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QgsMapUnitScale mStrokeWidthMapUnitScale
void setParameters(const QMap< QString, QgsProperty > ¶meters)
Sets the dynamic SVG parameters.
double mFixedAspectRatio
The marker fixed aspect ratio.
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
void setPath(const QString &path)
Set the marker SVG path.
static bool externalMarkerFromSld(QDomElement &element, QString &path, QString &format, int &markIndex, QColor &color, double &size)
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsStringMap evaluatePropertiesMap(const QMap< QString, QgsProperty > &propertiesMap, const QgsExpressionContext &context)
Evaluates a map of properties using the given context and returns a variant map with evaluated expres...
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QColor decodeColor(const QString &str)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static double rescaleUom(double size, QgsUnitTypes::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
static Qgis::ScaleMethod decodeScaleMethod(const QString &str)
Decodes a symbol scale method from a string.
static QString encodePenCapStyle(Qt::PenCapStyle style)
static void externalMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format, int *markIndex=nullptr, const QColor &color=QColor(), double size=-1)
static double sizeInPixelsFromSldUom(const QString &uom, double size)
Returns the size scaled in pixels according to the uom attribute.
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
static QString encodeScaleMethod(Qgis::ScaleMethod scaleMethod)
Encodes a symbol scale method to a string.
static Qt::PenStyle decodePenStyle(const QString &str)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ PropertyCapStyle
Line cap style.
@ PropertyAngle
Symbol angle.
@ PropertySize
Symbol size.
@ PropertyJoinStyle
Line join style.
@ PropertyOpacity
Opacity.
@ PropertyCharacter
Character, eg for font marker symbol layers.
@ PropertyOffset
Symbol offset.
@ PropertyStrokeWidth
Stroke width.
@ PropertyFillColor
Fill color.
@ PropertyFontStyle
Font style.
@ PropertyHeight
Symbol height.
@ PropertyFontFamily
Font family.
@ PropertyName
Name, eg shape name for simple markers.
@ PropertyStrokeColor
Stroke color.
@ PropertyWidth
Symbol width.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
virtual QColor color() const
The fill color.
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
virtual void prepareExpressions(const QgsSymbolRenderContext &context)
Prepares all data defined property expressions for evaluation.
virtual void setColor(const QColor &color)
The fill color.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
QgsPropertyCollection mDataDefinedProperties
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QgsFields fields() const
Fields of the layer.
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
Qgis::SymbolRenderHints renderHints() const
Returns the rendering hint flags for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
const QgsFeature * feature() const
Returns the current feature being rendered.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
qreal opacity() const
Returns the opacity for the symbol.
Abstract base class for all rendered symbols.
Qgis::SymbolType type() const
Returns the symbol's type.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
RenderUnit
Rendering size units.
@ RenderUnknownUnit
Mixed or unknown units.
@ RenderMetersInMapUnits
Meters value as Map units.
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
@ RenderMillimeters
Millimeters.
@ RenderMapUnits
Map units.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QString > QgsStringMap
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
#define QgsDebugMsgLevel(str, level)
Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()
#define DEFAULT_FONTMARKER_JOINSTYLE
#define DEFAULT_RASTERMARKER_ANGLE
#define DEFAULT_RASTERMARKER_SIZE
#define DEFAULT_SVGMARKER_ANGLE
#define DEFAULT_SIMPLEMARKER_JOINSTYLE
#define DEFAULT_FONTMARKER_CHR
#define DEFAULT_SIMPLEMARKER_BORDERCOLOR
#define DEFAULT_SIMPLEMARKER_SIZE
#define DEFAULT_SIMPLEMARKER_NAME
#define DEFAULT_SIMPLEMARKER_ANGLE
#define DEFAULT_SVGMARKER_SIZE
#define DEFAULT_FONTMARKER_FONT
#define DEFAULT_FONTMARKER_BORDERCOLOR
#define DEFAULT_FONTMARKER_ANGLE
#define DEFAULT_FONTMARKER_COLOR
#define DEFAULT_FONTMARKER_SIZE
#define DEFAULT_SIMPLEMARKER_COLOR
#define DEFAULT_SCALE_METHOD