30 bool isNullSize =
false;
31 const QFont font = format.
scaledFont( context, scaleFactor, &isNullSize );
39 double heightLabelMode = 0;
40 double heightPointRectMode = 0;
41 const int blockSize = document.
size();
42 res.mFragmentFonts.reserve( blockSize );
43 double currentLabelBaseline = 0;
44 double currentPointBaseline = 0;
45 double currentRectBaseline = 0;
46 double lastLineLeading = 0;
48 double heightVerticalOrientation = 0;
50 QVector < double > blockVerticalLineSpacing;
52 for (
int blockIndex = 0; blockIndex < blockSize; blockIndex++ )
57 double blockHeightUsingAscentDescent = 0;
58 double blockHeightUsingLineSpacing = 0;
59 double blockHeightVerticalOrientation = 0;
60 const int fragmentSize = block.
size();
62 double maxBlockAscent = 0;
63 double maxBlockDescent = 0;
64 double maxLineSpacing = 0;
65 double maxBlockLeading = 0;
66 double maxBlockMaxWidth = 0;
68 QList< QFont > fragmentFonts;
69 fragmentFonts.reserve( fragmentSize );
70 for (
int fragmentIndex = 0; fragmentIndex < fragmentSize; ++fragmentIndex )
74 QFont updatedFont = font;
76 const QFontMetricsF fm( updatedFont );
78 const double fragmentWidth = fm.horizontalAdvance( fragment.
text() ) / scaleFactor;
79 const double fragmentHeightUsingAscentDescent = ( fm.ascent() + fm.descent() ) / scaleFactor;
80 const double fragmentHeightUsingLineSpacing = fm.lineSpacing() / scaleFactor;
83 blockHeightUsingAscentDescent = std::max( blockHeightUsingAscentDescent, fragmentHeightUsingAscentDescent );
84 blockHeightUsingLineSpacing = std::max( blockHeightUsingLineSpacing, fragmentHeightUsingLineSpacing );
85 maxBlockAscent = std::max( maxBlockAscent, fm.ascent() / scaleFactor );
86 maxBlockDescent = std::max( maxBlockDescent, fm.descent() / scaleFactor );
87 maxBlockMaxWidth = std::max( maxBlockMaxWidth, fm.maxWidth() / scaleFactor );
89 if ( ( fm.lineSpacing() / scaleFactor ) > maxLineSpacing )
91 maxLineSpacing = fm.lineSpacing() / scaleFactor;
92 maxBlockLeading = fm.leading() / scaleFactor;
95 fragmentFonts << updatedFont;
97 const double verticalOrientationFragmentHeight = fragmentIndex == 0 ? ( fm.ascent() / scaleFactor * fragment.
text().size() + ( fragment.
text().size() - 1 ) * updatedFont.letterSpacing() / scaleFactor )
98 : ( fragment.
text().size() * ( fm.ascent() / scaleFactor + updatedFont.letterSpacing() / scaleFactor ) );
99 blockHeightVerticalOrientation += verticalOrientationFragmentHeight;
102 if ( blockIndex == 0 )
106 res.mFirstLineAscentOffset = 0.25 * maxBlockAscent;
107 res.mLastLineAscentOffset = res.mFirstLineAscentOffset;
108 const double lineHeight = ( maxBlockAscent + maxBlockDescent );
113 currentLabelBaseline = -res.mFirstLineAscentOffset;
116 currentRectBaseline = -res.mFirstLineAscentOffset + lineHeight - 1 ;
119 currentPointBaseline = 0;
121 heightLabelMode += blockHeightUsingAscentDescent;
122 heightPointRectMode += blockHeightUsingAscentDescent;
129 currentLabelBaseline += thisLineHeightUsingAscentDescent;
130 currentRectBaseline += thisLineHeightUsingLineSpacing;
131 currentPointBaseline += thisLineHeightUsingLineSpacing;
133 heightLabelMode += thisLineHeightUsingAscentDescent;
134 heightPointRectMode += thisLineHeightUsingLineSpacing;
135 if ( blockIndex == blockSize - 1 )
136 res.mLastLineAscentOffset = 0.25 * maxBlockAscent;
141 res.mBlockHeights << blockHeightUsingLineSpacing;
144 heightVerticalOrientation = std::max( heightVerticalOrientation, blockHeightVerticalOrientation );
146 res.mFragmentFonts << fragmentFonts;
147 res.mBaselineOffsetsLabelMode << currentLabelBaseline;
148 res.mBaselineOffsetsPointMode << currentPointBaseline;
149 res.mBaselineOffsetsRectMode << currentRectBaseline;
150 res.mBlockMaxDescent << maxBlockDescent;
151 res.mBlockMaxCharacterWidth << maxBlockMaxWidth;
153 if ( blockIndex > 0 )
154 lastLineLeading = maxBlockLeading;
157 heightLabelMode -= lastLineLeading;
158 heightPointRectMode -= lastLineLeading;
160 res.mDocumentSizeLabelMode = QSizeF( width, heightLabelMode );
161 res.mDocumentSizePointRectMode = QSizeF( width, heightPointRectMode );
164 if ( !res.mBaselineOffsetsLabelMode.isEmpty() )
166 const double labelModeBaselineAdjust = res.mBaselineOffsetsLabelMode.constLast() + res.mLastLineAscentOffset;
167 const double pointModeBaselineAdjust = res.mBaselineOffsetsPointMode.constLast();
168 for (
int i = 0; i < blockSize; ++i )
170 res.mBaselineOffsetsLabelMode[i] -= labelModeBaselineAdjust;
171 res.mBaselineOffsetsPointMode[i] -= pointModeBaselineAdjust;
175 if ( !res.mBlockMaxCharacterWidth.isEmpty() )
177 QList< double > adjustedRightToLeftXOffsets;
178 double currentOffset = 0;
179 const int size = res.mBlockMaxCharacterWidth.size();
181 double widthVerticalOrientation = 0;
182 for (
int i = 0; i < size; ++i )
184 const double rightToLeftBlockMaxCharacterWidth = res.mBlockMaxCharacterWidth[size - 1 - i ];
185 const double rightToLeftLineSpacing = blockVerticalLineSpacing[ size - 1 - i ];
187 adjustedRightToLeftXOffsets << currentOffset;
188 currentOffset += rightToLeftLineSpacing;
191 widthVerticalOrientation += rightToLeftBlockMaxCharacterWidth;
193 widthVerticalOrientation += rightToLeftLineSpacing;
195 std::reverse( adjustedRightToLeftXOffsets.begin(), adjustedRightToLeftXOffsets.end() );
196 res.mVerticalOrientationXOffsets = adjustedRightToLeftXOffsets;
198 res.mDocumentSizeVerticalOrientation = QSizeF( widthVerticalOrientation, heightVerticalOrientation );
double convertToPainterUnits(double size, QgsUnitTypes::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.
const QgsTextFragment & at(int index) const
Returns the fragment at the specified index.
QSizeF documentSize(Qgis::TextLayoutMode mode, Qgis::TextOrientation orientation) const
Returns the overall size of the document.
QFont fragmentFont(int blockIndex, int fragmentIndex) const
Returns the calculated font for the fragment at the specified block and fragment indices.
double baselineOffset(int blockIndex, Qgis::TextLayoutMode mode) const
Returns the offset from the top of the document to the text baseline for the given block index.
static QgsTextDocumentMetrics calculateMetrics(const QgsTextDocument &document, const QgsTextFormat &format, const QgsRenderContext &context, double scaleFactor=1.0)
Returns precalculated text metrics for a text document, when rendered using the given base format and...
Represents a document consisting of one or more QgsTextBlock objects.
const QgsTextBlock & at(int index) const
Returns the block at the specified index.
Stores a fragment of text along with formatting overrides to be used when rendering the fragment.
const QgsTextCharacterFormat & characterFormat() const
Returns the character formatting for the fragment.