Skip to content

Commit

Permalink
Add a character based text height calculation method to QgsTextRenderer
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 8, 2020
1 parent fd6dcf3 commit 573e46b
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
13 changes: 13 additions & 0 deletions python/core/auto_generated/textrenderer/qgstextrenderer.sip.in
Expand Up @@ -186,6 +186,19 @@ Returns the height of a text based on a given format.
:param textLines: list of lines of text to calculate width from
:param mode: draw mode
:param fontMetrics: font metrics
%End

static double textHeight( const QgsRenderContext &context, const QgsTextFormat &format, QChar character, bool includeEffects = false );
%Docstring
Returns the height of a character when rendered with the specified text ``format``.

:param context: render context
:param format: text format
:param character: character to determine height of. If ``character`` is invalid, then the maximum character height will be returned.
:param includeEffects: if ``True``, then the size of formatting effects such as buffers and shadows will be considered in the
returned height. If ``False``, then the returned size considers the character only.

.. versionadded:: 3.16
%End

static const double FONT_WORKAROUND_SCALE;
Expand Down
33 changes: 33 additions & 0 deletions src/core/textrenderer/qgstextrenderer.cpp
Expand Up @@ -533,6 +533,39 @@ double QgsTextRenderer::textHeight( const QgsRenderContext &context, const QgsTe
}
}

double QgsTextRenderer::textHeight( const QgsRenderContext &context, const QgsTextFormat &format, QChar character, bool includeEffects )
{
const double scaleFactor = ( context.flags() & QgsRenderContext::ApplyScalingWorkaroundForTextRendering ) ? FONT_WORKAROUND_SCALE : 1.0;
const QFont baseFont = format.scaledFont( context, scaleFactor );
const QFontMetrics fm( baseFont );
const double height = ( character.isNull() ? fm.height() : fm.boundingRect( character ).height() ) / scaleFactor;

if ( !includeEffects )
return height;

double maxExtension = 0;
if ( format.buffer().enabled() )
{
maxExtension += context.convertToPainterUnits( format.buffer().size(), format.buffer().sizeUnit(), format.buffer().sizeMapUnitScale() );
}
if ( format.shadow().enabled() )
{
maxExtension += context.convertToPainterUnits( format.shadow().offsetDistance(), format.shadow().offsetUnit(), format.shadow().offsetMapUnitScale() )
+ context.convertToPainterUnits( format.shadow().blurRadius(), format.shadow().blurRadiusUnit(), format.shadow().blurRadiusMapUnitScale() );
}
if ( format.background().enabled() )
{
maxExtension += context.convertToPainterUnits( std::fabs( format.background().offset().y() ), format.background().offsetUnit(), format.background().offsetMapUnitScale() )
+ context.convertToPainterUnits( format.background().strokeWidth(), format.background().strokeWidthUnit(), format.background().strokeWidthMapUnitScale() ) / 2.0;
if ( format.background().sizeType() == QgsTextBackgroundSettings::SizeBuffer && format.background().size().height() > 0 )
{
maxExtension += context.convertToPainterUnits( format.background().size().height(), format.background().sizeUnit(), format.background().sizeMapUnitScale() );
}
}

return height + maxExtension;
}

double QgsTextRenderer::textHeight( const QgsRenderContext &context, const QgsTextFormat &format, const QgsTextDocument &document, DrawMode mode )
{
//calculate max height of text lines
Expand Down
13 changes: 13 additions & 0 deletions src/core/textrenderer/qgstextrenderer.h
Expand Up @@ -199,6 +199,19 @@ class CORE_EXPORT QgsTextRenderer
static double textHeight( const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, DrawMode mode = Point,
QFontMetricsF *fontMetrics = nullptr );

/**
* Returns the height of a character when rendered with the specified text \a format.
*
* \param context render context
* \param format text format
* \param character character to determine height of. If \a character is invalid, then the maximum character height will be returned.
* \param includeEffects if TRUE, then the size of formatting effects such as buffers and shadows will be considered in the
* returned height. If FALSE, then the returned size considers the character only.
*
* \since QGIS 3.16
*/
static double textHeight( const QgsRenderContext &context, const QgsTextFormat &format, QChar character, bool includeEffects = false );

/**
* Scale factor for upscaling font sizes and downscaling destination painter devices.
*
Expand Down

0 comments on commit 573e46b

Please sign in to comment.