60 const QFont &baseFont,
61 const QFontMetricsF &fontMetrics,
72 const QList< QgsTextFormat::Tab > tabPositions = format.
tabPositions();
73 QList< double > tabStopDistancesPainterUnits;
74 tabStopDistancesPainterUnits.reserve( tabPositions.size() );
77 tabStopDistancesPainterUnits.append(
86 QStringList graphemes;
87 QVector< QgsTextCharacterFormat > graphemeFormats;
94 for (
const QString &grapheme : fragmentGraphemes )
96 graphemes.append( grapheme );
97 graphemeFormats.append( fragment.characterFormat() );
102 QVector< double > characterWidths( graphemes.count() );
103 QVector< double > characterHeights( graphemes.count() );
104 QVector< double > characterDescents( graphemes.count() );
106 QFont previousNonSuperSubScriptFont;
108 double currentWidth = 0;
109 for (
int i = 0; i < graphemes.count(); i++ )
114 double graphemeFirstCharHorizontalAdvanceWithLetterSpacing = 0;
115 double graphemeFirstCharHorizontalAdvance = 0;
116 double graphemeHorizontalAdvance = 0;
117 double characterDescent = 0;
118 double characterHeight = 0;
119 if ( graphemes[i] ==
'\t' )
121 double nextTabStop = 0;
122 if ( !tabStopDistancesPainterUnits.empty() )
125 nextTabStop = currentWidth;
126 for (
const double tabStop : std::as_const( tabStopDistancesPainterUnits ) )
128 if ( tabStop >= currentWidth )
130 nextTabStop = tabStop;
137 nextTabStop = ( std::floor( currentWidth / tabStopDistancePainterUnits ) + 1 ) * tabStopDistancePainterUnits;
140 const double thisTabWidth = nextTabStop - currentWidth;
142 graphemeFirstCharHorizontalAdvance = thisTabWidth;
143 graphemeFirstCharHorizontalAdvanceWithLetterSpacing = thisTabWidth;
144 graphemeHorizontalAdvance = thisTabWidth;
145 characterDescent = fontMetrics.descent();
146 characterHeight = fontMetrics.height();
148 else if (
const QgsTextCharacterFormat *graphemeFormat = !graphemeFormats.empty() ? &graphemeFormats[i] :
nullptr )
150 QFont graphemeFont = baseFont;
151 graphemeFormat->updateFontForFormat( graphemeFont, context, 1 );
154 previousNonSuperSubScriptFont = graphemeFont;
156 if ( graphemeFormat->hasVerticalAlignmentSet() )
158 switch ( graphemeFormat->verticalAlignment() )
161 previousNonSuperSubScriptFont = graphemeFont;
167 if ( graphemeFormat->fontPointSize() < 0 )
182 previousNonSuperSubScriptFont = graphemeFont;
185 const QFontMetricsF graphemeFontMetrics( graphemeFont );
186 graphemeFirstCharHorizontalAdvance = graphemeFontMetrics.horizontalAdvance( QString( graphemes[i].at( 0 ) ) );
187 graphemeFirstCharHorizontalAdvanceWithLetterSpacing = graphemeFontMetrics.horizontalAdvance( graphemes[i].at( 0 ) ) + letterSpacing;
188 graphemeHorizontalAdvance = graphemeFontMetrics.horizontalAdvance( QString( graphemes[i] ) );
189 characterDescent = graphemeFontMetrics.descent();
190 characterHeight = graphemeFontMetrics.height();
194 graphemeFirstCharHorizontalAdvance = fontMetrics.horizontalAdvance( QString( graphemes[i].at( 0 ) ) );
195 graphemeFirstCharHorizontalAdvanceWithLetterSpacing = fontMetrics.horizontalAdvance( graphemes[i].at( 0 ) ) + letterSpacing;
196 graphemeHorizontalAdvance = fontMetrics.horizontalAdvance( QString( graphemes[i] ) );
197 characterDescent = fontMetrics.descent();
198 characterHeight = fontMetrics.height();
201 qreal wordSpaceFix = qreal( 0.0 );
202 if ( graphemes[i] ==
" "_L1 )
206 wordSpaceFix = ( nxt < graphemes.count() && graphemes[nxt] !=
" "_L1 ) ? wordSpacing : qreal( 0.0 );
211 if ( graphemes[i].length() == 1 && !
qgsDoubleNear( graphemeFirstCharHorizontalAdvance, graphemeFirstCharHorizontalAdvanceWithLetterSpacing ) )
214 wordSpaceFix -= wordSpacing;
217 const double charWidth = graphemeHorizontalAdvance + wordSpaceFix;
218 characterWidths[i] = mapScale * charWidth;
219 characterHeights[i] = mapScale * characterHeight;
220 characterDescents[i] = mapScale * characterDescent;
222 currentWidth += charWidth;
225 QgsPrecalculatedTextMetrics res( graphemes, std::move( characterWidths ), std::move( characterHeights ), std::move( characterDescents ) );
Contains precalculated properties regarding text metrics for text to be rendered at a later stage.
void setGraphemeFormats(const QVector< QgsTextCharacterFormat > &formats)
Sets the character formats associated with the text graphemes().
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
Represents a block of text consisting of one or more QgsTextFragment objects.
Contains pre-calculated metrics of a QgsTextDocument.
Represents a document consisting of one or more QgsTextBlock objects.
Stores a fragment of document along with formatting overrides to be used when rendering the fragment.
const QgsTextDocument & document() const
Returns the document for the label.
QgsTextCharacterFormat characterFormat(int partId) const
Returns the character format corresponding to the specified label part.
QgsTextLabelFeature(QgsFeatureId id, geos::unique_ptr geometry, QSizeF size, int subPartId=0)
Construct text label feature.
static QgsPrecalculatedTextMetrics calculateTextMetrics(const QgsMapToPixel *xform, const QgsRenderContext &context, const QgsTextFormat &format, const QFont &baseFont, const QFontMetricsF &fontMetrics, double letterSpacing, double wordSpacing, const QgsTextDocument &document, const QgsTextDocumentMetrics &metrics)
Calculate text metrics for later retrieval via textMetrics().
QString text(int partId) const
Returns the text component corresponding to a specified label part.
bool hasCharacterFormat(int partId) const
Returns true if the feature contains specific character formatting for the part with matching ID.
std::optional< QgsPrecalculatedTextMetrics > mTextMetrics
void setDocument(const QgsTextDocument &document, const QgsTextDocumentMetrics &metrics)
Sets the document and document metrics for the label.
static constexpr double SUPERSCRIPT_SUBSCRIPT_FONT_SIZE_SCALING_FACTOR
Scale factor to use for super or subscript text which doesn't have an explicit font size set.