35 const QFont font = format.
scaledFont( context, scaleFactor, &res.mIsNullSize );
47 double heightLabelMode = 0;
48 double heightPointRectMode = 0;
49 double heightCapHeightMode = 0;
50 double heightAscentMode = 0;
51 const int blockSize = document.
size();
52 res.mFragmentFonts.reserve( blockSize );
53 double currentLabelBaseline = 0;
54 double currentPointBaseline = 0;
55 double currentRectBaseline = 0;
56 double currentCapHeightBasedBaseline = 0;
57 double currentAscentBasedBaseline = 0;
58 double lastLineLeading = 0;
60 double heightVerticalOrientation = 0;
62 QVector < double > blockVerticalLineSpacing;
66 double outerYMinLabel = 0;
67 double outerYMaxLabel = 0;
69 for (
int blockIndex = 0; blockIndex < blockSize; blockIndex++ )
75 double blockYMaxAdjustLabel = 0;
77 double blockHeightUsingAscentDescent = 0;
78 double blockHeightUsingLineSpacing = 0;
79 double blockHeightVerticalOrientation = 0;
81 double blockHeightUsingAscentAccountingForVerticalOffset = 0;
83 const int fragmentSize = block.
size();
85 double maxBlockAscent = 0;
86 double maxBlockDescent = 0;
87 double maxLineSpacing = 0;
88 double maxBlockLeading = 0;
89 double maxBlockMaxWidth = 0;
90 double maxBlockCapHeight = 0;
92 QList< double > fragmentVerticalOffsets;
93 fragmentVerticalOffsets.reserve( fragmentSize );
95 QList< QFont > fragmentFonts;
96 fragmentFonts.reserve( fragmentSize );
100 QFont previousNonSuperSubScriptFont;
102 bool isFirstNonTabFragment =
true;
104 for (
int fragmentIndex = 0; fragmentIndex < fragmentSize; ++fragmentIndex )
107 if ( fragment.
isTab() )
110 const double nextTabStop = ( std::floor( blockXMax / tabStopDistancePainterUnits ) + 1 ) * tabStopDistancePainterUnits;
111 const double fragmentWidth = nextTabStop - blockXMax;
114 blockXMax += fragmentWidth;
116 fragmentVerticalOffsets << 0;
118 fragmentFonts << QFont();
124 double fragmentHeightForVerticallyOffsetText = 0;
125 double fragmentYMaxAdjust = 0;
127 QFont updatedFont = font;
130 QFontMetricsF fm( updatedFont );
132 if ( isFirstNonTabFragment )
133 previousNonSuperSubScriptFont = updatedFont;
141 previousNonSuperSubScriptFont = updatedFont;
146 const QFontMetricsF previousFM( previousNonSuperSubScriptFont );
156 fm = QFontMetricsF( updatedFont );
170 const QFontMetricsF previousFM( previousNonSuperSubScriptFont );
176 fm = QFontMetricsF( updatedFont );
189 previousNonSuperSubScriptFont = updatedFont;
193 const double fragmentWidth = fm.horizontalAdvance( fragment.
text() ) / scaleFactor;
197 const double fragmentHeightUsingAscentDescent = ( fm.ascent() + fm.descent() ) / scaleFactor;
198 const double fragmentHeightUsingLineSpacing = fm.lineSpacing() / scaleFactor;
201 blockXMax += fragmentWidth;
202 blockHeightUsingAscentDescent = std::max( blockHeightUsingAscentDescent, fragmentHeightUsingAscentDescent );
204 blockHeightUsingLineSpacing = std::max( blockHeightUsingLineSpacing, fragmentHeightUsingLineSpacing );
205 maxBlockAscent = std::max( maxBlockAscent, fm.ascent() / scaleFactor );
207 maxBlockCapHeight = std::max( maxBlockCapHeight, fm.capHeight() / scaleFactor );
209 blockHeightUsingAscentAccountingForVerticalOffset = std::max( std::max( maxBlockAscent, fragmentHeightForVerticallyOffsetText ), blockHeightUsingAscentAccountingForVerticalOffset );
211 maxBlockDescent = std::max( maxBlockDescent, fm.descent() / scaleFactor );
212 maxBlockMaxWidth = std::max( maxBlockMaxWidth, fm.maxWidth() / scaleFactor );
214 blockYMaxAdjustLabel = std::max( blockYMaxAdjustLabel, fragmentYMaxAdjust );
216 if ( ( fm.lineSpacing() / scaleFactor ) > maxLineSpacing )
218 maxLineSpacing = fm.lineSpacing() / scaleFactor;
219 maxBlockLeading = fm.leading() / scaleFactor;
222 fragmentFonts << updatedFont;
224 const double verticalOrientationFragmentHeight = isFirstNonTabFragment ? ( fm.ascent() / scaleFactor * fragment.
text().size() + ( fragment.
text().size() - 1 ) * updatedFont.letterSpacing() / scaleFactor )
225 : ( fragment.
text().size() * ( fm.ascent() / scaleFactor + updatedFont.letterSpacing() / scaleFactor ) );
226 blockHeightVerticalOrientation += verticalOrientationFragmentHeight;
228 isFirstNonTabFragment =
false;
232 if ( blockIndex == 0 )
236 res.mFirstLineAscentOffset = 0.25 * maxBlockAscent;
237 res.mLastLineAscentOffset = res.mFirstLineAscentOffset;
238 res.mFirstLineCapHeight = maxBlockCapHeight;
239 const double lineHeight = ( maxBlockAscent + maxBlockDescent );
244 currentLabelBaseline = -res.mFirstLineAscentOffset;
246 if ( blockHeightUsingAscentAccountingForVerticalOffset > maxBlockAscent )
247 outerYMinLabel = maxBlockAscent - blockHeightUsingAscentAccountingForVerticalOffset;
250 currentRectBaseline = -res.mFirstLineAscentOffset + lineHeight - 1 ;
252 currentCapHeightBasedBaseline = res.mFirstLineCapHeight;
253 currentAscentBasedBaseline = maxBlockAscent;
256 currentPointBaseline = 0;
258 heightLabelMode += blockHeightUsingAscentDescent;
259 heightPointRectMode += blockHeightUsingAscentDescent;
260 heightCapHeightMode += maxBlockCapHeight;
261 heightAscentMode += maxBlockAscent;
268 currentLabelBaseline += thisLineHeightUsingAscentDescent;
269 currentRectBaseline += thisLineHeightUsingLineSpacing;
270 currentPointBaseline += thisLineHeightUsingLineSpacing;
272 currentCapHeightBasedBaseline += thisLineHeightUsingLineSpacing;
274 currentAscentBasedBaseline += thisLineHeightUsingLineSpacing;
276 heightLabelMode += thisLineHeightUsingAscentDescent;
277 heightPointRectMode += thisLineHeightUsingLineSpacing;
278 heightCapHeightMode += thisLineHeightUsingLineSpacing;
279 heightAscentMode += thisLineHeightUsingLineSpacing;
280 if ( blockIndex == blockSize - 1 )
281 res.mLastLineAscentOffset = 0.25 * maxBlockAscent;
284 if ( blockIndex == blockSize - 1 )
286 if ( blockYMaxAdjustLabel > maxBlockDescent )
287 outerYMaxLabel = blockYMaxAdjustLabel - maxBlockDescent;
292 res.mBlockHeights << blockHeightUsingLineSpacing;
295 outerXMax = std::max( outerXMax, blockXMax );
297 heightVerticalOrientation = std::max( heightVerticalOrientation, blockHeightVerticalOrientation );
299 res.mFragmentFonts << fragmentFonts;
300 res.mBaselineOffsetsLabelMode << currentLabelBaseline;
301 res.mBaselineOffsetsPointMode << currentPointBaseline;
302 res.mBaselineOffsetsRectMode << currentRectBaseline;
303 res.mBaselineOffsetsCapHeightMode << currentCapHeightBasedBaseline;
304 res.mBaselineOffsetsAscentBased << currentAscentBasedBaseline;
305 res.mBlockMaxDescent << maxBlockDescent;
306 res.mBlockMaxCharacterWidth << maxBlockMaxWidth;
307 res.mFragmentVerticalOffsetsLabelMode << fragmentVerticalOffsets;
308 res.mFragmentVerticalOffsetsRectMode << fragmentVerticalOffsets;
309 res.mFragmentVerticalOffsetsPointMode << fragmentVerticalOffsets;
312 if ( blockIndex > 0 )
313 lastLineLeading = maxBlockLeading;
316 heightLabelMode -= lastLineLeading;
317 heightPointRectMode -= lastLineLeading;
319 res.mDocumentSizeLabelMode = QSizeF( width, heightLabelMode );
320 res.mDocumentSizePointRectMode = QSizeF( width, heightPointRectMode );
321 res.mDocumentSizeCapHeightMode = QSizeF( width, heightCapHeightMode );
322 res.mDocumentSizeAscentMode = QSizeF( width, heightAscentMode );
325 if ( !res.mBaselineOffsetsLabelMode.isEmpty() )
327 const double labelModeBaselineAdjust = res.mBaselineOffsetsLabelMode.constLast() + res.mLastLineAscentOffset;
328 const double pointModeBaselineAdjust = res.mBaselineOffsetsPointMode.constLast();
329 for (
int i = 0; i < blockSize; ++i )
331 res.mBaselineOffsetsLabelMode[i] -= labelModeBaselineAdjust;
332 res.mBaselineOffsetsPointMode[i] -= pointModeBaselineAdjust;
336 if ( !res.mBlockMaxCharacterWidth.isEmpty() )
338 QList< double > adjustedRightToLeftXOffsets;
339 double currentOffset = 0;
340 const int size = res.mBlockMaxCharacterWidth.size();
342 double widthVerticalOrientation = 0;
343 for (
int i = 0; i < size; ++i )
345 const double rightToLeftBlockMaxCharacterWidth = res.mBlockMaxCharacterWidth[size - 1 - i ];
346 const double rightToLeftLineSpacing = blockVerticalLineSpacing[ size - 1 - i ];
348 adjustedRightToLeftXOffsets << currentOffset;
349 currentOffset += rightToLeftLineSpacing;
352 widthVerticalOrientation += rightToLeftBlockMaxCharacterWidth;
354 widthVerticalOrientation += rightToLeftLineSpacing;
356 std::reverse( adjustedRightToLeftXOffsets.begin(), adjustedRightToLeftXOffsets.end() );
357 res.mVerticalOrientationXOffsets = adjustedRightToLeftXOffsets;
359 res.mDocumentSizeVerticalOrientation = QSizeF( widthVerticalOrientation, heightVerticalOrientation );
362 res.mOuterBoundsLabelMode = QRectF( outerXMin, -outerYMaxLabel,
363 outerXMax - outerXMin,
364 heightLabelMode - outerYMinLabel + outerYMaxLabel );