QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
qgstextformat.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgstextformat.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 
16 #include "qgstextformat.h"
17 #include "qgstextrenderer_p.h"
18 #include "qgstextrenderer.h"
19 #include "qgsvectorlayer.h"
20 #include "qgsfontutils.h"
21 #include "qgssymbollayerutils.h"
22 #include "qgspainting.h"
23 #include "qgstextrendererutils.h"
24 #include "qgspallabeling.h"
25 #include <QFontDatabase>
26 #include <QDesktopWidget>
27 #include <QMimeData>
28 
30 {
31  d = new QgsTextSettingsPrivate();
32 }
33 
35  : mBufferSettings( other.mBufferSettings )
36  , mBackgroundSettings( other.mBackgroundSettings )
37  , mShadowSettings( other.mShadowSettings )
38  , mMaskSettings( other.mMaskSettings )
39  , mTextFontFamily( other.mTextFontFamily )
40  , mTextFontFound( other.mTextFontFound )
41  , d( other.d )
42 {
43 
44 }
45 
47 {
48  d = other.d;
49  mBufferSettings = other.mBufferSettings;
50  mBackgroundSettings = other.mBackgroundSettings;
51  mShadowSettings = other.mShadowSettings;
52  mMaskSettings = other.mMaskSettings;
53  mTextFontFamily = other.mTextFontFamily;
54  mTextFontFound = other.mTextFontFound;
55  return *this;
56 }
57 
59 {
60 
61 }
62 
63 bool QgsTextFormat::operator==( const QgsTextFormat &other ) const
64 {
65  if ( d->isValid != other.isValid()
66  || d->textFont != other.font()
67  || namedStyle() != other.namedStyle()
68  || d->fontSizeUnits != other.sizeUnit()
69  || d->fontSizeMapUnitScale != other.sizeMapUnitScale()
70  || d->fontSize != other.size()
71  || d->textColor != other.color()
72  || d->opacity != other.opacity()
73  || d->blendMode != other.blendMode()
74  || d->multilineHeight != other.lineHeight()
75  || d->orientation != other.orientation()
76  || d->previewBackgroundColor != other.previewBackgroundColor()
77  || d->allowHtmlFormatting != other.allowHtmlFormatting()
78  || d->capitalization != other.capitalization()
79  || mBufferSettings != other.mBufferSettings
80  || mBackgroundSettings != other.mBackgroundSettings
81  || mShadowSettings != other.mShadowSettings
82  || mMaskSettings != other.mMaskSettings
83  || d->mDataDefinedProperties != other.dataDefinedProperties() )
84  return false;
85 
86  return true;
87 }
88 
89 bool QgsTextFormat::operator!=( const QgsTextFormat &other ) const
90 {
91  return !( *this == other );
92 }
93 
95 {
96  return d->isValid;
97 }
98 
100 {
101  d->isValid = true;
102 }
103 
105 {
106  d->isValid = true;
107  return mBufferSettings;
108 }
109 
110 void QgsTextFormat::setBuffer( const QgsTextBufferSettings &bufferSettings )
111 {
112  d->isValid = true;
113  mBufferSettings = bufferSettings;
114 }
115 
117 {
118  d->isValid = true;
119  return mBackgroundSettings;
120 }
121 
123 {
124  d->isValid = true;
125  mBackgroundSettings = backgroundSettings;
126 }
127 
129 {
130  d->isValid = true;
131  return mShadowSettings;
132 }
133 
134 void QgsTextFormat::setShadow( const QgsTextShadowSettings &shadowSettings )
135 {
136  d->isValid = true;
137  mShadowSettings = shadowSettings;
138 }
139 
141 {
142  d->isValid = true;
143  return mMaskSettings;
144 }
145 
146 void QgsTextFormat::setMask( const QgsTextMaskSettings &maskSettings )
147 {
148  d->isValid = true;
149  mMaskSettings = maskSettings;
150 }
151 
152 QFont QgsTextFormat::font() const
153 {
154  return d->textFont;
155 }
156 
157 QFont QgsTextFormat::scaledFont( const QgsRenderContext &context, double scaleFactor ) const
158 {
159  QFont font = d->textFont;
160  if ( scaleFactor == 1 )
161  {
162  int fontPixelSize = QgsTextRenderer::sizeToPixel( d->fontSize, context, d->fontSizeUnits,
163  d->fontSizeMapUnitScale );
164  font.setPixelSize( fontPixelSize );
165  }
166  else
167  {
168  double fontPixelSize = context.convertToPainterUnits( d->fontSize, d->fontSizeUnits, d->fontSizeMapUnitScale );
169  font.setPixelSize( std::round( scaleFactor * fontPixelSize + 0.5 ) );
170  }
171 
172  font.setLetterSpacing( QFont::AbsoluteSpacing, context.convertToPainterUnits( d->textFont.letterSpacing(), d->fontSizeUnits, d->fontSizeMapUnitScale ) * scaleFactor );
173  font.setWordSpacing( context.convertToPainterUnits( d->textFont.wordSpacing(), d->fontSizeUnits, d->fontSizeMapUnitScale ) * scaleFactor * scaleFactor );
174 
175  return font;
176 }
177 
178 void QgsTextFormat::setFont( const QFont &font )
179 {
180  d->isValid = true;
181  d->textFont = font;
182 }
183 
185 {
186  if ( !d->textNamedStyle.isEmpty() )
187  return d->textNamedStyle;
188 
189  QFontDatabase db;
190  return db.styleString( d->textFont );
191 }
192 
193 void QgsTextFormat::setNamedStyle( const QString &style )
194 {
195  d->isValid = true;
196  QgsFontUtils::updateFontViaStyle( d->textFont, style );
197  d->textNamedStyle = style;
198 }
199 
201 {
202  return d->fontSizeUnits;
203 }
204 
206 {
207  d->isValid = true;
208  d->fontSizeUnits = unit;
209 }
210 
212 {
213  return d->fontSizeMapUnitScale;
214 }
215 
217 {
218  d->isValid = true;
219  d->fontSizeMapUnitScale = scale;
220 }
221 
222 double QgsTextFormat::size() const
223 {
224  return d->fontSize;
225 }
226 
227 void QgsTextFormat::setSize( double size )
228 {
229  d->isValid = true;
230  d->fontSize = size;
231 }
232 
233 QColor QgsTextFormat::color() const
234 {
235  return d->textColor;
236 }
237 
238 void QgsTextFormat::setColor( const QColor &color )
239 {
240  d->isValid = true;
241  d->textColor = color;
242 }
243 
245 {
246  return d->opacity;
247 }
248 
249 void QgsTextFormat::setOpacity( double opacity )
250 {
251  d->isValid = true;
252  d->opacity = opacity;
253 }
254 
255 QPainter::CompositionMode QgsTextFormat::blendMode() const
256 {
257  return d->blendMode;
258 }
259 
260 void QgsTextFormat::setBlendMode( QPainter::CompositionMode mode )
261 {
262  d->isValid = true;
263  d->blendMode = mode;
264 }
265 
267 {
268  return d->multilineHeight;
269 }
270 
271 void QgsTextFormat::setLineHeight( double height )
272 {
273  d->isValid = true;
274  d->multilineHeight = height;
275 }
276 
278 {
279  return d->orientation;
280 }
281 
283 {
284  d->isValid = true;
285  d->orientation = orientation;
286 }
287 
289 {
290  // bit of complexity here to maintain API..
291  return d->capitalization == QgsStringUtils::MixedCase && d->textFont.capitalization() != QFont::MixedCase ? static_cast< QgsStringUtils::Capitalization >( d->textFont.capitalization() ) : d->capitalization ;
292 }
293 
295 {
296  d->isValid = true;
297  d->capitalization = capitalization;
298  d->textFont.setCapitalization( QFont::MixedCase );
299 }
300 
302 {
303  return d->allowHtmlFormatting;
304 }
305 
307 {
308  d->isValid = true;
309  d->allowHtmlFormatting = allow;
310 }
311 
313 {
314  return d->previewBackgroundColor;
315 }
316 
317 void QgsTextFormat::setPreviewBackgroundColor( const QColor &color )
318 {
319  d->isValid = true;
320  d->previewBackgroundColor = color;
321 }
322 
324 {
325  d->isValid = true;
326  QFont appFont = QApplication::font();
327  mTextFontFamily = layer->customProperty( QStringLiteral( "labeling/fontFamily" ), QVariant( appFont.family() ) ).toString();
328  QString fontFamily = mTextFontFamily;
329  if ( mTextFontFamily != appFont.family() && !QgsFontUtils::fontFamilyMatchOnSystem( mTextFontFamily ) )
330  {
331  // trigger to notify about font family substitution
332  mTextFontFound = false;
333 
334  // TODO: update when pref for how to resolve missing family (use matching algorithm or just default font) is implemented
335  // currently only defaults to matching algorithm for resolving [foundry], if a font of similar family is found (default for QFont)
336 
337  // for now, do not use matching algorithm for substitution if family not found, substitute default instead
338  fontFamily = appFont.family();
339  }
340  else
341  {
342  mTextFontFound = true;
343  }
344 
345  if ( !layer->customProperty( QStringLiteral( "labeling/fontSize" ) ).isValid() )
346  {
347  d->fontSize = appFont.pointSizeF();
348  }
349  else
350  {
351  d->fontSize = layer->customProperty( QStringLiteral( "labeling/fontSize" ) ).toDouble();
352  }
353 
354  if ( layer->customProperty( QStringLiteral( "labeling/fontSizeUnit" ) ).toString().isEmpty() )
355  {
356  d->fontSizeUnits = layer->customProperty( QStringLiteral( "labeling/fontSizeInMapUnits" ), QVariant( false ) ).toBool() ?
358  }
359  else
360  {
361  bool ok = false;
362  d->fontSizeUnits = QgsUnitTypes::decodeRenderUnit( layer->customProperty( QStringLiteral( "labeling/fontSizeUnit" ) ).toString(), &ok );
363  if ( !ok )
364  d->fontSizeUnits = QgsUnitTypes::RenderPoints;
365  }
366  if ( layer->customProperty( QStringLiteral( "labeling/fontSizeMapUnitScale" ) ).toString().isEmpty() )
367  {
368  //fallback to older property
369  double oldMin = layer->customProperty( QStringLiteral( "labeling/fontSizeMapUnitMinScale" ), 0.0 ).toDouble();
370  d->fontSizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
371  double oldMax = layer->customProperty( QStringLiteral( "labeling/fontSizeMapUnitMaxScale" ), 0.0 ).toDouble();
372  d->fontSizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
373  }
374  else
375  {
376  d->fontSizeMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( layer->customProperty( QStringLiteral( "labeling/fontSizeMapUnitScale" ) ).toString() );
377  }
378  int fontWeight = layer->customProperty( QStringLiteral( "labeling/fontWeight" ) ).toInt();
379  bool fontItalic = layer->customProperty( QStringLiteral( "labeling/fontItalic" ) ).toBool();
380  d->textFont = QFont( fontFamily, d->fontSize, fontWeight, fontItalic );
381  d->textNamedStyle = QgsFontUtils::translateNamedStyle( layer->customProperty( QStringLiteral( "labeling/namedStyle" ), QVariant( "" ) ).toString() );
382  QgsFontUtils::updateFontViaStyle( d->textFont, d->textNamedStyle ); // must come after textFont.setPointSizeF()
383  d->capitalization = static_cast< QgsStringUtils::Capitalization >( layer->customProperty( QStringLiteral( "labeling/fontCapitals" ), QVariant( 0 ) ).toUInt() );
384  d->textFont.setUnderline( layer->customProperty( QStringLiteral( "labeling/fontUnderline" ) ).toBool() );
385  d->textFont.setStrikeOut( layer->customProperty( QStringLiteral( "labeling/fontStrikeout" ) ).toBool() );
386  d->textFont.setLetterSpacing( QFont::AbsoluteSpacing, layer->customProperty( QStringLiteral( "labeling/fontLetterSpacing" ), QVariant( 0.0 ) ).toDouble() );
387  d->textFont.setWordSpacing( layer->customProperty( QStringLiteral( "labeling/fontWordSpacing" ), QVariant( 0.0 ) ).toDouble() );
388  d->textColor = QgsTextRendererUtils::readColor( layer, QStringLiteral( "labeling/textColor" ), Qt::black, false );
389  if ( layer->customProperty( QStringLiteral( "labeling/textOpacity" ) ).toString().isEmpty() )
390  {
391  d->opacity = ( 1 - layer->customProperty( QStringLiteral( "labeling/textTransp" ) ).toInt() / 100.0 ); //0 -100
392  }
393  else
394  {
395  d->opacity = ( layer->customProperty( QStringLiteral( "labeling/textOpacity" ) ).toDouble() );
396  }
397  d->blendMode = QgsPainting::getCompositionMode(
398  static_cast< QgsPainting::BlendMode >( layer->customProperty( QStringLiteral( "labeling/blendMode" ), QVariant( QgsPainting::BlendNormal ) ).toUInt() ) );
399  d->multilineHeight = layer->customProperty( QStringLiteral( "labeling/multilineHeight" ), QVariant( 1.0 ) ).toDouble();
400  d->previewBackgroundColor = QgsTextRendererUtils::readColor( layer, QStringLiteral( "labeling/previewBkgrdColor" ), QColor( 255, 255, 255 ), false );
401 
402  mBufferSettings.readFromLayer( layer );
403  mShadowSettings.readFromLayer( layer );
404  mBackgroundSettings.readFromLayer( layer );
405 }
406 
407 void QgsTextFormat::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
408 {
409  d->isValid = true;
410  QDomElement textStyleElem;
411  if ( elem.nodeName() == QLatin1String( "text-style" ) )
412  textStyleElem = elem;
413  else
414  textStyleElem = elem.firstChildElement( QStringLiteral( "text-style" ) );
415  QFont appFont = QApplication::font();
416  mTextFontFamily = textStyleElem.attribute( QStringLiteral( "fontFamily" ), appFont.family() );
417  QString fontFamily = mTextFontFamily;
418  if ( mTextFontFamily != appFont.family() && !QgsFontUtils::fontFamilyMatchOnSystem( mTextFontFamily ) )
419  {
420  // trigger to notify user about font family substitution (signal emitted in QgsVectorLayer::prepareLabelingAndDiagrams)
421  mTextFontFound = false;
422 
423  // TODO: update when pref for how to resolve missing family (use matching algorithm or just default font) is implemented
424  // currently only defaults to matching algorithm for resolving [foundry], if a font of similar family is found (default for QFont)
425 
426  // for now, do not use matching algorithm for substitution if family not found, substitute default instead
427  fontFamily = appFont.family();
428  }
429  else
430  {
431  mTextFontFound = true;
432  }
433 
434  if ( textStyleElem.hasAttribute( QStringLiteral( "fontSize" ) ) )
435  {
436  d->fontSize = textStyleElem.attribute( QStringLiteral( "fontSize" ) ).toDouble();
437  }
438  else
439  {
440  d->fontSize = appFont.pointSizeF();
441  }
442 
443  if ( !textStyleElem.hasAttribute( QStringLiteral( "fontSizeUnit" ) ) )
444  {
445  d->fontSizeUnits = textStyleElem.attribute( QStringLiteral( "fontSizeInMapUnits" ) ).toUInt() == 0 ? QgsUnitTypes::RenderPoints
447  }
448  else
449  {
450  d->fontSizeUnits = QgsUnitTypes::decodeRenderUnit( textStyleElem.attribute( QStringLiteral( "fontSizeUnit" ) ) );
451  }
452 
453  if ( !textStyleElem.hasAttribute( QStringLiteral( "fontSizeMapUnitScale" ) ) )
454  {
455  //fallback to older property
456  double oldMin = textStyleElem.attribute( QStringLiteral( "fontSizeMapUnitMinScale" ), QStringLiteral( "0" ) ).toDouble();
457  d->fontSizeMapUnitScale.minScale = oldMin != 0 ? 1.0 / oldMin : 0;
458  double oldMax = textStyleElem.attribute( QStringLiteral( "fontSizeMapUnitMaxScale" ), QStringLiteral( "0" ) ).toDouble();
459  d->fontSizeMapUnitScale.maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
460  }
461  else
462  {
463  d->fontSizeMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( textStyleElem.attribute( QStringLiteral( "fontSizeMapUnitScale" ) ) );
464  }
465  int fontWeight = textStyleElem.attribute( QStringLiteral( "fontWeight" ) ).toInt();
466  bool fontItalic = textStyleElem.attribute( QStringLiteral( "fontItalic" ) ).toInt();
467  d->textFont = QFont( fontFamily, d->fontSize, fontWeight, fontItalic );
468  d->textFont.setPointSizeF( d->fontSize ); //double precision needed because of map units
469  d->textNamedStyle = QgsFontUtils::translateNamedStyle( textStyleElem.attribute( QStringLiteral( "namedStyle" ) ) );
470  QgsFontUtils::updateFontViaStyle( d->textFont, d->textNamedStyle ); // must come after textFont.setPointSizeF()
471  d->textFont.setUnderline( textStyleElem.attribute( QStringLiteral( "fontUnderline" ) ).toInt() );
472  d->textFont.setStrikeOut( textStyleElem.attribute( QStringLiteral( "fontStrikeout" ) ).toInt() );
473  d->textFont.setKerning( textStyleElem.attribute( QStringLiteral( "fontKerning" ), QStringLiteral( "1" ) ).toInt() );
474  d->textFont.setLetterSpacing( QFont::AbsoluteSpacing, textStyleElem.attribute( QStringLiteral( "fontLetterSpacing" ), QStringLiteral( "0" ) ).toDouble() );
475  d->textFont.setWordSpacing( textStyleElem.attribute( QStringLiteral( "fontWordSpacing" ), QStringLiteral( "0" ) ).toDouble() );
476  d->textColor = QgsSymbolLayerUtils::decodeColor( textStyleElem.attribute( QStringLiteral( "textColor" ), QgsSymbolLayerUtils::encodeColor( Qt::black ) ) );
477  if ( !textStyleElem.hasAttribute( QStringLiteral( "textOpacity" ) ) )
478  {
479  d->opacity = ( 1 - textStyleElem.attribute( QStringLiteral( "textTransp" ) ).toInt() / 100.0 ); //0 -100
480  }
481  else
482  {
483  d->opacity = ( textStyleElem.attribute( QStringLiteral( "textOpacity" ) ).toDouble() );
484  }
485  d->orientation = QgsTextRendererUtils::decodeTextOrientation( textStyleElem.attribute( QStringLiteral( "textOrientation" ) ) );
486  d->previewBackgroundColor = QgsSymbolLayerUtils::decodeColor( textStyleElem.attribute( QStringLiteral( "previewBkgrdColor" ), QgsSymbolLayerUtils::encodeColor( Qt::white ) ) );
487 
488  d->blendMode = QgsPainting::getCompositionMode(
489  static_cast< QgsPainting::BlendMode >( textStyleElem.attribute( QStringLiteral( "blendMode" ), QString::number( QgsPainting::BlendNormal ) ).toUInt() ) );
490 
491  if ( !textStyleElem.hasAttribute( QStringLiteral( "multilineHeight" ) ) )
492  {
493  QDomElement textFormatElem = elem.firstChildElement( QStringLiteral( "text-format" ) );
494  d->multilineHeight = textFormatElem.attribute( QStringLiteral( "multilineHeight" ), QStringLiteral( "1" ) ).toDouble();
495  }
496  else
497  {
498  d->multilineHeight = textStyleElem.attribute( QStringLiteral( "multilineHeight" ), QStringLiteral( "1" ) ).toDouble();
499  }
500 
501  if ( textStyleElem.hasAttribute( QStringLiteral( "capitalization" ) ) )
502  d->capitalization = static_cast< QgsStringUtils::Capitalization >( textStyleElem.attribute( QStringLiteral( "capitalization" ), QString::number( QgsStringUtils::MixedCase ) ).toInt() );
503  else
504  d->capitalization = static_cast< QgsStringUtils::Capitalization >( textStyleElem.attribute( QStringLiteral( "fontCapitals" ), QStringLiteral( "0" ) ).toUInt() );
505 
506  d->allowHtmlFormatting = textStyleElem.attribute( QStringLiteral( "allowHtml" ), QStringLiteral( "0" ) ).toInt();
507 
508  if ( textStyleElem.firstChildElement( QStringLiteral( "text-buffer" ) ).isNull() )
509  {
510  mBufferSettings.readXml( elem );
511  }
512  else
513  {
514  mBufferSettings.readXml( textStyleElem );
515  }
516  if ( textStyleElem.firstChildElement( QStringLiteral( "text-mask" ) ).isNull() )
517  {
518  mMaskSettings.readXml( elem );
519  }
520  else
521  {
522  mMaskSettings.readXml( textStyleElem );
523  }
524  if ( textStyleElem.firstChildElement( QStringLiteral( "shadow" ) ).isNull() )
525  {
526  mShadowSettings.readXml( elem );
527  }
528  else
529  {
530  mShadowSettings.readXml( textStyleElem );
531  }
532  if ( textStyleElem.firstChildElement( QStringLiteral( "background" ) ).isNull() )
533  {
534  mBackgroundSettings.readXml( elem, context );
535  }
536  else
537  {
538  mBackgroundSettings.readXml( textStyleElem, context );
539  }
540 
541  QDomElement ddElem = textStyleElem.firstChildElement( QStringLiteral( "dd_properties" ) );
542  if ( ddElem.isNull() )
543  {
544  ddElem = elem.firstChildElement( QStringLiteral( "dd_properties" ) );
545  }
546  if ( !ddElem.isNull() )
547  {
548  d->mDataDefinedProperties.readXml( ddElem, QgsPalLayerSettings::propertyDefinitions() );
549  }
550  else
551  {
552  d->mDataDefinedProperties.clear();
553  }
554 }
555 
556 QDomElement QgsTextFormat::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
557 {
558  // text style
559  QDomElement textStyleElem = doc.createElement( QStringLiteral( "text-style" ) );
560  textStyleElem.setAttribute( QStringLiteral( "fontFamily" ), d->textFont.family() );
561  textStyleElem.setAttribute( QStringLiteral( "namedStyle" ), QgsFontUtils::untranslateNamedStyle( d->textNamedStyle ) );
562  textStyleElem.setAttribute( QStringLiteral( "fontSize" ), d->fontSize );
563  textStyleElem.setAttribute( QStringLiteral( "fontSizeUnit" ), QgsUnitTypes::encodeUnit( d->fontSizeUnits ) );
564  textStyleElem.setAttribute( QStringLiteral( "fontSizeMapUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( d->fontSizeMapUnitScale ) );
565  textStyleElem.setAttribute( QStringLiteral( "fontWeight" ), d->textFont.weight() );
566  textStyleElem.setAttribute( QStringLiteral( "fontItalic" ), d->textFont.italic() );
567  textStyleElem.setAttribute( QStringLiteral( "fontStrikeout" ), d->textFont.strikeOut() );
568  textStyleElem.setAttribute( QStringLiteral( "fontUnderline" ), d->textFont.underline() );
569  textStyleElem.setAttribute( QStringLiteral( "textColor" ), QgsSymbolLayerUtils::encodeColor( d->textColor ) );
570  textStyleElem.setAttribute( QStringLiteral( "previewBkgrdColor" ), QgsSymbolLayerUtils::encodeColor( d->previewBackgroundColor ) );
571  textStyleElem.setAttribute( QStringLiteral( "fontLetterSpacing" ), d->textFont.letterSpacing() );
572  textStyleElem.setAttribute( QStringLiteral( "fontWordSpacing" ), d->textFont.wordSpacing() );
573  textStyleElem.setAttribute( QStringLiteral( "fontKerning" ), d->textFont.kerning() );
574  textStyleElem.setAttribute( QStringLiteral( "textOpacity" ), d->opacity );
575  textStyleElem.setAttribute( QStringLiteral( "textOrientation" ), QgsTextRendererUtils::encodeTextOrientation( d->orientation ) );
576  textStyleElem.setAttribute( QStringLiteral( "blendMode" ), QgsPainting::getBlendModeEnum( d->blendMode ) );
577  textStyleElem.setAttribute( QStringLiteral( "multilineHeight" ), d->multilineHeight );
578  textStyleElem.setAttribute( QStringLiteral( "allowHtml" ), d->allowHtmlFormatting ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
579  textStyleElem.setAttribute( QStringLiteral( "capitalization" ), QString::number( static_cast< int >( d->capitalization ) ) );
580 
581  QDomElement ddElem = doc.createElement( QStringLiteral( "dd_properties" ) );
582  d->mDataDefinedProperties.writeXml( ddElem, QgsPalLayerSettings::propertyDefinitions() );
583 
584  textStyleElem.appendChild( mBufferSettings.writeXml( doc ) );
585  textStyleElem.appendChild( mMaskSettings.writeXml( doc ) );
586  textStyleElem.appendChild( mBackgroundSettings.writeXml( doc, context ) );
587  textStyleElem.appendChild( mShadowSettings.writeXml( doc ) );
588  textStyleElem.appendChild( ddElem );
589 
590  return textStyleElem;
591 }
592 
593 QMimeData *QgsTextFormat::toMimeData() const
594 {
595  //set both the mime color data, and the text (format settings).
596 
597  QMimeData *mimeData = new QMimeData;
598  mimeData->setColorData( QVariant( color() ) );
599 
600  QgsReadWriteContext rwContext;
601  QDomDocument textDoc;
602  QDomElement textElem = writeXml( textDoc, rwContext );
603  textDoc.appendChild( textElem );
604  mimeData->setText( textDoc.toString() );
605 
606  return mimeData;
607 }
608 
610 {
611  QgsTextFormat format;
612  format.setFont( font );
613  if ( font.pointSizeF() > 0 )
614  {
615  format.setSize( font.pointSizeF() );
617  }
618  else if ( font.pixelSize() > 0 )
619  {
620  format.setSize( font.pixelSize() );
622  }
623 
624  return format;
625 }
626 
628 {
629  QFont f = font();
630  switch ( sizeUnit() )
631  {
633  f.setPointSizeF( size() );
634  break;
635 
637  f.setPointSizeF( size() * 2.83464567 );
638  break;
639 
641  f.setPointSizeF( size() * 72 );
642  break;
643 
645  f.setPixelSize( static_cast< int >( std::round( size() ) ) );
646  break;
647 
652  // no meaning here
653  break;
654  }
655  return f;
656 }
657 
658 QgsTextFormat QgsTextFormat::fromMimeData( const QMimeData *data, bool *ok )
659 {
660  if ( ok )
661  *ok = false;
662  QgsTextFormat format;
663  if ( !data )
664  return format;
665 
666  QString text = data->text();
667  if ( !text.isEmpty() )
668  {
669  QDomDocument doc;
670  QDomElement elem;
671  QgsReadWriteContext rwContext;
672 
673  if ( doc.setContent( text ) )
674  {
675  elem = doc.documentElement();
676 
677  format.readXml( elem, rwContext );
678  if ( ok )
679  *ok = true;
680  return format;
681  }
682  }
683  return format;
684 }
685 
687 {
688  if ( d->blendMode != QPainter::CompositionMode_SourceOver )
689  return true;
690 
691  if ( mBufferSettings.enabled() && mBufferSettings.blendMode() != QPainter::CompositionMode_SourceOver )
692  return true;
693 
694  if ( mBackgroundSettings.enabled() && mBackgroundSettings.blendMode() != QPainter::CompositionMode_SourceOver )
695  return true;
696 
697  if ( mShadowSettings.enabled() && mShadowSettings.blendMode() != QPainter::CompositionMode_SourceOver )
698  return true;
699 
700  return false;
701 }
702 
704 {
705  d->isValid = true;
706  return d->mDataDefinedProperties;
707 }
708 
710 {
711  return d->mDataDefinedProperties;
712 }
713 
714 QSet<QString> QgsTextFormat::referencedFields( const QgsRenderContext &context ) const
715 {
716  QSet< QString > fields = d->mDataDefinedProperties.referencedFields( context.expressionContext(), true );
717  fields.unite( mBufferSettings.referencedFields( context ) );
718  fields.unite( mBackgroundSettings.referencedFields( context ) );
719  fields.unite( mShadowSettings.referencedFields( context ) );
720  fields.unite( mMaskSettings.referencedFields( context ) );
721  return fields;
722 }
723 
725 {
726  d->isValid = true;
727  d->mDataDefinedProperties = collection;
728 }
729 
731 {
732  d->isValid = true;
733  if ( !d->mDataDefinedProperties.hasActiveProperties() )
734  return;
735 
736  QString ddFontFamily;
737  context.expressionContext().setOriginalValueVariable( d->textFont.family() );
738  QVariant exprVal = d->mDataDefinedProperties.value( QgsPalLayerSettings::Family, context.expressionContext() );
739  if ( exprVal.isValid() )
740  {
741  QString family = exprVal.toString().trimmed();
742  if ( d->textFont.family() != family )
743  {
744  // testing for ddFontFamily in QFontDatabase.families() may be slow to do for every feature
745  // (i.e. don't use QgsFontUtils::fontFamilyMatchOnSystem( family ) here)
746  if ( QgsFontUtils::fontFamilyOnSystem( family ) )
747  {
748  ddFontFamily = family;
749  }
750  }
751  }
752 
753  // data defined named font style?
754  QString ddFontStyle;
755  context.expressionContext().setOriginalValueVariable( d->textNamedStyle );
756  exprVal = d->mDataDefinedProperties.value( QgsPalLayerSettings::FontStyle, context.expressionContext() );
757  if ( exprVal.isValid() )
758  {
759  QString fontstyle = exprVal.toString().trimmed();
760  ddFontStyle = fontstyle;
761  }
762 
763  bool ddBold = false;
764  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::Bold ) )
765  {
766  context.expressionContext().setOriginalValueVariable( d->textFont.bold() );
767  ddBold = d->mDataDefinedProperties.valueAsBool( QgsPalLayerSettings::Bold, context.expressionContext(), false ) ;
768  }
769 
770  bool ddItalic = false;
771  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::Italic ) )
772  {
773  context.expressionContext().setOriginalValueVariable( d->textFont.italic() );
774  ddItalic = d->mDataDefinedProperties.valueAsBool( QgsPalLayerSettings::Italic, context.expressionContext(), false );
775  }
776 
777  // TODO: update when pref for how to resolve missing family (use matching algorithm or just default font) is implemented
778  // (currently defaults to what has been read in from layer settings)
779  QFont newFont;
780  QFontDatabase fontDb;
781  QFont appFont = QApplication::font();
782  bool newFontBuilt = false;
783  if ( ddBold || ddItalic )
784  {
785  // new font needs built, since existing style needs removed
786  newFont = QFont( !ddFontFamily.isEmpty() ? ddFontFamily : d->textFont.family() );
787  newFontBuilt = true;
788  newFont.setBold( ddBold );
789  newFont.setItalic( ddItalic );
790  }
791  else if ( !ddFontStyle.isEmpty()
792  && ddFontStyle.compare( QLatin1String( "Ignore" ), Qt::CaseInsensitive ) != 0 )
793  {
794  if ( !ddFontFamily.isEmpty() )
795  {
796  // both family and style are different, build font from database
797  QFont styledfont = fontDb.font( ddFontFamily, ddFontStyle, appFont.pointSize() );
798  if ( appFont != styledfont )
799  {
800  newFont = styledfont;
801  newFontBuilt = true;
802  }
803  }
804 
805  // update the font face style
806  QgsFontUtils::updateFontViaStyle( newFontBuilt ? newFont : d->textFont, ddFontStyle );
807  }
808  else if ( !ddFontFamily.isEmpty() )
809  {
810  if ( ddFontStyle.compare( QLatin1String( "Ignore" ), Qt::CaseInsensitive ) != 0 )
811  {
812  // just family is different, build font from database
813  QFont styledfont = fontDb.font( ddFontFamily, d->textNamedStyle, appFont.pointSize() );
814  if ( appFont != styledfont )
815  {
816  newFont = styledfont;
817  newFontBuilt = true;
818  }
819  }
820  else
821  {
822  newFont = QFont( ddFontFamily );
823  newFontBuilt = true;
824  }
825  }
826 
827  if ( newFontBuilt )
828  {
829  // copy over existing font settings
830  newFont.setUnderline( d->textFont.underline() );
831  newFont.setStrikeOut( d->textFont.strikeOut() );
832  newFont.setWordSpacing( d->textFont.wordSpacing() );
833  newFont.setLetterSpacing( QFont::AbsoluteSpacing, d->textFont.letterSpacing() );
834  d->textFont = newFont;
835  }
836 
837  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::Underline ) )
838  {
839  context.expressionContext().setOriginalValueVariable( d->textFont.underline() );
840  d->textFont.setUnderline( d->mDataDefinedProperties.valueAsBool( QgsPalLayerSettings::Underline, context.expressionContext(), d->textFont.underline() ) );
841  }
842 
843  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::Strikeout ) )
844  {
845  context.expressionContext().setOriginalValueVariable( d->textFont.strikeOut() );
846  d->textFont.setStrikeOut( d->mDataDefinedProperties.valueAsBool( QgsPalLayerSettings::Strikeout, context.expressionContext(), d->textFont.strikeOut() ) );
847  }
848 
849  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::Color ) )
850  {
852  d->textColor = d->mDataDefinedProperties.valueAsColor( QgsPalLayerSettings::Color, context.expressionContext(), d->textColor );
853  }
854 
855  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::Size ) )
856  {
858  d->fontSize = d->mDataDefinedProperties.valueAsDouble( QgsPalLayerSettings::Size, context.expressionContext(), d->fontSize );
859  }
860 
861  exprVal = d->mDataDefinedProperties.value( QgsPalLayerSettings::FontSizeUnit, context.expressionContext() );
862  if ( exprVal.isValid() )
863  {
864  QString units = exprVal.toString();
865  if ( !units.isEmpty() )
866  {
867  bool ok;
869  if ( ok )
870  d->fontSizeUnits = res;
871  }
872  }
873 
874  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::FontOpacity ) )
875  {
876  context.expressionContext().setOriginalValueVariable( d->opacity * 100 );
877  d->opacity = d->mDataDefinedProperties.value( QgsPalLayerSettings::FontOpacity, context.expressionContext(), d->opacity * 100 ).toDouble() / 100.0;
878  }
879 
880  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::TextOrientation ) )
881  {
882  const QString encoded = QgsTextRendererUtils::encodeTextOrientation( d->orientation );
883  context.expressionContext().setOriginalValueVariable( encoded );
884  d->orientation = QgsTextRendererUtils::decodeTextOrientation( d->mDataDefinedProperties.value( QgsPalLayerSettings::TextOrientation, context.expressionContext(), encoded ).toString() );
885  }
886 
887  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::FontLetterSpacing ) )
888  {
889  context.expressionContext().setOriginalValueVariable( d->textFont.letterSpacing() );
890  d->textFont.setLetterSpacing( QFont::AbsoluteSpacing, d->mDataDefinedProperties.value( QgsPalLayerSettings::FontLetterSpacing, context.expressionContext(), d->textFont.letterSpacing() ).toDouble() );
891  }
892 
893  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::FontWordSpacing ) )
894  {
895  context.expressionContext().setOriginalValueVariable( d->textFont.wordSpacing() );
896  d->textFont.setWordSpacing( d->mDataDefinedProperties.value( QgsPalLayerSettings::FontWordSpacing, context.expressionContext(), d->textFont.wordSpacing() ).toDouble() );
897  }
898 
899  if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::FontBlendMode ) )
900  {
901  exprVal = d->mDataDefinedProperties.value( QgsPalLayerSettings::FontBlendMode, context.expressionContext() );
902  QString blendstr = exprVal.toString().trimmed();
903  if ( !blendstr.isEmpty() )
904  d->blendMode = QgsSymbolLayerUtils::decodeBlendMode( blendstr );
905  }
906 
907  mShadowSettings.updateDataDefinedProperties( context, d->mDataDefinedProperties );
908  mBackgroundSettings.updateDataDefinedProperties( context, d->mDataDefinedProperties );
909  mBufferSettings.updateDataDefinedProperties( context, d->mDataDefinedProperties );
910  mMaskSettings.updateDataDefinedProperties( context, d->mDataDefinedProperties );
911 }
912 
913 QPixmap QgsTextFormat::textFormatPreviewPixmap( const QgsTextFormat &format, QSize size, const QString &previewText, int padding )
914 {
915  QgsTextFormat tempFormat = format;
916  QPixmap pixmap( size );
917  pixmap.fill( Qt::transparent );
918  QPainter painter;
919  painter.begin( &pixmap );
920 
921  painter.setRenderHint( QPainter::Antialiasing );
922 
923  QRect rect( 0, 0, size.width(), size.height() );
924 
925  // shameless eye candy - use a subtle gradient when drawing background
926  painter.setPen( Qt::NoPen );
927  QColor background1 = tempFormat.previewBackgroundColor();
928  if ( ( background1.lightnessF() < 0.7 ) )
929  {
930  background1 = background1.darker( 125 );
931  }
932  else
933  {
934  background1 = background1.lighter( 125 );
935  }
936  QColor background2 = tempFormat.previewBackgroundColor();
937  QLinearGradient linearGrad( QPointF( 0, 0 ), QPointF( 0, rect.height() ) );
938  linearGrad.setColorAt( 0, background1 );
939  linearGrad.setColorAt( 1, background2 );
940  painter.setBrush( QBrush( linearGrad ) );
941  if ( size.width() > 30 )
942  {
943  painter.drawRoundedRect( rect, 6, 6 );
944  }
945  else
946  {
947  // don't use rounded rect for small previews
948  painter.drawRect( rect );
949  }
950  painter.setBrush( Qt::NoBrush );
951  painter.setPen( Qt::NoPen );
952  padding += 1; // move text away from background border
953 
954  QgsRenderContext context;
955  QgsMapToPixel newCoordXForm;
956  newCoordXForm.setParameters( 1, 0, 0, 0, 0, 0 );
957  context.setMapToPixel( newCoordXForm );
958 
959  context.setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 );
960  context.setUseAdvancedEffects( true );
961  context.setFlag( QgsRenderContext::Antialiasing, true );
962  context.setPainter( &painter );
963  context.setFlag( QgsRenderContext::Antialiasing, true );
964 
965  // slightly inset text to account for buffer/background
966  double xtrans = 0;
967  if ( tempFormat.buffer().enabled() )
968  xtrans = context.convertToPainterUnits( tempFormat.buffer().size(), tempFormat.buffer().sizeUnit(), tempFormat.buffer().sizeMapUnitScale() );
969  if ( tempFormat.background().enabled() && tempFormat.background().sizeType() != QgsTextBackgroundSettings::SizeFixed )
970  xtrans = std::max( xtrans, context.convertToPainterUnits( tempFormat.background().size().width(), tempFormat.background().sizeUnit(), tempFormat.background().sizeMapUnitScale() ) );
971 
972  double ytrans = 0.0;
973  if ( tempFormat.buffer().enabled() )
974  ytrans = std::max( ytrans, context.convertToPainterUnits( tempFormat.buffer().size(), tempFormat.buffer().sizeUnit(), tempFormat.buffer().sizeMapUnitScale() ) );
975  if ( tempFormat.background().enabled() )
976  ytrans = std::max( ytrans, context.convertToPainterUnits( tempFormat.background().size().height(), tempFormat.background().sizeUnit(), tempFormat.background().sizeMapUnitScale() ) );
977 
978  const QStringList text = QStringList() << ( previewText.isEmpty() ? QObject::tr( "Aa" ) : previewText );
979  const double textHeight = QgsTextRenderer::textHeight( context, tempFormat, text, QgsTextRenderer::Rect );
980  QRectF textRect = rect;
981  textRect.setLeft( xtrans + padding );
982  textRect.setWidth( rect.width() - xtrans - 2 * padding );
983 
984  if ( textRect.width() > 2000 )
985  textRect.setWidth( 2000 - 2 * padding );
986 
987  const double bottom = textRect.height() / 2 + textHeight / 2;
988  textRect.setTop( bottom - textHeight );
989  textRect.setBottom( bottom );
990 
991  QgsTextRenderer::drawText( textRect, 0, QgsTextRenderer::AlignCenter, text, context, tempFormat );
992 
993  // draw border on top of text
994  painter.setBrush( Qt::NoBrush );
995  painter.setPen( QPen( tempFormat.previewBackgroundColor().darker( 150 ), 0 ) );
996  if ( size.width() > 30 )
997  {
998  painter.drawRoundedRect( rect, 6, 6 );
999  }
1000  else
1001  {
1002  // don't use rounded rect for small previews
1003  painter.drawRect( rect );
1004  }
1005  painter.end();
1006  return pixmap;
1007 }
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
static QString untranslateNamedStyle(const QString &namedStyle)
Returns the english named style of a font, if possible.
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=nullptr, bool *match=nullptr)
Check whether font family is on system.
static bool fontFamilyOnSystem(const QString &family)
Check whether font family is on system in a quick manner, which does not compare [foundry].
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:39
void setParameters(double mapUnitsPerPixel, double centerX, double centerY, int widthPixels, int heightPixels, double rotation)
Set parameters for use in transforming coordinates.
Struct for storing maximum and minimum scales for measurements in map units.
static QgsPainting::BlendMode getBlendModeEnum(QPainter::CompositionMode blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode.
Definition: qgspainting.cpp:80
static QPainter::CompositionMode getCompositionMode(QgsPainting::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
Definition: qgspainting.cpp:20
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer.
Definition: qgspainting.h:37
@ Strikeout
Use strikeout.
@ FontStyle
Font style name.
@ Underline
Use underline.
@ FontLetterSpacing
Letter spacing.
@ Bold
Use bold style.
@ FontSizeUnit
Font size units.
@ Italic
Use italic style.
@ FontWordSpacing
Word spacing.
@ FontBlendMode
Text blend mode.
@ Family
Font family.
@ FontOpacity
Text opacity.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the labeling property definitions.
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
The class is used as a container of context for various read/write operations on other objects.
Contains information about the context of a rendering operation.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
void setUseAdvancedEffects(bool enabled)
Used to enable or disable advanced effects such as blend modes.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
@ Antialiasing
Use antialiasing while drawing.
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
Capitalization
Capitalization options.
@ MixedCase
Mixed case, ie no change.
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QColor decodeColor(const QString &str)
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QPainter::CompositionMode decodeBlendMode(const QString &s)
static QString encodeColor(const QColor &color)
Container for settings relating to a text background object.
QSizeF size() const
Returns the size of the background shape.
QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns all field names referenced by the configuration (e.g.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the background shape.
bool enabled() const
Returns whether the background is enabled.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
void updateDataDefinedProperties(QgsRenderContext &context, const QgsPropertyCollection &properties)
Updates the format by evaluating current values of data defined properties.
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
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.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units used for the shape's size.
Container for settings relating to a text buffer.
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns all field names referenced by the configuration (e.g.
double size() const
Returns the size of the buffer.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the buffer size.
bool enabled() const
Returns whether the buffer is enabled.
QDomElement writeXml(QDomDocument &doc) const
Write settings into a DOM element.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the buffer.
void updateDataDefinedProperties(QgsRenderContext &context, const QgsPropertyCollection &properties)
Updates the format by evaluating current values of data defined properties.
void readXml(const QDomElement &elem)
Read settings from a DOM element.
Container for all settings relating to text rendering.
Definition: qgstextformat.h:41
QgsTextFormat()
Default constructor for QgsTextFormat.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the text.
void setSize(double size)
Sets the size for rendered text.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the size.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the format's property collection, used for data defined overrides.
void setFont(const QFont &font)
Sets the font used for rendering text.
QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns all field names referenced by the configuration (e.g.
static QgsTextFormat fromMimeData(const QMimeData *data, bool *ok=nullptr)
Attempts to parse the provided mime data as a QgsTextFormat.
double lineHeight() const
Returns the line height for text.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
void setOrientation(TextOrientation orientation)
Sets the orientation for the text.
void updateDataDefinedProperties(QgsRenderContext &context)
Updates the format by evaluating current values of data defined properties.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the format's property collection, used for data defined overrides.
void setShadow(const QgsTextShadowSettings &shadowSettings)
Sets the text's drop shadow settings.
void setMask(const QgsTextMaskSettings &maskSettings)
Sets the text's masking settings.
void setPreviewBackgroundColor(const QColor &color)
Sets the background color that text will be rendered on for previews.
void setOpacity(double opacity)
Sets the text's opacity.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the text.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
bool operator==(const QgsTextFormat &other) const
TextOrientation orientation() const
Returns the orientation of the text.
void setAllowHtmlFormatting(bool allow)
Sets whether text should be treated as a HTML document and HTML tags should be used for formatting th...
QgsTextMaskSettings & mask()
Returns a reference to the masking settings.
static QPixmap textFormatPreviewPixmap(const QgsTextFormat &format, QSize size, const QString &previewText=QString(), int padding=0)
Returns a pixmap preview for a text format.
bool isValid() const
Returns true if the format is valid.
void setCapitalization(QgsStringUtils::Capitalization capitalization)
Sets the text capitalization style.
void setBuffer(const QgsTextBufferSettings &bufferSettings)
Sets the text's buffer settings.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
TextOrientation
Text orientation.
Definition: qgstextformat.h:46
static QgsTextFormat fromQFont(const QFont &font)
Returns a text format matching the settings from an input font.
void setValid()
Sets the format to a valid state, without changing any of the default format settings.
bool allowHtmlFormatting() const
Returns true if text should be treated as a HTML document and HTML tags should be used for formatting...
QFont toQFont() const
Returns a QFont matching the relevant settings from this text format.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
bool operator!=(const QgsTextFormat &other) const
double opacity() const
Returns the text's opacity.
QFont scaledFont(const QgsRenderContext &context, double scaleFactor=1.0) const
Returns a font with the size scaled to match the format's size settings (including units and map unit...
QString namedStyle() const
Returns the named style for the font used for rendering text (e.g., "bold").
double size() const
Returns the size for rendered text.
QgsTextShadowSettings & shadow()
Returns a reference to the text drop shadow settings.
QgsTextFormat & operator=(const QgsTextFormat &other)
void setBackground(const QgsTextBackgroundSettings &backgroundSettings)
Sets the text's background settings.q.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QMimeData * toMimeData() const
Returns new mime data representing the text format settings.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the size.
void setNamedStyle(const QString &style)
Sets the named style for the font used for rendering text.
QgsStringUtils::Capitalization capitalization() const
Returns the text capitalization style.
QColor color() const
Returns the color that text will be rendered in.
QFont font() const
Returns the font used for rendering text.
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
QColor previewBackgroundColor() const
Returns the background color for text previews.
bool containsAdvancedEffects() const
Returns true if any component of the font format requires advanced effects such as blend modes,...
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
void setLineHeight(double height)
Sets the line height for text.
Container for settings relating to a selective masking around a text.
QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns all field names referenced by the configuration (e.g.
void updateDataDefinedProperties(QgsRenderContext &context, const QgsPropertyCollection &properties)
Updates the format by evaluating current values of data defined properties.
void readXml(const QDomElement &elem)
Read settings from a DOM element.
QDomElement writeXml(QDomDocument &doc) const
Write settings into a DOM element.
static QString encodeTextOrientation(QgsTextFormat::TextOrientation orientation)
Encodes a text orientation.
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 QgsTextFormat::TextOrientation decodeTextOrientation(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a text orientation.
@ AlignCenter
Center align.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, DrawMode mode=Point, QFontMetricsF *fontMetrics=nullptr)
Returns the height of a text based on a given format.
static int sizeToPixel(double size, const QgsRenderContext &c, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &mapUnitScale=QgsMapUnitScale())
Calculates pixel size (considering output size should be in pixel or map units, scale factors and opt...
static void drawText(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, VAlignment vAlignment=AlignTop)
Draws text within a rectangle using the specified settings.
@ Rect
Text within rectangle draw mode.
Container for settings relating to a text shadow.
bool enabled() const
Returns whether the shadow is enabled.
void readXml(const QDomElement &elem)
Read settings from a DOM element.
QDomElement writeXml(QDomDocument &doc) const
Write settings into a DOM element.
void updateDataDefinedProperties(QgsRenderContext &context, const QgsPropertyCollection &properties)
Updates the format by evaluating current values of data defined properties.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the drop shadow.
QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns all field names referenced by the configuration (e.g.
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:167
@ RenderUnknownUnit
Mixed or unknown units.
Definition: qgsunittypes.h:174
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:175
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
Definition: qgsunittypes.h:171
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:172
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:170
@ RenderInches
Inches.
Definition: qgsunittypes.h:173
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:168
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:169
Represents a vector layer which manages a vector based data sets.