QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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#include "qgstextrenderer_p.h"
18#include "qgsvectorlayer.h"
19#include "qgspallabeling.h"
20#include "qgssymbollayerutils.h"
21#include "qgsfillsymbollayer.h"
22#include "qgspainting.h"
25#include "qgsapplication.h"
26#include "qgsunittypes.h"
27
29{
30 d = new QgsTextBackgroundSettingsPrivate();
31
32 // Create a default fill symbol to preserve API promise until QGIS 4.0
33 QgsSimpleFillSymbolLayer *fill = new QgsSimpleFillSymbolLayer( d->fillColor, Qt::SolidPattern, d->strokeColor );
34 fill->setStrokeWidth( d->strokeWidth );
35 fill->setStrokeWidthUnit( d->strokeWidthUnits );
36 fill->setStrokeWidthMapUnitScale( d->strokeWidthMapUnitScale );
37 fill->setStrokeStyle( !qgsDoubleNear( d->strokeWidth, 0.0 ) ? Qt::SolidLine : Qt::NoPen );
38 fill->setPenJoinStyle( d->joinStyle );
39
41 fillSymbol->changeSymbolLayer( 0, fill );
43}
44
46 : d( other.d )
47{
48
49}
50
52{
53 d = other.d;
54 return *this;
55}
56
58{
59
60}
61
63{
64 if ( !d->enabled == other.enabled()
65 || d->type != other.type()
66 || d->svgFile != other.svgFile()
67 || d->sizeType != other.sizeType()
68 || d->size != other.size()
69 || d->sizeUnits != other.sizeUnit()
70 || d->sizeMapUnitScale != other.sizeMapUnitScale()
71 || d->rotationType != other.rotationType()
72 || d->rotation != other.rotation()
73 || d->offset != other.offset()
74 || d->offsetUnits != other.offsetUnit()
75 || d->offsetMapUnitScale != other.offsetMapUnitScale()
76 || d->radii != other.radii()
77 || d->radiiUnits != other.radiiUnit()
78 || d->radiiMapUnitScale != other.radiiMapUnitScale()
79 || d->blendMode != other.blendMode()
80 || d->fillColor != other.fillColor()
81 || d->strokeColor != other.strokeColor()
82 || d->opacity != other.opacity()
83 || d->strokeWidth != other.strokeWidth()
84 || d->strokeWidthUnits != other.strokeWidthUnit()
85 || d->strokeWidthMapUnitScale != other.strokeWidthMapUnitScale()
86 || d->joinStyle != other.joinStyle() )
87 return false;
88
89 if ( static_cast< bool >( d->paintEffect ) != static_cast< bool >( other.paintEffect() )
90 || ( d->paintEffect && d->paintEffect->properties() != other.paintEffect()->properties() ) )
91 return false;
92
93 if ( static_cast< bool >( d->markerSymbol ) != static_cast< bool >( other.markerSymbol() )
94 || ( d->markerSymbol && QgsSymbolLayerUtils::symbolProperties( d->markerSymbol.get() ) != QgsSymbolLayerUtils::symbolProperties( other.markerSymbol() ) ) )
95 return false;
96
97 if ( static_cast< bool >( d->fillSymbol ) != static_cast< bool >( other.fillSymbol() )
98 || ( d->fillSymbol && QgsSymbolLayerUtils::symbolProperties( d->fillSymbol.get() ) != QgsSymbolLayerUtils::symbolProperties( other.fillSymbol() ) ) )
99 return false;
100
101 return true;
102}
103
105{
106 return !( *this == other );
107}
108
110{
111 return d->enabled;
112}
113
115{
116 d->enabled = enabled;
117}
118
120{
121 return d->type;
122}
123
125{
126 d->type = type;
127}
128
130{
131 return d->svgFile;
132}
133
134void QgsTextBackgroundSettings::setSvgFile( const QString &file )
135{
136 d->svgFile = file;
137}
138
140{
141 return d->markerSymbol.get();
142}
143
145{
146 if ( symbol )
147 // Remove symbol layer unique id to have correct settings equality
149
150 d->markerSymbol.reset( symbol );
151}
152
154{
155 return d->fillSymbol.get();
156}
157
159{
160 if ( symbol )
161 // Remove symbol layer unique id to have correct settings equality
163
164 d->fillSymbol.reset( symbol );
165}
166
168{
169 return d->sizeType;
170}
171
173{
174 d->sizeType = type;
175}
176
178{
179 return d->size;
180}
181
183{
184 d->size = size;
185}
186
188{
189 return d->sizeUnits;
190}
191
193{
194 d->sizeUnits = unit;
195}
196
198{
199 return d->sizeMapUnitScale;
200}
201
203{
204 d->sizeMapUnitScale = scale;
205}
206
208{
209 return d->rotationType;
210}
211
213{
214 d->rotationType = type;
215}
216
218{
219 return d->rotation;
220}
221
223{
224 d->rotation = rotation;
225}
226
228{
229 return d->offset;
230}
231
233{
234 d->offset = offset;
235}
236
238{
239 return d->offsetUnits;
240}
241
243{
244 d->offsetUnits = units;
245}
246
248{
249 return d->offsetMapUnitScale;
250}
251
253{
254 d->offsetMapUnitScale = scale;
255}
256
258{
259 return d->radii;
260}
261
263{
264 d->radii = radii;
265}
266
268{
269 return d->radiiUnits;
270}
271
273{
274 d->radiiUnits = units;
275}
276
278{
279 return d->radiiMapUnitScale;
280}
281
283{
284 d->radiiMapUnitScale = scale;
285}
286
288{
289 return d->opacity;
290}
291
293{
294 d->opacity = opacity;
295}
296
297QPainter::CompositionMode QgsTextBackgroundSettings::blendMode() const
298{
299 return d->blendMode;
300}
301
302void QgsTextBackgroundSettings::setBlendMode( QPainter::CompositionMode mode )
303{
304 d->blendMode = mode;
305}
306
308{
309 return d->fillColor;
310}
311
313{
314 d->fillColor = color;
315 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == QLatin1String( "SimpleFill" ) )
316 {
317 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setColor( color );
318 }
319}
320
322{
323 return d->strokeColor;
324}
325
327{
328 d->strokeColor = color;
329 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == QLatin1String( "SimpleFill" ) )
330 {
331 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setStrokeColor( color );
332 }
333}
334
336{
337 return d->strokeWidth;
338}
339
341{
342 d->strokeWidth = width;
343 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == QLatin1String( "SimpleFill" ) )
344 {
345 QgsSimpleFillSymbolLayer *fill = qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) );
346 fill->setStrokeWidth( width );
347 fill->setStrokeStyle( !qgsDoubleNear( width, 0.0 ) ? Qt::SolidLine : Qt::NoPen );
348 }
349}
350
352{
353 return d->strokeWidthUnits;
354}
355
357{
358 d->strokeWidthUnits = units;
359 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == QLatin1String( "SimpleFill" ) )
360 {
361 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setStrokeWidthUnit( units );
362 }
363}
364
366{
367 return d->strokeWidthMapUnitScale;
368}
369
371{
372 d->strokeWidthMapUnitScale = scale;
373 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == QLatin1String( "SimpleFill" ) )
374 {
375 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setStrokeWidthMapUnitScale( scale );
376 }
377}
378
380{
381 return d->joinStyle;
382}
383
384void QgsTextBackgroundSettings::setJoinStyle( Qt::PenJoinStyle style )
385{
386 d->joinStyle = style;
387 if ( d->fillSymbol && d->fillSymbol->symbolLayers().at( 0 )->layerType() == QLatin1String( "SimpleFill" ) )
388 {
389 qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) )->setPenJoinStyle( style );
390 }
391}
392
394{
395 return d->paintEffect.get();
396}
397
399{
400 d->paintEffect.reset( effect );
401}
402
404{
405 d->enabled = layer->customProperty( QStringLiteral( "labeling/shapeDraw" ), QVariant( false ) ).toBool();
406 d->type = static_cast< ShapeType >( layer->customProperty( QStringLiteral( "labeling/shapeType" ), QVariant( ShapeRectangle ) ).toUInt() );
407 d->svgFile = layer->customProperty( QStringLiteral( "labeling/shapeSVGFile" ), QVariant( "" ) ).toString();
408 d->sizeType = static_cast< SizeType >( layer->customProperty( QStringLiteral( "labeling/shapeSizeType" ), QVariant( SizeBuffer ) ).toUInt() );
409 d->size = QSizeF( layer->customProperty( QStringLiteral( "labeling/shapeSizeX" ), QVariant( 0.0 ) ).toDouble(),
410 layer->customProperty( QStringLiteral( "labeling/shapeSizeY" ), QVariant( 0.0 ) ).toDouble() );
411
412 if ( layer->customProperty( QStringLiteral( "labeling/shapeSizeUnit" ) ).toString().isEmpty() )
413 {
414 d->sizeUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( QStringLiteral( "labeling/shapeSizeUnits" ), 0 ).toUInt() );
415 }
416 else
417 {
418 d->sizeUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( QStringLiteral( "labeling/shapeSizeUnit" ) ).toString() );
419 }
420
421 if ( layer->customProperty( QStringLiteral( "labeling/shapeSizeMapUnitScale" ) ).toString().isEmpty() )
422 {
423 //fallback to older property
424 const double oldMin = layer->customProperty( QStringLiteral( "labeling/shapeSizeMapUnitMinScale" ), 0.0 ).toDouble();
425 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
426 const double oldMax = layer->customProperty( QStringLiteral( "labeling/shapeSizeMapUnitMaxScale" ), 0.0 ).toDouble();
427 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
428 }
429 else
430 {
431 d->sizeMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( QStringLiteral( "labeling/shapeSizeMapUnitScale" ) ).toString() );
432 }
433 d->rotationType = static_cast< RotationType >( layer->customProperty( QStringLiteral( "labeling/shapeRotationType" ), QVariant( RotationSync ) ).toUInt() );
434 d->rotation = layer->customProperty( QStringLiteral( "labeling/shapeRotation" ), QVariant( 0.0 ) ).toDouble();
435 d->offset = QPointF( layer->customProperty( QStringLiteral( "labeling/shapeOffsetX" ), QVariant( 0.0 ) ).toDouble(),
436 layer->customProperty( QStringLiteral( "labeling/shapeOffsetY" ), QVariant( 0.0 ) ).toDouble() );
437
438 if ( layer->customProperty( QStringLiteral( "labeling/shapeOffsetUnit" ) ).toString().isEmpty() )
439 {
440 d->offsetUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( QStringLiteral( "labeling/shapeOffsetUnits" ), 0 ).toUInt() );
441 }
442 else
443 {
444 d->offsetUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( QStringLiteral( "labeling/shapeOffsetUnit" ) ).toString() );
445 }
446
447 if ( layer->customProperty( QStringLiteral( "labeling/shapeOffsetMapUnitScale" ) ).toString().isEmpty() )
448 {
449 //fallback to older property
450 const double oldMin = layer->customProperty( QStringLiteral( "labeling/shapeOffsetMapUnitMinScale" ), 0.0 ).toDouble();
451 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
452 const double oldMax = layer->customProperty( QStringLiteral( "labeling/shapeOffsetMapUnitMaxScale" ), 0.0 ).toDouble();
453 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
454 }
455 else
456 {
457 d->offsetMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( QStringLiteral( "labeling/shapeOffsetMapUnitScale" ) ).toString() );
458 }
459 d->radii = QSizeF( layer->customProperty( QStringLiteral( "labeling/shapeRadiiX" ), QVariant( 0.0 ) ).toDouble(),
460 layer->customProperty( QStringLiteral( "labeling/shapeRadiiY" ), QVariant( 0.0 ) ).toDouble() );
461
462
463 if ( layer->customProperty( QStringLiteral( "labeling/shapeRadiiUnit" ) ).toString().isEmpty() )
464 {
465 d->radiiUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( QStringLiteral( "labeling/shapeRadiiUnits" ), 0 ).toUInt() );
466 }
467 else
468 {
469 d->radiiUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( QStringLiteral( "labeling/shapeRadiiUnit" ) ).toString() );
470 }
471
472 if ( layer->customProperty( QStringLiteral( "labeling/shapeRadiiMapUnitScale" ) ).toString().isEmpty() )
473 {
474 //fallback to older property
475 const double oldMin = layer->customProperty( QStringLiteral( "labeling/shapeRadiiMapUnitMinScale" ), 0.0 ).toDouble();
476 d->radiiMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
477 const double oldMax = layer->customProperty( QStringLiteral( "labeling/shapeRadiiMapUnitMaxScale" ), 0.0 ).toDouble();
478 d->radiiMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
479 }
480 else
481 {
482 d->radiiMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( QStringLiteral( "labeling/shapeRadiiMapUnitScale" ) ).toString() );
483 }
484 d->fillColor = QgsTextRendererUtils::readColor( layer, QStringLiteral( "labeling/shapeFillColor" ), Qt::white, true );
485 d->strokeColor = QgsTextRendererUtils::readColor( layer, QStringLiteral( "labeling/shapeBorderColor" ), Qt::darkGray, true );
486 d->strokeWidth = layer->customProperty( QStringLiteral( "labeling/shapeBorderWidth" ), QVariant( .0 ) ).toDouble();
487 if ( layer->customProperty( QStringLiteral( "labeling/shapeBorderWidthUnit" ) ).toString().isEmpty() )
488 {
489 d->strokeWidthUnits = QgsTextRendererUtils::convertFromOldLabelUnit( layer->customProperty( QStringLiteral( "labeling/shapeBorderWidthUnits" ), 0 ).toUInt() );
490 }
491 else
492 {
493 d->strokeWidthUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( QStringLiteral( "labeling/shapeBorderWidthUnit" ) ).toString() );
494 }
495 if ( layer->customProperty( QStringLiteral( "labeling/shapeBorderWidthMapUnitScale" ) ).toString().isEmpty() )
496 {
497 //fallback to older property
498 const double oldMin = layer->customProperty( QStringLiteral( "labeling/shapeBorderWidthMapUnitMinScale" ), 0.0 ).toDouble();
499 d->strokeWidthMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
500 const double oldMax = layer->customProperty( QStringLiteral( "labeling/shapeBorderWidthMapUnitMaxScale" ), 0.0 ).toDouble();
501 d->strokeWidthMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
502 }
503 else
504 {
505 d->strokeWidthMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( QStringLiteral( "labeling/shapeBorderWidthMapUnitScale" ) ).toString() );
506 }
507 d->joinStyle = static_cast< Qt::PenJoinStyle >( layer->customProperty( QStringLiteral( "labeling/shapeJoinStyle" ), QVariant( Qt::BevelJoin ) ).toUInt() );
508
509 if ( layer->customProperty( QStringLiteral( "labeling/shapeOpacity" ) ).toString().isEmpty() )
510 {
511 d->opacity = ( 1 - layer->customProperty( QStringLiteral( "labeling/shapeTransparency" ) ).toInt() / 100.0 ); //0 -100
512 }
513 else
514 {
515 d->opacity = ( layer->customProperty( QStringLiteral( "labeling/shapeOpacity" ) ).toDouble() );
516 }
517 d->blendMode = QgsPainting::getCompositionMode(
518 static_cast< Qgis::BlendMode >( layer->customProperty( QStringLiteral( "labeling/shapeBlendMode" ), QVariant( static_cast< int>( Qgis::BlendMode::Normal ) ) ).toUInt() ) );
519
520 if ( layer->customProperty( QStringLiteral( "labeling/shapeEffect" ) ).isValid() )
521 {
522 QDomDocument doc( QStringLiteral( "effect" ) );
523 doc.setContent( layer->customProperty( QStringLiteral( "labeling/shapeEffect" ) ).toString() );
524 const QDomElement effectElem = doc.firstChildElement( QStringLiteral( "effect" ) ).firstChildElement( QStringLiteral( "effect" ) );
525 setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
526 }
527 else
528 setPaintEffect( nullptr );
529}
530
531void QgsTextBackgroundSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
532{
533 const QDomElement backgroundElem = elem.firstChildElement( QStringLiteral( "background" ) );
534 d->enabled = backgroundElem.attribute( QStringLiteral( "shapeDraw" ), QStringLiteral( "0" ) ).toInt();
535 d->type = static_cast< ShapeType >( backgroundElem.attribute( QStringLiteral( "shapeType" ), QString::number( ShapeRectangle ) ).toUInt() );
536 d->svgFile = QgsSymbolLayerUtils::svgSymbolNameToPath( backgroundElem.attribute( QStringLiteral( "shapeSVGFile" ) ), context.pathResolver() );
537 d->sizeType = static_cast< SizeType >( backgroundElem.attribute( QStringLiteral( "shapeSizeType" ), QString::number( SizeBuffer ) ).toUInt() );
538 d->size = QSizeF( backgroundElem.attribute( QStringLiteral( "shapeSizeX" ), QStringLiteral( "0" ) ).toDouble(),
539 backgroundElem.attribute( QStringLiteral( "shapeSizeY" ), QStringLiteral( "0" ) ).toDouble() );
540
541 if ( !backgroundElem.hasAttribute( QStringLiteral( "shapeSizeUnit" ) ) )
542 {
543 d->sizeUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( QStringLiteral( "shapeSizeUnits" ) ).toUInt() );
544 }
545 else
546 {
547 d->sizeUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( QStringLiteral( "shapeSizeUnit" ) ) );
548 }
549
550 if ( !backgroundElem.hasAttribute( QStringLiteral( "shapeSizeMapUnitScale" ) ) )
551 {
552 //fallback to older property
553 const double oldMin = backgroundElem.attribute( QStringLiteral( "shapeSizeMapUnitMinScale" ), QStringLiteral( "0" ) ).toDouble();
554 d->sizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
555 const double oldMax = backgroundElem.attribute( QStringLiteral( "shapeSizeMapUnitMaxScale" ), QStringLiteral( "0" ) ).toDouble();
556 d->sizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
557 }
558 else
559 {
560 d->sizeMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( QStringLiteral( "shapeSizeMapUnitScale" ) ) );
561 }
562 d->rotationType = static_cast< RotationType >( backgroundElem.attribute( QStringLiteral( "shapeRotationType" ), QString::number( RotationSync ) ).toUInt() );
563 d->rotation = backgroundElem.attribute( QStringLiteral( "shapeRotation" ), QStringLiteral( "0" ) ).toDouble();
564 d->offset = QPointF( backgroundElem.attribute( QStringLiteral( "shapeOffsetX" ), QStringLiteral( "0" ) ).toDouble(),
565 backgroundElem.attribute( QStringLiteral( "shapeOffsetY" ), QStringLiteral( "0" ) ).toDouble() );
566
567 if ( !backgroundElem.hasAttribute( QStringLiteral( "shapeOffsetUnit" ) ) )
568 {
569 d->offsetUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( QStringLiteral( "shapeOffsetUnits" ) ).toUInt() );
570 }
571 else
572 {
573 d->offsetUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( QStringLiteral( "shapeOffsetUnit" ) ) );
574 }
575
576 if ( !backgroundElem.hasAttribute( QStringLiteral( "shapeOffsetMapUnitScale" ) ) )
577 {
578 //fallback to older property
579 const double oldMin = backgroundElem.attribute( QStringLiteral( "shapeOffsetMapUnitMinScale" ), QStringLiteral( "0" ) ).toDouble();
580 d->offsetMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
581 const double oldMax = backgroundElem.attribute( QStringLiteral( "shapeOffsetMapUnitMaxScale" ), QStringLiteral( "0" ) ).toDouble();
582 d->offsetMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
583 }
584 else
585 {
586 d->offsetMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( QStringLiteral( "shapeOffsetMapUnitScale" ) ) );
587 }
588 d->radii = QSizeF( backgroundElem.attribute( QStringLiteral( "shapeRadiiX" ), QStringLiteral( "0" ) ).toDouble(),
589 backgroundElem.attribute( QStringLiteral( "shapeRadiiY" ), QStringLiteral( "0" ) ).toDouble() );
590
591 if ( !backgroundElem.hasAttribute( QStringLiteral( "shapeRadiiUnit" ) ) )
592 {
593 d->radiiUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( QStringLiteral( "shapeRadiiUnits" ) ).toUInt() );
594 }
595 else
596 {
597 d->radiiUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( QStringLiteral( "shapeRadiiUnit" ) ) );
598 }
599 if ( !backgroundElem.hasAttribute( QStringLiteral( "shapeRadiiMapUnitScale" ) ) )
600 {
601 //fallback to older property
602 const double oldMin = backgroundElem.attribute( QStringLiteral( "shapeRadiiMapUnitMinScale" ), QStringLiteral( "0" ) ).toDouble();
603 d->radiiMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
604 const double oldMax = backgroundElem.attribute( QStringLiteral( "shapeRadiiMapUnitMaxScale" ), QStringLiteral( "0" ) ).toDouble();
605 d->radiiMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
606 }
607 else
608 {
609 d->radiiMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( QStringLiteral( "shapeRadiiMapUnitScale" ) ) );
610 }
611 d->fillColor = QgsSymbolLayerUtils::decodeColor( backgroundElem.attribute( QStringLiteral( "shapeFillColor" ), QgsSymbolLayerUtils::encodeColor( Qt::white ) ) );
612 d->strokeColor = QgsSymbolLayerUtils::decodeColor( backgroundElem.attribute( QStringLiteral( "shapeBorderColor" ), QgsSymbolLayerUtils::encodeColor( Qt::darkGray ) ) );
613 d->strokeWidth = backgroundElem.attribute( QStringLiteral( "shapeBorderWidth" ), QStringLiteral( "0" ) ).toDouble();
614
615 if ( !backgroundElem.hasAttribute( QStringLiteral( "shapeBorderWidthUnit" ) ) )
616 {
617 d->strokeWidthUnits = QgsTextRendererUtils::convertFromOldLabelUnit( backgroundElem.attribute( QStringLiteral( "shapeBorderWidthUnits" ) ).toUInt() );
618 }
619 else
620 {
621 d->strokeWidthUnits = QgsUnitTypes::decodeRenderUnit( backgroundElem.attribute( QStringLiteral( "shapeBorderWidthUnit" ) ) );
622 }
623 if ( !backgroundElem.hasAttribute( QStringLiteral( "shapeBorderWidthMapUnitScale" ) ) )
624 {
625 //fallback to older property
626 const double oldMin = backgroundElem.attribute( QStringLiteral( "shapeBorderWidthMapUnitMinScale" ), QStringLiteral( "0" ) ).toDouble();
627 d->strokeWidthMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
628 const double oldMax = backgroundElem.attribute( QStringLiteral( "shapeBorderWidthMapUnitMaxScale" ), QStringLiteral( "0" ) ).toDouble();
629 d->strokeWidthMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
630 }
631 else
632 {
633 d->strokeWidthMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( backgroundElem.attribute( QStringLiteral( "shapeBorderWidthMapUnitScale" ) ) );
634 }
635 d->joinStyle = static_cast< Qt::PenJoinStyle >( backgroundElem.attribute( QStringLiteral( "shapeJoinStyle" ), QString::number( Qt::BevelJoin ) ).toUInt() );
636
637 if ( !backgroundElem.hasAttribute( QStringLiteral( "shapeOpacity" ) ) )
638 {
639 d->opacity = ( 1 - backgroundElem.attribute( QStringLiteral( "shapeTransparency" ) ).toInt() / 100.0 ); //0 -100
640 }
641 else
642 {
643 d->opacity = ( backgroundElem.attribute( QStringLiteral( "shapeOpacity" ) ).toDouble() );
644 }
645
646 d->blendMode = QgsPainting::getCompositionMode(
647 static_cast< Qgis::BlendMode >( backgroundElem.attribute( QStringLiteral( "shapeBlendMode" ), QString::number( static_cast< int >( Qgis::BlendMode::Normal ) ) ).toUInt() ) );
648
649 const QDomElement effectElem = backgroundElem.firstChildElement( QStringLiteral( "effect" ) );
650 if ( !effectElem.isNull() )
651 setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
652 else
653 setPaintEffect( nullptr );
654
655 setMarkerSymbol( nullptr );
656 setFillSymbol( nullptr );
657 const QDomNodeList symbols = backgroundElem.elementsByTagName( QStringLiteral( "symbol" ) );
658 for ( int i = 0; i < symbols.size(); ++i )
659 {
660 if ( symbols.at( i ).isElement() )
661 {
662 const QDomElement symbolElement = symbols.at( i ).toElement();
663 const QString symbolElementName = symbolElement.attribute( QStringLiteral( "name" ) );
664 if ( symbolElementName == QLatin1String( "markerSymbol" ) )
665 {
666 setMarkerSymbol( QgsSymbolLayerUtils::loadSymbol< QgsMarkerSymbol >( symbolElement, context ) );
667 }
668 else if ( symbolElementName == QLatin1String( "fillSymbol" ) )
669 {
670 setFillSymbol( QgsSymbolLayerUtils::loadSymbol< QgsFillSymbol >( symbolElement, context ) );
671 }
672 }
673 }
674
675 if ( !d->fillSymbol )
676 {
677 QgsSimpleFillSymbolLayer *fill = new QgsSimpleFillSymbolLayer( d->fillColor, Qt::SolidPattern, d->strokeColor );
678 fill->setStrokeWidth( d->strokeWidth );
679 fill->setStrokeWidthUnit( d->strokeWidthUnits );
680 fill->setStrokeWidthMapUnitScale( d->strokeWidthMapUnitScale );
681 fill->setStrokeStyle( !qgsDoubleNear( d->strokeWidth, 0.0 ) ? Qt::SolidLine : Qt::NoPen );
682 fill->setPenJoinStyle( d->joinStyle );
683
685 fillSymbol->changeSymbolLayer( 0, fill );
687 }
688}
689
690QDomElement QgsTextBackgroundSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
691{
692 QDomElement backgroundElem = doc.createElement( QStringLiteral( "background" ) );
693 backgroundElem.setAttribute( QStringLiteral( "shapeDraw" ), d->enabled );
694 backgroundElem.setAttribute( QStringLiteral( "shapeType" ), static_cast< unsigned int >( d->type ) );
695 backgroundElem.setAttribute( QStringLiteral( "shapeSVGFile" ), QgsSymbolLayerUtils::svgSymbolPathToName( d->svgFile, context.pathResolver() ) );
696 backgroundElem.setAttribute( QStringLiteral( "shapeSizeType" ), static_cast< unsigned int >( d->sizeType ) );
697 backgroundElem.setAttribute( QStringLiteral( "shapeSizeX" ), d->size.width() );
698 backgroundElem.setAttribute( QStringLiteral( "shapeSizeY" ), d->size.height() );
699 backgroundElem.setAttribute( QStringLiteral( "shapeSizeUnit" ), QgsUnitTypes::encodeUnit( d->sizeUnits ) );
700 backgroundElem.setAttribute( QStringLiteral( "shapeSizeMapUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( d->sizeMapUnitScale ) );
701 backgroundElem.setAttribute( QStringLiteral( "shapeRotationType" ), static_cast< unsigned int >( d->rotationType ) );
702 backgroundElem.setAttribute( QStringLiteral( "shapeRotation" ), d->rotation );
703 backgroundElem.setAttribute( QStringLiteral( "shapeOffsetX" ), d->offset.x() );
704 backgroundElem.setAttribute( QStringLiteral( "shapeOffsetY" ), d->offset.y() );
705 backgroundElem.setAttribute( QStringLiteral( "shapeOffsetUnit" ), QgsUnitTypes::encodeUnit( d->offsetUnits ) );
706 backgroundElem.setAttribute( QStringLiteral( "shapeOffsetMapUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( d->offsetMapUnitScale ) );
707 backgroundElem.setAttribute( QStringLiteral( "shapeRadiiX" ), d->radii.width() );
708 backgroundElem.setAttribute( QStringLiteral( "shapeRadiiY" ), d->radii.height() );
709 backgroundElem.setAttribute( QStringLiteral( "shapeRadiiUnit" ), QgsUnitTypes::encodeUnit( d->radiiUnits ) );
710 backgroundElem.setAttribute( QStringLiteral( "shapeRadiiMapUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( d->radiiMapUnitScale ) );
711 backgroundElem.setAttribute( QStringLiteral( "shapeFillColor" ), QgsSymbolLayerUtils::encodeColor( d->fillColor ) );
712 backgroundElem.setAttribute( QStringLiteral( "shapeBorderColor" ), QgsSymbolLayerUtils::encodeColor( d->strokeColor ) );
713 backgroundElem.setAttribute( QStringLiteral( "shapeBorderWidth" ), d->strokeWidth );
714 backgroundElem.setAttribute( QStringLiteral( "shapeBorderWidthUnit" ), QgsUnitTypes::encodeUnit( d->strokeWidthUnits ) );
715 backgroundElem.setAttribute( QStringLiteral( "shapeBorderWidthMapUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( d->strokeWidthMapUnitScale ) );
716 backgroundElem.setAttribute( QStringLiteral( "shapeJoinStyle" ), static_cast< unsigned int >( d->joinStyle ) );
717 backgroundElem.setAttribute( QStringLiteral( "shapeOpacity" ), d->opacity );
718 backgroundElem.setAttribute( QStringLiteral( "shapeBlendMode" ), static_cast< int >( QgsPainting::getBlendModeEnum( d->blendMode ) ) );
719 if ( d->paintEffect && !QgsPaintEffectRegistry::isDefaultStack( d->paintEffect.get() ) )
720 d->paintEffect->saveProperties( doc, backgroundElem );
721
722 if ( d->markerSymbol )
723 backgroundElem.appendChild( QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "markerSymbol" ), d->markerSymbol.get(), doc, context ) );
724
725 if ( d->fillSymbol )
726 backgroundElem.appendChild( QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "fillSymbol" ), d->fillSymbol.get(), doc, context ) );
727
728 return backgroundElem;
729}
730
732{
733 if ( !d->fillSymbol || d->fillSymbol->symbolLayers().at( 0 )->layerType() != QLatin1String( "SimpleFill" ) )
734 return;
735 QgsSimpleFillSymbolLayer *fill = qgis::down_cast< QgsSimpleFillSymbolLayer * >( d->fillSymbol->symbolLayers().at( 0 ) );
736
738 {
741 {
744 }
745
748 {
751 }
752
755 {
758 }
759
762 {
765 }
766 }
767}
768
770{
771 if ( properties.isActive( QgsPalLayerSettings::ShapeDraw ) )
772 {
773 context.expressionContext().setOriginalValueVariable( d->enabled );
774 d->enabled = properties.valueAsBool( QgsPalLayerSettings::ShapeDraw, context.expressionContext(), d->enabled );
775 }
776
777 if ( properties.isActive( QgsPalLayerSettings::ShapeSizeX ) )
778 {
779 context.expressionContext().setOriginalValueVariable( d->size.width() );
780 d->size.setWidth( properties.valueAsDouble( QgsPalLayerSettings::ShapeSizeX, context.expressionContext(), d->size.width() ) );
781 }
782 if ( properties.isActive( QgsPalLayerSettings::ShapeSizeY ) )
783 {
784 context.expressionContext().setOriginalValueVariable( d->size.height() );
785 d->size.setHeight( properties.valueAsDouble( QgsPalLayerSettings::ShapeSizeY, context.expressionContext(), d->size.height() ) );
786 }
787
788 QVariant exprVal = properties.value( QgsPalLayerSettings::ShapeSizeUnits, context.expressionContext() );
789 if ( !QgsVariantUtils::isNull( exprVal ) )
790 {
791 const QString units = exprVal.toString();
792 if ( !units.isEmpty() )
793 {
794 bool ok;
795 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
796 if ( ok )
797 d->sizeUnits = res;
798 }
799 }
800
801 exprVal = properties.value( QgsPalLayerSettings::ShapeKind, context.expressionContext() );
802 if ( !QgsVariantUtils::isNull( exprVal ) )
803 {
804 const QString skind = exprVal.toString().trimmed();
805 if ( !skind.isEmpty() )
806 {
807 d->type = QgsTextRendererUtils::decodeShapeType( skind );
808 }
809 }
810
811 exprVal = properties.value( QgsPalLayerSettings::ShapeSizeType, context.expressionContext() );
812 if ( !QgsVariantUtils::isNull( exprVal ) )
813 {
814 const QString stype = exprVal.toString().trimmed();
815 if ( !stype.isEmpty() )
816 {
818 }
819 }
820
821 // data defined shape SVG path?
822 context.expressionContext().setOriginalValueVariable( d->svgFile );
823 exprVal = properties.value( QgsPalLayerSettings::ShapeSVGFile, context.expressionContext() );
824 if ( !QgsVariantUtils::isNull( exprVal ) )
825 {
826 const QString svgfile = exprVal.toString().trimmed();
827 d->svgFile = QgsSymbolLayerUtils::svgSymbolNameToPath( svgfile, context.pathResolver() );
828 }
829
831 {
832 context.expressionContext().setOriginalValueVariable( d->rotation );
833 d->rotation = properties.valueAsDouble( QgsPalLayerSettings::ShapeRotation, context.expressionContext(), d->rotation );
834 }
835 exprVal = properties.value( QgsPalLayerSettings::ShapeRotationType, context.expressionContext() );
836 if ( !QgsVariantUtils::isNull( exprVal ) )
837 {
838 const QString rotstr = exprVal.toString().trimmed();
839 if ( !rotstr.isEmpty() )
840 {
841 d->rotationType = QgsTextRendererUtils::decodeBackgroundRotationType( rotstr );
842 }
843 }
844
845 exprVal = properties.value( QgsPalLayerSettings::ShapeOffset, context.expressionContext() );
846 if ( !QgsVariantUtils::isNull( exprVal ) )
847 {
848 bool ok = false;
849 const QPointF res = QgsSymbolLayerUtils::toPoint( exprVal, &ok );
850 if ( ok )
851 {
852 d->offset = res;
853 }
854 }
855 exprVal = properties.value( QgsPalLayerSettings::ShapeOffsetUnits, context.expressionContext() );
856 if ( !QgsVariantUtils::isNull( exprVal ) )
857 {
858 const QString units = exprVal.toString();
859 if ( !units.isEmpty() )
860 {
861 bool ok;
862 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
863 if ( ok )
864 d->offsetUnits = res;
865 }
866 }
867
868 exprVal = properties.value( QgsPalLayerSettings::ShapeRadii, context.expressionContext() );
869 if ( !QgsVariantUtils::isNull( exprVal ) )
870 {
871 bool ok = false;
872 const QSizeF res = QgsSymbolLayerUtils::toSize( exprVal, &ok );
873 if ( ok )
874 {
875 d->radii = res;
876 }
877 }
878
879 exprVal = properties.value( QgsPalLayerSettings::ShapeRadiiUnits, context.expressionContext() );
880 if ( !QgsVariantUtils::isNull( exprVal ) )
881 {
882 const QString units = exprVal.toString();
883 if ( !units.isEmpty() )
884 {
885 bool ok;
886 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
887 if ( ok )
888 d->radiiUnits = res;
889 }
890 }
891
893 {
894 context.expressionContext().setOriginalValueVariable( d->opacity * 100 );
895 const QVariant val = properties.value( QgsPalLayerSettings::ShapeOpacity, context.expressionContext(), d->opacity * 100 );
896 if ( !QgsVariantUtils::isNull( val ) )
897 {
898 d->opacity = val.toDouble() / 100.0;
899 }
900 }
901
902 // for non-SVG background types, those data defined properties will not having an impact,
903 // instead use data defined properties within symbols
905 {
907 d->fillColor = properties.valueAsColor( QgsPalLayerSettings::ShapeFillColor, context.expressionContext(), d->fillColor );
908 }
910 {
912 d->strokeColor = properties.valueAsColor( QgsPalLayerSettings::ShapeStrokeColor, context.expressionContext(), d->strokeColor );
913 }
914
916 {
917 context.expressionContext().setOriginalValueVariable( d->strokeWidth );
918 d->strokeWidth = properties.valueAsDouble( QgsPalLayerSettings::ShapeStrokeWidth, context.expressionContext(), d->strokeWidth );
919 }
920 exprVal = properties.value( QgsPalLayerSettings::ShapeStrokeWidthUnits, context.expressionContext() );
921 if ( !QgsVariantUtils::isNull( exprVal ) )
922 {
923 const QString units = exprVal.toString();
924 if ( !units.isEmpty() )
925 {
926 bool ok;
927 const Qgis::RenderUnit res = QgsUnitTypes::decodeRenderUnit( units, &ok );
928 if ( ok )
929 d->strokeWidthUnits = res;
930 }
931 }
932
934 {
935 exprVal = properties.value( QgsPalLayerSettings::ShapeBlendMode, context.expressionContext() );
936 const QString blendstr = exprVal.toString().trimmed();
937 if ( !blendstr.isEmpty() )
938 d->blendMode = QgsSymbolLayerUtils::decodeBlendMode( blendstr );
939 }
940
942 {
943 exprVal = properties.value( QgsPalLayerSettings::ShapeJoinStyle, context.expressionContext() );
944 const QString joinstr = exprVal.toString().trimmed();
945 if ( !joinstr.isEmpty() )
946 {
947 d->joinStyle = QgsSymbolLayerUtils::decodePenJoinStyle( joinstr );
948 }
949 }
950}
951
953{
954 QSet< QString > fields;
955 if ( d->markerSymbol )
956 {
957 fields.unite( d->markerSymbol->usedAttributes( context ) );
958 }
959 if ( d->fillSymbol )
960 {
961 fields.unite( d->fillSymbol->usedAttributes( context ) );
962 }
963 return fields;
964}
BlendMode
Blending modes defining the available composition modes that can be used when painting.
Definition: qgis.h:2978
RenderUnit
Rendering size units.
Definition: qgis.h:3176
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.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
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.
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 BlendMode corresponding to a QPainter::CompositionMode.
Definition: qgspainting.cpp:80
static QPainter::CompositionMode getCompositionMode(Qgis::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
Definition: qgspainting.cpp:20
@ ShapeOpacity
Shape opacity.
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
bool hasProperty(int key) const override
Returns true if the collection contains a property with the specified key.
QgsProperty property(int key) const override
Returns a matching property from the collection, if one exists.
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.
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
A store for object properties.
Definition: qgsproperty.h:230
The class is used as a container of context for various read/write operations on other 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...
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 QColor decodeColor(const QString &str)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QSizeF toSize(const QVariant &value, bool *ok=nullptr)
Converts a value to a size.
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.
@ PropertyJoinStyle
Line join style.
@ PropertyStrokeWidth
Stroke width.
@ PropertyFillColor
Fill color.
@ PropertyStrokeColor
Stroke color.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
bool changeSymbolLayer(int index, QgsSymbolLayer *layer)
Deletes the current layer at the specified index and replaces it with layer.
Definition: qgssymbol.cpp:809
Container for settings relating to a text background object.
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...
ShapeType
Background shape types.
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)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based data sets.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:3509