From 573e46b67191f9a2e4a39eec2b98cd203287d12a Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 8 Jul 2020 10:59:37 +1000 Subject: [PATCH] Add a character based text height calculation method to QgsTextRenderer --- .../textrenderer/qgstextrenderer.sip.in | 13 ++++++++ src/core/textrenderer/qgstextrenderer.cpp | 33 +++++++++++++++++++ src/core/textrenderer/qgstextrenderer.h | 13 ++++++++ 3 files changed, 59 insertions(+) diff --git a/python/core/auto_generated/textrenderer/qgstextrenderer.sip.in b/python/core/auto_generated/textrenderer/qgstextrenderer.sip.in index 4acd9f7f0cd..634f7a4b0d8 100644 --- a/python/core/auto_generated/textrenderer/qgstextrenderer.sip.in +++ b/python/core/auto_generated/textrenderer/qgstextrenderer.sip.in @@ -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; diff --git a/src/core/textrenderer/qgstextrenderer.cpp b/src/core/textrenderer/qgstextrenderer.cpp index 8499d9d2c04..dc2760a2c59 100644 --- a/src/core/textrenderer/qgstextrenderer.cpp +++ b/src/core/textrenderer/qgstextrenderer.cpp @@ -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 diff --git a/src/core/textrenderer/qgstextrenderer.h b/src/core/textrenderer/qgstextrenderer.h index 8f394a54013..118dce030a8 100644 --- a/src/core/textrenderer/qgstextrenderer.h +++ b/src/core/textrenderer/qgstextrenderer.h @@ -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. *