30 static void _fixQPictureDPI( QPainter *p )
36 p->scale(
static_cast< double >(
qt_defaultDpiX() ) / p->device()->logicalDpiX(),
37 static_cast< double >(
qt_defaultDpiY() ) / p->device()->logicalDpiY() );
42 return static_cast< int >(
c.convertToPainterUnits( size, unit, mapUnitScale ) + 0.5 );
50 tmpFormat = updateShadowPosition( tmpFormat );
61 drawPart( rect, rotation, alignment, document, context, tmpFormat,
Buffer );
64 drawPart( rect, rotation, alignment, document, context, tmpFormat,
Text );
72 tmpFormat = updateShadowPosition( tmpFormat );
83 drawPart( point, rotation, alignment, document, context, tmpFormat,
Buffer );
86 drawPart( point, rotation, alignment, document, context, tmpFormat,
Text );
115 drawPart( rect, rotation, alignment, document, context, format, part );
126 component.dpiRatio = 1.0;
127 component.origin = rect.topLeft();
128 component.rotation = rotation;
129 component.size = rect.size();
130 component.hAlign = alignment;
143 double xc = rect.width() / 2.0;
144 double yc = rect.height() / 2.0;
146 double angle = -rotation;
147 double xd = xc * std::cos(
angle ) - yc * std::sin(
angle );
148 double yd = xc * std::sin(
angle ) + yc * std::cos(
angle );
150 component.center = QPointF( component.origin.x() + xd, component.origin.y() + yd );
154 component.center = rect.center();
157 QgsTextRenderer::drawBackground( context, component, format, document,
Rect );
171 QFontMetricsF fm( format.
scaledFont( context ) );
172 drawTextInternal( part, context, format, component,
184 drawPart( origin, rotation, alignment, document, context, format, part );
195 component.dpiRatio = 1.0;
196 component.origin = origin;
197 component.rotation = rotation;
198 component.hAlign = alignment;
207 QgsTextRenderer::drawBackground( context, component, format, document,
Point );
220 QFontMetricsF fm( format.
scaledFont( context ) );
221 drawTextInternal( part, context, format, component,
238 QPainter *p = context.
painter();
243 if ( component.rotation >= -315 && component.rotation < -90 )
247 else if ( component.rotation >= -90 && component.rotation < -45 )
261 const QFont font = format.
scaledFont( context );
264 path.setFillRule( Qt::WindingFill );
266 switch ( orientation )
273 QFont fragmentFont = font;
276 path.addText( xOffset, 0, fragmentFont, fragment.
text() );
287 double letterSpacing = font.letterSpacing();
288 double partYOffset = component.offset.y();
291 QFont fragmentFont = font;
294 QFontMetricsF fragmentMetrics( fragmentFont );
295 const double labelWidth = fragmentMetrics.maxWidth();
298 for (
const QString &part : parts )
300 double partXOffset = ( labelWidth - ( fragmentMetrics.width( part ) - letterSpacing ) ) / 2;
301 path.addText( partXOffset, partYOffset, fragmentFont, part );
302 partYOffset += fragmentMetrics.ascent() + letterSpacing;
305 advance = partYOffset - component.offset.y();
310 QColor bufferColor = buffer.
color();
311 bufferColor.setAlphaF( buffer.
opacity() );
312 QPen pen( bufferColor );
313 pen.setWidthF( penSize );
315 QColor tmpColor( bufferColor );
319 tmpColor.setAlpha( 0 );
325 buffp.begin( &buffPict );
332 context.
painter()->setPen( pen );
333 context.
painter()->setBrush( tmpColor );
334 context.
painter()->drawPath( path );
342 buffp.setBrush( tmpColor );
343 buffp.drawPath( path );
349 QgsTextRenderer::Component bufferComponent = component;
350 bufferComponent.origin = QPointF( 0.0, 0.0 );
351 bufferComponent.picture = buffPict;
352 bufferComponent.pictureBuffer = penSize / 2.0;
356 bufferComponent.offset.setY( bufferComponent.offset.y() - bufferComponent.size.height() );
358 drawShadow( context, bufferComponent, format );
363 p->setCompositionMode( buffer.
blendMode() );
367 p->setRenderHint( QPainter::Antialiasing );
371 p->scale( component.dpiRatio, component.dpiRatio );
372 _fixQPictureDPI( p );
373 p->drawPicture( 0, 0, buffPict );
393 path.setFillRule( Qt::WindingFill );
398 const QFont font = format.
scaledFont( context );
402 QFont fragmentFont = font;
405 path.addText( xOffset, 0, fragmentFont, fragment.
text() );
410 QColor bufferColor( Qt::gray );
411 bufferColor.setAlphaF( mask.
opacity() );
415 brush.setColor( bufferColor );
416 pen.setColor( bufferColor );
417 pen.setWidthF( penSize );
424 p->setRenderHint( QPainter::Antialiasing );
428 p->scale( component.dpiRatio, component.dpiRatio );
434 context.
painter()->setPen( pen );
435 context.
painter()->setBrush( brush );
436 context.
painter()->drawPath( path );
442 p->setBrush( brush );
463 const QFont baseFont = format.
scaledFont( context );
470 double maxLineWidth = 0;
473 double blockWidth = 0;
478 maxLineWidth = std::max( maxLineWidth, blockWidth );
480 width = maxLineWidth;
486 double totalLineWidth = 0;
490 double blockWidth = 0;
493 QFont fragmentFont = baseFont;
495 blockWidth = std::max( QFontMetricsF( fragmentFont ).maxWidth(), blockWidth );
498 totalLineWidth += blockIndex == 0 ? blockWidth : blockWidth * format.
lineHeight();
501 width = totalLineWidth;
531 const QFont baseFont = format.
scaledFont( context );
538 double totalHeight = 0;
541 double maxBlockHeight = 0;
542 double maxBlockLineSpacing = 0;
545 QFont fragmentFont = baseFont;
547 const QFontMetricsF fm( fragmentFont );
549 const double fragmentHeight = fm.ascent() + fm.descent();
551 maxBlockHeight = std::max( maxBlockHeight, fragmentHeight );
552 maxBlockLineSpacing = std::max( maxBlockLineSpacing, fm.lineSpacing() );
561 totalHeight += blockIndex == 0 ? maxBlockHeight : maxBlockHeight * format.
lineHeight();
567 totalHeight += blockIndex == 0 ? maxBlockHeight : maxBlockLineSpacing * format.
lineHeight();
579 double maxBlockHeight = 0;
582 double blockHeight = 0;
583 int fragmentIndex = 0;
586 QFont fragmentFont = baseFont;
588 const QFontMetricsF fm( fragmentFont );
590 const double labelHeight = fm.ascent();
591 const double letterSpacing = fragmentFont.letterSpacing();
593 blockHeight += fragmentIndex = 0 ? labelHeight * fragment.
text().size() + ( fragment.
text().size() - 1 ) * letterSpacing
594 : fragment.
text().size() * ( labelHeight + letterSpacing );
597 maxBlockHeight = std::max( maxBlockHeight, blockHeight );
600 return maxBlockHeight;
617 QPainter *prevP = context.
painter();
618 QPainter *p = context.
painter();
632 component.rotation = -( component.rotation * 180 / M_PI );
633 component.rotationOffset =
638 component.rotation = 0.0;
639 component.rotationOffset = background.
rotation();
645 QFontMetricsF fm( format.
scaledFont( context ) );
646 double width =
textWidth( context, format, document );
647 double height =
textHeight( context, format, document, mode );
652 switch ( component.hAlign )
655 component.center = QPointF( component.origin.x() + width / 2.0,
656 component.origin.y() + height / 2.0 );
660 component.center = QPointF( component.origin.x() + component.size.width() / 2.0,
661 component.origin.y() + height / 2.0 );
665 component.center = QPointF( component.origin.x() + component.size.width() - width / 2.0,
666 component.origin.y() + height / 2.0 );
673 double originAdjust = fm.ascent() / 2.0 - fm.leading() / 2.0;
674 switch ( component.hAlign )
677 component.center = QPointF( component.origin.x() + width / 2.0,
678 component.origin.y() - height / 2.0 + originAdjust );
682 component.center = QPointF( component.origin.x(),
683 component.origin.y() - height / 2.0 + originAdjust );
687 component.center = QPointF( component.origin.x() - width / 2.0,
688 component.origin.y() - height / 2.0 + originAdjust );
699 component.size = QSizeF( width, height );
704 switch ( background.
type() )
717 double sizeOut = 0.0;
725 sizeOut = std::max( component.size.width(), component.size.height() );
729 sizeOut += bufferSize * 2;
737 std::unique_ptr< QgsMarkerSymbol > renderedSymbol;
741 map[QStringLiteral(
"name" )] = background.
svgFile().trimmed();
742 map[QStringLiteral(
"size" )] = QString::number( sizeOut );
744 map[QStringLiteral(
"angle" )] = QString::number( 0.0 );
752 map[QStringLiteral(
"fill" )] = background.
fillColor().name();
753 map[QStringLiteral(
"outline" )] = background.
strokeColor().name();
754 map[QStringLiteral(
"outline-width" )] = QString::number( background.
strokeWidth() );
762 shdwmap[QStringLiteral(
"fill" )] = shadow.
color().name();
763 shdwmap[QStringLiteral(
"outline" )] = shadow.
color().name();
764 shdwmap[QStringLiteral(
"size" )] = QString::number( sizeOut );
769 svgp.begin( &svgPict );
786 svgShdwM->
renderPoint( QPointF( sizeOut / 2, -sizeOut / 2 ), svgShdwContext );
789 component.picture = svgPict;
791 component.pictureBuffer = 0.0;
793 component.size = QSizeF( sizeOut, sizeOut );
794 component.offset = QPointF( 0.0, 0.0 );
798 p->translate( component.center.x(), component.center.y() );
799 p->rotate( component.rotation );
802 p->translate( QPointF( xoff, yoff ) );
803 p->rotate( component.rotationOffset );
804 p->translate( -sizeOut / 2, sizeOut / 2 );
807 p->setRenderHint( QPainter::Antialiasing );
810 drawShadow( context, component, format );
816 renderedSymbol.reset( );
824 renderedSymbol->setSize( sizeOut );
828 renderedSymbol->setOpacity( background.
opacity() );
834 p->setCompositionMode( background.
blendMode() );
838 p->setRenderHint( QPainter::Antialiasing );
840 p->translate( component.center.x(), component.center.y() );
841 p->rotate( component.rotation );
844 p->translate( QPointF( xoff, yoff ) );
845 p->rotate( component.rotationOffset );
849 renderedSymbol->renderPoint( QPointF( 0, 0 ), &f, context );
850 renderedSymbol->stopRender( context );
851 p->setCompositionMode( QPainter::CompositionMode_SourceOver );
862 double w = component.size.width();
863 double h = component.size.height();
884 h = std::sqrt( std::pow( w, 2 ) + std::pow( h, 2 ) );
890 h = h * M_SQRT1_2 * 2;
891 w = w * M_SQRT1_2 * 2;
899 w += bufferWidth * 2;
900 h += bufferHeight * 2;
904 QRectF rect( -w / 2.0, - h / 2.0, w, h );
912 p->setRenderHint( QPainter::Antialiasing );
914 p->translate( QPointF( component.center.x(), component.center.y() ) );
915 p->rotate( component.rotation );
918 p->translate( QPointF( xoff, yoff ) );
919 p->rotate( component.rotationOffset );
927 pen.setWidthF( penSize );
929 pen.setJoinStyle( background.
joinStyle() );
939 shapep.begin( &shapePict );
940 shapep.setPen( pen );
941 shapep.setBrush( background.
fillColor() );
948 shapep.drawRoundedRect( rect, background.
radii().width(), background.
radii().height(), Qt::RelativeSize );
954 shapep.drawRoundedRect( rect, xRadius, yRadius );
960 shapep.drawEllipse( rect );
966 component.picture = shapePict;
967 component.pictureBuffer = penSize / 2.0;
969 component.size = rect.size();
970 component.offset = QPointF( rect.width() / 2, -rect.height() / 2 );
971 drawShadow( context, component, format );
974 p->setOpacity( background.
opacity() );
977 p->setCompositionMode( background.
blendMode() );
981 p->scale( component.dpiRatio, component.dpiRatio );
982 _fixQPictureDPI( p );
983 p->drawPicture( 0, 0, shapePict );
1004 QPainter *p = context.
painter();
1005 double componentWidth = component.size.width(), componentHeight = component.size.height();
1006 double xOffset = component.offset.x(), yOffset = component.offset.y();
1007 double pictbuffer = component.pictureBuffer;
1012 radius /= ( mapUnits ? context.
scaleFactor() / component.dpiRatio : 1 );
1013 radius =
static_cast< int >( radius + 0.5 );
1017 double blurBufferClippingScale = 3.75;
1018 int blurbuffer = ( radius > 17 ? 16 : radius ) * blurBufferClippingScale;
1020 QImage blurImg( componentWidth + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
1021 componentHeight + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
1022 QImage::Format_ARGB32_Premultiplied );
1026 int minBlurImgSize = 1;
1030 int maxBlurImgSize = 40000;
1031 if ( blurImg.isNull()
1032 || ( blurImg.width() < minBlurImgSize || blurImg.height() < minBlurImgSize )
1033 || ( blurImg.width() > maxBlurImgSize || blurImg.height() > maxBlurImgSize ) )
1036 blurImg.fill( QColor( Qt::transparent ).rgba() );
1038 if ( !pictp.begin( &blurImg ) )
1040 pictp.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
1041 QPointF imgOffset( blurbuffer + pictbuffer + xOffset,
1042 blurbuffer + pictbuffer + componentHeight + yOffset );
1044 pictp.drawPicture( imgOffset,
1045 component.picture );
1048 pictp.setCompositionMode( QPainter::CompositionMode_SourceIn );
1049 pictp.fillRect( blurImg.rect(), shadow.
color() );
1053 if ( shadow.
blurRadius() > 0.0 && radius > 0 )
1061 picti.begin( &blurImg );
1062 picti.setBrush( Qt::Dense7Pattern );
1063 QPen imgPen( QColor( 0, 0, 255, 255 ) );
1064 imgPen.setWidth( 1 );
1065 picti.setPen( imgPen );
1066 picti.setOpacity( 0.1 );
1067 picti.drawRect( 0, 0, blurImg.width(), blurImg.height() );
1072 double angleRad = shadow.
offsetAngle() * M_PI / 180;
1080 angleRad -= ( component.rotation * M_PI / 180 + component.rotationOffset * M_PI / 180 );
1083 QPointF transPt( -offsetDist * std::cos( angleRad + M_PI_2 ),
1084 -offsetDist * std::sin( angleRad + M_PI_2 ) );
1087 p->setRenderHint( QPainter::SmoothPixmapTransform );
1090 p->setRenderHint( QPainter::Antialiasing );
1094 p->setCompositionMode( shadow.
blendMode() );
1096 p->setOpacity( shadow.
opacity() );
1098 double scale = shadow.
scale() / 100.0;
1100 p->scale( scale, scale );
1101 if ( component.useOrigin )
1103 p->translate( component.origin.x(), component.origin.y() );
1105 p->translate( transPt );
1106 p->translate( -imgOffset.x(),
1108 p->drawImage( 0, 0, blurImg );
1115 p->setBrush( Qt::NoBrush );
1116 QPen imgPen( QColor( 255, 0, 0, 10 ) );
1117 imgPen.setWidth( 2 );
1118 imgPen.setStyle( Qt::DashLine );
1119 p->setPen( imgPen );
1120 p->scale( scale, scale );
1121 if ( component.useOrigin() )
1123 p->translate( component.origin().x(), component.origin().y() );
1125 p->translate( transPt );
1126 p->translate( -imgOffset.x(),
1128 p->drawRect( 0, 0, blurImg.width(), blurImg.height() );
1133 p->setBrush( Qt::NoBrush );
1134 QPen componentRectPen( QColor( 0, 255, 0, 70 ) );
1135 componentRectPen.setWidth( 1 );
1136 if ( component.useOrigin() )
1138 p->translate( component.origin().x(), component.origin().y() );
1140 p->setPen( componentRectPen );
1141 p->drawRect( QRect( -xOffset, -componentHeight - yOffset, componentWidth, componentHeight ) );
1146 void QgsTextRenderer::drawTextInternal( TextPart drawType,
1149 const Component &component,
1151 const QFontMetricsF *fontMetrics,
1152 HAlignment alignment, DrawMode mode )
1162 double rotation = -component.rotation * 180 / M_PI;
1166 if ( rotation >= -315 && rotation < -90 )
1171 else if ( rotation >= -90 && rotation < -45 )
1182 const QStringList textLines = document.
toPlainText();
1184 switch ( orientation )
1188 double labelWidest = 0.0;
1193 for (
const QString &line : textLines )
1196 if ( labelWidth > labelWidest )
1198 labelWidest = labelWidth;
1204 labelWidest = component.size.width();
1212 double ascentOffset = 0.25 *
fontMetrics->ascent();
1216 bool adjustForAlignment = alignment !=
AlignLeft && ( mode !=
Label || textLines.size() > 1 );
1218 for (
const QString &line : qgis::as_const( textLines ) )
1225 context.
painter()->setRenderHint( QPainter::Antialiasing );
1227 context.
painter()->translate( component.origin );
1229 context.
painter()->rotate( rotation );
1234 maskPainter->save();
1235 maskPainter->translate( component.origin );
1237 maskPainter->rotate( rotation );
1241 double xMultiLineOffset = 0.0;
1243 if ( adjustForAlignment )
1245 double labelWidthDiff = labelWidest - labelWidth;
1248 labelWidthDiff /= 2;
1254 xMultiLineOffset = labelWidthDiff;
1259 xMultiLineOffset = labelWidthDiff - labelWidest;
1261 xMultiLineOffset = labelWidthDiff - labelWidest / 2.0;
1268 double yMultiLineOffset = ascentOffset;
1275 yMultiLineOffset = - ascentOffset - ( textLines.size() - 1 - i ) * labelHeight * format.
lineHeight();
1280 yMultiLineOffset = - ascentOffset + labelHeight - 1 + format.
lineHeight() *
fontMetrics->lineSpacing() * i;
1285 yMultiLineOffset = 0 - ( textLines.size() - 1 - i ) *
fontMetrics->lineSpacing() * format.
lineHeight();
1290 context.
painter()->translate( QPointF( xMultiLineOffset, yMultiLineOffset ) );
1292 maskPainter->translate( QPointF( xMultiLineOffset, yMultiLineOffset ) );
1294 Component subComponent;
1295 subComponent.block = block;
1296 subComponent.
size = QSizeF( labelWidth, labelHeight );
1297 subComponent.offset = QPointF( 0.0, -ascentOffset );
1298 subComponent.rotation = -component.rotation * 180 / M_PI;
1299 subComponent.rotationOffset = 0.0;
1304 QgsTextRenderer::drawMask( context, subComponent, format );
1309 QgsTextRenderer::drawBuffer( context, subComponent, format );
1316 textp.begin( &textPict );
1317 textp.setPen( Qt::NoPen );
1318 const QFont font = format.
scaledFont( context );
1325 path.setFillRule( Qt::WindingFill );
1327 QFont fragmentFont = font;
1329 QFontMetricsF fragmentMetrics = QFontMetricsF( fragmentFont );
1331 path.addText( xOffset, 0, fragmentFont, fragment.
text() );
1334 textColor.setAlphaF( format.
opacity() );
1335 textp.setBrush( textColor );
1336 textp.drawPath( path );
1350 subComponent.picture = textPict;
1351 subComponent.pictureBuffer = 0.0;
1352 subComponent.origin = QPointF( 0.0, 0.0 );
1354 QgsTextRenderer::drawShadow( context, subComponent, format );
1364 context.
painter()->scale( subComponent.dpiRatio, subComponent.dpiRatio );
1371 _fixQPictureDPI( context.
painter() );
1372 context.
painter()->drawPicture( 0, 0, textPict );
1381 QFont fragmentFont = font;
1385 textColor.setAlphaF( format.
opacity() );
1387 context.
painter()->setPen( textColor );
1388 context.
painter()->setFont( fragmentFont );
1389 context.
painter()->setRenderHint( QPainter::TextAntialiasing );
1391 context.
painter()->drawText( xOffset, 0, fragment.
text() );
1400 maskPainter->restore();
1409 const QFont font = format.
scaledFont( context );
1410 double letterSpacing = font.letterSpacing();
1413 double actualLabelWidest = labelWidth + ( textLines.size() - 1 ) * labelWidth * format.
lineHeight();
1414 double labelWidest = 0.0;
1419 labelWidest = actualLabelWidest;
1423 labelWidest = component.size.width();
1427 int maxLineLength = 0;
1428 for (
const QString &line : qgis::as_const( textLines ) )
1430 maxLineLength = std::max( maxLineLength, line.length() );
1432 double actualLabelHeight =
fontMetrics->ascent() + (
fontMetrics->ascent() + letterSpacing ) * ( maxLineLength - 1 );
1437 bool adjustForAlignment = alignment !=
AlignLeft && ( mode !=
Label || textLines.size() > 1 );
1444 context.
painter()->setRenderHint( QPainter::Antialiasing );
1446 context.
painter()->translate( component.origin );
1448 context.
painter()->rotate( rotation );
1453 maskPainter->save();
1454 maskPainter->translate( component.origin );
1456 maskPainter->rotate( rotation );
1460 double xOffset = actualLabelWidest - labelWidth - ( i * labelWidth * format.
lineHeight() );
1461 if ( adjustForAlignment )
1463 double labelWidthDiff = labelWidest - actualLabelWidest;
1466 labelWidthDiff /= 2;
1472 xOffset += labelWidthDiff;
1480 double yOffset = 0.0;
1486 if ( rotation >= -405 && rotation < -180 )
1488 yOffset = ascentOffset;
1490 else if ( rotation >= 0 && rotation < 45 )
1492 xOffset -= actualLabelWidest;
1493 yOffset = -actualLabelHeight + ascentOffset +
fontMetrics->descent();
1498 yOffset = -actualLabelHeight + ascentOffset;
1503 yOffset = -actualLabelHeight + ascentOffset;
1507 yOffset = ascentOffset;
1511 context.
painter()->translate( QPointF( xOffset, yOffset ) );
1513 double fragmentYOffset = 0;
1519 QFont fragmentFont( font );
1522 QFontMetricsF fragmentMetrics( fragmentFont );
1524 double labelHeight = fragmentMetrics.ascent() + ( fragmentMetrics.ascent() + letterSpacing ) * ( line.length() - 1 );
1526 Component subComponent;
1528 subComponent.size = QSizeF( labelWidth, labelHeight );
1529 subComponent.offset = QPointF( 0.0, fragmentYOffset );
1530 subComponent.rotation = -component.rotation * 180 / M_PI;
1531 subComponent.rotationOffset = 0.0;
1538 QgsTextRenderer::drawMask( context, subComponent, format );
1544 fragmentYOffset += QgsTextRenderer::drawBuffer( context, subComponent, format );
1550 path.setFillRule( Qt::WindingFill );
1552 double partYOffset = 0.0;
1553 for (
const auto &part : parts )
1555 double partXOffset = ( labelWidth - ( fragmentMetrics.width( part ) - letterSpacing ) ) / 2;
1556 path.addText( partXOffset, partYOffset, fragmentFont, part );
1557 partYOffset += fragmentMetrics.ascent() + letterSpacing;
1563 textp.begin( &textPict );
1564 textp.setPen( Qt::NoPen );
1566 textColor.setAlphaF( format.
opacity() );
1567 textp.setBrush( textColor );
1568 textp.drawPath( path );
1578 subComponent.picture = textPict;
1579 subComponent.pictureBuffer = 0.0;
1580 subComponent.origin = QPointF( 0.0, fragmentYOffset );
1581 const double prevY = subComponent.offset.y();
1582 subComponent.offset = QPointF( 0, -labelHeight );
1583 subComponent.useOrigin =
true;
1584 QgsTextRenderer::drawShadow( context, subComponent, format );
1585 subComponent.useOrigin =
false;
1586 subComponent.offset = QPointF( 0, prevY );
1596 context.
painter()->scale( subComponent.dpiRatio, subComponent.dpiRatio );
1603 _fixQPictureDPI( context.
painter() );
1604 context.
painter()->drawPicture( 0, fragmentYOffset, textPict );
1605 fragmentYOffset += partYOffset;
1611 context.
painter()->setFont( fragmentFont );
1612 context.
painter()->setPen( textColor );
1613 context.
painter()->setRenderHint( QPainter::TextAntialiasing );
1615 double partYOffset = 0.0;
1616 for (
const QString &part : parts )
1618 double partXOffset = ( labelWidth - ( fragmentMetrics.width( part ) - letterSpacing ) ) / 2;
1619 context.
painter()->drawText( partXOffset, fragmentYOffset + partYOffset, part );
1620 partYOffset += fragmentMetrics.ascent() + letterSpacing;
1622 fragmentYOffset += partYOffset;
1630 maskPainter->restore();