29 #include <QTextBoundaryFinder> 
   34 static void _fixQPictureDPI( QPainter *p )
 
   40   p->scale( 
static_cast< double >( 
qt_defaultDpiX() ) / p->device()->logicalDpiX(),
 
   41             static_cast< double >( 
qt_defaultDpiY() ) / p->device()->logicalDpiY() );
 
   46   if ( alignment & Qt::AlignLeft )
 
   48   else if ( alignment & Qt::AlignRight )
 
   50   else if ( alignment & Qt::AlignHCenter )
 
   52   else if ( alignment & Qt::AlignJustify )
 
   61   if ( alignment & Qt::AlignTop )
 
   63   else if ( alignment & Qt::AlignBottom )
 
   65   else if ( alignment & Qt::AlignVCenter )
 
   68   else if ( alignment & Qt::AlignBaseline )
 
   76   return static_cast< int >( 
c.convertToPainterUnits( size, unit, mapUnitScale ) + 0.5 ); 
 
   84   tmpFormat = updateShadowPosition( tmpFormat );
 
   91     drawPart( rect, rotation, alignment, vAlignment, document, context, tmpFormat, 
Background );
 
   96     drawPart( rect, rotation, alignment, vAlignment, document, context, tmpFormat, 
Buffer );
 
   99   drawPart( rect, rotation, alignment, vAlignment, document, context, tmpFormat, 
Text );
 
  107   tmpFormat = updateShadowPosition( tmpFormat );
 
  119     drawPart( point, rotation, alignment, document, context, tmpFormat, 
Buffer );
 
  122   drawPart( point, rotation, alignment, document, context, tmpFormat, 
Text );
 
  151   drawPart( rect, rotation, alignment, 
AlignTop, document, context, format, part );
 
  162   component.dpiRatio = 1.0;
 
  163   component.origin = rect.topLeft();
 
  164   component.rotation = rotation;
 
  165   component.size = rect.size();
 
  166   component.hAlign = alignment;
 
  179         double xc = rect.width() / 2.0;
 
  180         double yc = rect.height() / 2.0;
 
  182         double angle = -rotation;
 
  183         double xd = xc * std::cos( 
angle ) - yc * std::sin( 
angle );
 
  184         double yd = xc * std::sin( 
angle ) + yc * std::cos( 
angle );
 
  186         component.center = QPointF( component.origin.x() + xd, component.origin.y() + yd );
 
  190         component.center = rect.center();
 
  193       QgsTextRenderer::drawBackground( context, component, format, document, 
Rect );
 
  207       drawTextInternal( part, context, format, component,
 
  210                         alignment, vAlignment );
 
  219   drawPart( origin, rotation, alignment, document, context, format, part );
 
  230   component.dpiRatio = 1.0;
 
  231   component.origin = origin;
 
  232   component.rotation = rotation;
 
  233   component.hAlign = alignment;
 
  242       QgsTextRenderer::drawBackground( context, component, format, document, 
Point );
 
  255       drawTextInternal( part, context, format, component,
 
  267   return QFontMetricsF( format.
scaledFont( context, scaleFactor ), context.
painter() ? context.
painter()->device() : 
nullptr );
 
  272   QPainter *p = context.
painter();
 
  277     if ( component.rotation >= -315 && component.rotation < -90 )
 
  281     else if ( component.rotation >= -90 && component.rotation < -45 )
 
  296   const QFont font = format.
scaledFont( context, scaleFactor );
 
  299   path.setFillRule( Qt::WindingFill );
 
  301   switch ( orientation )
 
  308         QFont fragmentFont = font;
 
  311         if ( component.extraWordSpacing || component.extraLetterSpacing )
 
  312           applyExtraSpacingForLineJustification( fragmentFont, component.extraWordSpacing, component.extraLetterSpacing );
 
  314         path.addText( xOffset, 0, fragmentFont, fragment.
text() );
 
  325       double letterSpacing = font.letterSpacing();
 
  326       double partYOffset = component.offset.y() * scaleFactor;
 
  329         QFont fragmentFont = font;
 
  332         QFontMetricsF fragmentMetrics( fragmentFont );
 
  333         const double labelWidth = fragmentMetrics.maxWidth();
 
  336         for ( 
const QString &part : parts )
 
  338           double partXOffset = ( labelWidth - ( fragmentMetrics.horizontalAdvance( part ) - letterSpacing ) ) / 2;
 
  339           path.addText( partXOffset, partYOffset, fragmentFont, part );
 
  340           partYOffset += fragmentMetrics.ascent() + letterSpacing;
 
  343       advance = partYOffset - component.offset.y() * scaleFactor;
 
  348   QColor bufferColor = buffer.
color();
 
  349   bufferColor.setAlphaF( buffer.
opacity() );
 
  350   QPen pen( bufferColor );
 
  351   pen.setWidthF( penSize * scaleFactor );
 
  353   QColor tmpColor( bufferColor );
 
  357     tmpColor.setAlpha( 0 );
 
  363   buffp.begin( &buffPict );
 
  367     std::unique_ptr< QgsPaintEffect > tmpEffect( buffer.
paintEffect()->
clone() );
 
  369     tmpEffect->begin( context );
 
  370     context.
painter()->setPen( pen );
 
  371     context.
painter()->setBrush( tmpColor );
 
  372     if ( scaleFactor != 1.0 )
 
  373       context.
painter()->scale( 1 / scaleFactor, 1 / scaleFactor );
 
  374     context.
painter()->drawPath( path );
 
  375     if ( scaleFactor != 1.0 )
 
  376       context.
painter()->scale( scaleFactor, scaleFactor );
 
  377     tmpEffect->end( context );
 
  383     if ( scaleFactor != 1.0 )
 
  384       buffp.scale( 1 / scaleFactor, 1 / scaleFactor );
 
  386     buffp.setBrush( tmpColor );
 
  387     buffp.drawPath( path );
 
  393     QgsTextRenderer::Component bufferComponent = component;
 
  394     bufferComponent.origin = QPointF( 0.0, 0.0 );
 
  395     bufferComponent.picture = buffPict;
 
  396     bufferComponent.pictureBuffer = penSize / 2.0;
 
  400       bufferComponent.offset.setY( bufferComponent.offset.y() - bufferComponent.size.height() );
 
  402     drawShadow( context, bufferComponent, format );
 
  410     p->setCompositionMode( buffer.
blendMode() );
 
  414   p->scale( component.dpiRatio, component.dpiRatio );
 
  415   _fixQPictureDPI( p );
 
  416   p->drawPicture( 0, 0, buffPict );
 
  418   return advance / scaleFactor;
 
  435   path.setFillRule( Qt::WindingFill );
 
  442   const QFont font = format.
scaledFont( context, scaleFactor );
 
  446     QFont fragmentFont = font;
 
  449     path.addText( xOffset, 0, fragmentFont, fragment.
text() );
 
  454   QColor bufferColor( Qt::gray );
 
  455   bufferColor.setAlphaF( mask.
opacity() );
 
  459   brush.setColor( bufferColor );
 
  460   pen.setColor( bufferColor );
 
  461   pen.setWidthF( penSize * scaleFactor );
 
  468   p->scale( component.dpiRatio, component.dpiRatio );
 
  474       if ( scaleFactor != 1.0 )
 
  475         context.
painter()->scale( 1 / scaleFactor, 1 / scaleFactor );
 
  476       context.
painter()->setPen( pen );
 
  477       context.
painter()->setBrush( brush );
 
  478       context.
painter()->drawPath( path );
 
  479       if ( scaleFactor != 1.0 )
 
  480         context.
painter()->scale( scaleFactor, scaleFactor );
 
  485     if ( scaleFactor != 1.0 )
 
  486       p->scale( 1 / scaleFactor, 1 / scaleFactor );
 
  488     p->setBrush( brush );
 
  490     if ( scaleFactor != 1.0 )
 
  491       p->scale( scaleFactor, scaleFactor );
 
  508   return textWidth( context, format, doc );
 
  515   const QFont baseFont = format.
scaledFont( context, scaleFactor );
 
  522       double maxLineWidth = 0;
 
  525         double blockWidth = 0;
 
  530         maxLineWidth = std::max( maxLineWidth, blockWidth );
 
  532       width = maxLineWidth;
 
  538       double totalLineWidth = 0;
 
  542         double blockWidth = 0;
 
  545           QFont fragmentFont = baseFont;
 
  547           blockWidth = std::max( QFontMetricsF( fragmentFont ).maxWidth(), blockWidth );
 
  550         totalLineWidth += blockIndex == 0 ? blockWidth : blockWidth * format.
lineHeight();
 
  553       width = totalLineWidth;
 
  564   return width / scaleFactor;
 
  582   const QFont baseFont = format.
scaledFont( context, scaleFactor );
 
  583   const QFontMetrics fm( baseFont );
 
  584   const double height = ( character.isNull() ? fm.height() : fm.boundingRect( character ).height() ) / scaleFactor;
 
  586   if ( !includeEffects )
 
  589   double maxExtension = 0;
 
  609   return height + maxExtension;
 
  620   const QFont baseFont = format.
scaledFont( context, scaleFactor );
 
  627       double totalHeight = 0;
 
  628       double lastLineLeading = 0;
 
  631         double maxBlockHeight = 0;
 
  632         double maxBlockLineSpacing = 0;
 
  633         double maxBlockLeading = 0;
 
  636           QFont fragmentFont = baseFont;
 
  638           const QFontMetricsF fm( fragmentFont );
 
  640           const double fragmentHeight = fm.ascent() + fm.descent(); 
 
  642           maxBlockHeight = std::max( maxBlockHeight, fragmentHeight );
 
  643           if ( fm.lineSpacing() > maxBlockLineSpacing )
 
  645             maxBlockLineSpacing = fm.lineSpacing();
 
  646             maxBlockLeading = fm.leading();
 
  656             totalHeight += blockIndex == 0 ? maxBlockHeight : maxBlockHeight * format.
lineHeight();
 
  662             totalHeight += blockIndex == 0 ? maxBlockHeight : maxBlockLineSpacing * format.
lineHeight();
 
  663             if ( blockIndex > 0 )
 
  664               lastLineLeading = maxBlockLeading;
 
  671       return ( totalHeight - lastLineLeading ) / scaleFactor;
 
  676       double maxBlockHeight = 0;
 
  679         double blockHeight = 0;
 
  680         int fragmentIndex = 0;
 
  683           QFont fragmentFont = baseFont;
 
  685           const QFontMetricsF fm( fragmentFont );
 
  687           const double labelHeight = fm.ascent();
 
  688           const double letterSpacing = fragmentFont.letterSpacing();
 
  690           blockHeight += fragmentIndex = 0 ? labelHeight * fragment.
text().size() + ( fragment.
text().size() - 1 ) * letterSpacing
 
  691                                          : fragment.
text().size() * ( labelHeight + letterSpacing );
 
  694         maxBlockHeight = std::max( maxBlockHeight, blockHeight );
 
  697       return maxBlockHeight / scaleFactor;
 
  714   QPainter *prevP = context.
painter();
 
  715   QPainter *p = context.
painter();
 
  716   std::unique_ptr< QgsPaintEffect > tmpEffect;
 
  720     tmpEffect->begin( context );
 
  731     component.rotation = -( component.rotation * 180 / M_PI ); 
 
  732     component.rotationOffset =
 
  737     component.rotation = 0.0; 
 
  738     component.rotationOffset = background.
rotation();
 
  746     QFontMetricsF fm( format.
scaledFont( context, scaleFactor ) );
 
  747     double width = 
textWidth( context, format, document );
 
  748     double height = 
textHeight( context, format, document, mode );
 
  753         switch ( component.hAlign )
 
  757             component.center = QPointF( component.origin.x() + width / 2.0,
 
  758                                         component.origin.y() + height / 2.0 );
 
  762             component.center = QPointF( component.origin.x() + component.size.width() / 2.0,
 
  763                                         component.origin.y() + height / 2.0 );
 
  767             component.center = QPointF( component.origin.x() + component.size.width() - width / 2.0,
 
  768                                         component.origin.y() + height / 2.0 );
 
  775         double originAdjust = fm.ascent() / scaleFactor / 2.0 - fm.leading() / scaleFactor / 2.0;
 
  776         switch ( component.hAlign )
 
  780             component.center = QPointF( component.origin.x() + width / 2.0,
 
  781                                         component.origin.y() - height / 2.0 + originAdjust );
 
  785             component.center = QPointF( component.origin.x(),
 
  786                                         component.origin.y() - height / 2.0 + originAdjust );
 
  790             component.center = QPointF( component.origin.x() - width / 2.0,
 
  791                                         component.origin.y() - height / 2.0 + originAdjust );
 
  802       component.size = QSizeF( width, height );
 
  807   switch ( background.
type() )
 
  820       double sizeOut = 0.0;
 
  828         sizeOut = std::max( component.size.width(), component.size.height() );
 
  832         sizeOut += bufferSize * 2;
 
  840       std::unique_ptr< QgsMarkerSymbol > renderedSymbol;
 
  844         map[QStringLiteral( 
"name" )] = background.
svgFile().trimmed();
 
  845         map[QStringLiteral( 
"size" )] = QString::number( sizeOut );
 
  847         map[QStringLiteral( 
"angle" )] = QString::number( 0.0 ); 
 
  855         map[QStringLiteral( 
"fill" )] = background.
fillColor().name();
 
  856         map[QStringLiteral( 
"outline" )] = background.
strokeColor().name();
 
  857         map[QStringLiteral( 
"outline-width" )] = QString::number( background.
strokeWidth() );
 
  864           QVariantMap shdwmap( map );
 
  865           shdwmap[QStringLiteral( 
"fill" )] = shadow.
color().name();
 
  866           shdwmap[QStringLiteral( 
"outline" )] = shadow.
color().name();
 
  867           shdwmap[QStringLiteral( 
"size" )] = QString::number( sizeOut );
 
  872           svgp.begin( &svgPict );
 
  889           svgShdwM->
renderPoint( QPointF( sizeOut / 2, -sizeOut / 2 ), svgShdwContext );
 
  892           component.picture = svgPict;
 
  894           component.pictureBuffer = 0.0;
 
  896           component.size = QSizeF( sizeOut, sizeOut );
 
  897           component.offset = QPointF( 0.0, 0.0 );
 
  903           p->translate( component.center.x(), component.center.y() );
 
  904           p->rotate( component.rotation );
 
  907           p->translate( QPointF( xoff, yoff ) );
 
  908           p->rotate( component.rotationOffset );
 
  909           p->translate( -sizeOut / 2, sizeOut / 2 );
 
  911           drawShadow( context, component, format );
 
  913         renderedSymbol.reset( );
 
  921         renderedSymbol->setSize( sizeOut );
 
  925       renderedSymbol->setOpacity( renderedSymbol->opacity() * background.
opacity() );
 
  933         p->setCompositionMode( background.
blendMode() );
 
  935       p->translate( component.center.x(), component.center.y() );
 
  936       p->rotate( component.rotation );
 
  939       p->translate( QPointF( xoff, yoff ) );
 
  940       p->rotate( component.rotationOffset );
 
  944       renderedSymbol->renderPoint( QPointF( 0, 0 ), &f, context );
 
  945       renderedSymbol->stopRender( context );
 
  946       p->setCompositionMode( QPainter::CompositionMode_SourceOver ); 
 
  956       double w = component.size.width();
 
  957       double h = component.size.height();
 
  978           h = std::sqrt( std::pow( w, 2 ) + std::pow( h, 2 ) );
 
  984           h = h * M_SQRT1_2 * 2;
 
  985           w = w * M_SQRT1_2 * 2;
 
  993         w += bufferWidth * 2;
 
  994         h += bufferHeight * 2;
 
  998       QRectF rect( -w / 2.0, - h / 2.0, w, h );
 
 1000       if ( rect.isNull() )
 
 1006       p->translate( QPointF( component.center.x(), component.center.y() ) );
 
 1007       p->rotate( component.rotation );
 
 1010       p->translate( QPointF( xoff, yoff ) );
 
 1011       p->rotate( component.rotationOffset );
 
 1017       QTransform t = QTransform::fromScale( 10, 10 );
 
 1019       QTransform ti = t.inverted();
 
 1026           path.addRoundedRect( rect, background.
radii().width(), background.
radii().height(), Qt::RelativeSize );
 
 1032           path.addRoundedRect( rect, xRadius, yRadius );
 
 1038         path.addEllipse( rect );
 
 1040       QPolygonF tempPolygon = path.toFillPolygon( t );
 
 1041       QPolygonF polygon = ti.map( tempPolygon );
 
 1043       QPainter *oldp = context.
painter();
 
 1046       shapep.begin( &shapePict );
 
 1049       std::unique_ptr< QgsFillSymbol > renderedSymbol;
 
 1051       renderedSymbol->setOpacity( renderedSymbol->opacity() * background.
opacity() );
 
 1055       renderedSymbol->renderPolygon( polygon, 
nullptr, &f, context );
 
 1056       renderedSymbol->stopRender( context );
 
 1063         component.picture = shapePict;
 
 1066         component.size = rect.size();
 
 1067         component.offset = QPointF( rect.width() / 2, -rect.height() / 2 );
 
 1068         drawShadow( context, component, format );
 
 1073         p->setCompositionMode( background.
blendMode() );
 
 1077       p->scale( component.dpiRatio, component.dpiRatio );
 
 1078       _fixQPictureDPI( p );
 
 1079       p->drawPicture( 0, 0, shapePict );
 
 1080       p->setCompositionMode( QPainter::CompositionMode_SourceOver ); 
 
 1087     tmpEffect->end( context );
 
 1100   QPainter *p = context.
painter();
 
 1101   double componentWidth = component.size.width(), componentHeight = component.size.height();
 
 1102   double xOffset = component.offset.x(), yOffset = component.offset.y();
 
 1103   double pictbuffer = component.pictureBuffer;
 
 1108   radius /= ( mapUnits ? context.
scaleFactor() / component.dpiRatio : 1 );
 
 1109   radius = 
static_cast< int >( radius + 0.5 ); 
 
 1113   double blurBufferClippingScale = 3.75;
 
 1114   int blurbuffer = ( radius > 17 ? 16 : radius ) * blurBufferClippingScale;
 
 1116   QImage blurImg( componentWidth + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
 
 1117                   componentHeight + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
 
 1118                   QImage::Format_ARGB32_Premultiplied );
 
 1122   int minBlurImgSize = 1;
 
 1126   int maxBlurImgSize = 40000;
 
 1127   if ( blurImg.isNull()
 
 1128        || ( blurImg.width() < minBlurImgSize || blurImg.height() < minBlurImgSize )
 
 1129        || ( blurImg.width() > maxBlurImgSize || blurImg.height() > maxBlurImgSize ) )
 
 1132   blurImg.fill( QColor( Qt::transparent ).rgba() );
 
 1134   if ( !pictp.begin( &blurImg ) )
 
 1136   pictp.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
 
 1137   QPointF imgOffset( blurbuffer + pictbuffer + xOffset,
 
 1138                      blurbuffer + pictbuffer + componentHeight + yOffset );
 
 1140   pictp.drawPicture( imgOffset,
 
 1141                      component.picture );
 
 1144   pictp.setCompositionMode( QPainter::CompositionMode_SourceIn );
 
 1145   pictp.fillRect( blurImg.rect(), shadow.
color() );
 
 1149   if ( shadow.
blurRadius() > 0.0 && radius > 0 )
 
 1157   picti.begin( &blurImg );
 
 1158   picti.setBrush( Qt::Dense7Pattern );
 
 1159   QPen imgPen( QColor( 0, 0, 255, 255 ) );
 
 1160   imgPen.setWidth( 1 );
 
 1161   picti.setPen( imgPen );
 
 1162   picti.setOpacity( 0.1 );
 
 1163   picti.drawRect( 0, 0, blurImg.width(), blurImg.height() );
 
 1168   double angleRad = shadow.
offsetAngle() * M_PI / 180; 
 
 1176     angleRad -= ( component.rotation * M_PI / 180 + component.rotationOffset * M_PI / 180 );
 
 1179   QPointF transPt( -offsetDist * std::cos( angleRad + M_PI_2 ),
 
 1180                    -offsetDist * std::sin( angleRad + M_PI_2 ) );
 
 1183   p->setRenderHint( QPainter::SmoothPixmapTransform );
 
 1187     p->setCompositionMode( shadow.
blendMode() );
 
 1189   p->setOpacity( shadow.
opacity() );
 
 1191   double scale = shadow.
scale() / 100.0;
 
 1193   p->scale( scale, scale );
 
 1194   if ( component.useOrigin )
 
 1196     p->translate( component.origin.x(), component.origin.y() );
 
 1198   p->translate( transPt );
 
 1199   p->translate( -imgOffset.x(),
 
 1201   p->drawImage( 0, 0, blurImg );
 
 1208   p->setBrush( Qt::NoBrush );
 
 1209   QPen imgPen( QColor( 255, 0, 0, 10 ) );
 
 1210   imgPen.setWidth( 2 );
 
 1211   imgPen.setStyle( Qt::DashLine );
 
 1212   p->setPen( imgPen );
 
 1213   p->scale( scale, scale );
 
 1214   if ( component.useOrigin() )
 
 1216     p->translate( component.origin().x(), component.origin().y() );
 
 1218   p->translate( transPt );
 
 1219   p->translate( -imgOffset.x(),
 
 1221   p->drawRect( 0, 0, blurImg.width(), blurImg.height() );
 
 1226   p->setBrush( Qt::NoBrush );
 
 1227   QPen componentRectPen( QColor( 0, 255, 0, 70 ) );
 
 1228   componentRectPen.setWidth( 1 );
 
 1229   if ( component.useOrigin() )
 
 1231     p->translate( component.origin().x(), component.origin().y() );
 
 1233   p->setPen( componentRectPen );
 
 1234   p->drawRect( QRect( -xOffset, -componentHeight - yOffset, componentWidth, componentHeight ) );
 
 1240 void QgsTextRenderer::drawTextInternal( TextPart drawType,
 
 1243                                         const Component &component,
 
 1245                                         const QFontMetricsF *fontMetrics,
 
 1246                                         HAlignment alignment, VAlignment vAlignment, DrawMode mode )
 
 1253   double fontScale = 1.0;
 
 1254   std::unique_ptr< QFontMetricsF > tmpMetrics;
 
 1258     const QFont f = format.
scaledFont( context, fontScale );
 
 1259     tmpMetrics = std::make_unique< QFontMetricsF >( f );
 
 1263   double rotation = 0;
 
 1265   switch ( orientation )
 
 1269       drawTextInternalHorizontal( context, format, drawType, mode, component, document, fontScale, 
fontMetrics, alignment, vAlignment, rotation );
 
 1276       drawTextInternalVertical( context, format, drawType, mode, component, document, fontScale, 
fontMetrics, alignment, vAlignment, rotation );
 
 1284   rotation = -component.rotation * 180 / M_PI;
 
 1291       if ( rotation >= -315 && rotation < -90 )
 
 1296       else if ( rotation >= -90 && rotation < -45 )
 
 1312 void QgsTextRenderer::calculateExtraSpacingForLineJustification( 
const double spaceToDistribute, 
const QgsTextBlock &block, 
double &extraWordSpace, 
double &extraLetterSpace )
 
 1315   QTextBoundaryFinder 
finder( QTextBoundaryFinder::Word, blockText );
 
 1317   int wordBoundaries = 0;
 
 1318   while ( 
finder.toNextBoundary() != -1 )
 
 1320     if ( 
finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem )
 
 1324   if ( wordBoundaries > 0 )
 
 1327     extraWordSpace = spaceToDistribute / wordBoundaries;
 
 1332     QTextBoundaryFinder 
finder( QTextBoundaryFinder::Grapheme, blockText );
 
 1335     int graphemeBoundaries = 0;
 
 1336     while ( 
finder.toNextBoundary() != -1 )
 
 1338       if ( 
finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem )
 
 1339         graphemeBoundaries++;
 
 1342     if ( graphemeBoundaries > 0 )
 
 1344       extraLetterSpace = spaceToDistribute / graphemeBoundaries;
 
 1349 void QgsTextRenderer::applyExtraSpacingForLineJustification( QFont &font, 
double extraWordSpace, 
double extraLetterSpace )
 
 1351   const double prevWordSpace = font.wordSpacing();
 
 1352   font.setWordSpacing( prevWordSpace + extraWordSpace );
 
 1353   const double prevLetterSpace = font.letterSpacing();
 
 1354   font.setLetterSpacing( QFont::AbsoluteSpacing, prevLetterSpace + extraLetterSpace );
 
 1357 void QgsTextRenderer::drawTextInternalHorizontal( 
QgsRenderContext &context, 
const QgsTextFormat &format, TextPart drawType, DrawMode mode, 
const Component &component, 
const QgsTextDocument &document, 
double fontScale, 
const QFontMetricsF *fontMetrics, HAlignment hAlignment,
 
 1358     VAlignment vAlignment, 
double rotation )
 
 1361   const QStringList textLines = document.
toPlainText();
 
 1363   double labelWidest = 0.0;
 
 1368       for ( 
const QString &line : textLines )
 
 1370         double labelWidth = 
fontMetrics->horizontalAdvance( line ) / fontScale;
 
 1371         if ( labelWidth > labelWidest )
 
 1373           labelWidest = labelWidth;
 
 1379       labelWidest = component.size.width();
 
 1387   double ascentOffset = 0.25 * 
fontMetrics->ascent() / fontScale; 
 
 1391   bool adjustForAlignment = hAlignment != 
AlignLeft && ( mode != 
Label || textLines.size() > 1 );
 
 1396     const double overallHeight = 
textHeight( context, format, textLines, 
Rect );
 
 1397     switch ( vAlignment )
 
 1403         ascentOffset = -( component.size.height() - overallHeight ) * 0.5 + ascentOffset;
 
 1407         ascentOffset = -( component.size.height() - overallHeight ) + ascentOffset;
 
 1412   for ( 
const QString &line : std::as_const( textLines ) )
 
 1416     const bool isFinalLine = i == document.
size() - 1;
 
 1420     context.
painter()->translate( component.origin );
 
 1422       context.
painter()->rotate( rotation );
 
 1427       maskPainter->save();
 
 1428       maskPainter->translate( component.origin );
 
 1430         maskPainter->rotate( rotation );
 
 1434     double xMultiLineOffset = 0.0;
 
 1435     double labelWidth = 
fontMetrics->horizontalAdvance( line ) / fontScale;
 
 1436     double extraWordSpace = 0;
 
 1437     double extraLetterSpace = 0;
 
 1438     if ( adjustForAlignment )
 
 1440       double labelWidthDiff = 0;
 
 1441       switch ( hAlignment )
 
 1444           labelWidthDiff = ( labelWidest - labelWidth ) * 0.5;
 
 1448           labelWidthDiff = labelWidest - labelWidth;
 
 1452           if ( !isFinalLine && labelWidest > labelWidth )
 
 1454             calculateExtraSpacingForLineJustification( labelWidest - labelWidth, block, extraWordSpace, extraLetterSpace );
 
 1466           xMultiLineOffset = labelWidthDiff;
 
 1471           switch ( hAlignment )
 
 1474               xMultiLineOffset = labelWidthDiff - labelWidest;
 
 1478               xMultiLineOffset = labelWidthDiff - labelWidest / 2.0;
 
 1490     double yMultiLineOffset = ascentOffset;
 
 1497         yMultiLineOffset = - ascentOffset - ( textLines.size() - 1 - i ) * labelHeight * format.
lineHeight();
 
 1502         yMultiLineOffset = - ascentOffset + labelHeight - 1  + format.
lineHeight() * 
fontMetrics->lineSpacing() * i / fontScale;
 
 1507         yMultiLineOffset = 0 - ( textLines.size() - 1 - i ) * 
fontMetrics->lineSpacing() * format.
lineHeight() / fontScale;
 
 1512     context.
painter()->translate( QPointF( xMultiLineOffset, yMultiLineOffset ) );
 
 1514       maskPainter->translate( QPointF( xMultiLineOffset, yMultiLineOffset ) );
 
 1516     Component subComponent;
 
 1517     subComponent.block = block;
 
 1518     subComponent.
size = QSizeF( labelWidth, labelHeight );
 
 1519     subComponent.offset = QPointF( 0.0, -ascentOffset );
 
 1520     subComponent.rotation = -component.rotation * 180 / M_PI;
 
 1521     subComponent.rotationOffset = 0.0;
 
 1522     subComponent.extraWordSpacing = extraWordSpace * fontScale;
 
 1523     subComponent.extraLetterSpacing = extraLetterSpace * fontScale;
 
 1528       QgsTextRenderer::drawMask( context, subComponent, format );
 
 1533       QgsTextRenderer::drawBuffer( context, subComponent, format );
 
 1540       textp.begin( &textPict );
 
 1541       textp.setPen( Qt::NoPen );
 
 1542       const QFont font = format.
scaledFont( context, fontScale );
 
 1543       textp.scale( 1 / fontScale, 1 / fontScale );
 
 1550         path.setFillRule( Qt::WindingFill );
 
 1552         QFont fragmentFont = font;
 
 1555         if ( extraWordSpace || extraLetterSpace )
 
 1556           applyExtraSpacingForLineJustification( fragmentFont, extraWordSpace * fontScale, extraLetterSpace * fontScale );
 
 1558         path.addText( xOffset, 0, fragmentFont, fragment.
text() );
 
 1562         textp.setBrush( textColor );
 
 1563         textp.drawPath( path );
 
 1571         subComponent.picture = textPict;
 
 1572         subComponent.pictureBuffer = 0.0; 
 
 1573         subComponent.origin = QPointF( 0.0, 0.0 );
 
 1575         QgsTextRenderer::drawShadow( context, subComponent, format );
 
 1585       context.
painter()->scale( subComponent.dpiRatio, subComponent.dpiRatio );
 
 1592           _fixQPictureDPI( context.
painter() );
 
 1593           context.
painter()->drawPicture( 0, 0, textPict );
 
 1602             QFont fragmentFont = font;
 
 1605             if ( extraWordSpace || extraLetterSpace )
 
 1606               applyExtraSpacingForLineJustification( fragmentFont, extraWordSpace * fontScale, extraLetterSpace * fontScale );
 
 1611             context.
painter()->setPen( textColor );
 
 1612             context.
painter()->setFont( fragmentFont );
 
 1613             context.
painter()->setRenderHint( QPainter::TextAntialiasing );
 
 1615             context.
painter()->scale( 1 / fontScale, 1 / fontScale );
 
 1616             context.
painter()->drawText( xOffset, 0, fragment.
text() );
 
 1617             context.
painter()->scale( fontScale, fontScale );
 
 1625       maskPainter->restore();
 
 1630 void QgsTextRenderer::drawTextInternalVertical( 
QgsRenderContext &context, 
const QgsTextFormat &format, 
QgsTextRenderer::TextPart drawType, 
QgsTextRenderer::DrawMode mode, 
const QgsTextRenderer::Component &component, 
const QgsTextDocument &document, 
double fontScale, 
const QFontMetricsF *fontMetrics, 
QgsTextRenderer::HAlignment hAlignment, 
QgsTextRenderer::VAlignment, 
double rotation )
 
 1633   const QStringList textLines = document.
toPlainText();
 
 1635   const QFont font = format.
scaledFont( context, fontScale );
 
 1636   double letterSpacing = font.letterSpacing() / fontScale;
 
 1638   double labelWidth = 
fontMetrics->maxWidth() / fontScale; 
 
 1639   double actualLabelWidest = labelWidth + ( textLines.size() - 1 ) * labelWidth * format.
lineHeight();
 
 1640   double labelWidest = 0.0;
 
 1645       labelWidest = actualLabelWidest;
 
 1649       labelWidest = component.size.width();
 
 1653   int maxLineLength = 0;
 
 1654   for ( 
const QString &line : std::as_const( textLines ) )
 
 1656     maxLineLength = std::max( maxLineLength, 
static_cast<int>( line.length() ) );
 
 1658   double actualLabelHeight = 
fontMetrics->ascent() / fontScale + ( 
fontMetrics->ascent() / fontScale + letterSpacing ) * ( maxLineLength - 1 );
 
 1659   double ascentOffset = 
fontMetrics->ascent() / fontScale;
 
 1663   bool adjustForAlignment = hAlignment != 
AlignLeft && ( mode != 
Label || textLines.size() > 1 );
 
 1670     context.
painter()->translate( component.origin );
 
 1672       context.
painter()->rotate( rotation );
 
 1677       maskPainter->save();
 
 1678       maskPainter->translate( component.origin );
 
 1680         maskPainter->rotate( rotation );
 
 1684     double xOffset = actualLabelWidest - labelWidth - ( i * labelWidth * format.
lineHeight() );
 
 1685     if ( adjustForAlignment )
 
 1687       double labelWidthDiff = 0;
 
 1688       switch ( hAlignment )
 
 1691           labelWidthDiff = ( labelWidest - actualLabelWidest ) * 0.5;
 
 1695           labelWidthDiff = labelWidest - actualLabelWidest;
 
 1707           xOffset += labelWidthDiff;
 
 1715     double yOffset = 0.0;
 
 1721           if ( rotation >= -405 && rotation < -180 )
 
 1723             yOffset = ascentOffset;
 
 1725           else if ( rotation >= 0 && rotation < 45 )
 
 1727             xOffset -= actualLabelWidest;
 
 1728             yOffset = -actualLabelHeight + ascentOffset + 
fontMetrics->descent() / fontScale;
 
 1733           yOffset = -actualLabelHeight + ascentOffset;
 
 1738         yOffset = -actualLabelHeight + ascentOffset;
 
 1742         yOffset = ascentOffset;
 
 1746     context.
painter()->translate( QPointF( xOffset, yOffset ) );
 
 1748     double fragmentYOffset = 0;
 
 1754       QFont fragmentFont( font );
 
 1757       QFontMetricsF fragmentMetrics( fragmentFont );
 
 1759       double labelHeight = fragmentMetrics.ascent() / fontScale + ( fragmentMetrics.ascent() / fontScale + letterSpacing ) * ( line.length() - 1 );
 
 1761       Component subComponent;
 
 1763       subComponent.size = QSizeF( labelWidth, labelHeight );
 
 1764       subComponent.offset = QPointF( 0.0, fragmentYOffset );
 
 1765       subComponent.rotation = -component.rotation * 180 / M_PI;
 
 1766       subComponent.rotationOffset = 0.0;
 
 1773         QgsTextRenderer::drawMask( context, subComponent, format );
 
 1779         fragmentYOffset += QgsTextRenderer::drawBuffer( context, subComponent, format );
 
 1785         path.setFillRule( Qt::WindingFill );
 
 1787         double partYOffset = 0.0;
 
 1788         for ( 
const auto &part : parts )
 
 1790           double partXOffset = ( labelWidth - ( fragmentMetrics.horizontalAdvance( part ) / fontScale - letterSpacing ) ) / 2;
 
 1791           path.addText( partXOffset * fontScale, partYOffset * fontScale, fragmentFont, part );
 
 1792           partYOffset += fragmentMetrics.ascent() / fontScale + letterSpacing;
 
 1798         textp.begin( &textPict );
 
 1799         textp.setPen( Qt::NoPen );
 
 1802         textp.setBrush( textColor );
 
 1803         textp.scale( 1 / fontScale, 1 / fontScale );
 
 1804         textp.drawPath( path );
 
 1814           subComponent.picture = textPict;
 
 1815           subComponent.pictureBuffer = 0.0; 
 
 1816           subComponent.origin = QPointF( 0.0, fragmentYOffset );
 
 1817           const double prevY = subComponent.offset.y();
 
 1818           subComponent.offset = QPointF( 0, -labelHeight );
 
 1819           subComponent.useOrigin = 
true;
 
 1820           QgsTextRenderer::drawShadow( context, subComponent, format );
 
 1821           subComponent.useOrigin = 
false;
 
 1822           subComponent.offset = QPointF( 0, prevY );
 
 1832         context.
painter()->scale( subComponent.dpiRatio, subComponent.dpiRatio );
 
 1839             _fixQPictureDPI( context.
painter() );
 
 1840             context.
painter()->drawPicture( 0, fragmentYOffset, textPict );
 
 1841             fragmentYOffset += partYOffset;
 
 1847             context.
painter()->setFont( fragmentFont );
 
 1848             context.
painter()->setPen( textColor );
 
 1849             context.
painter()->setRenderHint( QPainter::TextAntialiasing );
 
 1851             double partYOffset = 0.0;
 
 1852             for ( 
const QString &part : parts )
 
 1854               double partXOffset = ( labelWidth - ( fragmentMetrics.horizontalAdvance( part ) / fontScale - letterSpacing ) ) / 2;
 
 1855               context.
painter()->scale( 1 / fontScale, 1 / fontScale );
 
 1856               context.
painter()->drawText( partXOffset * fontScale, ( fragmentYOffset + partYOffset ) * fontScale, part );
 
 1857               context.
painter()->scale( fontScale, fontScale );
 
 1858               partYOffset += fragmentMetrics.ascent() / fontScale + letterSpacing;
 
 1860             fragmentYOffset += partYOffset;
 
 1867       maskPainter->restore();
 
A class to manager painter saving and restoring required for effect drawing.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
Struct for storing maximum and minimum scales for measurements in map units.
A marker symbol type, for rendering Point and MultiPoint geometries.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
virtual QgsPaintEffect * clone() const =0
Duplicates an effect by creating a deep copy of the effect.
bool enabled() const
Returns whether the effect is enabled.
A class to manage painter saving and restoring required for drawing on a different painter (mask pain...
static QStringList splitToGraphemes(const QString &text)
Splits a text string to a list of graphemes, which are the smallest allowable character divisions in ...
bool hasActiveProperties() const override
Returns true if the collection has any active properties, or false if all properties within the colle...
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
QPainter * maskPainter(int id=0)
Returns a mask QPainter for the render operation.
bool useAdvancedEffects() const
Returns true if advanced effects such as blend modes such be used.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
@ TextFormatAlwaysText
Always render text as text objects.
@ TextFormatAlwaysOutlines
Always render text using path objects (AKA outlines/curves).
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
bool isGuiPreview() const
Returns the Gui preview mode.
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
int currentMaskId() const
Returns the current mask id, which can be used with maskPainter()
Flags flags() const
Returns combination of flags used for rendering.
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).
TextRenderFormat textRenderFormat() const
Returns the text render format, which dictates how text is rendered (e.g.
Scoped object for saving and restoring a QPainter object's state.
static QString substituteVerticalCharacters(QString string)
Returns a string with characters having vertical representation form substituted.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates the symbol.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
static void blurImageInPlace(QImage &image, QRect rect, int radius, bool alphaOnly)
Blurs an image in place, e.g. creating Qt-independent drop shadows.
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
Container for settings relating to a text background object.
QgsMapUnitScale strokeWidthMapUnitScale() const
Returns the map unit scale object for the shape stroke width.
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.
QgsMapUnitScale radiiMapUnitScale() const
Returns the map unit scale object for the shape radii.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the units used for the shape's stroke width.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the background shape.
@ SizeBuffer
Shape size is determined by adding a buffer margin around text.
bool enabled() const
Returns whether the background is enabled.
double opacity() const
Returns the background shape's opacity.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the shape's offset.
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.
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
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).
@ ShapeMarkerSymbol
Marker symbol.
@ ShapeSquare
Square - buffered sizes only.
@ ShapeRectangle
Rectangle.
QColor strokeColor() const
Returns the color used for outlining the background shape.
QgsFillSymbol * fillSymbol() const
Returns the fill symbol to be rendered in the background.
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.
@ RotationOffset
Shape rotation is offset from text rotation.
@ RotationFixed
Shape rotation is a fixed angle.
QgsUnitTypes::RenderUnit radiiUnit() const
Returns the units used for the shape's radii.
QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol to be rendered in the background.
const QgsPaintEffect * paintEffect() const
Returns the current paint effect for the background shape.
QgsMapUnitScale offsetMapUnitScale() const
Returns the map unit scale object for the shape offset.
QPointF offset() const
Returns the offset used for drawing the background shape.
Represents a block of text consisting of one or more QgsTextFragment objects.
int size() const
Returns the number of fragments in the block.
QString toPlainText() const
Converts the block to plain text.
Container for settings relating to a text buffer.
Qt::PenJoinStyle joinStyle() const
Returns the buffer join style.
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.
double opacity() const
Returns the buffer opacity.
bool fillBufferInterior() const
Returns whether the interior of the buffer will be filled in.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
const QgsPaintEffect * paintEffect() const
Returns the current paint effect for the buffer.
QColor color() const
Returns the color of the buffer.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the buffer.
QColor textColor() const
Returns the character's text color, or an invalid color if no color override is set and the default f...
void updateFontForFormat(QFont &font, double scaleFactor=1.0) const
Updates the specified font in place, applying character formatting options which are applicable on a ...
Represents a document consisting of one or more QgsTextBlock objects.
void applyCapitalization(QgsStringUtils::Capitalization capitalization)
Applies a capitalization style to the document's text.
const QgsTextBlock & at(int index) const
Returns the block at the specified index.
QStringList toPlainText() const
Returns a list of plain text lines of text representing the document.
int size() const
Returns the number of blocks in the document.
static QgsTextDocument fromHtml(const QStringList &lines)
Constructor for QgsTextDocument consisting of a set of HTML formatted lines.
static QgsTextDocument fromPlainText(const QStringList &lines)
Constructor for QgsTextDocument consisting of a set of plain text lines.
Container for all settings relating to text rendering.
double lineHeight() const
Returns the line height for 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.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the text.
TextOrientation orientation() const
Returns the orientation of the text.
QgsTextMaskSettings & mask()
Returns a reference to the masking settings.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
TextOrientation
Text orientation.
@ HorizontalOrientation
Vertically oriented text.
@ RotationBasedOrientation
Horizontally or vertically oriented text based on rotation (only available for map labeling)
@ VerticalOrientation
Horizontally oriented text.
bool allowHtmlFormatting() const
Returns true if text should be treated as a HTML document and HTML tags should be used for formatting...
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...
QgsTextShadowSettings & shadow()
Returns a reference to the text drop shadow settings.
QgsStringUtils::Capitalization capitalization() const
Returns the text capitalization style.
QColor color() const
Returns the color that text will be rendered in.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
Stores a fragment of text along with formatting overrides to be used when rendering the fragment.
QString text() const
Returns the text content of the fragment.
double horizontalAdvance(const QFont &font, bool fontHasBeenUpdatedForFragment=false, double scaleFactor=1.0) const
Returns the horizontal advance associated with this fragment, when rendered using the specified base ...
const QgsTextCharacterFormat & characterFormat() const
Returns the character formatting for the fragment.
Container for settings relating to a selective masking around a text.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the buffer size.
double size() const
Returns the size of the buffer.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the mask.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
double opacity() const
Returns the mask's opacity.
bool enabled() const
Returns whether the mask is enabled.
Qt::PenJoinStyle joinStyle() const
Returns the buffer join style.
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static Q_DECL_DEPRECATED void drawPart(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, TextPart part, bool drawAsOutlines=true)
Draws a single component of rendered text using the specified settings.
VAlignment
Vertical alignment.
@ AlignBottom
Align to bottom.
@ AlignVCenter
Center align.
TextPart
Components of text.
@ Buffer
Buffer component.
@ Background
Background shape.
HAlignment
Horizontal alignment.
@ AlignCenter
Center align.
@ AlignJustify
Justify 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 QFontMetricsF fontMetrics(QgsRenderContext &context, const QgsTextFormat &format, double scaleFactor=1.0)
Returns the font metrics for the given text format, when rendered in the specified render context.
static HAlignment convertQtHAlignment(Qt::Alignment alignment)
Converts a Qt horizontal alignment flag to a QgsTextRenderer::HAlignment value.
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 VAlignment convertQtVAlignment(Qt::Alignment alignment)
Converts a Qt vertical alignment flag to a QgsTextRenderer::VAlignment value.
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.
DrawMode
Draw mode to calculate width and height.
@ Point
Text at point of origin draw mode.
@ Rect
Text within rectangle draw mode.
@ Label
Label-specific draw mode.
static constexpr double FONT_WORKAROUND_SCALE
Scale factor for upscaling font sizes and downscaling destination painter devices.
Container for settings relating to a text shadow.
int offsetAngle() const
Returns the angle for offsetting the position of the shadow from the text.
bool enabled() const
Returns whether the shadow is enabled.
int scale() const
Returns the scaling used for the drop shadow (in percentage of original size).
void setShadowPlacement(QgsTextShadowSettings::ShadowPlacement placement)
Sets the placement for the drop shadow.
double opacity() const
Returns the shadow's opacity.
QgsMapUnitScale blurRadiusMapUnitScale() const
Returns the map unit scale object for the shadow blur radius.
QColor color() const
Returns the color of the drop shadow.
@ ShadowBuffer
Draw shadow under buffer.
@ ShadowShape
Draw shadow under background shape.
@ ShadowLowest
Draw shadow below all text components.
@ ShadowText
Draw shadow under text.
QgsTextShadowSettings::ShadowPlacement shadowPlacement() const
Returns the placement for the drop shadow.
double offsetDistance() const
Returns the distance for offsetting the position of the shadow from the text.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the drop shadow.
QgsMapUnitScale offsetMapUnitScale() const
Returns the map unit scale object for the shadow offset distance.
QgsUnitTypes::RenderUnit blurRadiusUnit() const
Returns the units used for the shadow's blur radius.
bool blurAlphaOnly() const
Returns whether only the alpha channel for the shadow will be blurred.
bool offsetGlobal() const
Returns true if the global shadow offset will be used.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the shadow's offset.
double blurRadius() const
Returns the blur radius for the shadow.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
RenderUnit
Rendering size units.
@ RenderUnknownUnit
Mixed or unknown units.
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
@ RenderMapUnits
Map units.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QList< QgsSymbolLayer * > QgsSymbolLayerList
Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()