58 const QList< QgsTextFormat::Tab > tabPositions = format.
tabPositions();
59 QList< double > tabStopDistancesPainterUnits;
60 tabStopDistancesPainterUnits.reserve( tabPositions.size() );
63 tabStopDistancesPainterUnits.append(
65 ? tab.position() * baseFont.pixelSize()
73 QStringList graphemes;
74 QVector< QgsTextCharacterFormat > graphemeFormats;
83 for (
const QString &grapheme : fragmentGraphemes )
85 graphemes.append( grapheme );
86 graphemeFormats.append( fragment.characterFormat() );
97 QVector< double > characterWidths( graphemes.count() );
98 QVector< double > characterHeights( graphemes.count() );
99 QVector< double > characterDescents( graphemes.count() );
101 QFont previousNonSuperSubScriptFont;
103 double currentWidth = 0;
104 for (
int i = 0; i < graphemes.count(); i++ )
109 double graphemeFirstCharHorizontalAdvanceWithLetterSpacing = 0;
110 double graphemeFirstCharHorizontalAdvance = 0;
111 double graphemeHorizontalAdvance = 0;
112 double characterDescent = 0;
113 double characterHeight = 0;
114 if (
const QgsTextCharacterFormat *graphemeFormat = !graphemeFormats.empty() ? &graphemeFormats[i] : nullptr )
116 QFont graphemeFont = baseFont;
117 graphemeFormat->updateFontForFormat( graphemeFont, context, 1 );
120 previousNonSuperSubScriptFont = graphemeFont;
122 if ( graphemeFormat->hasVerticalAlignmentSet() )
124 switch ( graphemeFormat->verticalAlignment() )
127 previousNonSuperSubScriptFont = graphemeFont;
133 if ( graphemeFormat->fontPointSize() < 0 )
148 previousNonSuperSubScriptFont = graphemeFont;
151 const QFontMetricsF graphemeFontMetrics( graphemeFont );
152 graphemeFirstCharHorizontalAdvance = graphemeFontMetrics.horizontalAdvance( QString( graphemes[i].at( 0 ) ) );
153 graphemeFirstCharHorizontalAdvanceWithLetterSpacing = graphemeFontMetrics.horizontalAdvance( graphemes[i].at( 0 ) ) + letterSpacing;
154 graphemeHorizontalAdvance = graphemeFontMetrics.horizontalAdvance( QString( graphemes[i] ) );
155 characterDescent = graphemeFontMetrics.descent();
156 characterHeight = graphemeFontMetrics.height();
158 else if ( graphemes[i] ==
'\t' )
160 double nextTabStop = 0;
161 if ( !tabStopDistancesPainterUnits.empty() )
164 nextTabStop = currentWidth;
165 for (
const double tabStop : std::as_const( tabStopDistancesPainterUnits ) )
167 if ( tabStop >= currentWidth )
169 nextTabStop = tabStop;
176 nextTabStop = ( std::floor( currentWidth / tabStopDistancePainterUnits ) + 1 ) * tabStopDistancePainterUnits;
179 const double thisTabWidth = nextTabStop - currentWidth;
181 graphemeFirstCharHorizontalAdvance = thisTabWidth;
182 graphemeFirstCharHorizontalAdvanceWithLetterSpacing = thisTabWidth;
183 graphemeHorizontalAdvance = thisTabWidth;
184 characterDescent = fontMetrics.descent();
185 characterHeight = fontMetrics.height();
189 graphemeFirstCharHorizontalAdvance = fontMetrics.horizontalAdvance( QString( graphemes[i].at( 0 ) ) );
190 graphemeFirstCharHorizontalAdvanceWithLetterSpacing = fontMetrics.horizontalAdvance( graphemes[i].at( 0 ) ) + letterSpacing;
191 graphemeHorizontalAdvance = fontMetrics.horizontalAdvance( QString( graphemes[i] ) );
192 characterDescent = fontMetrics.descent();
193 characterHeight = fontMetrics.height();
196 qreal wordSpaceFix = qreal( 0.0 );
197 if ( graphemes[i] == QLatin1String(
" " ) )
201 wordSpaceFix = ( nxt < graphemes.count() && graphemes[nxt] != QLatin1String(
" " ) ) ? wordSpacing : qreal( 0.0 );
206 if ( graphemes[i].length() == 1 &&
207 !
qgsDoubleNear( graphemeFirstCharHorizontalAdvance, graphemeFirstCharHorizontalAdvanceWithLetterSpacing ) )
210 wordSpaceFix -= wordSpacing;
213 const double charWidth = graphemeHorizontalAdvance + wordSpaceFix;
214 characterWidths[i] = mapScale * charWidth;
215 characterHeights[i] = mapScale * characterHeight;
216 characterDescents[i] = mapScale * characterDescent;
218 currentWidth += charWidth;
221 QgsPrecalculatedTextMetrics res( graphemes, std::move( characterWidths ), std::move( characterHeights ), std::move( characterDescents ) );
Contains precalculated properties regarding text metrics for text to be renderered 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.
QgsTextLabelFeature(QgsFeatureId id, geos::unique_ptr geometry, QSizeF size)
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 QString &text=QString(), QgsTextDocument *document=nullptr, QgsTextDocumentMetrics *metrics=nullptr)
Calculate text metrics for later retrieval via textMetrics().
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.
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.