27#include <QFontMetricsF>
155 res.mLastLineAscentOffset = res.mFirstLineAscentOffset;
191 thisLineHeightUsingAscentDescent = std::max( thisLineHeightUsingAscentDescent, metrics.
maxBlockFixedItemHeight );
194 documentMetrics.
currentLabelBaseline += verticalMarginBeforeBlock + thisLineHeightUsingAscentDescent;
195 documentMetrics.
currentRectBaseline += verticalMarginBeforeBlock + thisLineHeightUsingLineSpacing;
196 documentMetrics.
currentPointBaseline += verticalMarginBeforeBlock + thisLineHeightUsingLineSpacing;
202 documentMetrics.
heightLabelMode += verticalMarginBeforeBlock + thisLineHeightUsingAscentDescent;
203 documentMetrics.
heightPointRectMode += verticalMarginBeforeBlock + thisLineHeightUsingLineSpacing;
204 documentMetrics.
heightCapHeightMode += verticalMarginBeforeBlock + thisLineHeightUsingLineSpacing;
205 documentMetrics.
heightAscentMode += verticalMarginBeforeBlock + thisLineHeightUsingLineSpacing;
248 res.mDocument.
append( outputBlock );
261 if ( fragment.
isTab() )
264 double nextTabStop = 0;
268 nextTabStop = thisBlockMetrics.
blockXMax;
269 for (
const double tabStop : std::as_const( documentMetrics.tabStopDistancesPainterUnits ) )
271 if ( tabStop >= thisBlockMetrics.
blockXMax )
273 nextTabStop = tabStop;
282 const double fragmentWidth = nextTabStop - thisBlockMetrics.
blockXMax;
285 thisBlockMetrics.
blockXMax += fragmentWidth;
291 currentOutputBlock.
append( fragment );
297 double fragmentHeightForVerticallyOffsetText = 0;
298 double fragmentYMaxAdjust = 0;
300 QFont updatedFont = font;
303 QFontMetricsF fm( updatedFont );
331 fm = QFontMetricsF( updatedFont );
351 fm = QFontMetricsF( updatedFont );
369 &fragmentHeightForVerticallyOffsetText,
375 thisBlockMetrics.blockYMaxAdjustLabel = std::max( thisBlockMetrics.blockYMaxAdjustLabel, fragmentYMaxAdjust );
376 thisBlockMetrics.blockHeightUsingAscentAccountingForVerticalOffset = std::max( std::max( thisBlockMetrics.maxBlockAscent, fragmentHeightForVerticallyOffsetText ), thisBlockMetrics.blockHeightUsingAscentAccountingForVerticalOffset );
378 thisBlockMetrics.fragmentHorizontalAdvance << fragmentWidth;
380 thisBlockMetrics.blockWidth += fragmentWidth;
381 thisBlockMetrics.blockXMax += fragmentWidth;
383 thisBlockMetrics.fragmentFonts << updatedFont;
385 const double verticalOrientationFragmentHeight = thisBlockMetrics.isFirstNonTabFragment ? ( fm.ascent() / scaleFactor * fragment.
text().size() + ( fragment.
text().size() - 1 ) * updatedFont.letterSpacing() / scaleFactor )
386 : ( fragment.text().size() * ( fm.ascent() / scaleFactor + updatedFont.letterSpacing() / scaleFactor ) );
387 thisBlockMetrics.blockHeightVerticalOrientation += verticalOrientationFragmentHeight;
389 thisBlockMetrics.isFirstNonTabFragment =
false;
395 double imageHeight = 0;
396 double imageWidth = 0;
403 const QSizeF originalSizeMmAt96Dpi = imageSize / 3.7795275590551185;
405 imageWidth = originalSizeMmAt96Dpi.width() * pixelsPerMm;
406 imageHeight = originalSizeMmAt96Dpi.height() * pixelsPerMm;
413 imageWidth = originalImageSize.width() * imageHeight / originalImageSize.height();
420 imageHeight = originalImageSize.height() * imageWidth / originalImageSize.width();
430 && ( thisBlockMetrics.blockXMax + imageWidth > documentContext.
maximumWidth() )
431 && !currentOutputBlock.
empty() )
434 finalizeBlock( res, format, documentMetrics, currentOutputBlock, thisBlockMetrics );
435 thisBlockMetrics.isFirstBlock =
false;
439 thisBlockMetrics.blockHeightUsingAscentDescent = std::max( thisBlockMetrics.blockHeightUsingAscentDescent, imageHeight + fm.descent() / scaleFactor );
440 thisBlockMetrics.blockHeightUsingLineSpacing = std::max( thisBlockMetrics.blockHeightUsingLineSpacing, imageHeight + fm.leading() );
442 thisBlockMetrics.maxBlockAscent = std::max( thisBlockMetrics.maxBlockAscent, imageHeight );
443 thisBlockMetrics.maxBlockCapHeight = std::max( thisBlockMetrics.maxBlockCapHeight, imageHeight );
444 thisBlockMetrics.maxLineSpacing = std::max( thisBlockMetrics.maxLineSpacing, imageHeight + fm.leading() / scaleFactor );
445 thisBlockMetrics.maxBlockLeading = std::max( thisBlockMetrics.maxBlockLeading, fm.leading() / scaleFactor );
446 thisBlockMetrics.maxBlockMaxWidth = std::max( thisBlockMetrics.maxBlockMaxWidth, imageWidth );
447 thisBlockMetrics.maxBlockFixedItemHeight = std::max( thisBlockMetrics.maxBlockFixedItemHeight, imageHeight );
448 thisBlockMetrics.fragmentFixedHeights << imageHeight;
449 updateCommonBlockMetrics( thisBlockMetrics, imageWidth, fragment );
450 currentOutputBlock.
append( fragment );
454 const double fragmentHeightUsingAscentDescent = ( fm.ascent() + fm.descent() ) / scaleFactor;
455 const double fragmentHeightUsingLineSpacing = fm.lineSpacing() / scaleFactor;
457 auto finalizeTextFragment = [fragmentHeightUsingAscentDescent,
458 fragmentHeightUsingLineSpacing,
462 &updateCommonBlockMetrics
465 thisBlockMetrics.blockHeightUsingAscentDescent = std::max( thisBlockMetrics.blockHeightUsingAscentDescent, fragmentHeightUsingAscentDescent );
467 thisBlockMetrics.blockHeightUsingLineSpacing = std::max( thisBlockMetrics.blockHeightUsingLineSpacing, fragmentHeightUsingLineSpacing );
468 thisBlockMetrics.maxBlockAscent = std::max( thisBlockMetrics.maxBlockAscent, fm.ascent() / scaleFactor );
469 thisBlockMetrics.maxBlockAscentForTextFragments = std::max( thisBlockMetrics.maxBlockAscentForTextFragments, fm.ascent() / scaleFactor );
471 thisBlockMetrics.maxBlockCapHeight = std::max( thisBlockMetrics.maxBlockCapHeight, fm.capHeight() / scaleFactor );
473 thisBlockMetrics.maxBlockDescent = std::max( thisBlockMetrics.maxBlockDescent, fm.descent() / scaleFactor );
474 thisBlockMetrics.maxBlockMaxWidth = std::max( thisBlockMetrics.maxBlockMaxWidth, fm.maxWidth() / scaleFactor );
476 if ( ( fm.lineSpacing() / scaleFactor ) > thisBlockMetrics.maxLineSpacing )
478 thisBlockMetrics.maxLineSpacing = fm.lineSpacing() / scaleFactor;
479 thisBlockMetrics.maxBlockLeading = fm.leading() / scaleFactor;
481 thisBlockMetrics.fragmentFixedHeights << -1;
482 updateCommonBlockMetrics( thisBlockMetrics, fragmentWidth, fragment );
483 currentOutputBlock.append( fragment );
486 double fragmentWidth = fm.horizontalAdvance( fragment.text() ) / scaleFactor;
490 && ( thisBlockMetrics.blockXMax + fragmentWidth > documentContext.
maximumWidth() ) )
495 const QStringList words = fragment.text().split(
' ' );
496 QStringList linesToProcess;
497 QStringList wordsInCurrentLine;
498 double remainingWidthInCurrentLine = documentContext.
maximumWidth() - thisBlockMetrics.blockXMax;
499 for (
const QString &word : words )
501 const double wordWidth = fm.horizontalAdvance( word ) / scaleFactor;
502 if ( wordWidth > remainingWidthInCurrentLine )
505 if ( !wordsInCurrentLine.isEmpty() )
506 linesToProcess << wordsInCurrentLine.join(
' ' );
507 wordsInCurrentLine.clear();
508 linesToProcess << word;
509 remainingWidthInCurrentLine = documentContext.
maximumWidth();
513 wordsInCurrentLine.append( word );
516 if ( !wordsInCurrentLine.isEmpty() )
517 linesToProcess << wordsInCurrentLine.join(
' ' );
519 remainingWidthInCurrentLine = documentContext.
maximumWidth() - thisBlockMetrics.blockXMax;
520 for (
int lineIndex = 0; lineIndex < linesToProcess.size(); ++lineIndex )
522 QString remainingText = linesToProcess.at( lineIndex );
523 int lastPos = remainingText.lastIndexOf(
' ' );
524 while ( lastPos > -1 )
527 if ( ( fm.horizontalAdvance( remainingText ) / scaleFactor ) <= remainingWidthInCurrentLine )
532 const double widthTextToLastPos = fm.horizontalAdvance( remainingText.left( lastPos ) ) / scaleFactor;
533 if ( widthTextToLastPos <= remainingWidthInCurrentLine )
537 thisLineFragment.
setText( remainingText.left( lastPos ) );
538 finalizeTextFragment( thisBlockMetrics, thisLineFragment, widthTextToLastPos );
540 finalizeBlock( res, format, documentMetrics, currentOutputBlock, thisBlockMetrics );
541 thisBlockMetrics.isFirstBlock =
false;
542 remainingWidthInCurrentLine = documentContext.
maximumWidth();
543 remainingText = remainingText.mid( lastPos + 1 );
546 lastPos = remainingText.lastIndexOf(
' ', lastPos - 1 );
550 if ( ( fm.horizontalAdvance( remainingText ) / scaleFactor ) > remainingWidthInCurrentLine && !currentOutputBlock.empty() )
552 finalizeBlock( res, format, documentMetrics, currentOutputBlock, thisBlockMetrics );
553 thisBlockMetrics.isFirstBlock =
false;
554 remainingWidthInCurrentLine = documentContext.
maximumWidth();
559 thisLineFragment.
setText( remainingText );
560 finalizeTextFragment( thisBlockMetrics, thisLineFragment, fm.horizontalAdvance( remainingText ) / scaleFactor );
562 if ( lineIndex < linesToProcess.size() - 1 )
565 finalizeBlock( res, format, documentMetrics, currentOutputBlock, thisBlockMetrics );
566 thisBlockMetrics.isFirstBlock =
false;
567 remainingWidthInCurrentLine = documentContext.
maximumWidth();
570 thisBlockMetrics.isFirstBlock =
false;
576 finalizeTextFragment( thisBlockMetrics, fragment, fragmentWidth );
586 const QFont font = format.
scaledFont( context, scaleFactor, &res.mIsNullSize );
599 const QList< QgsTextFormat::Tab > tabPositions = format.
tabPositions();
605 ? tab.position() * font.pixelSize() / scaleFactor
612 res.mFragmentFonts.reserve( documentMetrics.
blockSize );
614 for (
int blockIndex = 0; blockIndex < documentMetrics.
blockSize; blockIndex++ )
621 const int fragmentSize = block.
size();
656 for (
int fragmentIndex = 0; fragmentIndex < fragmentSize; ++fragmentIndex )
659 processFragment( res, format, context, documentContext, scaleFactor, documentMetrics, thisBlockMetrics, font, fragment, outputBlock );
662 finalizeBlock( res, format, documentMetrics, outputBlock, thisBlockMetrics );
674 if ( !res.mBaselineOffsetsLabelMode.isEmpty() )
676 const double labelModeBaselineAdjust = res.mBaselineOffsetsLabelMode.constLast() + res.mLastLineAscentOffset;
677 const double pointModeBaselineAdjust = res.mBaselineOffsetsPointMode.constLast();
678 for (
int i = 0; i < documentMetrics.
blockSize; ++i )
680 res.mBaselineOffsetsLabelMode[i] -= labelModeBaselineAdjust;
681 res.mBaselineOffsetsPointMode[i] -= pointModeBaselineAdjust;
685 if ( !res.mBlockMaxCharacterWidth.isEmpty() )
687 QList< double > adjustedRightToLeftXOffsets;
688 double currentOffset = 0;
689 const int size = res.mBlockMaxCharacterWidth.size();
691 double widthVerticalOrientation = 0;
692 for (
int i = 0; i < size; ++i )
694 const double rightToLeftBlockMaxCharacterWidth = res.mBlockMaxCharacterWidth[size - 1 - i ];
697 adjustedRightToLeftXOffsets << currentOffset;
698 currentOffset += rightToLeftLineSpacing;
701 widthVerticalOrientation += rightToLeftBlockMaxCharacterWidth;
703 widthVerticalOrientation += rightToLeftLineSpacing;
705 std::reverse( adjustedRightToLeftXOffsets.begin(), adjustedRightToLeftXOffsets.end() );
706 res.mVerticalOrientationXOffsets = adjustedRightToLeftXOffsets;
724 switch ( orientation )
731 return mDocumentSizePointRectMode;
734 return mDocumentSizeCapHeightMode;
737 return mDocumentSizeAscentMode;
740 return mDocumentSizeLabelMode;
745 return mDocumentSizeVerticalOrientation;
755 switch ( orientation )
767 return mOuterBoundsLabelMode;
781 return mBlockWidths.value( blockIndex );
786 return mBlockHeights.value( blockIndex );
791 return mFirstLineCapHeight;
796 double verticalAdjustmentForBlockMargins = 0;
797 for (
int i = 0; i < blockIndex; ++i )
799 double marginBeforeBlock = 0;
800 verticalAdjustmentForBlockMargins += marginBeforeBlock;
806 return mBaselineOffsetsRectMode.value( blockIndex ) + verticalAdjustmentForBlockMargins;
808 return mBaselineOffsetsCapHeightMode.value( blockIndex ) + verticalAdjustmentForBlockMargins;
810 return mBaselineOffsetsAscentBased.value( blockIndex ) + verticalAdjustmentForBlockMargins;
812 return mBaselineOffsetsPointMode.value( blockIndex ) + verticalAdjustmentForBlockMargins;
814 return mBaselineOffsetsLabelMode.value( blockIndex ) + verticalAdjustmentForBlockMargins;
821 return mFragmentHorizontalAdvance.value( blockIndex ).value( fragmentIndex );
831 return mFragmentVerticalOffsetsRectMode.value( blockIndex ).value( fragmentIndex );
833 return mFragmentVerticalOffsetsPointMode.value( blockIndex ).value( fragmentIndex );
835 return mFragmentVerticalOffsetsLabelMode.value( blockIndex ).value( fragmentIndex );
842 return mFragmentFixedHeights.value( blockIndex ).value( fragmentIndex );
847 return mVerticalOrientationXOffsets.value( blockIndex );
852 return mBlockMaxCharacterWidth.value( blockIndex );
857 return mBlockMaxDescent.value( blockIndex );
862 return mFragmentFonts.value( blockIndex ).value( fragmentIndex );
867 if ( blockIndex < 0 )
868 return mVerticalMarginsBetweenBlocks.value( 0 );
870 return mVerticalMarginsBetweenBlocks.value( blockIndex + 1 );
875 return mLeftBlockMargins.value( blockIndex );
880 return mRightBlockMargins.value( blockIndex );
TextLayoutMode
Text layout modes.
@ Labeling
Labeling-specific layout mode.
@ Point
Text at point of origin layout mode.
@ RectangleAscentBased
Similar to Rectangle mode, but uses ascents only when calculating font and line heights.
@ RectangleCapHeightBased
Similar to Rectangle mode, but uses cap height only when calculating font heights for the first line ...
@ Rectangle
Text within rectangle layout mode.
TextOrientation
Text orientations.
@ Vertical
Vertically oriented text.
@ RotationBased
Horizontally or vertically oriented text based on rotation (only available for map labeling)
@ Horizontal
Horizontally oriented text.
@ Normal
Adjacent characters are positioned in the standard way for text in the writing system in use.
@ SubScript
Characters are placed below the base line for normal text.
@ SuperScript
Characters are placed above the base line for normal text.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size)
@ Points
Points (e.g., for font sizes)
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
@ WrapLines
Automatically wrap long lines of text.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
QSize originalSize(const QString &path, bool blocking=false) const
Returns the original size (in pixels) of the image at the specified path.
double top() const
Returns the top margin.
double right() const
Returns the right margin.
double bottom() const
Returns the bottom margin.
double left() const
Returns the left margin.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
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).
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
double lineHeight() const
Returns the line height in points, or NaN if the line height is not set and should be auto calculated...
double lineHeightPercentage() const
Returns the line height percentage size (as fraction of font size from 0.0 to 1.0),...
QgsMargins margins() const
Returns the block margins, in points.
Represents a block of text consisting of one or more QgsTextFragment objects.
int size() const
Returns the number of fragments in the block.
const QgsTextBlockFormat & blockFormat() const
Returns the block formatting for the fragment.
void clear()
Clears the block, removing all its contents.
void reserve(int count)
Reserves the specified count of fragments for optimised fragment appending.
void setBlockFormat(const QgsTextBlockFormat &format)
Sets the block format for the fragment.
void append(const QgsTextFragment &fragment)
Appends a fragment to the block.
const QgsTextFragment & at(int index) const
Returns the fragment at the specified index.
bool empty() const
Returns true if the block is empty.
Stores information relating to individual character formatting.
void updateFontForFormat(QFont &font, const QgsRenderContext &context, double scaleFactor=1.0) const
Updates the specified font in place, applying character formatting options which are applicable on a ...
QSizeF imageSize() const
Returns the image size, if the format applies to a document image fragment.
QString imagePath() const
Returns the path to the image to render, if the format applies to a document image fragment.
Qgis::TextCharacterVerticalAlignment verticalAlignment() const
Returns the format vertical alignment.
bool hasVerticalAlignmentSet() const
Returns true if the format has an explicit vertical alignment set.
double fontPointSize() const
Returns the font point size, or -1 if the font size is not set and should be inherited.
Contains pre-calculated metrics of a QgsTextDocument.
double verticalOrientationXOffset(int blockIndex) const
Returns the vertical orientation x offset for the specified block.
double fragmentVerticalOffset(int blockIndex, int fragmentIndex, Qgis::TextLayoutMode mode) const
Returns the vertical offset from a text block's baseline which should be applied to the fragment at t...
double blockMaximumDescent(int blockIndex) const
Returns the maximum descent encountered in the specified block.
QSizeF documentSize(Qgis::TextLayoutMode mode, Qgis::TextOrientation orientation) const
Returns the overall size of the document.
double blockRightMargin(int blockIndex) const
Returns the margin for the right side of the specified block index.
double firstLineCapHeight() const
Returns the cap height for the first line of text.
static QgsTextDocumentMetrics calculateMetrics(const QgsTextDocument &document, const QgsTextFormat &format, const QgsRenderContext &context, double scaleFactor=1.0, const QgsTextDocumentRenderContext &documentContext=QgsTextDocumentRenderContext())
Returns precalculated text metrics for a text document, when rendered using the given base format and...
QFont fragmentFont(int blockIndex, int fragmentIndex) const
Returns the calculated font for the fragment at the specified block and fragment indices.
double blockMaximumCharacterWidth(int blockIndex) const
Returns the maximum character width for the specified block.
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.
double fragmentFixedHeight(int blockIndex, int fragmentIndex, Qgis::TextLayoutMode mode) const
Returns the fixed height of the fragment at the specified block and fragment index,...
QRectF outerBounds(Qgis::TextLayoutMode mode, Qgis::TextOrientation orientation) const
Returns the outer bounds of the document, which is the documentSize() adjusted to account for any tex...
double blockLeftMargin(int blockIndex) const
Returns the margin for the left side of the specified block index.
double blockHeight(int blockIndex) const
Returns the height of the block at the specified index.
double fragmentHorizontalAdvance(int blockIndex, int fragmentIndex, Qgis::TextLayoutMode mode) const
Returns the horizontal advance of the fragment at the specified block and fragment index.
bool isNullFontSize() const
Returns true if the metrics could not be calculated because the text format has a null font size.
const QgsTextDocument & document() const
Returns the document associated with the calculated metrics.
double blockWidth(int blockIndex) const
Returns the width of the block at the specified index.
double blockVerticalMargin(int blockIndex) const
Returns the vertical margin for the specified block index.
Encapsulates the context in which a text document is to be rendered.
Qgis::TextRendererFlags flags() const
Returns associated text renderer flags.
double maximumWidth() const
Returns the maximum width (in painter units) for rendered text.
Represents a document consisting of one or more QgsTextBlock objects.
const QgsTextBlock & at(int index) const
Returns the block at the specified index.
void reserve(int count)
Reserves the specified count of blocks for optimised block appending.
int size() const
Returns the number of blocks in the document.
void append(const QgsTextBlock &block)
Appends a block to the document.
Defines a tab position for a text format.
Container for all settings relating to text rendering.
QList< QgsTextFormat::Tab > tabPositions() const
Returns the list of tab positions for tab stops.
double lineHeight() const
Returns the line height for text.
double tabStopDistance() const
Returns the distance for tab stops.
QFont scaledFont(const QgsRenderContext &context, double scaleFactor=1.0, bool *isZeroSize=nullptr) const
Returns a font with the size scaled to match the format's size settings (including units and map unit...
Qgis::RenderUnit lineHeightUnit() const
Returns the units for the line height for text.
Qgis::RenderUnit tabStopDistanceUnit() const
Returns the units for the tab stop distance.
QgsMapUnitScale tabStopDistanceMapUnitScale() const
Returns the map unit scale object for the tab stop distance.
Stores a fragment of document along with formatting overrides to be used when rendering the fragment.
void setText(const QString &text)
Sets the text content of the fragment.
QString text() const
Returns the text content of the fragment.
void setCharacterFormat(const QgsTextCharacterFormat &format)
Sets the character format for the fragment.
const QgsTextCharacterFormat & characterFormat() const
Returns the character formatting for the fragment.
bool isImage() const
Returns true if the fragment represents an image.
bool isTab() const
Returns true if the fragment consists of just a tab character.
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.
#define BUILTIN_UNREACHABLE
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
constexpr double SUPERSCRIPT_VERTICAL_BASELINE_ADJUSTMENT_FACTOR
constexpr double SUBSCRIPT_VERTICAL_BASELINE_ADJUSTMENT_FACTOR
double maxBlockFixedItemHeight
double maxBlockAscentForTextFragments
void resetCalculatedStats()
double blockHeightUsingLineSpacing
QList< QFont > fragmentFonts
QList< double > fragmentFixedHeights
double lineHeightPainterUnits
QList< double > fragmentHorizontalAdvance
bool isFirstNonTabFragment
double blockHeightUsingAscentDescent
QFont previousNonSuperSubScriptFont
double blockHeightUsingAscentAccountingForVerticalOffset
QList< double > fragmentVerticalOffsets
double blockYMaxAdjustLabel
double lineHeightPercentage
double blockHeightVerticalOrientation
double heightVerticalOrientation
double tabStopDistancePainterUnits
QList< double > tabStopDistancesPainterUnits
QVector< double > blockRightMargin
double heightCapHeightMode
double currentCapHeightBasedBaseline
QVector< double > blockLeftMargin
double currentLabelBaseline
QVector< double > blockVerticalLineSpacing
double currentRectBaseline
QVector< double > verticalMarginsBetweenBlocks
Calculated vertical margins between blocks.
double currentPointBaseline
double heightPointRectMode
double currentAscentBasedBaseline