QGIS API Documentation 3.99.0-Master (8e76e220402)
Loading...
Searching...
No Matches
qgstextbackgroundsettings.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgstextbackgroundsettings.cpp
3 -----------------
4 begin : May 2020
5 copyright : (C) Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsapplication.h"
19#include "qgscolorutils.h"
20#include "qgsfillsymbollayer.h"
22#include "qgspainting.h"
23#include "qgspallabeling.h"
24#include "qgssymbollayerutils.h"
25#include "qgstextrenderer_p.h"
27#include "qgsunittypes.h"
28#include "qgsvectorlayer.h"
29
30#include <QString>
31
32using namespace Qt::StringLiterals;
33
35{
36 d = new QgsTextBackgroundSettingsPrivate();
37
38 // Create a default fill symbol to preserve API promise until QGIS 5.0
39 QgsSimpleFillSymbolLayer *fill = new QgsSimpleFillSymbolLayer( d->fillColor, Qt::SolidPattern, d->strokeColor );
40 fill->setStrokeWidth( d->strokeWidth );
41 fill->setStrokeWidthUnit( d->strokeWidthUnits );
42 fill->setStrokeWidthMapUnitScale( d->strokeWidthMapUnitScale );
43 fill->setStrokeStyle( !qgsDoubleNear( d->strokeWidth, 0.0 ) ? Qt::SolidLine : Qt::NoPen );
44 fill->setPenJoinStyle( d->joinStyle );
45
47 fillSymbol->changeSymbolLayer( 0, fill );
49}
50
52 : d( other.d )
53{
54
55}
56
58 : d( std::move( other.d ) )
59{
60
61}
62
64{
65 if ( &other == this )
66 return *this;
67
68 d = other.d;
69 return *this;
70}
71
73{
74 if ( &other == this )
75 return *this;
76
77 d = std::move( other.d );
78 return *this;
79}
80
85
87{
88 if ( d->enabled != other.enabled()
89 || d->type != other.type()
90 || d->svgFile != other.svgFile()
91 || d->sizeType != other.sizeType()
92 || d->size != other.size()
93 || d->sizeUnits != other.sizeUnit()
94 || d->sizeMapUnitScale != other.sizeMapUnitScale()
95 || d->rotationType != other.rotationType()
96 || d->rotation != other.rotation()
97 || d->offset != other.offset()
98 || d->offsetUnits != other.offsetUnit()
99 || d->offsetMapUnitScale != other.offsetMapUnitScale()
100 || d->radii != other.radii()
101 || d->radiiUnits != other.radiiUnit()
102 || d->radiiMapUnitScale != other.radiiMapUnitScale()
103 || d->blendMode != other.blendMode()
104 || d->fillColor != other.fillColor()
105 || d->strokeColor != other.strokeColor()
106 || d->opacity != other.opacity()
107 || d->strokeWidth != other.strokeWidth()
108 || d->strokeWidthUnits != other.strokeWidthUnit()
109 || d->strokeWidthMapUnitScale != other.strokeWidthMapUnitScale()
110 || d->joinStyle != other.joinStyle() )
111 return false;
112
113 if ( static_cast< bool >( d->paintEffect ) != static_cast< bool >( other.paintEffect() )
114 || ( d->paintEffect && d->paintEffect->properties() != other.paintEffect()->properties() ) )
115 return false;
116
117 if ( static_cast< bool >( d->markerSymbol ) != static_cast< bool >( other.markerSymbol() )
118 || ( d->markerSymbol && QgsSymbolLayerUtils::symbolProperties( d->markerSymbol.get() ) != QgsSymbolLayerUtils::symbolProperties( other.markerSymbol() ) ) )
119 return false;
120
121 if ( static_cast< bool >( d->fillSymbol ) != static_cast< bool >( other.fillSymbol() )
122 || ( d->fillSymbol && QgsSymbolLayerUtils::symbolProperties( d->fillSymbol.get() ) != QgsSymbolLayerUtils::symbolProperties( other.fillSymbol() ) ) )
123 return false;
124
125 return true;
126}
127
129{
130 return !( *this == other );
131}
132
134{
135 return d->enabled;
136}
137
139{
140 d->enabled = enabled;
141}
142
147
152
154{
155 return d->svgFile;
156}
157
158void QgsTextBackgroundSettings::setSvgFile( const QString &file )
159{
160 d->svgFile = file;
161}
162
164{
165 return d->markerSymbol.get();
166}
167
169{
170 if ( symbol )
171 // Remove symbol layer unique id to have correct settings equality
173
174 d->markerSymbol.reset( symbol );
175}
176
178{
179 return d->fillSymbol.get();
180}
181
183{
184 if ( symbol )
185 // Remove symbol layer unique id to have correct settings equality
187
188 d->fillSymbol.reset( symbol );
189}
190
195
200
202{
203 return d->size;
204}
205
207{
208 d->size = size;
209}
210
212{
213 return d->sizeUnits;
214}
215
217{
218 d->sizeUnits = unit;
219}
220
222{
223 return d->sizeMapUnitScale;
224}
225
227{
228 d->sizeMapUnitScale = scale;
229}
230
235
240
242{
243 return d->rotation;
244}
245
247{
248 d->rotation = rotation;
249}
250
252{
253 return d->offset;
254}
255
257{
258 d->offset = offset;
259}
260
262{
263 return d->offsetUnits;
264}
265
267{
268 d->offsetUnits = units;
269}
270
272{
273 return d->offsetMapUnitScale;
274}
275
277{
278 d->offsetMapUnitScale = scale;
279}
280
282{
283 return d->radii;
284}
285
287{
288 d->radii = radii;
289}
290
292{
293 return d->radiiUnits;
294}
295
297{
298 d->radiiUnits = units;
299}
300
302{
303 return d->radiiMapUnitScale;
304}
305
307{
308 d->radiiMapUnitScale = scale;
309}
310
312{
313 return d->opacity;
314}
315
317{
318 d->opacity = opacity;
319}
320
321QPainter::CompositionMode QgsTextBackgroundSettings::blendMode() const
322{
323 return d->blendMode;
324}
325
326void QgsTextBackgroundSettings::setBlendMode( QPainter::CompositionMode mode )
327{
328 d->blendMode = mode;
329}
330
332{
333 return d->fillSymbol ? d->fillSymbol->color() : d->fillColor;
334}
335
337{
338 d->fillColor = color;
339 if ( d->fillSymbol )
340 {
341 d->fillSymbol->setColor( color );
342 }
343}
344
346{
347 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
348 {
349 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->strokeColor();
350 }
351 return d->strokeColor;
352}
353
355{
356 d->strokeColor = color;
357 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
358 {
359 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setStrokeColor( color );
360 }
361}
362
364{
365 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
366 {
367 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->strokeWidth();
368 }
369 return d->strokeWidth;
370}
371
373{
374 d->strokeWidth = width;
375 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
376 {
377 QgsSimpleFillSymbolLayer *fill = qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) );
378 fill->setStrokeWidth( width );
379 fill->setStrokeStyle( !qgsDoubleNear( width, 0.0 ) ? Qt::SolidLine : Qt::NoPen );
380 }
381}
382
384{
385 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
386 {
387 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->strokeWidthUnit();
388 }
389 return d->strokeWidthUnits;
390}
391
393{
394 d->strokeWidthUnits = units;
395 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
396 {
397 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setStrokeWidthUnit( units );
398 }
399}
400
402{
403 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
404 {
405 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->strokeWidthMapUnitScale();
406 }
407 return d->strokeWidthMapUnitScale;
408}
409
411{
412 d->strokeWidthMapUnitScale = scale;
413 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
414 {
415 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setStrokeWidthMapUnitScale( scale );
416 }
417}
418
420{
421 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
422 {
423 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->penJoinStyle();
424 }
425 return d->joinStyle;
426}
427
428void QgsTextBackgroundSettings::setJoinStyle( Qt::PenJoinStyle style )
429{
430 d->joinStyle = style;
431 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
432 {
433 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setPenJoinStyle( style );
434 }
435}
436
438{
439 return d->paintEffect.get();
440}
441
443{
444 d->paintEffect.reset( effect );
445}
446
448{
449 d->enabled = layer->customProperty( u"labeling/shapeDraw"_s, QVariant( false ) ).toBool();
450 d->type = static_cast< ShapeType >( layer->customProperty( u"labeling/shapeType"_s, QVariant( ShapeRectangle ) ).toUInt() );
451 d->svgFile = layer->customProperty( u"labeling/shapeSVGFile"_s, QVariant( "" ) ).toString();
452 d->sizeType = static_cast< SizeType >( layer->customProperty( u"labeling/shapeSizeType"_s, QVariant( SizeBuffer ) ).toUInt() );
453 d->size = QSizeF( layer->customProperty( u"labeling/shapeSizeX"_s, QVariant( 0.0 ) ).toDouble(),
454 layer->customProperty( u"labeling/shapeSizeY"_s, QVariant( 0.0 ) ).toDouble() );
455
456 if ( layer->customProperty( u"labeling/shapeSizeUnit"_s ).toString().isEmpty() )
457 {
458 d->sizeUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( u"labeling/shapeSizeUnits"_s, 0 ).toUInt() );
459 }
460 else
461 {
462 d->sizeUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( u"labeling/shapeSizeUnit"_s ).toString() );
463 }
464
465 if ( layer->customProperty( u"labeling/shapeSizeMapUnitScale"_s ).toString().isEmpty() )
466 {
467 //fallback to older property
468 const double oldMin = layer->customProperty( u"labeling/shapeSizeMapUnitMinScale"_s, 0.0 ).toDouble();
469 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
470 const double oldMax = layer->customProperty( u"labeling/shapeSizeMapUnitMaxScale"_s, 0.0 ).toDouble();
471 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
472 }
473 else
474 {
475 d->sizeMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( u"labeling/shapeSizeMapUnitScale"_s ).toString() );
476 }
477 d->rotationType = static_cast< RotationType >( layer->customProperty( u"labeling/shapeRotationType"_s, QVariant( RotationSync ) ).toUInt() );
478 d->rotation = layer->customProperty( u"labeling/shapeRotation"_s, QVariant( 0.0 ) ).toDouble();
479 d->offset = QPointF( layer->customProperty( u"labeling/shapeOffsetX"_s, QVariant( 0.0 ) ).toDouble(),
480 layer->customProperty( u"labeling/shapeOffsetY"_s, QVariant( 0.0 ) ).toDouble() );
481
482 if ( layer->customProperty( u"labeling/shapeOffsetUnit"_s ).toString().isEmpty() )
483 {
484 d->offsetUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( u"labeling/shapeOffsetUnits"_s, 0 ).toUInt() );
485 }
486 else
487 {
488 d->offsetUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( u"labeling/shapeOffsetUnit"_s ).toString() );
489 }
490
491 if ( layer->customProperty( u"labeling/shapeOffsetMapUnitScale"_s ).toString().isEmpty() )
492 {
493 //fallback to older property
494 const double oldMin = layer->customProperty( u"labeling/shapeOffsetMapUnitMinScale"_s, 0.0 ).toDouble();
495 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
496 const double oldMax = layer->customProperty( u"labeling/shapeOffsetMapUnitMaxScale"_s, 0.0 ).toDouble();
497 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
498 }
499 else
500 {
501 d->offsetMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( u"labeling/shapeOffsetMapUnitScale"_s ).toString() );
502 }
503 d->radii = QSizeF( layer->customProperty( u"labeling/shapeRadiiX"_s, QVariant( 0.0 ) ).toDouble(),
504 layer->customProperty( u"labeling/shapeRadiiY"_s, QVariant( 0.0 ) ).toDouble() );
505
506
507 if ( layer->customProperty( u"labeling/shapeRadiiUnit"_s ).toString().isEmpty() )
508 {
509 d->radiiUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( u"labeling/shapeRadiiUnits"_s, 0 ).toUInt() );
510 }
511 else
512 {
513 d->radiiUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( u"labeling/shapeRadiiUnit"_s ).toString() );
514 }
515
516 if ( layer->customProperty( u"labeling/shapeRadiiMapUnitScale"_s ).toString().isEmpty() )
517 {
518 //fallback to older property
519 const double oldMin = layer->customProperty( u"labeling/shapeRadiiMapUnitMinScale"_s, 0.0 ).toDouble();
520 d->radiiMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
521 const double oldMax = layer->customProperty( u"labeling/shapeRadiiMapUnitMaxScale"_s, 0.0 ).toDouble();
522 d->radiiMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
523 }
524 else
525 {
526 d->radiiMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( u"labeling/shapeRadiiMapUnitScale"_s ).toString() );
527 }
528 d->fillColor = QgsTextRendererUtils::readColor( layer, u"labeling/shapeFillColor"_s, Qt::white, true );
529 d->strokeColor = QgsTextRendererUtils::readColor( layer, u"labeling/shapeBorderColor"_s, Qt::darkGray, true );
530 d->strokeWidth = layer->customProperty( u"labeling/shapeBorderWidth"_s, QVariant( .0 ) ).toDouble();
531 if ( layer->customProperty( u"labeling/shapeBorderWidthUnit"_s ).toString().isEmpty() )
532 {
533 d->strokeWidthUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( u"labeling/shapeBorderWidthUnits"_s, 0 ).toUInt() );
534 }
535 else
536 {
537 d->strokeWidthUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( u"labeling/shapeBorderWidthUnit"_s ).toString() );
538 }
539 if ( layer->customProperty( u"labeling/shapeBorderWidthMapUnitScale"_s ).toString().isEmpty() )
540 {
541 //fallback to older property
542 const double oldMin = layer->customProperty( u"labeling/shapeBorderWidthMapUnitMinScale"_s, 0.0 ).toDouble();
543 d->strokeWidthMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
544 const double oldMax = layer->customProperty( u"labeling/shapeBorderWidthMapUnitMaxScale"_s, 0.0 ).toDouble();
545 d->strokeWidthMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
546 }
547 else
548 {
549 d->strokeWidthMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( u"labeling/shapeBorderWidthMapUnitScale"_s ).toString() );
550 }
551 d->joinStyle = static_cast< Qt::PenJoinStyle >( layer->customProperty( u"labeling/shapeJoinStyle"_s, QVariant( Qt::BevelJoin ) ).toUInt() );
552
553 if ( layer->customProperty( u"labeling/shapeOpacity"_s ).toString().isEmpty() )
554 {
555 d->opacity = ( 1 - layer->customProperty( u"labeling/shapeTransparency"_s ).toInt() / 100.0 ); //0 -100
556 }
557 else
558 {
559 d->opacity = ( layer->customProperty( u"labeling/shapeOpacity"_s ).toDouble() );
560 }
561 d->blendMode = QgsPainting::getCompositionMode(
562 static_cast< Qgis::BlendMode >( layer->customProperty( u"labeling/shapeBlendMode"_s, QVariant( static_cast< int>( Qgis::BlendMode::Normal ) ) ).toUInt() ) );
563
564 if ( layer->customProperty( u"labeling/shapeEffect"_s ).isValid() )
565 {
566 QDomDocument doc( u"effect"_s );
567 doc.setContent( layer->customProperty( u"labeling/shapeEffect"_s ).toString() );
568 const QDomElement effectElem = doc.firstChildElement( u"effect"_s ).firstChildElement( u"effect"_s );
569 setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
570 }
571 else
572 setPaintEffect( nullptr );
573}
574
575void QgsTextBackgroundSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
576{
577 const QDomElement backgroundElem = elem.firstChildElement( u"background"_s );
578 d->enabled = backgroundElem.attribute( u"shapeDraw"_s, u"0"_s ).toInt();
579 d->type = static_cast< ShapeType >( backgroundElem.attribute( u"shapeType"_s, QString::number( ShapeRectangle ) ).toUInt() );
580 d->svgFile = QgsSymbolLayerUtils::svgSymbolNameToPath( backgroundElem.attribute( u"shapeSVGFile"_s ), context.pathResolver() );
581 d->sizeType = static_cast< SizeType >( backgroundElem.attribute( u"shapeSizeType"_s, QString::number( SizeBuffer ) ).toUInt() );
582 d->size = QSizeF( backgroundElem.attribute( u"shapeSizeX"_s, u"0"_s ).toDouble(),
583 backgroundElem.attribute( u"shapeSizeY"_s, u"0"_s ).toDouble() );
584
585 if ( !backgroundElem.hasAttribute( u"shapeSizeUnit"_s ) )
586 {
587 d->sizeUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( u"shapeSizeUnits"_s ).toUInt() );
588 }
589 else
590 {
591 d->sizeUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( u"shapeSizeUnit"_s ) );
592 }
593
594 if ( !backgroundElem.hasAttribute( u"shapeSizeMapUnitScale"_s ) )
595 {
596 //fallback to older property
597 const double oldMin = backgroundElem.attribute( u"shapeSizeMapUnitMinScale"_s, u"0"_s ).toDouble();
598 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
599 const double oldMax = backgroundElem.attribute( u"shapeSizeMapUnitMaxScale"_s, u"0"_s ).toDouble();
600 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
601 }
602 else
603 {
604 d->sizeMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( u"shapeSizeMapUnitScale"_s ) );
605 }
606 d->rotationType = static_cast< RotationType >( backgroundElem.attribute( u"shapeRotationType"_s, QString::number( RotationSync ) ).toUInt() );
607 d->rotation = backgroundElem.attribute( u"shapeRotation"_s, u"0"_s ).toDouble();
608 d->offset = QPointF( backgroundElem.attribute( u"shapeOffsetX"_s, u"0"_s ).toDouble(),
609 backgroundElem.attribute( u"shapeOffsetY"_s, u"0"_s ).toDouble() );
610
611 if ( !backgroundElem.hasAttribute( u"shapeOffsetUnit"_s ) )
612 {
613 d->offsetUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( u"shapeOffsetUnits"_s ).toUInt() );
614 }
615 else
616 {
617 d->offsetUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( u"shapeOffsetUnit"_s ) );
618 }
619
620 if ( !backgroundElem.hasAttribute( u"shapeOffsetMapUnitScale"_s ) )
621 {
622 //fallback to older property
623 const double oldMin = backgroundElem.attribute( u"shapeOffsetMapUnitMinScale"_s, u"0"_s ).toDouble();
624 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
625 const double oldMax = backgroundElem.attribute( u"shapeOffsetMapUnitMaxScale"_s, u"0"_s ).toDouble();
626 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
627 }
628 else
629 {
630 d->offsetMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( u"shapeOffsetMapUnitScale"_s ) );
631 }
632 d->radii = QSizeF( backgroundElem.attribute( u"shapeRadiiX"_s, u"0"_s ).toDouble(),
633 backgroundElem.attribute( u"shapeRadiiY"_s, u"0"_s ).toDouble() );
634
635 if ( !backgroundElem.hasAttribute( u"shapeRadiiUnit"_s ) )
636 {
637 d->radiiUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( u"shapeRadiiUnits"_s ).toUInt() );
638 }
639 else
640 {
641 d->radiiUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( u"shapeRadiiUnit"_s ) );
642 }
643 if ( !backgroundElem.hasAttribute( u"shapeRadiiMapUnitScale"_s ) )
644 {
645 //fallback to older property
646 const double oldMin = backgroundElem.attribute( u"shapeRadiiMapUnitMinScale"_s, u"0"_s ).toDouble();
647 d->radiiMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
648 const double oldMax = backgroundElem.attribute( u"shapeRadiiMapUnitMaxScale"_s, u"0"_s ).toDouble();
649 d->radiiMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
650 }
651 else
652 {
653 d->radiiMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( u"shapeRadiiMapUnitScale"_s ) );
654 }
655 d->fillColor = QgsColorUtils::colorFromString( backgroundElem.attribute( u"shapeFillColor"_s, QgsColorUtils::colorToString( Qt::white ) ) );
656 d->strokeColor = QgsColorUtils::colorFromString( backgroundElem.attribute( u"shapeBorderColor"_s, QgsColorUtils::colorToString( Qt::darkGray ) ) );
657 d->strokeWidth = backgroundElem.attribute( u"shapeBorderWidth"_s, u"0"_s ).toDouble();
658
659 if ( !backgroundElem.hasAttribute( u"shapeBorderWidthUnit"_s ) )
660 {
661 d->strokeWidthUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( u"shapeBorderWidthUnits"_s ).toUInt() );
662 }
663 else
664 {
665 d->strokeWidthUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( u"shapeBorderWidthUnit"_s ) );
666 }
667 if ( !backgroundElem.hasAttribute( u"shapeBorderWidthMapUnitScale"_s ) )
668 {
669 //fallback to older property
670 const double oldMin = backgroundElem.attribute( u"shapeBorderWidthMapUnitMinScale"_s, u"0"_s ).toDouble();
671 d->strokeWidthMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
672 const double oldMax = backgroundElem.attribute( u"shapeBorderWidthMapUnitMaxScale"_s, u"0"_s ).toDouble();
673 d->strokeWidthMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
674 }
675 else
676 {
677 d->strokeWidthMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( u"shapeBorderWidthMapUnitScale"_s ) );
678 }
679 d->joinStyle = static_cast< Qt::PenJoinStyle >( backgroundElem.attribute( u"shapeJoinStyle"_s, QString::number( Qt::BevelJoin ) ).toUInt() );
680
681 if ( !backgroundElem.hasAttribute( u"shapeOpacity"_s ) )
682 {
683 d->opacity = ( 1 - backgroundElem.attribute( u"shapeTransparency"_s ).toInt() / 100.0 ); //0 -100
684 }
685 else
686 {
687 d->opacity = ( backgroundElem.attribute( u"shapeOpacity"_s ).toDouble() );
688 }
689
690 d->blendMode = QgsPainting::getCompositionMode(
691 static_cast< Qgis::BlendMode >( backgroundElem.attribute( u"shapeBlendMode"_s, QString::number( static_cast< int >( Qgis::BlendMode::Normal ) ) ).toUInt() ) );
692
693 const QDomElement effectElem = backgroundElem.firstChildElement( u"effect"_s );
694 if ( !effectElem.isNull() )
695 setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
696 else
697 setPaintEffect( nullptr );
698
699 setMarkerSymbol( nullptr );
700 setFillSymbol( nullptr );
701 const QDomNodeList symbols = backgroundElem.elementsByTagName( u"symbol"_s );
702 for ( int i = 0; i < symbols.size(); ++i )
703 {
704 if ( symbols.at( i ).isElement() )
705 {
706 const QDomElement symbolElement = symbols.at( i ).toElement();
707 const QString symbolElementName = symbolElement.attribute( u"name"_s );
708 if ( symbolElementName == "markerSymbol"_L1 )
709 {
710 setMarkerSymbol( QgsSymbolLayerUtils::loadSymbol< QgsMarkerSymbol >( symbolElement, context ).release() );
711 }
712 else if ( symbolElementName == "fillSymbol"_L1 )
713 {
714 setFillSymbol( QgsSymbolLayerUtils::loadSymbol< QgsFillSymbol >( symbolElement, context ).release() );
715 }
716 }
717 }
718
719 if ( !d->fillSymbol )
720 {
721 QgsSimpleFillSymbolLayer *fill = new QgsSimpleFillSymbolLayer( d->fillColor, Qt::SolidPattern, d->strokeColor );
722 fill->setStrokeWidth( d->strokeWidth );
723 fill->setStrokeWidthUnit( d->strokeWidthUnits );
724 fill->setStrokeWidthMapUnitScale( d->strokeWidthMapUnitScale );
725 fill->setStrokeStyle( !qgsDoubleNear( d->strokeWidth, 0.0 ) ? Qt::SolidLine : Qt::NoPen );
726 fill->setPenJoinStyle( d->joinStyle );
727
729 fillSymbol->changeSymbolLayer( 0, fill );
731 }
732}
733
734QDomElement QgsTextBackgroundSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
735{
736 QDomElement backgroundElem = doc.createElement( u"background"_s );
737 backgroundElem.setAttribute( u"shapeDraw"_s, d->enabled );
738 backgroundElem.setAttribute( u"shapeType"_s, static_cast< unsigned int >( d->type ) );
739 backgroundElem.setAttribute( u"shapeSVGFile"_s, QgsSymbolLayerUtils::svgSymbolPathToName( d->svgFile, context.pathResolver() ) );
740 backgroundElem.setAttribute( u"shapeSizeType"_s, static_cast< unsigned int >( d->sizeType ) );
741 backgroundElem.setAttribute( u"shapeSizeX"_s, d->size.width() );
742 backgroundElem.setAttribute( u"shapeSizeY"_s, d->size.height() );
743 backgroundElem.setAttribute( u"shapeSizeUnit"_s, QgsUnitTypes::encodeUnit( d->sizeUnits ) );
744 backgroundElem.setAttribute( u"shapeSizeMapUnitScale"_s, QgsSymbolLayerUtils::encodeMapUnitScale( d->sizeMapUnitScale ) );
745 backgroundElem.setAttribute( u"shapeRotationType"_s, static_cast< unsigned int >( d->rotationType ) );
746 backgroundElem.setAttribute( u"shapeRotation"_s, d->rotation );
747 backgroundElem.setAttribute( u"shapeOffsetX"_s, d->offset.x() );
748 backgroundElem.setAttribute( u"shapeOffsetY"_s, d->offset.y() );
749 backgroundElem.setAttribute( u"shapeOffsetUnit"_s, QgsUnitTypes::encodeUnit( d->offsetUnits ) );
750 backgroundElem.setAttribute( u"shapeOffsetMapUnitScale"_s, QgsSymbolLayerUtils::encodeMapUnitScale( d->offsetMapUnitScale ) );
751 backgroundElem.setAttribute( u"shapeRadiiX"_s, d->radii.width() );
752 backgroundElem.setAttribute( u"shapeRadiiY"_s, d->radii.height() );
753 backgroundElem.setAttribute( u"shapeRadiiUnit"_s, QgsUnitTypes::encodeUnit( d->radiiUnits ) );
754 backgroundElem.setAttribute( u"shapeRadiiMapUnitScale"_s, QgsSymbolLayerUtils::encodeMapUnitScale( d->radiiMapUnitScale ) );
755 backgroundElem.setAttribute( u"shapeFillColor"_s, QgsColorUtils::colorToString( d->fillColor ) );
756 backgroundElem.setAttribute( u"shapeBorderColor"_s, QgsColorUtils::colorToString( d->strokeColor ) );
757 backgroundElem.setAttribute( u"shapeBorderWidth"_s, d->strokeWidth );
758 backgroundElem.setAttribute( u"shapeBorderWidthUnit"_s, QgsUnitTypes::encodeUnit( d->strokeWidthUnits ) );
759 backgroundElem.setAttribute( u"shapeBorderWidthMapUnitScale"_s, QgsSymbolLayerUtils::encodeMapUnitScale( d->strokeWidthMapUnitScale ) );
760 backgroundElem.setAttribute( u"shapeJoinStyle"_s, static_cast< unsigned int >( d->joinStyle ) );
761 backgroundElem.setAttribute( u"shapeOpacity"_s, d->opacity );
762 backgroundElem.setAttribute( u"shapeBlendMode"_s, static_cast< int >( QgsPainting::getBlendModeEnum( d->blendMode ) ) );
763 if ( d->paintEffect && !QgsPaintEffectRegistry::isDefaultStack( d->paintEffect.get() ) )
764 d->paintEffect->saveProperties( doc, backgroundElem );
765
766 if ( d->markerSymbol )
767 backgroundElem.appendChild( QgsSymbolLayerUtils::saveSymbol( u"markerSymbol"_s, d->markerSymbol.get(), doc, context ) );
768
769 if ( d->fillSymbol )
770 backgroundElem.appendChild( QgsSymbolLayerUtils::saveSymbol( u"fillSymbol"_s, d->fillSymbol.get(), doc, context ) );
771
772 return backgroundElem;
773}
774
776{
777 if ( !d->fillSymbol || d->fillSymbol->symbolLayers().at( 0 )->layerType() != "SimpleFill"_L1 )
778 return;
779 QgsSimpleFillSymbolLayer *fill = qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) );
780
782 {
785 {
788 }
789
792 {
795 }
796
799 {
802 }
803
806 {
809 }
810 }
811}
812
814{
816 {
817 context.expressionContext().setOriginalValueVariable( d->enabled );
818 d->enabled = properties.valueAsBool( QgsPalLayerSettings::Property::ShapeDraw, context.expressionContext(), d->enabled );
819 }
820
822 {
823 context.expressionContext().setOriginalValueVariable( d->size.width() );
824 d->size.setWidth( properties.valueAsDouble( QgsPalLayerSettings::Property::ShapeSizeX, context.expressionContext(), d->size.width() ) );
825 }
827 {
828 context.expressionContext().setOriginalValueVariable( d->size.height() );
829 d->size.setHeight( properties.valueAsDouble( QgsPalLayerSettings::Property::ShapeSizeY, context.expressionContext(), d->size.height() ) );
830 }
831
832 QVariant exprVal = properties.value( QgsPalLayerSettings::Property::ShapeSizeUnits, context.expressionContext() );
833 if ( !QgsVariantUtils::isNull( exprVal ) )
834 {
835 const QString units = exprVal.toString();
836 if ( !units.isEmpty() )
837 {
838 bool ok;
839 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
840 if ( ok )
841 d->sizeUnits = res;
842 }
843 }
844
845 exprVal = properties.value( QgsPalLayerSettings::Property::ShapeKind, context.expressionContext() );
846 if ( !QgsVariantUtils::isNull( exprVal ) )
847 {
848 const QString skind = exprVal.toString().trimmed();
849 if ( !skind.isEmpty() )
850 {
851 d->type = QgsTextRendererUtils::decodeShapeType( skind );
852 }
853 }
854
856 if ( !QgsVariantUtils::isNull( exprVal ) )
857 {
858 const QString stype = exprVal.toString().trimmed();
859 if ( !stype.isEmpty() )
860 {
862 }
863 }
864
865 // data defined shape SVG path?
866 context.expressionContext().setOriginalValueVariable( d->svgFile );
868 if ( !QgsVariantUtils::isNull( exprVal ) )
869 {
870 const QString svgfile = exprVal.toString().trimmed();
871 d->svgFile = QgsSymbolLayerUtils::svgSymbolNameToPath( svgfile, context.pathResolver() );
872 }
873
875 {
876 context.expressionContext().setOriginalValueVariable( d->rotation );
877 d->rotation = properties.valueAsDouble( QgsPalLayerSettings::Property::ShapeRotation, context.expressionContext(), d->rotation );
878 }
880 if ( !QgsVariantUtils::isNull( exprVal ) )
881 {
882 const QString rotstr = exprVal.toString().trimmed();
883 if ( !rotstr.isEmpty() )
884 {
885 d->rotationType = QgsTextRendererUtils::decodeBackgroundRotationType( rotstr );
886 }
887 }
888
889 exprVal = properties.value( QgsPalLayerSettings::Property::ShapeOffset, context.expressionContext() );
890 if ( !QgsVariantUtils::isNull( exprVal ) )
891 {
892 bool ok = false;
893 const QPointF res = QgsSymbolLayerUtils::toPoint( exprVal, &ok );
894 if ( ok )
895 {
896 d->offset = res;
897 }
898 }
900 if ( !QgsVariantUtils::isNull( exprVal ) )
901 {
902 const QString units = exprVal.toString();
903 if ( !units.isEmpty() )
904 {
905 bool ok;
906 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
907 if ( ok )
908 d->offsetUnits = res;
909 }
910 }
911
912 exprVal = properties.value( QgsPalLayerSettings::Property::ShapeRadii, context.expressionContext() );
913 if ( !QgsVariantUtils::isNull( exprVal ) )
914 {
915 bool ok = false;
916 const QSizeF res = QgsSymbolLayerUtils::toSize( exprVal, &ok );
917 if ( ok )
918 {
919 d->radii = res;
920 }
921 }
922
924 if ( !QgsVariantUtils::isNull( exprVal ) )
925 {
926 const QString units = exprVal.toString();
927 if ( !units.isEmpty() )
928 {
929 bool ok;
930 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
931 if ( ok )
932 d->radiiUnits = res;
933 }
934 }
935
937 {
938 context.expressionContext().setOriginalValueVariable( d->opacity * 100 );
939 const QVariant val = properties.value( QgsPalLayerSettings::Property::ShapeOpacity, context.expressionContext(), d->opacity * 100 );
940 if ( !QgsVariantUtils::isNull( val ) )
941 {
942 d->opacity = val.toDouble() / 100.0;
943 }
944 }
945
946 // for non-SVG background types, using data defined properties within the fill symbol is preferable
948 {
951 }
953 {
956 }
957
959 {
960 context.expressionContext().setOriginalValueVariable( d->strokeWidth );
962 }
964 if ( !QgsVariantUtils::isNull( exprVal ) )
965 {
966 const QString units = exprVal.toString();
967 if ( !units.isEmpty() )
968 {
969 bool ok;
970 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
971 if ( ok )
972 setStrokeWidthUnit( res );
973 }
974 }
975
977 {
979 const QString blendstr = exprVal.toString().trimmed();
980 if ( !blendstr.isEmpty() )
981 d->blendMode = QgsSymbolLayerUtils::decodeBlendMode( blendstr );
982 }
983
985 {
987 const QString joinstr = exprVal.toString().trimmed();
988 if ( !joinstr.isEmpty() )
989 {
991 }
992 }
993}
994
996{
997 QSet< QString > fields;
998 if ( d->markerSymbol )
999 {
1000 fields.unite( d->markerSymbol->usedAttributes( context ) );
1001 }
1002 if ( d->fillSymbol )
1003 {
1004 fields.unite( d->fillSymbol->usedAttributes( context ) );
1005 }
1006 return fields;
1007}
BlendMode
Blending modes defining the available composition modes that can be used when painting.
Definition qgis.h:5037
@ Normal
Normal.
Definition qgis.h:5038
RenderUnit
Rendering size units.
Definition qgis.h:5290
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.
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.
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.
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
Struct for storing maximum and minimum scales for measurements in map units.
A marker symbol type, for rendering Point and MultiPoint geometries.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
Base class for visual effects which can be applied to QPicture drawings.
bool enabled() const
Returns whether the effect is enabled.
virtual QVariantMap properties() const =0
Returns the properties describing the paint effect encoded in a string format.
static Qgis::BlendMode getBlendModeEnum(QPainter::CompositionMode blendMode)
Returns a Qgis::BlendMode corresponding to a QPainter::CompositionMode.
static QPainter::CompositionMode getCompositionMode(Qgis::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a Qgis::BlendMode.
A grouped map of multiple QgsProperty objects, each referenced by an integer key value.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const final
Returns the calculated value of the property with the specified key from within the collection.
bool hasProperty(int key) const final
Returns true if the collection contains a property with the specified key.
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
A store for object properties.
A container for the context for various read/write operations on objects.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
Contains information about the context of a rendering operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
Renders polygons using a single fill and stroke color.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
void setStrokeWidthUnit(Qgis::RenderUnit unit)
Sets the units for the width of the fill's stroke.
void setPenJoinStyle(Qt::PenJoinStyle style)
void setStrokeWidth(double strokeWidth)
void setStrokeStyle(Qt::PenStyle strokeStyle)
static void clearSymbolLayerIds(QgsSymbol *symbol)
Remove recursively unique id from all symbol symbol layers and set an empty string instead.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QSizeF toSize(const QVariant &value, bool *ok=nullptr)
Converts a value to a size.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QPainter::CompositionMode decodeBlendMode(const QString &s)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
@ JoinStyle
Line join style.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
QgsMapUnitScale strokeWidthMapUnitScale() const
Returns the map unit scale object for the shape stroke width.
void setRadiiUnit(Qgis::RenderUnit units)
Sets the units used for the shape's radii.
void setFillSymbol(QgsFillSymbol *symbol)
Sets the current fill symbol for the background shape.
RotationType rotationType() const
Returns the method used for rotating the background shape.
QString svgFile() const
Returns the absolute path to the background SVG file, if set.
QSizeF size() const
Returns the size of the background shape.
QSizeF radii() const
Returns the radii used for rounding the corners of shapes.
QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns all field names referenced by the configuration (e.g.
QgsMapUnitScale radiiMapUnitScale() const
Returns the map unit scale object for the shape radii.
void upgradeDataDefinedProperties(QgsPropertyCollection &properties)
Upgrade data defined properties when reading a project file saved in QGIS prior to version 3....
void setOpacity(double opacity)
Sets the background shape's opacity.
void setStrokeColor(const QColor &color)
Sets the color used for outlining the background shape.
Qgis::RenderUnit radiiUnit() const
Returns the units used for the shape's radii.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape size.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the background shape.
Qt::PenJoinStyle joinStyle() const
Returns the join style used for drawing the background shape.
SizeType
Methods for determining the background shape size.
@ SizeBuffer
Shape size is determined by adding a buffer margin around text.
bool enabled() const
Returns whether the background is enabled.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the background shape.
double opacity() const
Returns the background shape's opacity.
bool operator!=(const QgsTextBackgroundSettings &other) const
void updateDataDefinedProperties(QgsRenderContext &context, const QgsPropertyCollection &properties)
Updates the format by evaluating current values of data defined properties.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape stroke width.
double rotation() const
Returns the rotation for the background shape, in degrees clockwise.
QColor fillColor() const
Returns the color used for filing the background shape.
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the current marker symbol for the background shape.
void setRadii(QSizeF radii)
Sets the radii used for rounding the corners of shapes.
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
QgsTextBackgroundSettings & operator=(const QgsTextBackgroundSettings &other)
Qgis::RenderUnit strokeWidthUnit() const
Returns the units used for the shape's stroke width.
ShapeType type() const
Returns the type of background shape (e.g., square, ellipse, SVG).
double strokeWidth() const
Returns the width of the shape's stroke (stroke).
void setSizeType(SizeType type)
Sets the method used to determine the size of the background shape (e.g., fixed size or buffer around...
void setFillColor(const QColor &color)
Sets the color used for filing the background shape.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the background shape.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units used for the shape's size.
Qgis::RenderUnit offsetUnit() const
Returns the units used for the shape's offset.
QColor strokeColor() const
Returns the color used for outlining the background shape.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
void setRotationType(RotationType type)
Sets the method used for rotating the background shape.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape offset.
QgsFillSymbol * fillSymbol() const
Returns the fill symbol to be rendered in the background.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the background shape.
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the shape size.
void setType(ShapeType type)
Sets the type of background shape to draw (e.g., square, ellipse, SVG).
Qgis::RenderUnit sizeUnit() const
Returns the units used for the shape's size.
RotationType
Methods for determining the rotation of the background shape.
@ RotationSync
Shape rotation is synced with text rotation.
bool operator==(const QgsTextBackgroundSettings &other) const
void setEnabled(bool enabled)
Sets whether the text background will be drawn.
QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol to be rendered in the background.
void setRadiiMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape radii.
void setRotation(double rotation)
Sets the rotation for the background shape, in degrees clockwise.
void setStrokeWidthUnit(Qgis::RenderUnit units)
Sets the units used for the shape's stroke width.
void setOffsetUnit(Qgis::RenderUnit units)
Sets the units used for the shape's offset.
void setOffset(QPointF offset)
Sets the offset used for drawing the background shape.
void setSize(QSizeF size)
Sets the size of the background shape.
const QgsPaintEffect * paintEffect() const
Returns the current paint effect for the background shape.
void setSvgFile(const QString &file)
Sets the path to the background SVG file.
QgsMapUnitScale offsetMapUnitScale() const
Returns the map unit scale object for the shape offset.
void setStrokeWidth(double width)
Sets the width of the shape's stroke (stroke).
QPointF offset() const
Returns the offset used for drawing the background shape.
static QgsTextBackgroundSettings::ShapeType decodeShapeType(const QString &string)
Decodes a string representation of a background shape type to a type.
static QColor readColor(QgsVectorLayer *layer, const QString &property, const QColor &defaultColor=Qt::black, bool withAlpha=true)
Converts an encoded color value from a layer property.
static QgsTextBackgroundSettings::RotationType decodeBackgroundRotationType(const QString &string)
Decodes a string representation of a background rotation type to a type.
static QgsTextBackgroundSettings::SizeType decodeBackgroundSizeType(const QString &string)
Decodes a string representation of a background size type to a type.
static Qgis::RenderUnit convertFromOldLabelUnit(int val)
Converts a unit from an old (pre 3.0) label unit.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based dataset.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6935