QGIS API Documentation 4.1.0-Master (60fea48833c)
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
54
56 : d( std::move( other.d ) )
57{}
58
60{
61 if ( &other == this )
62 return *this;
63
64 d = other.d;
65 return *this;
66}
67
69{
70 if ( &other == this )
71 return *this;
72
73 d = std::move( other.d );
74 return *this;
75}
76
79
81{
82 if ( d->enabled != other.enabled()
83 || d->type != other.type()
84 || d->svgFile != other.svgFile()
85 || d->sizeType != other.sizeType()
86 || d->size != other.size()
87 || d->sizeUnits != other.sizeUnit()
88 || d->sizeMapUnitScale != other.sizeMapUnitScale()
89 || d->rotationType != other.rotationType()
90 || d->rotation != other.rotation()
91 || d->offset != other.offset()
92 || d->offsetUnits != other.offsetUnit()
93 || d->offsetMapUnitScale != other.offsetMapUnitScale()
94 || d->radii != other.radii()
95 || d->radiiUnits != other.radiiUnit()
96 || d->radiiMapUnitScale != other.radiiMapUnitScale()
97 || d->blendMode != other.blendMode()
98 || d->fillColor != other.fillColor()
99 || d->strokeColor != other.strokeColor()
100 || d->opacity != other.opacity()
101 || d->strokeWidth != other.strokeWidth()
102 || d->strokeWidthUnits != other.strokeWidthUnit()
103 || d->strokeWidthMapUnitScale != other.strokeWidthMapUnitScale()
104 || d->joinStyle != other.joinStyle() )
105 return false;
106
107 if ( static_cast< bool >( d->paintEffect ) != static_cast< bool >( other.paintEffect() ) || ( d->paintEffect && d->paintEffect->properties() != other.paintEffect()->properties() ) )
108 return false;
109
110 if ( static_cast< bool >( d->markerSymbol ) != static_cast< bool >( other.markerSymbol() )
111 || ( d->markerSymbol && QgsSymbolLayerUtils::symbolProperties( d->markerSymbol.get() ) != QgsSymbolLayerUtils::symbolProperties( other.markerSymbol() ) ) )
112 return false;
113
114 if ( static_cast< bool >( d->fillSymbol ) != static_cast< bool >( other.fillSymbol() )
115 || ( d->fillSymbol && QgsSymbolLayerUtils::symbolProperties( d->fillSymbol.get() ) != QgsSymbolLayerUtils::symbolProperties( other.fillSymbol() ) ) )
116 return false;
117
118 return true;
119}
120
122{
123 return !( *this == other );
124}
125
127{
128 return d->enabled;
129}
130
132{
133 d->enabled = enabled;
134}
135
140
145
147{
148 return d->svgFile;
149}
150
151void QgsTextBackgroundSettings::setSvgFile( const QString &file )
152{
153 d->svgFile = file;
154}
155
157{
158 return d->markerSymbol.get();
159}
160
162{
163 if ( symbol )
164 // Remove symbol layer unique id to have correct settings equality
166
167 d->markerSymbol.reset( symbol );
168}
169
171{
172 return d->fillSymbol.get();
173}
174
176{
177 if ( symbol )
178 // Remove symbol layer unique id to have correct settings equality
180
181 d->fillSymbol.reset( symbol );
182}
183
188
193
195{
196 return d->size;
197}
198
200{
201 d->size = size;
202}
203
205{
206 return d->sizeUnits;
207}
208
210{
211 d->sizeUnits = unit;
212}
213
215{
216 return d->sizeMapUnitScale;
217}
218
220{
221 d->sizeMapUnitScale = scale;
222}
223
228
233
235{
236 return d->rotation;
237}
238
240{
241 d->rotation = rotation;
242}
243
245{
246 return d->offset;
247}
248
250{
251 d->offset = offset;
252}
253
255{
256 return d->offsetUnits;
257}
258
260{
261 d->offsetUnits = units;
262}
263
265{
266 return d->offsetMapUnitScale;
267}
268
270{
271 d->offsetMapUnitScale = scale;
272}
273
275{
276 return d->radii;
277}
278
280{
281 d->radii = radii;
282}
283
285{
286 return d->radiiUnits;
287}
288
290{
291 d->radiiUnits = units;
292}
293
295{
296 return d->radiiMapUnitScale;
297}
298
300{
301 d->radiiMapUnitScale = scale;
302}
303
305{
306 return d->opacity;
307}
308
310{
311 d->opacity = opacity;
312}
313
314QPainter::CompositionMode QgsTextBackgroundSettings::blendMode() const
315{
316 return d->blendMode;
317}
318
319void QgsTextBackgroundSettings::setBlendMode( QPainter::CompositionMode mode )
320{
321 d->blendMode = mode;
322}
323
325{
326 return d->fillSymbol ? d->fillSymbol->color() : d->fillColor;
327}
328
330{
331 d->fillColor = color;
332 if ( d->fillSymbol )
333 {
334 d->fillSymbol->setColor( color );
335 }
336}
337
339{
340 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
341 {
342 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->strokeColor();
343 }
344 return d->strokeColor;
345}
346
348{
349 d->strokeColor = color;
350 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
351 {
352 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setStrokeColor( color );
353 }
354}
355
357{
358 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
359 {
360 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->strokeWidth();
361 }
362 return d->strokeWidth;
363}
364
366{
367 d->strokeWidth = width;
368 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
369 {
370 QgsSimpleFillSymbolLayer *fill = qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) );
371 fill->setStrokeWidth( width );
372 fill->setStrokeStyle( !qgsDoubleNear( width, 0.0 ) ? Qt::SolidLine : Qt::NoPen );
373 }
374}
375
377{
378 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
379 {
380 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->strokeWidthUnit();
381 }
382 return d->strokeWidthUnits;
383}
384
386{
387 d->strokeWidthUnits = units;
388 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
389 {
390 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setStrokeWidthUnit( units );
391 }
392}
393
395{
396 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
397 {
398 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->strokeWidthMapUnitScale();
399 }
400 return d->strokeWidthMapUnitScale;
401}
402
404{
405 d->strokeWidthMapUnitScale = scale;
406 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
407 {
408 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setStrokeWidthMapUnitScale( scale );
409 }
410}
411
413{
414 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
415 {
416 return qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->penJoinStyle();
417 }
418 return d->joinStyle;
419}
420
421void QgsTextBackgroundSettings::setJoinStyle( Qt::PenJoinStyle style )
422{
423 d->joinStyle = style;
424 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == "SimpleFill"_L1 )
425 {
426 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setPenJoinStyle( style );
427 }
428}
429
431{
432 return d->paintEffect.get();
433}
434
436{
437 d->paintEffect.reset( effect );
438}
439
441{
442 d->enabled = layer->customProperty( u"labeling/shapeDraw"_s, QVariant( false ) ).toBool();
443 d->type = static_cast< ShapeType >( layer->customProperty( u"labeling/shapeType"_s, QVariant( ShapeRectangle ) ).toUInt() );
444 d->svgFile = layer->customProperty( u"labeling/shapeSVGFile"_s, QVariant( "" ) ).toString();
445 d->sizeType = static_cast< SizeType >( layer->customProperty( u"labeling/shapeSizeType"_s, QVariant( SizeBuffer ) ).toUInt() );
446 d->size = QSizeF( layer->customProperty( u"labeling/shapeSizeX"_s, QVariant( 0.0 ) ).toDouble(), layer->customProperty( u"labeling/shapeSizeY"_s, QVariant( 0.0 ) ).toDouble() );
447
448 if ( layer->customProperty( u"labeling/shapeSizeUnit"_s ).toString().isEmpty() )
449 {
450 d->sizeUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( u"labeling/shapeSizeUnits"_s, 0 ).toUInt() );
451 }
452 else
453 {
454 d->sizeUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( u"labeling/shapeSizeUnit"_s ).toString() );
455 }
456
457 if ( layer->customProperty( u"labeling/shapeSizeMapUnitScale"_s ).toString().isEmpty() )
458 {
459 //fallback to older property
460 const double oldMin = layer->customProperty( u"labeling/shapeSizeMapUnitMinScale"_s, 0.0 ).toDouble();
461 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
462 const double oldMax = layer->customProperty( u"labeling/shapeSizeMapUnitMaxScale"_s, 0.0 ).toDouble();
463 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
464 }
465 else
466 {
467 d->sizeMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( u"labeling/shapeSizeMapUnitScale"_s ).toString() );
468 }
469 d->rotationType = static_cast< RotationType >( layer->customProperty( u"labeling/shapeRotationType"_s, QVariant( RotationSync ) ).toUInt() );
470 d->rotation = layer->customProperty( u"labeling/shapeRotation"_s, QVariant( 0.0 ) ).toDouble();
471 d->offset = QPointF( layer->customProperty( u"labeling/shapeOffsetX"_s, QVariant( 0.0 ) ).toDouble(), layer->customProperty( u"labeling/shapeOffsetY"_s, QVariant( 0.0 ) ).toDouble() );
472
473 if ( layer->customProperty( u"labeling/shapeOffsetUnit"_s ).toString().isEmpty() )
474 {
475 d->offsetUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( u"labeling/shapeOffsetUnits"_s, 0 ).toUInt() );
476 }
477 else
478 {
479 d->offsetUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( u"labeling/shapeOffsetUnit"_s ).toString() );
480 }
481
482 if ( layer->customProperty( u"labeling/shapeOffsetMapUnitScale"_s ).toString().isEmpty() )
483 {
484 //fallback to older property
485 const double oldMin = layer->customProperty( u"labeling/shapeOffsetMapUnitMinScale"_s, 0.0 ).toDouble();
486 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
487 const double oldMax = layer->customProperty( u"labeling/shapeOffsetMapUnitMaxScale"_s, 0.0 ).toDouble();
488 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
489 }
490 else
491 {
492 d->offsetMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( u"labeling/shapeOffsetMapUnitScale"_s ).toString() );
493 }
494 d->radii = QSizeF( layer->customProperty( u"labeling/shapeRadiiX"_s, QVariant( 0.0 ) ).toDouble(), layer->customProperty( u"labeling/shapeRadiiY"_s, QVariant( 0.0 ) ).toDouble() );
495
496
497 if ( layer->customProperty( u"labeling/shapeRadiiUnit"_s ).toString().isEmpty() )
498 {
499 d->radiiUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( u"labeling/shapeRadiiUnits"_s, 0 ).toUInt() );
500 }
501 else
502 {
503 d->radiiUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( u"labeling/shapeRadiiUnit"_s ).toString() );
504 }
505
506 if ( layer->customProperty( u"labeling/shapeRadiiMapUnitScale"_s ).toString().isEmpty() )
507 {
508 //fallback to older property
509 const double oldMin = layer->customProperty( u"labeling/shapeRadiiMapUnitMinScale"_s, 0.0 ).toDouble();
510 d->radiiMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
511 const double oldMax = layer->customProperty( u"labeling/shapeRadiiMapUnitMaxScale"_s, 0.0 ).toDouble();
512 d->radiiMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
513 }
514 else
515 {
516 d->radiiMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( u"labeling/shapeRadiiMapUnitScale"_s ).toString() );
517 }
518 d->fillColor = QgsTextRendererUtils::readColor( layer, u"labeling/shapeFillColor"_s, Qt::white, true );
519 d->strokeColor = QgsTextRendererUtils::readColor( layer, u"labeling/shapeBorderColor"_s, Qt::darkGray, true );
520 d->strokeWidth = layer->customProperty( u"labeling/shapeBorderWidth"_s, QVariant( .0 ) ).toDouble();
521 if ( layer->customProperty( u"labeling/shapeBorderWidthUnit"_s ).toString().isEmpty() )
522 {
523 d->strokeWidthUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( u"labeling/shapeBorderWidthUnits"_s, 0 ).toUInt() );
524 }
525 else
526 {
527 d->strokeWidthUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( u"labeling/shapeBorderWidthUnit"_s ).toString() );
528 }
529 if ( layer->customProperty( u"labeling/shapeBorderWidthMapUnitScale"_s ).toString().isEmpty() )
530 {
531 //fallback to older property
532 const double oldMin = layer->customProperty( u"labeling/shapeBorderWidthMapUnitMinScale"_s, 0.0 ).toDouble();
533 d->strokeWidthMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
534 const double oldMax = layer->customProperty( u"labeling/shapeBorderWidthMapUnitMaxScale"_s, 0.0 ).toDouble();
535 d->strokeWidthMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
536 }
537 else
538 {
539 d->strokeWidthMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( u"labeling/shapeBorderWidthMapUnitScale"_s ).toString() );
540 }
541 d->joinStyle = static_cast< Qt::PenJoinStyle >( layer->customProperty( u"labeling/shapeJoinStyle"_s, QVariant( Qt::BevelJoin ) ).toUInt() );
542
543 if ( layer->customProperty( u"labeling/shapeOpacity"_s ).toString().isEmpty() )
544 {
545 d->opacity = ( 1 - layer->customProperty( u"labeling/shapeTransparency"_s ).toInt() / 100.0 ); //0 -100
546 }
547 else
548 {
549 d->opacity = ( layer->customProperty( u"labeling/shapeOpacity"_s ).toDouble() );
550 }
551 d->blendMode = QgsPainting::getCompositionMode(
552 static_cast< Qgis::BlendMode >( layer->customProperty( u"labeling/shapeBlendMode"_s, QVariant( static_cast< int>( Qgis::BlendMode::Normal ) ) ).toUInt() )
553 );
554
555 if ( layer->customProperty( u"labeling/shapeEffect"_s ).isValid() )
556 {
557 QDomDocument doc( u"effect"_s );
558 doc.setContent( layer->customProperty( u"labeling/shapeEffect"_s ).toString() );
559 const QDomElement effectElem = doc.firstChildElement( u"effect"_s ).firstChildElement( u"effect"_s );
560 setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
561 }
562 else
563 setPaintEffect( nullptr );
564}
565
566void QgsTextBackgroundSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
567{
568 const QDomElement backgroundElem = elem.firstChildElement( u"background"_s );
569 d->enabled = backgroundElem.attribute( u"shapeDraw"_s, u"0"_s ).toInt();
570 d->type = static_cast< ShapeType >( backgroundElem.attribute( u"shapeType"_s, QString::number( ShapeRectangle ) ).toUInt() );
571 d->svgFile = QgsSymbolLayerUtils::svgSymbolNameToPath( backgroundElem.attribute( u"shapeSVGFile"_s ), context.pathResolver() );
572 d->sizeType = static_cast< SizeType >( backgroundElem.attribute( u"shapeSizeType"_s, QString::number( SizeBuffer ) ).toUInt() );
573 d->size = QSizeF( backgroundElem.attribute( u"shapeSizeX"_s, u"0"_s ).toDouble(), backgroundElem.attribute( u"shapeSizeY"_s, u"0"_s ).toDouble() );
574
575 if ( !backgroundElem.hasAttribute( u"shapeSizeUnit"_s ) )
576 {
577 d->sizeUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( u"shapeSizeUnits"_s ).toUInt() );
578 }
579 else
580 {
581 d->sizeUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( u"shapeSizeUnit"_s ) );
582 }
583
584 if ( !backgroundElem.hasAttribute( u"shapeSizeMapUnitScale"_s ) )
585 {
586 //fallback to older property
587 const double oldMin = backgroundElem.attribute( u"shapeSizeMapUnitMinScale"_s, u"0"_s ).toDouble();
588 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
589 const double oldMax = backgroundElem.attribute( u"shapeSizeMapUnitMaxScale"_s, u"0"_s ).toDouble();
590 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
591 }
592 else
593 {
594 d->sizeMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( u"shapeSizeMapUnitScale"_s ) );
595 }
596 d->rotationType = static_cast< RotationType >( backgroundElem.attribute( u"shapeRotationType"_s, QString::number( RotationSync ) ).toUInt() );
597 d->rotation = backgroundElem.attribute( u"shapeRotation"_s, u"0"_s ).toDouble();
598 d->offset = QPointF( backgroundElem.attribute( u"shapeOffsetX"_s, u"0"_s ).toDouble(), backgroundElem.attribute( u"shapeOffsetY"_s, u"0"_s ).toDouble() );
599
600 if ( !backgroundElem.hasAttribute( u"shapeOffsetUnit"_s ) )
601 {
602 d->offsetUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( u"shapeOffsetUnits"_s ).toUInt() );
603 }
604 else
605 {
606 d->offsetUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( u"shapeOffsetUnit"_s ) );
607 }
608
609 if ( !backgroundElem.hasAttribute( u"shapeOffsetMapUnitScale"_s ) )
610 {
611 //fallback to older property
612 const double oldMin = backgroundElem.attribute( u"shapeOffsetMapUnitMinScale"_s, u"0"_s ).toDouble();
613 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
614 const double oldMax = backgroundElem.attribute( u"shapeOffsetMapUnitMaxScale"_s, u"0"_s ).toDouble();
615 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
616 }
617 else
618 {
619 d->offsetMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( u"shapeOffsetMapUnitScale"_s ) );
620 }
621 d->radii = QSizeF( backgroundElem.attribute( u"shapeRadiiX"_s, u"0"_s ).toDouble(), backgroundElem.attribute( u"shapeRadiiY"_s, u"0"_s ).toDouble() );
622
623 if ( !backgroundElem.hasAttribute( u"shapeRadiiUnit"_s ) )
624 {
625 d->radiiUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( u"shapeRadiiUnits"_s ).toUInt() );
626 }
627 else
628 {
629 d->radiiUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( u"shapeRadiiUnit"_s ) );
630 }
631 if ( !backgroundElem.hasAttribute( u"shapeRadiiMapUnitScale"_s ) )
632 {
633 //fallback to older property
634 const double oldMin = backgroundElem.attribute( u"shapeRadiiMapUnitMinScale"_s, u"0"_s ).toDouble();
635 d->radiiMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
636 const double oldMax = backgroundElem.attribute( u"shapeRadiiMapUnitMaxScale"_s, u"0"_s ).toDouble();
637 d->radiiMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
638 }
639 else
640 {
641 d->radiiMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( u"shapeRadiiMapUnitScale"_s ) );
642 }
643 d->fillColor = QgsColorUtils::colorFromString( backgroundElem.attribute( u"shapeFillColor"_s, QgsColorUtils::colorToString( Qt::white ) ) );
644 d->strokeColor = QgsColorUtils::colorFromString( backgroundElem.attribute( u"shapeBorderColor"_s, QgsColorUtils::colorToString( Qt::darkGray ) ) );
645 d->strokeWidth = backgroundElem.attribute( u"shapeBorderWidth"_s, u"0"_s ).toDouble();
646
647 if ( !backgroundElem.hasAttribute( u"shapeBorderWidthUnit"_s ) )
648 {
649 d->strokeWidthUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( u"shapeBorderWidthUnits"_s ).toUInt() );
650 }
651 else
652 {
653 d->strokeWidthUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( u"shapeBorderWidthUnit"_s ) );
654 }
655 if ( !backgroundElem.hasAttribute( u"shapeBorderWidthMapUnitScale"_s ) )
656 {
657 //fallback to older property
658 const double oldMin = backgroundElem.attribute( u"shapeBorderWidthMapUnitMinScale"_s, u"0"_s ).toDouble();
659 d->strokeWidthMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
660 const double oldMax = backgroundElem.attribute( u"shapeBorderWidthMapUnitMaxScale"_s, u"0"_s ).toDouble();
661 d->strokeWidthMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
662 }
663 else
664 {
665 d->strokeWidthMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( u"shapeBorderWidthMapUnitScale"_s ) );
666 }
667 d->joinStyle = static_cast< Qt::PenJoinStyle >( backgroundElem.attribute( u"shapeJoinStyle"_s, QString::number( Qt::BevelJoin ) ).toUInt() );
668
669 if ( !backgroundElem.hasAttribute( u"shapeOpacity"_s ) )
670 {
671 d->opacity = ( 1 - backgroundElem.attribute( u"shapeTransparency"_s ).toInt() / 100.0 ); //0 -100
672 }
673 else
674 {
675 d->opacity = ( backgroundElem.attribute( u"shapeOpacity"_s ).toDouble() );
676 }
677
678 d->blendMode = QgsPainting::getCompositionMode(
679 static_cast< Qgis::BlendMode >( backgroundElem.attribute( u"shapeBlendMode"_s, QString::number( static_cast< int >( Qgis::BlendMode::Normal ) ) ).toUInt() )
680 );
681
682 const QDomElement effectElem = backgroundElem.firstChildElement( u"effect"_s );
683 if ( !effectElem.isNull() )
684 setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
685 else
686 setPaintEffect( nullptr );
687
688 setMarkerSymbol( nullptr );
689 setFillSymbol( nullptr );
690 const QDomNodeList symbols = backgroundElem.elementsByTagName( u"symbol"_s );
691 for ( int i = 0; i < symbols.size(); ++i )
692 {
693 if ( symbols.at( i ).isElement() )
694 {
695 const QDomElement symbolElement = symbols.at( i ).toElement();
696 const QString symbolElementName = symbolElement.attribute( u"name"_s );
697 if ( symbolElementName == "markerSymbol"_L1 )
698 {
699 setMarkerSymbol( QgsSymbolLayerUtils::loadSymbol< QgsMarkerSymbol >( symbolElement, context ).release() );
700 }
701 else if ( symbolElementName == "fillSymbol"_L1 )
702 {
703 setFillSymbol( QgsSymbolLayerUtils::loadSymbol< QgsFillSymbol >( symbolElement, context ).release() );
704 }
705 }
706 }
707
708 if ( !d->fillSymbol )
709 {
710 QgsSimpleFillSymbolLayer *fill = new QgsSimpleFillSymbolLayer( d->fillColor, Qt::SolidPattern, d->strokeColor );
711 fill->setStrokeWidth( d->strokeWidth );
712 fill->setStrokeWidthUnit( d->strokeWidthUnits );
713 fill->setStrokeWidthMapUnitScale( d->strokeWidthMapUnitScale );
714 fill->setStrokeStyle( !qgsDoubleNear( d->strokeWidth, 0.0 ) ? Qt::SolidLine : Qt::NoPen );
715 fill->setPenJoinStyle( d->joinStyle );
716
718 fillSymbol->changeSymbolLayer( 0, fill );
720 }
721}
722
723QDomElement QgsTextBackgroundSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
724{
725 QDomElement backgroundElem = doc.createElement( u"background"_s );
726 backgroundElem.setAttribute( u"shapeDraw"_s, d->enabled );
727 backgroundElem.setAttribute( u"shapeType"_s, static_cast< unsigned int >( d->type ) );
728 backgroundElem.setAttribute( u"shapeSVGFile"_s, QgsSymbolLayerUtils::svgSymbolPathToName( d->svgFile, context.pathResolver() ) );
729 backgroundElem.setAttribute( u"shapeSizeType"_s, static_cast< unsigned int >( d->sizeType ) );
730 backgroundElem.setAttribute( u"shapeSizeX"_s, d->size.width() );
731 backgroundElem.setAttribute( u"shapeSizeY"_s, d->size.height() );
732 backgroundElem.setAttribute( u"shapeSizeUnit"_s, QgsUnitTypes::encodeUnit( d->sizeUnits ) );
733 backgroundElem.setAttribute( u"shapeSizeMapUnitScale"_s, QgsSymbolLayerUtils::encodeMapUnitScale( d->sizeMapUnitScale ) );
734 backgroundElem.setAttribute( u"shapeRotationType"_s, static_cast< unsigned int >( d->rotationType ) );
735 backgroundElem.setAttribute( u"shapeRotation"_s, d->rotation );
736 backgroundElem.setAttribute( u"shapeOffsetX"_s, d->offset.x() );
737 backgroundElem.setAttribute( u"shapeOffsetY"_s, d->offset.y() );
738 backgroundElem.setAttribute( u"shapeOffsetUnit"_s, QgsUnitTypes::encodeUnit( d->offsetUnits ) );
739 backgroundElem.setAttribute( u"shapeOffsetMapUnitScale"_s, QgsSymbolLayerUtils::encodeMapUnitScale( d->offsetMapUnitScale ) );
740 backgroundElem.setAttribute( u"shapeRadiiX"_s, d->radii.width() );
741 backgroundElem.setAttribute( u"shapeRadiiY"_s, d->radii.height() );
742 backgroundElem.setAttribute( u"shapeRadiiUnit"_s, QgsUnitTypes::encodeUnit( d->radiiUnits ) );
743 backgroundElem.setAttribute( u"shapeRadiiMapUnitScale"_s, QgsSymbolLayerUtils::encodeMapUnitScale( d->radiiMapUnitScale ) );
744 backgroundElem.setAttribute( u"shapeFillColor"_s, QgsColorUtils::colorToString( d->fillColor ) );
745 backgroundElem.setAttribute( u"shapeBorderColor"_s, QgsColorUtils::colorToString( d->strokeColor ) );
746 backgroundElem.setAttribute( u"shapeBorderWidth"_s, d->strokeWidth );
747 backgroundElem.setAttribute( u"shapeBorderWidthUnit"_s, QgsUnitTypes::encodeUnit( d->strokeWidthUnits ) );
748 backgroundElem.setAttribute( u"shapeBorderWidthMapUnitScale"_s, QgsSymbolLayerUtils::encodeMapUnitScale( d->strokeWidthMapUnitScale ) );
749 backgroundElem.setAttribute( u"shapeJoinStyle"_s, static_cast< unsigned int >( d->joinStyle ) );
750 backgroundElem.setAttribute( u"shapeOpacity"_s, d->opacity );
751 backgroundElem.setAttribute( u"shapeBlendMode"_s, static_cast< int >( QgsPainting::getBlendModeEnum( d->blendMode ) ) );
752 if ( d->paintEffect && !QgsPaintEffectRegistry::isDefaultStack( d->paintEffect.get() ) )
753 d->paintEffect->saveProperties( doc, backgroundElem );
754
755 if ( d->markerSymbol )
756 backgroundElem.appendChild( QgsSymbolLayerUtils::saveSymbol( u"markerSymbol"_s, d->markerSymbol.get(), doc, context ) );
757
758 if ( d->fillSymbol )
759 backgroundElem.appendChild( QgsSymbolLayerUtils::saveSymbol( u"fillSymbol"_s, d->fillSymbol.get(), doc, context ) );
760
761 return backgroundElem;
762}
763
765{
766 if ( !d->fillSymbol || d->fillSymbol->symbolLayers().at( 0 )->layerType() != "SimpleFill"_L1 )
767 return;
768 QgsSimpleFillSymbolLayer *fill = qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) );
769
771 {
773 {
776 }
777
779 {
782 }
783
785 {
788 }
789
791 {
794 }
795 }
796}
797
799{
801 {
802 context.expressionContext().setOriginalValueVariable( d->enabled );
803 d->enabled = properties.valueAsBool( QgsPalLayerSettings::Property::ShapeDraw, context.expressionContext(), d->enabled );
804 }
805
807 {
808 context.expressionContext().setOriginalValueVariable( d->size.width() );
809 d->size.setWidth( properties.valueAsDouble( QgsPalLayerSettings::Property::ShapeSizeX, context.expressionContext(), d->size.width() ) );
810 }
812 {
813 context.expressionContext().setOriginalValueVariable( d->size.height() );
814 d->size.setHeight( properties.valueAsDouble( QgsPalLayerSettings::Property::ShapeSizeY, context.expressionContext(), d->size.height() ) );
815 }
816
817 QVariant exprVal = properties.value( QgsPalLayerSettings::Property::ShapeSizeUnits, context.expressionContext() );
818 if ( !QgsVariantUtils::isNull( exprVal ) )
819 {
820 const QString units = exprVal.toString();
821 if ( !units.isEmpty() )
822 {
823 bool ok;
824 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
825 if ( ok )
826 d->sizeUnits = res;
827 }
828 }
829
830 exprVal = properties.value( QgsPalLayerSettings::Property::ShapeKind, context.expressionContext() );
831 if ( !QgsVariantUtils::isNull( exprVal ) )
832 {
833 const QString skind = exprVal.toString().trimmed();
834 if ( !skind.isEmpty() )
835 {
836 d->type = QgsTextRendererUtils::decodeShapeType( skind );
837 }
838 }
839
841 if ( !QgsVariantUtils::isNull( exprVal ) )
842 {
843 const QString stype = exprVal.toString().trimmed();
844 if ( !stype.isEmpty() )
845 {
847 }
848 }
849
850 // data defined shape SVG path?
851 context.expressionContext().setOriginalValueVariable( d->svgFile );
853 if ( !QgsVariantUtils::isNull( exprVal ) )
854 {
855 const QString svgfile = exprVal.toString().trimmed();
856 d->svgFile = QgsSymbolLayerUtils::svgSymbolNameToPath( svgfile, context.pathResolver() );
857 }
858
860 {
861 context.expressionContext().setOriginalValueVariable( d->rotation );
862 d->rotation = properties.valueAsDouble( QgsPalLayerSettings::Property::ShapeRotation, context.expressionContext(), d->rotation );
863 }
865 if ( !QgsVariantUtils::isNull( exprVal ) )
866 {
867 const QString rotstr = exprVal.toString().trimmed();
868 if ( !rotstr.isEmpty() )
869 {
870 d->rotationType = QgsTextRendererUtils::decodeBackgroundRotationType( rotstr );
871 }
872 }
873
874 exprVal = properties.value( QgsPalLayerSettings::Property::ShapeOffset, context.expressionContext() );
875 if ( !QgsVariantUtils::isNull( exprVal ) )
876 {
877 bool ok = false;
878 const QPointF res = QgsSymbolLayerUtils::toPoint( exprVal, &ok );
879 if ( ok )
880 {
881 d->offset = res;
882 }
883 }
885 if ( !QgsVariantUtils::isNull( exprVal ) )
886 {
887 const QString units = exprVal.toString();
888 if ( !units.isEmpty() )
889 {
890 bool ok;
891 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
892 if ( ok )
893 d->offsetUnits = res;
894 }
895 }
896
897 exprVal = properties.value( QgsPalLayerSettings::Property::ShapeRadii, context.expressionContext() );
898 if ( !QgsVariantUtils::isNull( exprVal ) )
899 {
900 bool ok = false;
901 const QSizeF res = QgsSymbolLayerUtils::toSize( exprVal, &ok );
902 if ( ok )
903 {
904 d->radii = res;
905 }
906 }
907
909 if ( !QgsVariantUtils::isNull( exprVal ) )
910 {
911 const QString units = exprVal.toString();
912 if ( !units.isEmpty() )
913 {
914 bool ok;
915 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
916 if ( ok )
917 d->radiiUnits = res;
918 }
919 }
920
922 {
923 context.expressionContext().setOriginalValueVariable( d->opacity * 100 );
924 const QVariant val = properties.value( QgsPalLayerSettings::Property::ShapeOpacity, context.expressionContext(), d->opacity * 100 );
925 if ( !QgsVariantUtils::isNull( val ) )
926 {
927 d->opacity = val.toDouble() / 100.0;
928 }
929 }
930
931 // for non-SVG background types, using data defined properties within the fill symbol is preferable
933 {
936 }
938 {
941 }
942
944 {
945 context.expressionContext().setOriginalValueVariable( d->strokeWidth );
947 }
949 if ( !QgsVariantUtils::isNull( exprVal ) )
950 {
951 const QString units = exprVal.toString();
952 if ( !units.isEmpty() )
953 {
954 bool ok;
955 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
956 if ( ok )
957 setStrokeWidthUnit( res );
958 }
959 }
960
962 {
964 const QString blendstr = exprVal.toString().trimmed();
965 if ( !blendstr.isEmpty() )
966 d->blendMode = QgsSymbolLayerUtils::decodeBlendMode( blendstr );
967 }
968
970 {
972 const QString joinstr = exprVal.toString().trimmed();
973 if ( !joinstr.isEmpty() )
974 {
976 }
977 }
978}
979
981{
982 QSet< QString > fields;
983 if ( d->markerSymbol )
984 {
985 fields.unite( d->markerSymbol->usedAttributes( context ) );
986 }
987 if ( d->fillSymbol )
988 {
989 fields.unite( d->fillSymbol->usedAttributes( context ) );
990 }
991 return fields;
992}
BlendMode
Blending modes defining the available composition modes that can be used when painting.
Definition qgis.h:5087
@ Normal
Normal.
Definition qgis.h:5088
RenderUnit
Rendering size units.
Definition qgis.h:5340
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:6975