30 #include <QFontDatabase> 31 #include <QDesktopWidget> 50 static void _fixQPictureDPI( QPainter *p )
56 p->scale( static_cast< double >(
qt_defaultDpiX() ) / p->device()->logicalDpiX(),
57 static_cast< double >(
qt_defaultDpiY() ) / p->device()->logicalDpiY() );
60 static QColor _readColor(
QgsVectorLayer *layer,
const QString &property,
const QColor &defaultColor = Qt::black,
bool withAlpha =
true )
62 int r = layer->
customProperty( property +
'R', QVariant( defaultColor.red() ) ).toInt();
63 int g = layer->
customProperty( property +
'G', QVariant( defaultColor.green() ) ).toInt();
64 int b = layer->
customProperty( property +
'B', QVariant( defaultColor.blue() ) ).toInt();
65 int a = withAlpha ? layer->
customProperty( property +
'A', QVariant( defaultColor.alpha() ) ).toInt() : 255;
66 return QColor( r, g, b, a );
71 d =
new QgsTextBufferSettingsPrivate();
122 return d->sizeMapUnitScale;
127 d->sizeMapUnitScale = scale;
142 return d->fillBufferInterior;
147 d->fillBufferInterior = fill;
167 d->joinStyle = style;
182 return d->paintEffect.get();
187 d->paintEffect.reset( effect );
205 if ( exprVal.isValid() )
207 QString units = exprVal.toString();
208 if ( !units.isEmpty() )
232 QString blendstr = exprVal.toString().trimmed();
233 if ( !blendstr.isEmpty() )
240 QString joinstr = exprVal.toString().trimmed();
241 if ( !joinstr.isEmpty() )
251 double bufSize = layer->
customProperty( QStringLiteral(
"labeling/bufferSize" ), QVariant( 0.0 ) ).toDouble();
254 QVariant drawBuffer = layer->
customProperty( QStringLiteral(
"labeling/bufferDraw" ), QVariant() );
255 if ( drawBuffer.isValid() )
257 d->enabled = drawBuffer.toBool();
260 else if ( bufSize != 0.0 )
271 if ( layer->
customProperty( QStringLiteral(
"labeling/bufferSizeUnits" ) ).toString().isEmpty() )
273 bool bufferSizeInMapUnits = layer->
customProperty( QStringLiteral(
"labeling/bufferSizeInMapUnits" ) ).toBool();
281 if ( layer->
customProperty( QStringLiteral(
"labeling/bufferSizeMapUnitScale" ) ).toString().isEmpty() )
284 double oldMin = layer->
customProperty( QStringLiteral(
"labeling/bufferSizeMapUnitMinScale" ), 0.0 ).toDouble();
285 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
286 double oldMax = layer->
customProperty( QStringLiteral(
"labeling/bufferSizeMapUnitMaxScale" ), 0.0 ).toDouble();
287 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
293 d->color = _readColor( layer, QStringLiteral(
"labeling/bufferColor" ), Qt::white,
false );
294 if ( layer->
customProperty( QStringLiteral(
"labeling/bufferOpacity" ) ).toString().isEmpty() )
296 d->opacity = ( 1 - layer->
customProperty( QStringLiteral(
"labeling/bufferTransp" ) ).toInt() / 100.0 );
300 d->opacity = ( layer->
customProperty( QStringLiteral(
"labeling/bufferOpacity" ) ).toDouble() );
304 d->joinStyle =
static_cast< Qt::PenJoinStyle
>( layer->
customProperty( QStringLiteral(
"labeling/bufferJoinStyle" ), QVariant( Qt::RoundJoin ) ).toUInt() );
306 d->fillBufferInterior = !layer->
customProperty( QStringLiteral(
"labeling/bufferNoFill" ), QVariant(
false ) ).toBool();
308 if ( layer->
customProperty( QStringLiteral(
"labeling/bufferEffect" ) ).isValid() )
310 QDomDocument doc( QStringLiteral(
"effect" ) );
311 doc.setContent( layer->
customProperty( QStringLiteral(
"labeling/bufferEffect" ) ).toString() );
312 QDomElement effectElem = doc.firstChildElement( QStringLiteral(
"effect" ) ).firstChildElement( QStringLiteral(
"effect" ) );
321 QDomElement textBufferElem = elem.firstChildElement( QStringLiteral(
"text-buffer" ) );
322 double bufSize = textBufferElem.attribute( QStringLiteral(
"bufferSize" ), QStringLiteral(
"0" ) ).toDouble();
325 QVariant drawBuffer = textBufferElem.attribute( QStringLiteral(
"bufferDraw" ) );
326 if ( drawBuffer.isValid() )
328 d->enabled = drawBuffer.toBool();
331 else if ( bufSize != 0.0 )
342 if ( !textBufferElem.hasAttribute( QStringLiteral(
"bufferSizeUnits" ) ) )
344 bool bufferSizeInMapUnits = textBufferElem.attribute( QStringLiteral(
"bufferSizeInMapUnits" ) ).toInt();
352 if ( !textBufferElem.hasAttribute( QStringLiteral(
"bufferSizeMapUnitScale" ) ) )
355 double oldMin = textBufferElem.attribute( QStringLiteral(
"bufferSizeMapUnitMinScale" ), QStringLiteral(
"0" ) ).toDouble();
356 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
357 double oldMax = textBufferElem.attribute( QStringLiteral(
"bufferSizeMapUnitMaxScale" ), QStringLiteral(
"0" ) ).toDouble();
358 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
366 if ( !textBufferElem.hasAttribute( QStringLiteral(
"bufferOpacity" ) ) )
368 d->opacity = ( 1 - textBufferElem.attribute( QStringLiteral(
"bufferTransp" ) ).toInt() / 100.0 );
372 d->opacity = ( textBufferElem.attribute( QStringLiteral(
"bufferOpacity" ) ).toDouble() );
376 static_cast< QgsPainting::BlendMode >( textBufferElem.attribute( QStringLiteral(
"bufferBlendMode" ), QString::number(
QgsPainting::BlendNormal ) ).toUInt() ) );
377 d->joinStyle =
static_cast< Qt::PenJoinStyle
>( textBufferElem.attribute( QStringLiteral(
"bufferJoinStyle" ), QString::number( Qt::RoundJoin ) ).toUInt() );
378 d->fillBufferInterior = !textBufferElem.attribute( QStringLiteral(
"bufferNoFill" ), QStringLiteral(
"0" ) ).toInt();
379 QDomElement effectElem = textBufferElem.firstChildElement( QStringLiteral(
"effect" ) );
380 if ( !effectElem.isNull() )
389 QDomElement textBufferElem = doc.createElement( QStringLiteral(
"text-buffer" ) );
390 textBufferElem.setAttribute( QStringLiteral(
"bufferDraw" ), d->enabled );
391 textBufferElem.setAttribute( QStringLiteral(
"bufferSize" ), d->size );
395 textBufferElem.setAttribute( QStringLiteral(
"bufferNoFill" ), !d->fillBufferInterior );
396 textBufferElem.setAttribute( QStringLiteral(
"bufferOpacity" ), d->opacity );
397 textBufferElem.setAttribute( QStringLiteral(
"bufferJoinStyle" ), static_cast< unsigned int >( d->joinStyle ) );
400 d->paintEffect->saveProperties( doc, textBufferElem );
401 return textBufferElem;
411 d =
new QgsTextBackgroundSettingsPrivate();
463 return d->markerSymbol.get();
468 d->markerSymbol.reset( symbol );
503 return d->sizeMapUnitScale;
508 d->sizeMapUnitScale = scale;
513 return d->rotationType;
518 d->rotationType =
type;
543 return d->offsetUnits;
548 d->offsetUnits = units;
553 return d->offsetMapUnitScale;
558 d->offsetMapUnitScale = scale;
573 return d->radiiUnits;
578 d->radiiUnits = units;
583 return d->radiiMapUnitScale;
588 d->radiiMapUnitScale = scale;
618 d->fillColor = color;
623 return d->strokeColor;
628 d->strokeColor = color;
633 return d->strokeWidth;
638 d->strokeWidth = width;
643 return d->strokeWidthUnits;
648 d->strokeWidthUnits = units;
653 return d->strokeWidthMapUnitScale;
658 d->strokeWidthMapUnitScale = scale;
668 d->joinStyle = style;
673 return d->paintEffect.get();
678 d->paintEffect.reset( effect );
683 d->enabled = layer->
customProperty( QStringLiteral(
"labeling/shapeDraw" ), QVariant(
false ) ).toBool();
685 d->svgFile = layer->
customProperty( QStringLiteral(
"labeling/shapeSVGFile" ), QVariant(
"" ) ).toString();
687 d->size = QSizeF( layer->
customProperty( QStringLiteral(
"labeling/shapeSizeX" ), QVariant( 0.0 ) ).toDouble(),
688 layer->
customProperty( QStringLiteral(
"labeling/shapeSizeY" ), QVariant( 0.0 ) ).toDouble() );
690 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeSizeUnit" ) ).toString().isEmpty() )
699 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeSizeMapUnitScale" ) ).toString().isEmpty() )
702 double oldMin = layer->
customProperty( QStringLiteral(
"labeling/shapeSizeMapUnitMinScale" ), 0.0 ).toDouble();
703 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
704 double oldMax = layer->
customProperty( QStringLiteral(
"labeling/shapeSizeMapUnitMaxScale" ), 0.0 ).toDouble();
705 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
712 d->rotation = layer->
customProperty( QStringLiteral(
"labeling/shapeRotation" ), QVariant( 0.0 ) ).toDouble();
713 d->offset = QPointF( layer->
customProperty( QStringLiteral(
"labeling/shapeOffsetX" ), QVariant( 0.0 ) ).toDouble(),
714 layer->
customProperty( QStringLiteral(
"labeling/shapeOffsetY" ), QVariant( 0.0 ) ).toDouble() );
716 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeOffsetUnit" ) ).toString().isEmpty() )
725 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeOffsetMapUnitScale" ) ).toString().isEmpty() )
728 double oldMin = layer->
customProperty( QStringLiteral(
"labeling/shapeOffsetMapUnitMinScale" ), 0.0 ).toDouble();
729 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
730 double oldMax = layer->
customProperty( QStringLiteral(
"labeling/shapeOffsetMapUnitMaxScale" ), 0.0 ).toDouble();
731 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
737 d->radii = QSizeF( layer->
customProperty( QStringLiteral(
"labeling/shapeRadiiX" ), QVariant( 0.0 ) ).toDouble(),
738 layer->
customProperty( QStringLiteral(
"labeling/shapeRadiiY" ), QVariant( 0.0 ) ).toDouble() );
741 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeRadiiUnit" ) ).toString().isEmpty() )
750 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeRadiiMapUnitScale" ) ).toString().isEmpty() )
753 double oldMin = layer->
customProperty( QStringLiteral(
"labeling/shapeRadiiMapUnitMinScale" ), 0.0 ).toDouble();
754 d->radiiMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
755 double oldMax = layer->
customProperty( QStringLiteral(
"labeling/shapeRadiiMapUnitMaxScale" ), 0.0 ).toDouble();
756 d->radiiMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
762 d->fillColor = _readColor( layer, QStringLiteral(
"labeling/shapeFillColor" ), Qt::white,
true );
763 d->strokeColor = _readColor( layer, QStringLiteral(
"labeling/shapeBorderColor" ), Qt::darkGray,
true );
764 d->strokeWidth = layer->
customProperty( QStringLiteral(
"labeling/shapeBorderWidth" ), QVariant( .0 ) ).toDouble();
765 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeBorderWidthUnit" ) ).toString().isEmpty() )
773 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeBorderWidthMapUnitScale" ) ).toString().isEmpty() )
776 double oldMin = layer->
customProperty( QStringLiteral(
"labeling/shapeBorderWidthMapUnitMinScale" ), 0.0 ).toDouble();
777 d->strokeWidthMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
778 double oldMax = layer->
customProperty( QStringLiteral(
"labeling/shapeBorderWidthMapUnitMaxScale" ), 0.0 ).toDouble();
779 d->strokeWidthMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
785 d->joinStyle =
static_cast< Qt::PenJoinStyle
>( layer->
customProperty( QStringLiteral(
"labeling/shapeJoinStyle" ), QVariant( Qt::BevelJoin ) ).toUInt() );
787 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeOpacity" ) ).toString().isEmpty() )
789 d->opacity = ( 1 - layer->
customProperty( QStringLiteral(
"labeling/shapeTransparency" ) ).toInt() / 100.0 );
793 d->opacity = ( layer->
customProperty( QStringLiteral(
"labeling/shapeOpacity" ) ).toDouble() );
798 if ( layer->
customProperty( QStringLiteral(
"labeling/shapeEffect" ) ).isValid() )
800 QDomDocument doc( QStringLiteral(
"effect" ) );
801 doc.setContent( layer->
customProperty( QStringLiteral(
"labeling/shapeEffect" ) ).toString() );
802 QDomElement effectElem = doc.firstChildElement( QStringLiteral(
"effect" ) ).firstChildElement( QStringLiteral(
"effect" ) );
811 QDomElement backgroundElem = elem.firstChildElement( QStringLiteral(
"background" ) );
812 d->enabled = backgroundElem.attribute( QStringLiteral(
"shapeDraw" ), QStringLiteral(
"0" ) ).toInt();
813 d->type =
static_cast< ShapeType >( backgroundElem.attribute( QStringLiteral(
"shapeType" ), QString::number(
ShapeRectangle ) ).toUInt() );
815 d->sizeType =
static_cast< SizeType >( backgroundElem.attribute( QStringLiteral(
"shapeSizeType" ), QString::number(
SizeBuffer ) ).toUInt() );
816 d->size = QSizeF( backgroundElem.attribute( QStringLiteral(
"shapeSizeX" ), QStringLiteral(
"0" ) ).toDouble(),
817 backgroundElem.attribute( QStringLiteral(
"shapeSizeY" ), QStringLiteral(
"0" ) ).toDouble() );
819 if ( !backgroundElem.hasAttribute( QStringLiteral(
"shapeSizeUnit" ) ) )
821 d->sizeUnits =
convertFromOldLabelUnit( backgroundElem.attribute( QStringLiteral(
"shapeSizeUnits" ) ).toUInt() );
828 if ( !backgroundElem.hasAttribute( QStringLiteral(
"shapeSizeMapUnitScale" ) ) )
831 double oldMin = backgroundElem.attribute( QStringLiteral(
"shapeSizeMapUnitMinScale" ), QStringLiteral(
"0" ) ).toDouble();
832 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
833 double oldMax = backgroundElem.attribute( QStringLiteral(
"shapeSizeMapUnitMaxScale" ), QStringLiteral(
"0" ) ).toDouble();
834 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
840 d->rotationType =
static_cast< RotationType >( backgroundElem.attribute( QStringLiteral(
"shapeRotationType" ), QString::number(
RotationSync ) ).toUInt() );
841 d->rotation = backgroundElem.attribute( QStringLiteral(
"shapeRotation" ), QStringLiteral(
"0" ) ).toDouble();
842 d->offset = QPointF( backgroundElem.attribute( QStringLiteral(
"shapeOffsetX" ), QStringLiteral(
"0" ) ).toDouble(),
843 backgroundElem.attribute( QStringLiteral(
"shapeOffsetY" ), QStringLiteral(
"0" ) ).toDouble() );
845 if ( !backgroundElem.hasAttribute( QStringLiteral(
"shapeOffsetUnit" ) ) )
847 d->offsetUnits =
convertFromOldLabelUnit( backgroundElem.attribute( QStringLiteral(
"shapeOffsetUnits" ) ).toUInt() );
854 if ( !backgroundElem.hasAttribute( QStringLiteral(
"shapeOffsetMapUnitScale" ) ) )
857 double oldMin = backgroundElem.attribute( QStringLiteral(
"shapeOffsetMapUnitMinScale" ), QStringLiteral(
"0" ) ).toDouble();
858 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
859 double oldMax = backgroundElem.attribute( QStringLiteral(
"shapeOffsetMapUnitMaxScale" ), QStringLiteral(
"0" ) ).toDouble();
860 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
866 d->radii = QSizeF( backgroundElem.attribute( QStringLiteral(
"shapeRadiiX" ), QStringLiteral(
"0" ) ).toDouble(),
867 backgroundElem.attribute( QStringLiteral(
"shapeRadiiY" ), QStringLiteral(
"0" ) ).toDouble() );
869 if ( !backgroundElem.hasAttribute( QStringLiteral(
"shapeRadiiUnit" ) ) )
871 d->radiiUnits =
convertFromOldLabelUnit( backgroundElem.attribute( QStringLiteral(
"shapeRadiiUnits" ) ).toUInt() );
877 if ( !backgroundElem.hasAttribute( QStringLiteral(
"shapeRadiiMapUnitScale" ) ) )
880 double oldMin = backgroundElem.attribute( QStringLiteral(
"shapeRadiiMapUnitMinScale" ), QStringLiteral(
"0" ) ).toDouble();
881 d->radiiMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
882 double oldMax = backgroundElem.attribute( QStringLiteral(
"shapeRadiiMapUnitMaxScale" ), QStringLiteral(
"0" ) ).toDouble();
883 d->radiiMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
891 d->strokeWidth = backgroundElem.attribute( QStringLiteral(
"shapeBorderWidth" ), QStringLiteral(
"0" ) ).toDouble();
893 if ( !backgroundElem.hasAttribute( QStringLiteral(
"shapeBorderWidthUnit" ) ) )
895 d->strokeWidthUnits =
convertFromOldLabelUnit( backgroundElem.attribute( QStringLiteral(
"shapeBorderWidthUnits" ) ).toUInt() );
901 if ( !backgroundElem.hasAttribute( QStringLiteral(
"shapeBorderWidthMapUnitScale" ) ) )
904 double oldMin = backgroundElem.attribute( QStringLiteral(
"shapeBorderWidthMapUnitMinScale" ), QStringLiteral(
"0" ) ).toDouble();
905 d->strokeWidthMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
906 double oldMax = backgroundElem.attribute( QStringLiteral(
"shapeBorderWidthMapUnitMaxScale" ), QStringLiteral(
"0" ) ).toDouble();
907 d->strokeWidthMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
913 d->joinStyle =
static_cast< Qt::PenJoinStyle
>( backgroundElem.attribute( QStringLiteral(
"shapeJoinStyle" ), QString::number( Qt::BevelJoin ) ).toUInt() );
915 if ( !backgroundElem.hasAttribute( QStringLiteral(
"shapeOpacity" ) ) )
917 d->opacity = ( 1 - backgroundElem.attribute( QStringLiteral(
"shapeTransparency" ) ).toInt() / 100.0 );
921 d->opacity = ( backgroundElem.attribute( QStringLiteral(
"shapeOpacity" ) ).toDouble() );
925 static_cast< QgsPainting::BlendMode >( backgroundElem.attribute( QStringLiteral(
"shapeBlendMode" ), QString::number(
QgsPainting::BlendNormal ) ).toUInt() ) );
927 QDomElement effectElem = backgroundElem.firstChildElement( QStringLiteral(
"effect" ) );
928 if ( !effectElem.isNull() )
933 const QDomElement symbolElem = backgroundElem.firstChildElement( QStringLiteral(
"symbol" ) );
934 if ( !symbolElem.isNull() )
935 setMarkerSymbol( QgsSymbolLayerUtils::loadSymbol< QgsMarkerSymbol >( symbolElem, context ) );
942 QDomElement backgroundElem = doc.createElement( QStringLiteral(
"background" ) );
943 backgroundElem.setAttribute( QStringLiteral(
"shapeDraw" ), d->enabled );
944 backgroundElem.setAttribute( QStringLiteral(
"shapeType" ), static_cast< unsigned int >( d->type ) );
946 backgroundElem.setAttribute( QStringLiteral(
"shapeSizeType" ), static_cast< unsigned int >( d->sizeType ) );
947 backgroundElem.setAttribute( QStringLiteral(
"shapeSizeX" ), d->size.width() );
948 backgroundElem.setAttribute( QStringLiteral(
"shapeSizeY" ), d->size.height() );
951 backgroundElem.setAttribute( QStringLiteral(
"shapeRotationType" ), static_cast< unsigned int >( d->rotationType ) );
952 backgroundElem.setAttribute( QStringLiteral(
"shapeRotation" ), d->rotation );
953 backgroundElem.setAttribute( QStringLiteral(
"shapeOffsetX" ), d->offset.x() );
954 backgroundElem.setAttribute( QStringLiteral(
"shapeOffsetY" ), d->offset.y() );
957 backgroundElem.setAttribute( QStringLiteral(
"shapeRadiiX" ), d->radii.width() );
958 backgroundElem.setAttribute( QStringLiteral(
"shapeRadiiY" ), d->radii.height() );
963 backgroundElem.setAttribute( QStringLiteral(
"shapeBorderWidth" ), d->strokeWidth );
964 backgroundElem.setAttribute( QStringLiteral(
"shapeBorderWidthUnit" ),
QgsUnitTypes::encodeUnit( d->strokeWidthUnits ) );
966 backgroundElem.setAttribute( QStringLiteral(
"shapeJoinStyle" ), static_cast< unsigned int >( d->joinStyle ) );
967 backgroundElem.setAttribute( QStringLiteral(
"shapeOpacity" ), d->opacity );
970 d->paintEffect->saveProperties( doc, backgroundElem );
972 if ( d->markerSymbol )
975 return backgroundElem;
998 if ( exprVal.isValid() )
1000 QString units = exprVal.toString();
1001 if ( !units.isEmpty() )
1011 if ( exprVal.isValid() )
1013 const QString skind = exprVal.toString().trimmed();
1014 if ( !skind.isEmpty() )
1021 if ( exprVal.isValid() )
1023 QString stype = exprVal.toString().trimmed();
1024 if ( !stype.isEmpty() )
1033 if ( exprVal.isValid() )
1035 QString svgfile = exprVal.toString().trimmed();
1045 if ( exprVal.isValid() )
1047 QString rotstr = exprVal.toString().trimmed();
1048 if ( !rotstr.isEmpty() )
1055 if ( exprVal.isValid() )
1065 if ( exprVal.isValid() )
1067 QString units = exprVal.toString();
1068 if ( !units.isEmpty() )
1073 d->offsetUnits = res;
1078 if ( exprVal.isValid() )
1089 if ( exprVal.isValid() )
1091 QString units = exprVal.toString();
1092 if ( !units.isEmpty() )
1097 d->radiiUnits = res;
1124 if ( exprVal.isValid() )
1126 QString units = exprVal.toString();
1127 if ( !units.isEmpty() )
1132 d->strokeWidthUnits = res;
1139 QString blendstr = exprVal.toString().trimmed();
1140 if ( !blendstr.isEmpty() )
1147 QString joinstr = exprVal.toString().trimmed();
1148 if ( !joinstr.isEmpty() )
1162 d =
new QgsTextShadowSettingsPrivate();
1194 return d->shadowUnder;
1199 d->shadowUnder = placement;
1204 return d->offsetAngle;
1209 d->offsetAngle =
angle;
1214 return d->offsetDist;
1219 d->offsetDist = distance;
1224 return d->offsetUnits;
1229 d->offsetUnits = units;
1234 return d->offsetMapUnitScale;
1239 d->offsetMapUnitScale =
scale;
1244 return d->offsetGlobal;
1249 d->offsetGlobal = global;
1264 return d->radiusUnits;
1269 d->radiusUnits = units;
1274 return d->radiusMapUnitScale;
1279 d->radiusMapUnitScale =
scale;
1284 return d->radiusAlphaOnly;
1289 d->radiusAlphaOnly = alphaOnly;
1324 return d->blendMode;
1329 d->blendMode = mode;
1334 d->enabled = layer->
customProperty( QStringLiteral(
"labeling/shadowDraw" ), QVariant(
false ) ).toBool();
1336 d->offsetAngle = layer->
customProperty( QStringLiteral(
"labeling/shadowOffsetAngle" ), QVariant( 135 ) ).toInt();
1337 d->offsetDist = layer->
customProperty( QStringLiteral(
"labeling/shadowOffsetDist" ), QVariant( 1.0 ) ).toDouble();
1339 if ( layer->
customProperty( QStringLiteral(
"labeling/shadowOffsetUnit" ) ).toString().isEmpty() )
1347 if ( layer->
customProperty( QStringLiteral(
"labeling/shadowOffsetMapUnitScale" ) ).toString().isEmpty() )
1350 double oldMin = layer->
customProperty( QStringLiteral(
"labeling/shadowOffsetMapUnitMinScale" ), 0.0 ).toDouble();
1351 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
1352 double oldMax = layer->
customProperty( QStringLiteral(
"labeling/shadowOffsetMapUnitMaxScale" ), 0.0 ).toDouble();
1353 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
1359 d->offsetGlobal = layer->
customProperty( QStringLiteral(
"labeling/shadowOffsetGlobal" ), QVariant(
true ) ).toBool();
1360 d->radius = layer->
customProperty( QStringLiteral(
"labeling/shadowRadius" ), QVariant( 1.5 ) ).toDouble();
1362 if ( layer->
customProperty( QStringLiteral(
"labeling/shadowRadiusUnit" ) ).toString().isEmpty() )
1370 if ( layer->
customProperty( QStringLiteral(
"labeling/shadowRadiusMapUnitScale" ) ).toString().isEmpty() )
1373 double oldMin = layer->
customProperty( QStringLiteral(
"labeling/shadowRadiusMapUnitMinScale" ), 0.0 ).toDouble();
1374 d->radiusMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
1375 double oldMax = layer->
customProperty( QStringLiteral(
"labeling/shadowRadiusMapUnitMaxScale" ), 0.0 ).toDouble();
1376 d->radiusMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
1382 d->radiusAlphaOnly = layer->
customProperty( QStringLiteral(
"labeling/shadowRadiusAlphaOnly" ), QVariant(
false ) ).toBool();
1384 if ( layer->
customProperty( QStringLiteral(
"labeling/shadowOpacity" ) ).toString().isEmpty() )
1386 d->opacity = ( 1 - layer->
customProperty( QStringLiteral(
"labeling/shadowTransparency" ) ).toInt() / 100.0 );
1390 d->opacity = ( layer->
customProperty( QStringLiteral(
"labeling/shadowOpacity" ) ).toDouble() );
1392 d->scale = layer->
customProperty( QStringLiteral(
"labeling/shadowScale" ), QVariant( 100 ) ).toInt();
1393 d->color = _readColor( layer, QStringLiteral(
"labeling/shadowColor" ), Qt::black,
false );
1400 QDomElement shadowElem = elem.firstChildElement( QStringLiteral(
"shadow" ) );
1401 d->enabled = shadowElem.attribute( QStringLiteral(
"shadowDraw" ), QStringLiteral(
"0" ) ).toInt();
1402 d->shadowUnder =
static_cast< ShadowPlacement >( shadowElem.attribute( QStringLiteral(
"shadowUnder" ), QString::number(
ShadowLowest ) ).toUInt() );
1403 d->offsetAngle = shadowElem.attribute( QStringLiteral(
"shadowOffsetAngle" ), QStringLiteral(
"135" ) ).toInt();
1404 d->offsetDist = shadowElem.attribute( QStringLiteral(
"shadowOffsetDist" ), QStringLiteral(
"1" ) ).toDouble();
1406 if ( !shadowElem.hasAttribute( QStringLiteral(
"shadowOffsetUnit" ) ) )
1408 d->offsetUnits =
convertFromOldLabelUnit( shadowElem.attribute( QStringLiteral(
"shadowOffsetUnits" ) ).toUInt() );
1415 if ( !shadowElem.hasAttribute( QStringLiteral(
"shadowOffsetMapUnitScale" ) ) )
1418 double oldMin = shadowElem.attribute( QStringLiteral(
"shadowOffsetMapUnitMinScale" ), QStringLiteral(
"0" ) ).toDouble();
1419 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
1420 double oldMax = shadowElem.attribute( QStringLiteral(
"shadowOffsetMapUnitMaxScale" ), QStringLiteral(
"0" ) ).toDouble();
1421 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
1427 d->offsetGlobal = shadowElem.attribute( QStringLiteral(
"shadowOffsetGlobal" ), QStringLiteral(
"1" ) ).toInt();
1428 d->radius = shadowElem.attribute( QStringLiteral(
"shadowRadius" ), QStringLiteral(
"1.5" ) ).toDouble();
1430 if ( !shadowElem.hasAttribute( QStringLiteral(
"shadowRadiusUnit" ) ) )
1432 d->radiusUnits =
convertFromOldLabelUnit( shadowElem.attribute( QStringLiteral(
"shadowRadiusUnits" ) ).toUInt() );
1438 if ( !shadowElem.hasAttribute( QStringLiteral(
"shadowRadiusMapUnitScale" ) ) )
1441 double oldMin = shadowElem.attribute( QStringLiteral(
"shadowRadiusMapUnitMinScale" ), QStringLiteral(
"0" ) ).toDouble();
1442 d->radiusMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
1443 double oldMax = shadowElem.attribute( QStringLiteral(
"shadowRadiusMapUnitMaxScale" ), QStringLiteral(
"0" ) ).toDouble();
1444 d->radiusMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
1450 d->radiusAlphaOnly = shadowElem.attribute( QStringLiteral(
"shadowRadiusAlphaOnly" ), QStringLiteral(
"0" ) ).toInt();
1452 if ( !shadowElem.hasAttribute( QStringLiteral(
"shadowOpacity" ) ) )
1454 d->opacity = ( 1 - shadowElem.attribute( QStringLiteral(
"shadowTransparency" ) ).toInt() / 100.0 );
1458 d->opacity = ( shadowElem.attribute( QStringLiteral(
"shadowOpacity" ) ).toDouble() );
1460 d->scale = shadowElem.attribute( QStringLiteral(
"shadowScale" ), QStringLiteral(
"100" ) ).toInt();
1463 static_cast< QgsPainting::BlendMode >( shadowElem.attribute( QStringLiteral(
"shadowBlendMode" ), QString::number(
QgsPainting::BlendMultiply ) ).toUInt() ) );
1468 QDomElement shadowElem = doc.createElement( QStringLiteral(
"shadow" ) );
1469 shadowElem.setAttribute( QStringLiteral(
"shadowDraw" ), d->enabled );
1470 shadowElem.setAttribute( QStringLiteral(
"shadowUnder" ), static_cast< unsigned int >( d->shadowUnder ) );
1471 shadowElem.setAttribute( QStringLiteral(
"shadowOffsetAngle" ), d->offsetAngle );
1472 shadowElem.setAttribute( QStringLiteral(
"shadowOffsetDist" ), d->offsetDist );
1475 shadowElem.setAttribute( QStringLiteral(
"shadowOffsetGlobal" ), d->offsetGlobal );
1476 shadowElem.setAttribute( QStringLiteral(
"shadowRadius" ), d->radius );
1479 shadowElem.setAttribute( QStringLiteral(
"shadowRadiusAlphaOnly" ), d->radiusAlphaOnly );
1480 shadowElem.setAttribute( QStringLiteral(
"shadowOpacity" ), d->opacity );
1481 shadowElem.setAttribute( QStringLiteral(
"shadowScale" ), d->scale );
1497 if ( exprVal.isValid() )
1499 QString str = exprVal.toString().trimmed();
1500 if ( !str.isEmpty() )
1518 if ( exprVal.isValid() )
1520 QString units = exprVal.toString();
1521 if ( !units.isEmpty() )
1526 d->offsetUnits = res;
1537 if ( exprVal.isValid() )
1539 QString units = exprVal.toString();
1540 if ( !units.isEmpty() )
1545 d->radiusUnits = res;
1570 QString blendstr = exprVal.toString().trimmed();
1571 if ( !blendstr.isEmpty() )
1582 d =
new QgsTextMaskSettingsPrivate();
1641 return d->sizeMapUnitScale;
1646 d->sizeMapUnitScale = scale;
1651 return d->joinStyle;
1656 d->joinStyle = style;
1671 return d->paintEffect.get();
1676 d->paintEffect.reset( effect );
1696 if ( exprVal.isValid() )
1698 QString units = exprVal.toString();
1699 if ( !units.isEmpty() )
1718 QString joinstr = exprVal.toString().trimmed();
1719 if ( !joinstr.isEmpty() )
1728 QDomElement textMaskElem = elem.firstChildElement( QStringLiteral(
"text-mask" ) );
1729 d->enabled = textMaskElem.attribute( QStringLiteral(
"maskEnabled" ), QStringLiteral(
"0" ) ).toInt();
1730 d->type =
static_cast<QgsTextMaskSettings::MaskType>( textMaskElem.attribute( QStringLiteral(
"maskType" ), QStringLiteral(
"0" ) ).toInt() );
1731 d->size = textMaskElem.attribute( QStringLiteral(
"maskSize" ), QStringLiteral(
"0" ) ).toDouble();
1734 d->joinStyle =
static_cast< Qt::PenJoinStyle
>( textMaskElem.attribute( QStringLiteral(
"maskJoinStyle" ), QString::number( Qt::RoundJoin ) ).toUInt() );
1735 d->opacity = textMaskElem.attribute( QStringLiteral(
"maskOpacity" ), QStringLiteral(
"1.0" ) ).toDouble();
1736 QDomElement effectElem = textMaskElem.firstChildElement( QStringLiteral(
"effect" ) );
1737 if ( !effectElem.isNull() )
1746 QDomElement textMaskElem = doc.createElement( QStringLiteral(
"text-mask" ) );
1747 textMaskElem.setAttribute( QStringLiteral(
"maskEnabled" ), d->enabled );
1748 textMaskElem.setAttribute( QStringLiteral(
"maskType" ), d->type );
1749 textMaskElem.setAttribute( QStringLiteral(
"maskSize" ), d->size );
1752 textMaskElem.setAttribute( QStringLiteral(
"maskJoinStyle" ), static_cast< unsigned int >( d->joinStyle ) );
1753 textMaskElem.setAttribute( QStringLiteral(
"maskOpacity" ), d->opacity );
1755 d->paintEffect->saveProperties( doc, textMaskElem );
1757 return textMaskElem;
1762 return d->maskedSymbolLayers;
1767 d->maskedSymbolLayers = maskedSymbols;
1776 d =
new QgsTextSettingsPrivate();
1780 : mBufferSettings( other.mBufferSettings )
1781 , mBackgroundSettings( other.mBackgroundSettings )
1782 , mShadowSettings( other.mShadowSettings )
1783 , mMaskSettings( other.mMaskSettings )
1784 , mTextFontFamily( other.mTextFontFamily )
1785 , mTextFontFound( other.mTextFontFound )
1794 mBufferSettings = other.mBufferSettings;
1795 mBackgroundSettings = other.mBackgroundSettings;
1796 mShadowSettings = other.mShadowSettings;
1797 mMaskSettings = other.mMaskSettings;
1798 mTextFontFamily = other.mTextFontFamily;
1799 mTextFontFound = other.mTextFontFound;
1815 QFont
font = d->textFont;
1817 d->fontSizeMapUnitScale );
1818 font.setPixelSize( fontPixelSize );
1829 if ( !d->textNamedStyle.isEmpty() )
1830 return d->textNamedStyle;
1833 return db.styleString( d->textFont );
1839 d->textNamedStyle = style;
1844 return d->fontSizeUnits;
1849 d->fontSizeUnits = unit;
1854 return d->fontSizeMapUnitScale;
1859 d->fontSizeMapUnitScale = scale;
1874 return d->textColor;
1879 d->textColor =
color;
1894 return d->blendMode;
1899 d->blendMode = mode;
1904 return d->multilineHeight;
1909 d->multilineHeight = height;
1914 return d->orientation;
1924 return d->previewBackgroundColor;
1929 d->previewBackgroundColor =
color;
1934 QFont appFont = QApplication::font();
1935 mTextFontFamily = layer->
customProperty( QStringLiteral(
"labeling/fontFamily" ), QVariant( appFont.family() ) ).toString();
1936 QString fontFamily = mTextFontFamily;
1940 mTextFontFound =
false;
1946 fontFamily = appFont.family();
1950 mTextFontFound =
true;
1953 if ( !layer->
customProperty( QStringLiteral(
"labeling/fontSize" ) ).isValid() )
1955 d->fontSize = appFont.pointSizeF();
1959 d->fontSize = layer->
customProperty( QStringLiteral(
"labeling/fontSize" ) ).toDouble();
1962 if ( layer->
customProperty( QStringLiteral(
"labeling/fontSizeUnit" ) ).toString().isEmpty() )
1964 d->fontSizeUnits = layer->
customProperty( QStringLiteral(
"labeling/fontSizeInMapUnits" ), QVariant(
false ) ).toBool() ?
1974 if ( layer->
customProperty( QStringLiteral(
"labeling/fontSizeMapUnitScale" ) ).toString().isEmpty() )
1977 double oldMin = layer->
customProperty( QStringLiteral(
"labeling/fontSizeMapUnitMinScale" ), 0.0 ).toDouble();
1978 d->fontSizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
1979 double oldMax = layer->
customProperty( QStringLiteral(
"labeling/fontSizeMapUnitMaxScale" ), 0.0 ).toDouble();
1980 d->fontSizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
1986 int fontWeight = layer->
customProperty( QStringLiteral(
"labeling/fontWeight" ) ).toInt();
1987 bool fontItalic = layer->
customProperty( QStringLiteral(
"labeling/fontItalic" ) ).toBool();
1988 d->textFont = QFont( fontFamily, d->fontSize, fontWeight, fontItalic );
1991 d->textFont.setCapitalization( static_cast< QFont::Capitalization >( layer->
customProperty( QStringLiteral(
"labeling/fontCapitals" ), QVariant( 0 ) ).toUInt() ) );
1992 d->textFont.setUnderline( layer->
customProperty( QStringLiteral(
"labeling/fontUnderline" ) ).toBool() );
1993 d->textFont.setStrikeOut( layer->
customProperty( QStringLiteral(
"labeling/fontStrikeout" ) ).toBool() );
1994 d->textFont.setLetterSpacing( QFont::AbsoluteSpacing, layer->
customProperty( QStringLiteral(
"labeling/fontLetterSpacing" ), QVariant( 0.0 ) ).toDouble() );
1995 d->textFont.setWordSpacing( layer->
customProperty( QStringLiteral(
"labeling/fontWordSpacing" ), QVariant( 0.0 ) ).toDouble() );
1996 d->textColor = _readColor( layer, QStringLiteral(
"labeling/textColor" ), Qt::black,
false );
1997 if ( layer->
customProperty( QStringLiteral(
"labeling/textOpacity" ) ).toString().isEmpty() )
1999 d->opacity = ( 1 - layer->
customProperty( QStringLiteral(
"labeling/textTransp" ) ).toInt() / 100.0 );
2003 d->opacity = ( layer->
customProperty( QStringLiteral(
"labeling/textOpacity" ) ).toDouble() );
2007 d->multilineHeight = layer->
customProperty( QStringLiteral(
"labeling/multilineHeight" ), QVariant( 1.0 ) ).toDouble();
2008 d->previewBackgroundColor = _readColor( layer, QStringLiteral(
"labeling/previewBkgrdColor" ), QColor( 255, 255, 255 ),
false );
2017 QDomElement textStyleElem;
2018 if ( elem.nodeName() == QStringLiteral(
"text-style" ) )
2019 textStyleElem = elem;
2021 textStyleElem = elem.firstChildElement( QStringLiteral(
"text-style" ) );
2022 QFont appFont = QApplication::font();
2023 mTextFontFamily = textStyleElem.attribute( QStringLiteral(
"fontFamily" ), appFont.family() );
2024 QString fontFamily = mTextFontFamily;
2028 mTextFontFound =
false;
2034 fontFamily = appFont.family();
2038 mTextFontFound =
true;
2041 if ( textStyleElem.hasAttribute( QStringLiteral(
"fontSize" ) ) )
2043 d->fontSize = textStyleElem.attribute( QStringLiteral(
"fontSize" ) ).toDouble();
2047 d->fontSize = appFont.pointSizeF();
2050 if ( !textStyleElem.hasAttribute( QStringLiteral(
"fontSizeUnit" ) ) )
2052 d->fontSizeUnits = textStyleElem.attribute( QStringLiteral(
"fontSizeInMapUnits" ) ).toUInt() == 0 ?
QgsUnitTypes::RenderPoints 2060 if ( !textStyleElem.hasAttribute( QStringLiteral(
"fontSizeMapUnitScale" ) ) )
2063 double oldMin = textStyleElem.attribute( QStringLiteral(
"fontSizeMapUnitMinScale" ), QStringLiteral(
"0" ) ).toDouble();
2064 d->fontSizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
2065 double oldMax = textStyleElem.attribute( QStringLiteral(
"fontSizeMapUnitMaxScale" ), QStringLiteral(
"0" ) ).toDouble();
2066 d->fontSizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
2072 int fontWeight = textStyleElem.attribute( QStringLiteral(
"fontWeight" ) ).toInt();
2073 bool fontItalic = textStyleElem.attribute( QStringLiteral(
"fontItalic" ) ).toInt();
2074 d->textFont = QFont( fontFamily, d->fontSize, fontWeight, fontItalic );
2075 d->textFont.setPointSizeF( d->fontSize );
2078 d->textFont.setCapitalization( static_cast< QFont::Capitalization >( textStyleElem.attribute( QStringLiteral(
"fontCapitals" ), QStringLiteral(
"0" ) ).toUInt() ) );
2079 d->textFont.setUnderline( textStyleElem.attribute( QStringLiteral(
"fontUnderline" ) ).toInt() );
2080 d->textFont.setStrikeOut( textStyleElem.attribute( QStringLiteral(
"fontStrikeout" ) ).toInt() );
2081 d->textFont.setKerning( textStyleElem.attribute( QStringLiteral(
"fontKerning" ), QStringLiteral(
"1" ) ).toInt() );
2082 d->textFont.setLetterSpacing( QFont::AbsoluteSpacing, textStyleElem.attribute( QStringLiteral(
"fontLetterSpacing" ), QStringLiteral(
"0" ) ).toDouble() );
2083 d->textFont.setWordSpacing( textStyleElem.attribute( QStringLiteral(
"fontWordSpacing" ), QStringLiteral(
"0" ) ).toDouble() );
2085 if ( !textStyleElem.hasAttribute( QStringLiteral(
"textOpacity" ) ) )
2087 d->opacity = ( 1 - textStyleElem.attribute( QStringLiteral(
"textTransp" ) ).toInt() / 100.0 );
2091 d->opacity = ( textStyleElem.attribute( QStringLiteral(
"textOpacity" ) ).toDouble() );
2097 static_cast< QgsPainting::BlendMode >( textStyleElem.attribute( QStringLiteral(
"blendMode" ), QString::number(
QgsPainting::BlendNormal ) ).toUInt() ) );
2099 if ( !textStyleElem.hasAttribute( QStringLiteral(
"multilineHeight" ) ) )
2101 QDomElement textFormatElem = elem.firstChildElement( QStringLiteral(
"text-format" ) );
2102 d->multilineHeight = textFormatElem.attribute( QStringLiteral(
"multilineHeight" ), QStringLiteral(
"1" ) ).toDouble();
2106 d->multilineHeight = textStyleElem.attribute( QStringLiteral(
"multilineHeight" ), QStringLiteral(
"1" ) ).toDouble();
2109 if ( textStyleElem.firstChildElement( QStringLiteral(
"text-buffer" ) ).isNull() )
2111 mBufferSettings.
readXml( elem );
2115 mBufferSettings.
readXml( textStyleElem );
2117 if ( textStyleElem.firstChildElement( QStringLiteral(
"text-mask" ) ).isNull() )
2119 mMaskSettings.
readXml( elem );
2123 mMaskSettings.
readXml( textStyleElem );
2125 if ( textStyleElem.firstChildElement( QStringLiteral(
"shadow" ) ).isNull() )
2127 mShadowSettings.
readXml( elem );
2131 mShadowSettings.
readXml( textStyleElem );
2133 if ( textStyleElem.firstChildElement( QStringLiteral(
"background" ) ).isNull() )
2135 mBackgroundSettings.
readXml( elem, context );
2139 mBackgroundSettings.
readXml( textStyleElem, context );
2142 QDomElement ddElem = textStyleElem.firstChildElement( QStringLiteral(
"dd_properties" ) );
2143 if ( ddElem.isNull() )
2145 ddElem = elem.firstChildElement( QStringLiteral(
"dd_properties" ) );
2147 if ( !ddElem.isNull() )
2153 d->mDataDefinedProperties.clear();
2160 QDomElement textStyleElem = doc.createElement( QStringLiteral(
"text-style" ) );
2161 textStyleElem.setAttribute( QStringLiteral(
"fontFamily" ), d->textFont.family() );
2163 textStyleElem.setAttribute( QStringLiteral(
"fontSize" ), d->fontSize );
2166 textStyleElem.setAttribute( QStringLiteral(
"fontWeight" ), d->textFont.weight() );
2167 textStyleElem.setAttribute( QStringLiteral(
"fontItalic" ), d->textFont.italic() );
2168 textStyleElem.setAttribute( QStringLiteral(
"fontStrikeout" ), d->textFont.strikeOut() );
2169 textStyleElem.setAttribute( QStringLiteral(
"fontUnderline" ), d->textFont.underline() );
2172 textStyleElem.setAttribute( QStringLiteral(
"fontCapitals" ), static_cast< unsigned int >( d->textFont.capitalization() ) );
2173 textStyleElem.setAttribute( QStringLiteral(
"fontLetterSpacing" ), d->textFont.letterSpacing() );
2174 textStyleElem.setAttribute( QStringLiteral(
"fontWordSpacing" ), d->textFont.wordSpacing() );
2175 textStyleElem.setAttribute( QStringLiteral(
"fontKerning" ), d->textFont.kerning() );
2176 textStyleElem.setAttribute( QStringLiteral(
"textOpacity" ), d->opacity );
2179 textStyleElem.setAttribute( QStringLiteral(
"multilineHeight" ), d->multilineHeight );
2181 QDomElement ddElem = doc.createElement( QStringLiteral(
"dd_properties" ) );
2184 textStyleElem.appendChild( mBufferSettings.
writeXml( doc ) );
2185 textStyleElem.appendChild( mMaskSettings.
writeXml( doc ) );
2186 textStyleElem.appendChild( mBackgroundSettings.
writeXml( doc, context ) );
2187 textStyleElem.appendChild( mShadowSettings.
writeXml( doc ) );
2188 textStyleElem.appendChild( ddElem );
2190 return textStyleElem;
2196 QMimeData *mimeData =
new QMimeData;
2197 mimeData->setColorData( QVariant(
color() ) );
2200 QDomDocument textDoc;
2201 QDomElement textElem =
writeXml( textDoc, rwContext );
2202 textDoc.appendChild( textElem );
2203 mimeData->setText( textDoc.toString() );
2212 if ( font.pointSizeF() > 0 )
2214 format.
setSize( font.pointSizeF() );
2217 else if ( font.pixelSize() > 0 )
2219 format.
setSize( font.pixelSize() );
2232 f.setPointSizeF(
size() );
2236 f.setPointSizeF(
size() * 2.83464567 );
2240 f.setPointSizeF(
size() * 72 );
2244 f.setPixelSize( static_cast< int >( std::round(
size() ) ) );
2265 QString text = data->text();
2266 if ( !text.isEmpty() )
2272 if ( doc.setContent( text ) )
2274 elem = doc.documentElement();
2276 format.
readXml( elem, rwContext );
2287 if ( d->blendMode != QPainter::CompositionMode_SourceOver )
2290 if ( mBufferSettings.
enabled() && mBufferSettings.
blendMode() != QPainter::CompositionMode_SourceOver )
2293 if ( mBackgroundSettings.
enabled() && mBackgroundSettings.
blendMode() != QPainter::CompositionMode_SourceOver )
2296 if ( mShadowSettings.
enabled() && mShadowSettings.
blendMode() != QPainter::CompositionMode_SourceOver )
2304 return d->mDataDefinedProperties;
2309 return d->mDataDefinedProperties;
2314 d->mDataDefinedProperties = collection;
2319 if ( !d->mDataDefinedProperties.hasActiveProperties() )
2322 QString ddFontFamily;
2325 if ( exprVal.isValid() )
2327 QString family = exprVal.toString().trimmed();
2328 if ( d->textFont.family() != family )
2334 ddFontFamily = family;
2340 QString ddFontStyle;
2343 if ( exprVal.isValid() )
2345 QString fontstyle = exprVal.toString().trimmed();
2346 ddFontStyle = fontstyle;
2349 bool ddBold =
false;
2356 bool ddItalic =
false;
2366 QFontDatabase fontDb;
2367 QFont appFont = QApplication::font();
2368 bool newFontBuilt =
false;
2369 if ( ddBold || ddItalic )
2372 newFont = QFont( !ddFontFamily.isEmpty() ? ddFontFamily : d->textFont.family() );
2373 newFontBuilt =
true;
2374 newFont.setBold( ddBold );
2375 newFont.setItalic( ddItalic );
2377 else if ( !ddFontStyle.isEmpty()
2378 && ddFontStyle.compare( QLatin1String(
"Ignore" ), Qt::CaseInsensitive ) != 0 )
2380 if ( !ddFontFamily.isEmpty() )
2383 QFont styledfont = fontDb.font( ddFontFamily, ddFontStyle, appFont.pointSize() );
2384 if ( appFont != styledfont )
2386 newFont = styledfont;
2387 newFontBuilt =
true;
2394 else if ( !ddFontFamily.isEmpty() )
2396 if ( ddFontStyle.compare( QLatin1String(
"Ignore" ), Qt::CaseInsensitive ) != 0 )
2399 QFont styledfont = fontDb.font( ddFontFamily, d->textNamedStyle, appFont.pointSize() );
2400 if ( appFont != styledfont )
2402 newFont = styledfont;
2403 newFontBuilt =
true;
2408 newFont = QFont( ddFontFamily );
2409 newFontBuilt =
true;
2416 newFont.setUnderline( d->textFont.underline() );
2417 newFont.setStrikeOut( d->textFont.strikeOut() );
2418 newFont.setWordSpacing( d->textFont.wordSpacing() );
2419 newFont.setLetterSpacing( QFont::AbsoluteSpacing, d->textFont.letterSpacing() );
2420 d->textFont = newFont;
2448 if ( exprVal.isValid() )
2450 QString units = exprVal.toString();
2451 if ( !units.isEmpty() )
2456 d->fontSizeUnits = res;
2488 QString blendstr = exprVal.toString().trimmed();
2489 if ( !blendstr.isEmpty() )
2502 QPixmap pixmap( size );
2503 pixmap.fill( Qt::transparent );
2505 painter.begin( &pixmap );
2507 painter.setRenderHint( QPainter::Antialiasing );
2509 QRect rect( 0, 0, size.width(), size.height() );
2512 painter.setPen( Qt::NoPen );
2514 if ( ( background1.lightnessF() < 0.7 ) )
2516 background1 = background1.darker( 125 );
2520 background1 = background1.lighter( 125 );
2523 QLinearGradient linearGrad( QPointF( 0, 0 ), QPointF( 0, rect.height() ) );
2524 linearGrad.setColorAt( 0, background1 );
2525 linearGrad.setColorAt( 1, background2 );
2526 painter.setBrush( QBrush( linearGrad ) );
2527 if ( size.width() > 30 )
2529 painter.drawRoundedRect( rect, 6, 6 );
2534 painter.drawRect( rect );
2536 painter.setBrush( Qt::NoBrush );
2537 painter.setPen( Qt::NoPen );
2545 context.
setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 );
2556 double ytrans = 0.0;
2562 const QStringList text = QStringList() << ( previewText.isEmpty() ? QObject::tr(
"Aa" ) : previewText );
2564 QRectF textRect = rect;
2565 textRect.setLeft( xtrans + padding );
2566 textRect.setWidth( rect.width() - xtrans - 2 * padding );
2568 if ( textRect.width() > 2000 )
2569 textRect.setWidth( 2000 - 2 * padding );
2571 const double bottom = textRect.height() / 2 + textHeight / 2;
2572 textRect.setTop( bottom - textHeight );
2573 textRect.setBottom( bottom );
2578 painter.setBrush( Qt::NoBrush );
2580 if ( size.width() > 30 )
2582 painter.drawRoundedRect( rect, 6, 6 );
2587 painter.drawRect( rect );
2604 tmpFormat = updateShadowPosition( tmpFormat );
2608 drawPart( rect, rotation, alignment, textLines, context, tmpFormat, Background );
2613 drawPart( rect, rotation, alignment, textLines, context, tmpFormat, Buffer );
2616 drawPart( rect, rotation, alignment, textLines, context, tmpFormat, Text );
2624 tmpFormat = updateShadowPosition( tmpFormat );
2628 drawPart( point, rotation, alignment, textLines, context, tmpFormat, Background );
2633 drawPart( point, rotation, alignment, textLines, context, tmpFormat, Buffer );
2636 drawPart( point, rotation, alignment, textLines, context, tmpFormat, Text );
2668 Component component;
2669 component.dpiRatio = 1.0;
2670 component.origin = rect.topLeft();
2671 component.rotation = rotation;
2672 component.size = rect.size();
2673 component.hAlign = alignment;
2686 double xc = rect.width() / 2.0;
2687 double yc = rect.height() / 2.0;
2689 double angle = -rotation;
2690 double xd = xc * std::cos( angle ) - yc * std::sin( angle );
2691 double yd = xc * std::sin( angle ) + yc * std::cos( angle );
2693 component.center = QPointF( component.origin.x() + xd, component.origin.y() + yd );
2697 component.center = rect.center();
2700 QgsTextRenderer::drawBackground( context, component, format, textLines, Rect );
2714 QFontMetricsF fm( format.
scaledFont( context ) );
2715 drawTextInternal( part, context, format, component,
2731 Component component;
2732 component.dpiRatio = 1.0;
2733 component.origin = origin;
2734 component.rotation = rotation;
2735 component.hAlign = alignment;
2744 QgsTextRenderer::drawBackground( context, component, format, textLines, Point );
2757 QFontMetricsF fm( format.
scaledFont( context ) );
2758 drawTextInternal( part, context, format, component,
2773 void QgsTextRenderer::drawBuffer(
QgsRenderContext &context,
const QgsTextRenderer::Component &component,
const QgsTextFormat &format,
const QFontMetricsF *fontMetrics )
2775 QPainter *p = context.
painter();
2780 if ( component.rotation >= -315 && component.rotation < -90 )
2784 else if ( component.rotation >= -90 && component.rotation < -45 )
2799 path.setFillRule( Qt::WindingFill );
2800 switch ( orientation )
2803 path.addText( 0, 0, format.
scaledFont( context ), component.text );
2807 double letterSpacing = format.
scaledFont( context ).letterSpacing();
2808 double labelWidth = fontMetrics->maxWidth();
2810 double partYOffset = 0.0;
2811 for (
const auto &part : parts )
2813 double partXOffset = ( labelWidth - ( fontMetrics->width( part ) - letterSpacing ) ) / 2;
2814 path.addText( partXOffset, partYOffset, format.
scaledFont( context ), part );
2815 partYOffset += fontMetrics->ascent() + letterSpacing;
2819 QColor bufferColor = buffer.
color();
2820 bufferColor.setAlphaF( buffer.
opacity() );
2821 QPen pen( bufferColor );
2822 pen.setWidthF( penSize );
2824 QColor tmpColor( bufferColor );
2828 tmpColor.setAlpha( 0 );
2834 buffp.begin( &buffPict );
2841 context.
painter()->setPen( pen );
2842 context.
painter()->setBrush( tmpColor );
2843 context.
painter()->drawPath( path );
2850 buffp.setPen( pen );
2851 buffp.setBrush( tmpColor );
2852 buffp.drawPath( path );
2858 QgsTextRenderer::Component bufferComponent = component;
2859 bufferComponent.origin = QPointF( 0.0, 0.0 );
2860 bufferComponent.picture = buffPict;
2861 bufferComponent.pictureBuffer = penSize / 2.0;
2862 drawShadow( context, bufferComponent, format );
2867 p->setCompositionMode( buffer.
blendMode() );
2871 p->setRenderHint( QPainter::Antialiasing );
2875 p->scale( component.dpiRatio, component.dpiRatio );
2876 _fixQPictureDPI( p );
2877 p->drawPicture( 0, 0, buffPict );
2895 path.setFillRule( Qt::WindingFill );
2896 path.addText( 0, 0, format.
scaledFont( context ), component.text );
2898 QColor bufferColor( Qt::gray );
2899 bufferColor.setAlphaF( mask.
opacity() );
2903 brush.setColor( bufferColor );
2904 pen.setColor( bufferColor );
2905 pen.setWidthF( penSize );
2912 p->setRenderHint( QPainter::Antialiasing );
2916 p->scale( component.dpiRatio, component.dpiRatio );
2922 context.
painter()->setPen( pen );
2923 context.
painter()->setBrush( brush );
2924 context.
painter()->drawPath( path );
2930 p->setBrush( brush );
2931 p->drawPath( path );
2939 std::unique_ptr< QFontMetricsF > newFm;
2942 newFm.reset(
new QFontMetricsF( format.
scaledFont( context ) ) );
2943 fontMetrics = newFm.get();
2951 double maxLineWidth = 0;
2952 const auto constTextLines = textLines;
2953 for (
const QString &line : constTextLines )
2955 maxLineWidth = std::max( maxLineWidth, fontMetrics->width( line ) );
2957 width = maxLineWidth;
2963 double labelWidth = fontMetrics->maxWidth();
2964 width = labelWidth + ( textLines.size() - 1 ) * labelWidth * format.
lineHeight();
2981 std::unique_ptr< QFontMetricsF > newFm;
2984 newFm.reset(
new QFontMetricsF( format.
scaledFont( context ) ) );
2985 fontMetrics = newFm.get();
2992 double labelHeight = fontMetrics->ascent() + fontMetrics->descent();
2999 return labelHeight + ( textLines.size() - 1 ) * labelHeight * format.
lineHeight();
3004 return labelHeight + ( textLines.size() - 1 ) * fontMetrics->lineSpacing() * format.
lineHeight();
3011 double labelHeight = fontMetrics->ascent();
3012 double letterSpacing = format.
scaledFont( context ).letterSpacing();
3013 int maxLineLength = 0;
3014 for (
const auto &line : textLines )
3016 if ( line.length() > maxLineLength )
3017 maxLineLength = line.length();
3019 return labelHeight * maxLineLength + ( maxLineLength - 1 ) * letterSpacing;
3034 const QStringList &textLines,
DrawMode mode )
3038 QPainter *prevP = context.
painter();
3039 QPainter *p = context.
painter();
3053 component.rotation = -( component.rotation * 180 / M_PI );
3054 component.rotationOffset =
3059 component.rotation = 0.0;
3060 component.rotationOffset = background.
rotation();
3063 if ( mode != Label )
3066 QFontMetricsF fm( format.
scaledFont( context ) );
3067 double width = textWidth( context, format, textLines, &fm );
3068 double height = textHeight( context, format, textLines, mode, &fm );
3073 switch ( component.hAlign )
3076 component.center = QPointF( component.origin.x() + width / 2.0,
3077 component.origin.y() + height / 2.0 );
3081 component.center = QPointF( component.origin.x() + component.size.width() / 2.0,
3082 component.origin.y() + height / 2.0 );
3086 component.center = QPointF( component.origin.x() + component.size.width() - width / 2.0,
3087 component.origin.y() + height / 2.0 );
3094 double originAdjust = fm.ascent() / 2.0 - fm.leading() / 2.0;
3095 switch ( component.hAlign )
3098 component.center = QPointF( component.origin.x() + width / 2.0,
3099 component.origin.y() - height / 2.0 + originAdjust );
3103 component.center = QPointF( component.origin.x(),
3104 component.origin.y() - height / 2.0 + originAdjust );
3108 component.center = QPointF( component.origin.x() - width / 2.0,
3109 component.origin.y() - height / 2.0 + originAdjust );
3120 component.size = QSizeF( width, height );
3125 switch ( background.
type() )
3138 double sizeOut = 0.0;
3146 sizeOut = std::max( component.size.width(), component.size.height() );
3150 sizeOut += bufferSize * 2;
3155 if ( sizeOut < 1.0 )
3158 std::unique_ptr< QgsMarkerSymbol > renderedSymbol;
3162 map[QStringLiteral(
"name" )] = background.
svgFile().trimmed();
3163 map[QStringLiteral(
"size" )] = QString::number( sizeOut );
3165 map[QStringLiteral(
"angle" )] = QString::number( 0.0 );
3173 map[QStringLiteral(
"fill" )] = background.
fillColor().name();
3174 map[QStringLiteral(
"outline" )] = background.
strokeColor().name();
3175 map[QStringLiteral(
"outline-width" )] = QString::number( background.
strokeWidth() );
3183 shdwmap[QStringLiteral(
"fill" )] = shadow.
color().name();
3184 shdwmap[QStringLiteral(
"outline" )] = shadow.
color().name();
3185 shdwmap[QStringLiteral(
"size" )] = QString::number( sizeOut );
3190 svgp.begin( &svgPict );
3207 svgShdwM->
renderPoint( QPointF( sizeOut / 2, -sizeOut / 2 ), svgShdwContext );
3210 component.picture = svgPict;
3212 component.pictureBuffer = 0.0;
3214 component.size = QSizeF( sizeOut, sizeOut );
3215 component.offset = QPointF( 0.0, 0.0 );
3219 p->translate( component.center.x(), component.center.y() );
3220 p->rotate( component.rotation );
3223 p->translate( QPointF( xoff, yoff ) );
3224 p->rotate( component.rotationOffset );
3225 p->translate( -sizeOut / 2, sizeOut / 2 );
3228 p->setRenderHint( QPainter::Antialiasing );
3231 drawShadow( context, component, format );
3237 renderedSymbol.reset( );
3245 renderedSymbol->setSize( sizeOut );
3249 renderedSymbol->setOpacity( background.
opacity() );
3255 p->setCompositionMode( background.
blendMode() );
3259 p->setRenderHint( QPainter::Antialiasing );
3261 p->translate( component.center.x(), component.center.y() );
3262 p->rotate( component.rotation );
3265 p->translate( QPointF( xoff, yoff ) );
3266 p->rotate( component.rotationOffset );
3270 renderedSymbol->renderPoint( QPointF( 0, 0 ), &f, context );
3271 renderedSymbol->stopRender( context );
3272 p->setCompositionMode( QPainter::CompositionMode_SourceOver );
3283 double w = component.size.width();
3284 double h = component.size.height();
3305 h = std::sqrt( std::pow( w, 2 ) + std::pow( h, 2 ) );
3311 h = h * M_SQRT1_2 * 2;
3312 w = w * M_SQRT1_2 * 2;
3320 w += bufferWidth * 2;
3321 h += bufferHeight * 2;
3325 QRectF rect( -w / 2.0, - h / 2.0, w, h );
3327 if ( rect.isNull() )
3333 p->setRenderHint( QPainter::Antialiasing );
3335 p->translate( QPointF( component.center.x(), component.center.y() ) );
3336 p->rotate( component.rotation );
3339 p->translate( QPointF( xoff, yoff ) );
3340 p->rotate( component.rotationOffset );
3348 pen.setWidthF( penSize );
3350 pen.setJoinStyle( background.
joinStyle() );
3360 shapep.begin( &shapePict );
3361 shapep.setPen( pen );
3362 shapep.setBrush( background.
fillColor() );
3369 shapep.drawRoundedRect( rect, background.
radii().width(), background.
radii().height(), Qt::RelativeSize );
3375 shapep.drawRoundedRect( rect, xRadius, yRadius );
3381 shapep.drawEllipse( rect );
3387 component.picture = shapePict;
3388 component.pictureBuffer = penSize / 2.0;
3390 component.size = rect.size();
3391 component.offset = QPointF( rect.width() / 2, -rect.height() / 2 );
3392 drawShadow( context, component, format );
3395 p->setOpacity( background.
opacity() );
3398 p->setCompositionMode( background.
blendMode() );
3402 p->scale( component.dpiRatio, component.dpiRatio );
3403 _fixQPictureDPI( p );
3404 p->drawPicture( 0, 0, shapePict );
3425 QPainter *p = context.
painter();
3426 double componentWidth = component.size.width(), componentHeight = component.size.height();
3427 double xOffset = component.offset.x(), yOffset = component.offset.y();
3428 double pictbuffer = component.pictureBuffer;
3433 radius /= ( mapUnits ? context.
scaleFactor() / component.dpiRatio : 1 );
3434 radius =
static_cast< int >( radius + 0.5 );
3438 double blurBufferClippingScale = 3.75;
3439 int blurbuffer = ( radius > 17 ? 16 : radius ) * blurBufferClippingScale;
3441 QImage blurImg( componentWidth + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
3442 componentHeight + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
3443 QImage::Format_ARGB32_Premultiplied );
3447 int minBlurImgSize = 1;
3451 int maxBlurImgSize = 40000;
3452 if ( blurImg.isNull()
3453 || ( blurImg.width() < minBlurImgSize || blurImg.height() < minBlurImgSize )
3454 || ( blurImg.width() > maxBlurImgSize || blurImg.height() > maxBlurImgSize ) )
3457 blurImg.fill( QColor( Qt::transparent ).rgba() );
3459 if ( !pictp.begin( &blurImg ) )
3461 pictp.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
3462 QPointF imgOffset( blurbuffer + pictbuffer + xOffset,
3463 blurbuffer + pictbuffer + componentHeight + yOffset );
3465 pictp.drawPicture( imgOffset,
3466 component.picture );
3469 pictp.setCompositionMode( QPainter::CompositionMode_SourceIn );
3470 pictp.fillRect( blurImg.rect(), shadow.
color() );
3474 if ( shadow.
blurRadius() > 0.0 && radius > 0 )
3482 picti.begin( &blurImg );
3483 picti.setBrush( Qt::Dense7Pattern );
3484 QPen imgPen( QColor( 0, 0, 255, 255 ) );
3485 imgPen.setWidth( 1 );
3486 picti.setPen( imgPen );
3487 picti.setOpacity( 0.1 );
3488 picti.drawRect( 0, 0, blurImg.width(), blurImg.height() );
3493 double angleRad = shadow.
offsetAngle() * M_PI / 180;
3501 angleRad -= ( component.rotation * M_PI / 180 + component.rotationOffset * M_PI / 180 );
3504 QPointF transPt( -offsetDist * std::cos( angleRad + M_PI_2 ),
3505 -offsetDist * std::sin( angleRad + M_PI_2 ) );
3508 p->setRenderHint( QPainter::SmoothPixmapTransform );
3511 p->setRenderHint( QPainter::Antialiasing );
3515 p->setCompositionMode( shadow.
blendMode() );
3517 p->setOpacity( shadow.
opacity() );
3519 double scale = shadow.
scale() / 100.0;
3521 p->scale( scale, scale );
3522 if ( component.useOrigin )
3524 p->translate( component.origin.x(), component.origin.y() );
3526 p->translate( transPt );
3527 p->translate( -imgOffset.x(),
3529 p->drawImage( 0, 0, blurImg );
3536 p->setBrush( Qt::NoBrush );
3537 QPen imgPen( QColor( 255, 0, 0, 10 ) );
3538 imgPen.setWidth( 2 );
3539 imgPen.setStyle( Qt::DashLine );
3540 p->setPen( imgPen );
3541 p->scale( scale, scale );
3542 if ( component.useOrigin() )
3544 p->translate( component.origin().x(), component.origin().y() );
3546 p->translate( transPt );
3547 p->translate( -imgOffset.x(),
3549 p->drawRect( 0, 0, blurImg.width(), blurImg.height() );
3554 p->setBrush( Qt::NoBrush );
3555 QPen componentRectPen( QColor( 0, 255, 0, 70 ) );
3556 componentRectPen.setWidth( 1 );
3557 if ( component.useOrigin() )
3559 p->translate( component.origin().x(), component.origin().y() );
3561 p->setPen( componentRectPen );
3562 p->drawRect( QRect( -xOffset, -componentHeight - yOffset, componentWidth, componentHeight ) );
3567 void QgsTextRenderer::drawTextInternal(
TextPart drawType,
3570 const Component &component,
3571 const QStringList &textLines,
3572 const QFontMetricsF *fontMetrics,
3583 double rotation = -component.rotation * 180 / M_PI;
3587 if ( rotation >= -315 && rotation < -90 )
3592 else if ( rotation >= -90 && rotation < -45 )
3603 switch ( orientation )
3607 double labelWidest = 0.0;
3612 for (
const QString &line : textLines )
3614 double labelWidth = fontMetrics->width( line );
3615 if ( labelWidth > labelWidest )
3617 labelWidest = labelWidth;
3623 labelWidest = component.size.width();
3627 double labelHeight = fontMetrics->ascent() + fontMetrics->descent();
3631 double ascentOffset = 0.25 * fontMetrics->ascent();
3635 bool adjustForAlignment = alignment != AlignLeft && ( mode != Label || textLines.size() > 1 );
3637 const auto constTextLines = textLines;
3638 for (
const QString &line : constTextLines )
3643 context.
painter()->setRenderHint( QPainter::Antialiasing );
3645 context.
painter()->translate( component.origin );
3647 context.
painter()->rotate( rotation );
3652 maskPainter->save();
3653 maskPainter->translate( component.origin );
3655 maskPainter->rotate( rotation );
3659 double xMultiLineOffset = 0.0;
3660 double labelWidth = fontMetrics->width( line );
3661 if ( adjustForAlignment )
3663 double labelWidthDiff = labelWidest - labelWidth;
3664 if ( alignment == AlignCenter )
3666 labelWidthDiff /= 2;
3672 xMultiLineOffset = labelWidthDiff;
3676 if ( alignment == AlignRight )
3677 xMultiLineOffset = labelWidthDiff - labelWidest;
3678 else if ( alignment == AlignCenter )
3679 xMultiLineOffset = labelWidthDiff - labelWidest / 2.0;
3686 double yMultiLineOffset = ascentOffset;
3693 yMultiLineOffset = - ascentOffset - ( textLines.size() - 1 - i ) * labelHeight * format.
lineHeight();
3698 yMultiLineOffset = - ascentOffset + labelHeight - 1 + format.
lineHeight() * fontMetrics->lineSpacing() * i;
3703 yMultiLineOffset = 0 - ( textLines.size() - 1 - i ) * fontMetrics->lineSpacing() * format.
lineHeight();
3708 context.
painter()->translate( QPointF( xMultiLineOffset, yMultiLineOffset ) );
3710 maskPainter->translate( QPointF( xMultiLineOffset, yMultiLineOffset ) );
3712 Component subComponent;
3713 subComponent.text = line;
3714 subComponent.size = QSizeF( labelWidth, labelHeight );
3715 subComponent.offset = QPointF( 0.0, -ascentOffset );
3716 subComponent.rotation = -component.rotation * 180 / M_PI;
3717 subComponent.rotationOffset = 0.0;
3722 QgsTextRenderer::drawMask( context, subComponent, format );
3727 QgsTextRenderer::drawBuffer( context, subComponent, format, fontMetrics );
3733 path.setFillRule( Qt::WindingFill );
3734 path.addText( 0, 0, format.
scaledFont( context ), subComponent.text );
3739 textp.begin( &textPict );
3740 textp.setPen( Qt::NoPen );
3741 QColor textColor = format.
color();
3742 textColor.setAlphaF( format.
opacity() );
3743 textp.setBrush( textColor );
3744 textp.drawPath( path );
3754 subComponent.picture = textPict;
3755 subComponent.pictureBuffer = 0.0;
3756 subComponent.origin = QPointF( 0.0, 0.0 );
3758 QgsTextRenderer::drawShadow( context, subComponent, format );
3768 context.
painter()->scale( subComponent.dpiRatio, subComponent.dpiRatio );
3775 _fixQPictureDPI( context.
painter() );
3776 context.
painter()->drawPicture( 0, 0, textPict );
3783 QColor textColor = format.
color();
3784 textColor.setAlphaF( format.
opacity() );
3785 context.
painter()->setPen( textColor );
3786 context.
painter()->setRenderHint( QPainter::TextAntialiasing );
3787 context.
painter()->drawText( 0, 0, subComponent.text );
3793 maskPainter->restore();
3802 double letterSpacing = format.
scaledFont( context ).letterSpacing();
3804 double labelWidth = fontMetrics->maxWidth();
3805 double actualLabelWidest = labelWidth + ( textLines.size() - 1 ) * labelWidth * format.
lineHeight();
3806 double labelWidest = 0.0;
3811 labelWidest = actualLabelWidest;
3815 labelWidest = component.size.width();
3819 int maxLineLength = 0;
3820 for (
auto const &line : textLines )
3822 maxLineLength = std::max( maxLineLength, line.length() );
3824 double actualLabelHeight = fontMetrics->ascent() + ( fontMetrics->ascent() + letterSpacing ) * ( maxLineLength - 1 );
3825 double ascentOffset = fontMetrics->ascent();
3829 bool adjustForAlignment = alignment != AlignLeft && ( mode != Label || textLines.size() > 1 );
3832 QString lines = textLines.join(
'\n' );
3834 for ( QString line : constTextLines )
3839 context.
painter()->setRenderHint( QPainter::Antialiasing );
3841 context.
painter()->translate( component.origin );
3843 context.
painter()->rotate( rotation );
3848 maskPainter->save();
3849 maskPainter->translate( component.origin );
3851 maskPainter->rotate( rotation );
3855 double xOffset = actualLabelWidest - labelWidth - ( i * labelWidth * format.
lineHeight() );
3856 if ( adjustForAlignment )
3858 double labelWidthDiff = labelWidest - actualLabelWidest;
3859 if ( alignment == AlignCenter )
3861 labelWidthDiff /= 2;
3867 xOffset += labelWidthDiff;
3875 double yOffset = 0.0;
3881 if ( rotation >= -405 && rotation < -180 )
3883 yOffset = ascentOffset;
3885 else if ( rotation >= 0 && rotation < 45 )
3887 xOffset -= actualLabelWidest;
3888 yOffset = -actualLabelHeight + ascentOffset + fontMetrics->descent();
3893 yOffset = -actualLabelHeight + ascentOffset;
3898 yOffset = -actualLabelHeight + ascentOffset;
3902 yOffset = ascentOffset;
3906 context.
painter()->translate( QPointF( xOffset, yOffset ) );
3908 double labelHeight = fontMetrics->ascent() + ( fontMetrics->ascent() + letterSpacing ) * ( line.length() - 1 );
3910 Component subComponent;
3911 subComponent.text = line;
3912 subComponent.size = QSizeF( labelWidth, labelHeight );
3913 subComponent.offset = QPointF( 0.0, 0.0 );
3914 subComponent.rotation = -component.rotation * 180 / M_PI;
3915 subComponent.rotationOffset = 0.0;
3920 QgsTextRenderer::drawMask( context, subComponent, format );
3925 QgsTextRenderer::drawBuffer( context, subComponent, format, fontMetrics );
3931 path.setFillRule( Qt::WindingFill );
3933 double partYOffset = 0.0;
3934 for (
const auto &part : parts )
3936 double partXOffset = ( labelWidth - ( fontMetrics->width( part ) - letterSpacing ) ) / 2;
3937 path.addText( partXOffset, partYOffset, format.
scaledFont( context ), part );
3938 partYOffset += fontMetrics->ascent() + letterSpacing;
3944 textp.begin( &textPict );
3945 textp.setPen( Qt::NoPen );
3946 QColor textColor = format.
color();
3947 textColor.setAlphaF( format.
opacity() );
3948 textp.setBrush( textColor );
3949 textp.drawPath( path );
3959 subComponent.picture = textPict;
3960 subComponent.pictureBuffer = 0.0;
3961 subComponent.origin = QPointF( 0.0, 0.0 );
3963 QgsTextRenderer::drawShadow( context, subComponent, format );
3973 context.
painter()->scale( subComponent.dpiRatio, subComponent.dpiRatio );
3980 _fixQPictureDPI( context.
painter() );
3981 context.
painter()->drawPicture( 0, 0, textPict );
3988 QColor textColor = format.
color();
3989 textColor.setAlphaF( format.
opacity() );
3990 context.
painter()->setPen( textColor );
3991 context.
painter()->setRenderHint( QPainter::TextAntialiasing );
3992 context.
painter()->drawText( 0, 0, subComponent.text );
3998 maskPainter->restore();
4014 const QString skind =
string.trimmed();
4016 if ( skind.compare( QLatin1String(
"Square" ), Qt::CaseInsensitive ) == 0 )
4020 else if ( skind.compare( QLatin1String(
"Ellipse" ), Qt::CaseInsensitive ) == 0 )
4024 else if ( skind.compare( QLatin1String(
"Circle" ), Qt::CaseInsensitive ) == 0 )
4028 else if ( skind.compare( QLatin1String(
"SVG" ), Qt::CaseInsensitive ) == 0 )
4032 else if ( skind.compare( QLatin1String(
"marker" ), Qt::CaseInsensitive ) == 0 )
4041 const QString stype =
string.trimmed();
4045 if ( stype.compare( QLatin1String(
"Fixed" ), Qt::CaseInsensitive ) == 0 )
4054 const QString rotstr =
string.trimmed();
4058 if ( rotstr.compare( QLatin1String(
"Offset" ), Qt::CaseInsensitive ) == 0 )
4062 else if ( rotstr.compare( QLatin1String(
"Fixed" ), Qt::CaseInsensitive ) == 0 )
4071 const QString str =
string.trimmed();
4075 if ( str.compare( QLatin1String(
"Text" ), Qt::CaseInsensitive ) == 0 )
4079 else if ( str.compare( QLatin1String(
"Buffer" ), Qt::CaseInsensitive ) == 0 )
4083 else if ( str.compare( QLatin1String(
"Background" ), Qt::CaseInsensitive ) == 0 )
4092 switch ( orientation )
4095 return QStringLiteral(
"horizontal" );
4097 return QStringLiteral(
"vertical" );
4099 return QStringLiteral(
"rotation-based" );
4109 QString cleaned = name.toLower().trimmed();
4111 if ( cleaned == QLatin1String(
"horizontal" ) )
4113 else if ( cleaned == QLatin1String(
"vertical" ) )
4115 else if ( cleaned == QLatin1String(
"rotation-based" ) )
TextOrientation
Text orientation.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the buffer.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the labeling property definitions.
The class is used as a container of context for various read/write operations on other objects...
QColor strokeColor() const
Returns the color used for outlining the background shape.
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...
Meters value as Map units.
void setScale(int scale)
Sets the scaling used for the drop shadow (in percentage of original size).
Shape size is determined by adding a buffer margin around text.
void setLineHeight(double height)
Sets the line height for text.
void setRadiiUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shape's radii.
void setStrokeWidth(double width)
Sets the width of the shape's stroke (stroke).
RotationType
Methods for determining the rotation of the background shape.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shadow offset distance.
Horizontally or vertically oriented text based on rotation (only available for map labeling) ...
void setOpacity(double opacity)
Sets the text's opacity.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape stroke width.
void setOffsetUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shadow's offset.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
void readXml(const QDomElement &elem)
Read settings from a DOM element.
MaskType
Mask shape types.
QgsTextShadowSettings::ShadowPlacement shadowPlacement() const
Returns the placement for the drop shadow.
QSizeF radii() const
Returns the radii used for rounding the corners of shapes.
QSizeF size() const
Returns the size of the background shape.
double opacity() const
Returns the text's opacity.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units used for the shape's size.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
void setOrientation(TextOrientation orientation)
Sets the orientation for the text.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the drop shadow.
QPointF offset() const
Returns the offset used for drawing the background shape.
QColor fillColor() const
Returns the color used for filing the background shape.
QgsMapUnitScale strokeWidthMapUnitScale() const
Returns the map unit scale object for the shape stroke width.
static QgsTextBackgroundSettings::RotationType decodeBackgroundRotationType(const QString &string)
Decodes a string representation of a background rotation type to a type.
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...
QFont toQFont() const
Returns a QFont matching the relevant settings from this text format.
QgsTextShadowSettings & operator=(const QgsTextShadowSettings &other)
static QString substituteVerticalCharacters(QString string)
Returns a string with characters having vertical representation form substituted. ...
void readXml(const QDomElement &elem)
Read settings from a DOM element.
Use antialiasing while drawing.
void setPreviewBackgroundColor(const QColor &color)
Sets the background color that text will be rendered on for previews.
Draw shadow under buffer.
ShadowPlacement
Placement positions for text shadow.
Always render text as text objects.
QgsTextShadowSettings & shadow()
Returns a reference to the text drop shadow settings.
double blurRadius() const
Returns the blur radius for the shadow.
QgsUnitTypes::RenderUnit convertFromOldLabelUnit(int val)
double opacity() const
Returns the background shape's opacity.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the size.
void setStrokeColor(const QColor &color)
Sets the color used for outlining the background shape.
void setSize(double size)
Sets the size of the buffer.
double strokeWidth() const
Returns the width of the shape's stroke (stroke).
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units used for the buffer size.
HAlignment
Horizontal alignment.
double offsetDistance() const
Returns the distance for offsetting the position of the shadow from the text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the buffer.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
static QgsPainting::BlendMode getBlendModeEnum(QPainter::CompositionMode blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode.
Base class for visual effects which can be applied to QPicture drawings.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the mask.
void setOffsetUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shape's offset.
static QgsTextBackgroundSettings::SizeType decodeBackgroundSizeType(const QString &string)
Decodes a string representation of a background size type to a type.
QColor color() const
Returns the color that text will be rendered in.
double size() const
Returns the size of the buffer.
static void drawPart(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, TextPart part, bool drawAsOutlines=true)
Draws a single component of rendered text using the specified settings.
void setFillBufferInterior(bool fill)
Sets whether the interior of the buffer will be filled in.
void setBlurRadius(double blurRadius)
Sets the blur radius for the shadow.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the buffer.
void setOpacity(double opacity)
Sets the shadow's opacity.
QgsTextBufferSettings & operator=(const QgsTextBufferSettings &other)
Copy constructor.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape size.
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QPainter::CompositionMode getCompositionMode(QgsPainting::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
Flags flags() const
Returns combination of flags used for rendering.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
void setType(MaskType type)
Sets the type of mask shape.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the background shape.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
TextRenderFormat textRenderFormat() const
Returns the text render format, which dictates how text is rendered (e.g.
static QgsTextFormat fromQFont(const QFont &font)
Returns a text format matching the settings from an input font.
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the current marker symbol for the background shape.
Qt::PenJoinStyle joinStyle() const
Returns the buffer join style.
void updateDataDefinedProperties(QgsRenderContext &context, const QgsPropertyCollection &properties)
Updates the format by evaluating current values of data defined properties.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Container for settings relating to a text background object.
Percentage of another measurement (e.g., canvas size, feature size)
static int sizeToPixel(double size, const QgsRenderContext &c, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &mapUnitScale=QgsMapUnitScale())
Calculates pixel size (considering output size should be in pixel or map units, scale factors and opt...
QgsMapUnitScale offsetMapUnitScale() const
Returns the map unit scale object for the shape offset.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the buffer size.
void setRadiiMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape radii.
void setBlurRadiusUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shadow's blur radius.
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
QMap< QString, QString > QgsStringMap
void setBlurRadiusMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shadow blur radius.
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)
A marker symbol type, for rendering Point and MultiPoint geometries.
void readXml(const QDomElement &elem)
Read settings from a DOM element.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects. ...
ShapeType type() const
Returns the type of background shape (e.g., square, ellipse, SVG).
void setOffset(QPointF offset)
Sets the offset used for drawing the background shape.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QDomElement writeXml(QDomDocument &doc) const
Write settings into a DOM element.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
Qt::PenJoinStyle joinStyle() const
Returns the buffer join style.
QgsSymbolLayerReferenceList maskedSymbolLayers() const
Returns a list of references to symbol layers that are masked by this buffer.
static QString encodeColor(const QColor &color)
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the buffer size.
static QgsTextFormat fromMimeData(const QMimeData *data, bool *ok=nullptr)
Attempts to parse the provided mime data as a QgsTextFormat.
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
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
static QSizeF toSize(const QVariant &value, bool *ok=nullptr)
Converts a value to a size.
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...
Perform transforms between map coordinates and device coordinates.
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the background shape.
void updateDataDefinedProperties(QgsRenderContext &context, const QgsPropertyCollection &properties)
Updates the format by evaluating current values of data defined properties.
Shape rotation is a fixed angle.
static QString encodeTextOrientation(QgsTextFormat::TextOrientation orientation)
Encodes a text orientation.
QgsMapUnitScale offsetMapUnitScale() const
Returns the map unit scale object for the shadow offset distance.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the text.
void setUseAdvancedEffects(bool enabled)
Used to enable or disable advanced effects such as blend modes.
QColor color() const
Returns the color of the drop shadow.
void setSize(double size)
Sets the size for rendered text.
void setOffsetDistance(double distance)
Sets the distance for offsetting the position of the shadow from the text.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
bool isGuiPreview() const
Returns the Gui preview mode.
static QgsTextFormat::TextOrientation decodeTextOrientation(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a text orientation.
Text within rectangle draw mode.
QColor previewBackgroundColor() const
Returns the background color for text previews.
QgsMapUnitScale blurRadiusMapUnitScale() const
Returns the map unit scale object for the shadow blur radius.
bool fillBufferInterior() const
Returns whether the interior of the buffer will be filled in.
TextOrientation orientation() const
Returns the orientation of the text.
double opacity() const
Returns the mask's opacity.
static bool fontFamilyOnSystem(const QString &family)
Check whether font family is on system in a quick manner, which does not compare [foundry].
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape offset.
~QgsTextBackgroundSettings()
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
void setBlurAlphaOnly(bool alphaOnly)
Sets whether only the alpha channel for the shadow should be blurred.
RotationType rotationType() const
Returns the method used for rotating the background shape.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the buffer size.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the background shape.
Always render text using path objects (AKA outlines/curves).
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the drop shadow.
Vertically oriented text.
static QPixmap textFormatPreviewPixmap(const QgsTextFormat &format, QSize size, const QString &previewText=QString(), int padding=0)
Returns a pixmap preview for a text format.
void setColor(const QColor &color)
Sets the color for the drop shadow.
QList< QgsSymbolLayerReference > QgsSymbolLayerReferenceList
QgsTextMaskSettings & operator=(const QgsTextMaskSettings &other)
Copy constructor.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
void setEnabled(bool enabled)
Sets whether the text shadow will be drawn.
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
QgsMapUnitScale radiiMapUnitScale() const
Returns the map unit scale object for the shape radii.
QString svgFile() const
Returns the absolute path to the background SVG file, if set.
Qt::PenJoinStyle joinStyle() const
Returns the join style used for drawing the background shape.
void setNamedStyle(const QString &style)
Sets the named style for the font used for rendering text.
QList< QgsSymbolLayer * > QgsSymbolLayerList
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
QDomElement writeXml(QDomDocument &doc) const
Write settings into a DOM element.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
SizeType
Methods for determining the background shape size.
QgsTextBackgroundSettings()
double opacity() const
Returns the buffer opacity.
QgsTextMaskSettings & mask()
Returns a reference to the masking settings.
static QPainter::CompositionMode decodeBlendMode(const QString &s)
void updateDataDefinedProperties(QgsRenderContext &context)
Updates the format by evaluating current values of data defined properties.
bool enabled() const
Returns whether the effect is enabled.
Q_GUI_EXPORT int qt_defaultDpiY()
static QgsTextShadowSettings::ShadowPlacement decodeShadowPlacementType(const QString &string)
Decodes a string representation of a shadow placement type to a type.
void setSize(QSizeF size)
Sets the size of the background shape.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
QPainter * maskPainter(int id=0)
Returns a mask QPainter for the render operation.
QMimeData * toMimeData() const
Returns new mime data representing the text format settings.
void setRadii(QSizeF radii)
Sets the radii used for rounding the corners of shapes.
static QFontMetricsF fontMetrics(QgsRenderContext &context, const QgsTextFormat &format)
Returns the font metrics for the given text format, when rendered in the specified render context...
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the buffer.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the format's property collection, used for data defined overrides.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the units used for the shape's stroke width.
void setSizeType(SizeType type)
Sets the method used to determine the size of the background shape (e.g., fixed size or buffer around...
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the buffer size.
void setType(ShapeType type)
Sets the type of background shape to draw (e.g., square, ellipse, SVG).
Draw shadow below all text components.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the background shape.
static void drawText(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true)
Draws text within a rectangle using the specified settings.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setMaskedSymbolLayers(QgsSymbolLayerReferenceList maskedLayers)
Sets the symbol layers that will be masked by this buffer.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the shape's offset.
void setParameters(double mapUnitsPerPixel, double centerX, double centerY, int widthPixels, int heightPixels, double rotation)
Set parameters for use in transforming coordinates.
double rotation() const
Returns the rotation for the background shape, in degrees clockwise.
double lineHeight() const
Returns the line height for text.
void setEnabled(bool enabled)
Sets whether the text background will be drawn.
int offsetAngle() const
Returns the angle for offsetting the position of the shadow from the text.
ShapeType
Background shape types.
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean...
TextPart
Components of text.
void updateDataDefinedProperties(QgsRenderContext &context, const QgsPropertyCollection &properties)
Updates the format by evaluating current values of data defined properties.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the mask.
static QString untranslateNamedStyle(const QString &namedStyle)
Returns the english named style of a font, if possible.
QgsSymbolLayerReferenceList stringToSymbolLayerReferenceList(const QString &str)
Utilitary function to parse a string originated from symbolLayerReferenceListToString into a QgsSymbo...
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
QFont scaledFont(const QgsRenderContext &context) const
Returns a font with the size scaled to match the format's size settings (including units and map unit...
Contains information about the context of a rendering operation.
Shape rotation is offset from text rotation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=nullptr, bool *match=nullptr)
Check whether font family is on system.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the size.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
QPainter * painter()
Returns the destination QPainter for the render operation.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
static void blurImageInPlace(QImage &image, QRect rect, int radius, bool alphaOnly)
Blurs an image in place, e.g. creating Qt-independent drop shadows.
Points (e.g., for font sizes)
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the shadow's offset.
bool enabled() const
Returns whether the shadow is enabled.
void updateDataDefinedProperties(QgsRenderContext &context, const QgsPropertyCollection &properties)
Updates the format by evaluating current values of data defined properties.
QgsTextBackgroundSettings & operator=(const QgsTextBackgroundSettings &other)
Struct for storing maximum and minimum scales for measurements in map units.
QgsTextFormat & operator=(const QgsTextFormat &other)
Container for settings relating to a text shadow.
bool offsetGlobal() const
Returns true if the global shadow offset will be used.
QColor color() const
Returns the color of the buffer.
double size() const
Returns the size of the buffer.
QgsUnitTypes::RenderUnit radiiUnit() const
Returns the units used for the shape's radii.
QDomElement writeXml(QDomDocument &doc) const
Write settings into a DOM element.
Container for settings relating to a text buffer.
void setFillColor(const QColor &color)
Sets the color used for filing the background shape.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
bool useAdvancedEffects() const
Returns true if advanced effects such as blend modes such be used.
double size() const
Returns the size for rendered text.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shape's stroke width.
bool enabled() const
Returns whether the background is enabled.
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
static QStringList splitToGraphemes(const QString &text)
Splits a text string to a list of graphemes, which are the smallest allowable character divisions in ...
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the format's property collection, used for data defined overrides.
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
QgsUnitTypes::RenderUnit blurRadiusUnit() const
Returns the units used for the shadow's blur radius.
QString symbolLayerReferenceListToString(const QgsSymbolLayerReferenceList &lst)
Utilitary function to turn a QgsSymbolLayerReferenceList into a string.
MaskType type() const
Returns the type of mask shape.
bool enabled() const
Returns whether the buffer is enabled.
int scale() const
Returns the scaling used for the drop shadow (in percentage of original size).
Shape rotation is synced with text rotation.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
void setShadowPlacement(QgsTextShadowSettings::ShadowPlacement placement)
Sets the placement for the drop shadow.
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the text.
Q_GUI_EXPORT int qt_defaultDpiX()
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
Draw shadow under background shape.
bool hasActiveProperties() const override
Returns true if the collection has any active properties, or false if all properties within the colle...
Whether the mask is enabled.
void setEnabled(bool)
Returns whether the mask is enabled.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the buffer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the shape size.
A class to manage painter saving and restoring required for drawing on a different painter (mask pain...
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
void setOpacity(double opacity)
Sets the mask's opacity.
Container for all settings relating to text rendering.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
QgsPaintEffect * createEffect(const QString &name, const QgsStringMap &properties=QgsStringMap()) const
Creates a new paint effect given the effect name and properties map.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the buffer.
void setSvgFile(const QString &file)
Sets the path to the background SVG file.
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
void setSize(double size)
Sets the size of the buffer.
bool blurAlphaOnly() const
Returns whether only the alpha channel for the shadow will be blurred.
void setOffsetGlobal(bool global)
Sets whether the global shadow offset should be used.
DrawMode
Draw mode to calculate width and height.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
Represents a vector layer which manages a vector based data sets.
void setOpacity(double opacity)
Sets the buffer opacity.
Square - buffered sizes only.
int valueAsInt(int key, const QgsExpressionContext &context, int defaultValue=0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an integer...
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
virtual void end(QgsRenderContext &context)
Ends interception of paint operations to a render context, and draws the result to the render context...
bool containsAdvancedEffects() const
Returns true if any component of the font format requires advanced effects such as blend modes...
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units used for the buffer size.
QString namedStyle() const
Returns the named style for the font used for rendering text (e.g., "bold").
QFont font() const
Returns the font used for rendering text.
void setRotationType(RotationType type)
Sets the method used for rotating the background shape.
void setColor(const QColor &color)
Sets the color for the buffer.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units used for the shape's size.
A class to manager painter saving and restoring required for effect drawing.
bool enabled() const
Returns whether the mask is enabled.
virtual void begin(QgsRenderContext &context)
Begins intercepting paint operations to a render context.
Container for settings relating to a selective masking around a text.
double opacity() const
Returns the shadow's opacity.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
void setOpacity(double opacity)
Sets the background shape's opacity.
RenderUnit
Rendering size units.
static QColor decodeColor(const QString &str)
QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol to be rendered in the background.
int currentMaskId() const
Returns the current mask id, which can be used with maskPainter()
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the background shape.
Horizontally oriented text.
void setOffsetAngle(int angle)
Sets the angle for offsetting the position of the shadow from the text.
static QgsTextBackgroundSettings::ShapeType decodeShapeType(const QString &string)
Decodes a string representation of a background shape type to a type.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, DrawMode mode, QFontMetricsF *fontMetrics=nullptr)
Returns the height of a text based on a given format.
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
void setRotation(double rotation)
Sets the rotation for the background shape, in degrees clockwise.