mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-07 00:15:48 -04:00
Add more efficient method to draw document when a QgsTextDocument is already available
This commit is contained in:
parent
a10b971156
commit
cfbf5ef51d
@ -77,6 +77,44 @@ Draws text within a rectangle using the specified settings.
|
||||
:param vAlignment: vertical alignment (since QGIS 3.16)
|
||||
:param flags: text rendering flags (since QGIS 3.24)
|
||||
:param mode: text layout mode. Only Qgis.TextLayoutMode.Rectangle, Qgis.TextLayoutMode.RectangleCapHeightBased and Qgis.TextLayoutMode.RectangleAscentBased are accepted (since QGIS 3.30)
|
||||
|
||||
.. seealso:: :py:func:`drawDocument`
|
||||
%End
|
||||
|
||||
static void drawDocument( const QRectF &rect,
|
||||
const QgsTextFormat &format,
|
||||
const QgsTextDocument &document,
|
||||
const QgsTextDocumentMetrics &metrics,
|
||||
QgsRenderContext &context,
|
||||
Qgis::TextHorizontalAlignment horizontalAlignment = Qgis::TextHorizontalAlignment::Left,
|
||||
Qgis::TextVerticalAlignment verticalAlignment = Qgis::TextVerticalAlignment::Top,
|
||||
double rotation = 0,
|
||||
Qgis::TextLayoutMode mode = Qgis::TextLayoutMode::Rectangle,
|
||||
Qgis::TextRendererFlags flags = Qgis::TextRendererFlags() );
|
||||
%Docstring
|
||||
Draws a text document within a rectangle using the specified settings.
|
||||
|
||||
Calling this method is more efficient than calling :py:func:`~QgsTextRenderer.drawText` if the text document and metrics have already
|
||||
been calculated.
|
||||
|
||||
.. warning::
|
||||
|
||||
Unlike :py:func:`~QgsTextRenderer.drawText`, this method does not automatically update data defined properties in the text ``format``. This
|
||||
is the caller's responsibility to do, and must be done prior to generating the text ``document`` and ``metrics``.
|
||||
|
||||
:param rect: destination rectangle for text
|
||||
:param format: base text format
|
||||
:param document: text document to draw
|
||||
:param metrics: precalculated text metrics
|
||||
:param context: destination render context
|
||||
:param horizontalAlignment: horizontal alignment
|
||||
:param verticalAlignment: vertical alignment
|
||||
:param rotation: text rotation
|
||||
:param mode: text layout mode. Only Qgis.TextLayoutMode.Rectangle, Qgis.TextLayoutMode.RectangleCapHeightBased and Qgis.TextLayoutMode.RectangleAscentBased are accepted.
|
||||
:param flags: text rendering flags
|
||||
|
||||
|
||||
.. versionadded:: 3.30
|
||||
%End
|
||||
|
||||
static void drawText( QPointF point, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines,
|
||||
|
@ -105,17 +105,22 @@ void QgsTextRenderer::drawText( const QRectF &rect, double rotation, Qgis::TextH
|
||||
const double fontScale = calculateScaleFactorForFormat( context, format );
|
||||
const QgsTextDocumentMetrics metrics = QgsTextDocumentMetrics::calculateMetrics( document, format, context, fontScale );
|
||||
|
||||
if ( tmpFormat.background().enabled() )
|
||||
drawDocument( rect, tmpFormat, document, metrics, context, alignment, vAlignment, rotation, mode, flags );
|
||||
}
|
||||
|
||||
void QgsTextRenderer::drawDocument( const QRectF &rect, const QgsTextFormat &format, const QgsTextDocument &document, const QgsTextDocumentMetrics &metrics, QgsRenderContext &context, Qgis::TextHorizontalAlignment horizontalAlignment, Qgis::TextVerticalAlignment verticalAlignment, double rotation, Qgis::TextLayoutMode mode, Qgis::TextRendererFlags )
|
||||
{
|
||||
if ( format.background().enabled() )
|
||||
{
|
||||
drawPart( rect, rotation, alignment, vAlignment, document, metrics, context, tmpFormat, Qgis::TextComponent::Background, Qgis::TextLayoutMode::Rectangle );
|
||||
drawPart( rect, rotation, horizontalAlignment, verticalAlignment, document, metrics, context, format, Qgis::TextComponent::Background, mode );
|
||||
}
|
||||
|
||||
if ( tmpFormat.buffer().enabled() )
|
||||
if ( format.buffer().enabled() )
|
||||
{
|
||||
drawPart( rect, rotation, alignment, vAlignment, document, metrics, context, tmpFormat, Qgis::TextComponent::Buffer, Qgis::TextLayoutMode::Rectangle );
|
||||
drawPart( rect, rotation, horizontalAlignment, verticalAlignment, document, metrics, context, format, Qgis::TextComponent::Buffer, mode );
|
||||
}
|
||||
|
||||
drawPart( rect, rotation, alignment, vAlignment, document, metrics, context, tmpFormat, Qgis::TextComponent::Text, Qgis::TextLayoutMode::Rectangle );
|
||||
drawPart( rect, rotation, horizontalAlignment, verticalAlignment, document, metrics, context, format, Qgis::TextComponent::Text, mode );
|
||||
}
|
||||
|
||||
void QgsTextRenderer::drawText( QPointF point, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool )
|
||||
@ -241,7 +246,7 @@ void QgsTextRenderer::drawPart( const QRectF &rect, double rotation, Qgis::TextH
|
||||
{
|
||||
drawTextInternal( part, context, format, component,
|
||||
document, metrics,
|
||||
alignment, vAlignment );
|
||||
alignment, vAlignment, mode );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -86,11 +86,47 @@ class CORE_EXPORT QgsTextRenderer
|
||||
* \param vAlignment vertical alignment (since QGIS 3.16)
|
||||
* \param flags text rendering flags (since QGIS 3.24)
|
||||
* \param mode text layout mode. Only Qgis::TextLayoutMode::Rectangle, Qgis::TextLayoutMode::RectangleCapHeightBased and Qgis::TextLayoutMode::RectangleAscentBased are accepted (since QGIS 3.30)
|
||||
*
|
||||
* \see drawDocument(), which is more efficient if the text document and metrics have already been calculated.
|
||||
*/
|
||||
static void drawText( const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines,
|
||||
QgsRenderContext &context, const QgsTextFormat &format,
|
||||
bool drawAsOutlines = true, Qgis::TextVerticalAlignment vAlignment = Qgis::TextVerticalAlignment::Top,
|
||||
Qgis::TextRendererFlags flags = Qgis::TextRendererFlags() );
|
||||
Qgis::TextRendererFlags flags = Qgis::TextRendererFlags(),
|
||||
Qgis::TextLayoutMode mode = Qgis::TextLayoutMode::Rectangle );
|
||||
|
||||
/**
|
||||
* Draws a text document within a rectangle using the specified settings.
|
||||
*
|
||||
* Calling this method is more efficient than calling drawText() if the text document and metrics have already
|
||||
* been calculated.
|
||||
*
|
||||
* \warning Unlike drawText(), this method does not automatically update data defined properties in the text \a format. This
|
||||
* is the caller's responsibility to do, and must be done prior to generating the text \a document and \a metrics.
|
||||
*
|
||||
* \param rect destination rectangle for text
|
||||
* \param format base text format
|
||||
* \param document text document to draw
|
||||
* \param metrics precalculated text metrics
|
||||
* \param context destination render context
|
||||
* \param horizontalAlignment horizontal alignment
|
||||
* \param verticalAlignment vertical alignment
|
||||
* \param rotation text rotation
|
||||
* \param mode text layout mode. Only Qgis::TextLayoutMode::Rectangle, Qgis::TextLayoutMode::RectangleCapHeightBased and Qgis::TextLayoutMode::RectangleAscentBased are accepted.
|
||||
* \param flags text rendering flags
|
||||
*
|
||||
* \since QGIS 3.30
|
||||
*/
|
||||
static void drawDocument( const QRectF &rect,
|
||||
const QgsTextFormat &format,
|
||||
const QgsTextDocument &document,
|
||||
const QgsTextDocumentMetrics &metrics,
|
||||
QgsRenderContext &context,
|
||||
Qgis::TextHorizontalAlignment horizontalAlignment = Qgis::TextHorizontalAlignment::Left,
|
||||
Qgis::TextVerticalAlignment verticalAlignment = Qgis::TextVerticalAlignment::Top,
|
||||
double rotation = 0,
|
||||
Qgis::TextLayoutMode mode = Qgis::TextLayoutMode::Rectangle,
|
||||
Qgis::TextRendererFlags flags = Qgis::TextRendererFlags() );
|
||||
|
||||
/**
|
||||
* Draws text at a point origin using the specified settings.
|
||||
|
@ -41,7 +41,9 @@ from qgis.core import (Qgis,
|
||||
QgsFontUtils,
|
||||
QgsSymbolLayerId,
|
||||
QgsSymbolLayerReference,
|
||||
QgsStringUtils)
|
||||
QgsStringUtils,
|
||||
QgsTextDocument,
|
||||
QgsTextDocumentMetrics)
|
||||
from qgis.testing import unittest, start_app
|
||||
|
||||
from utilities import getTestFont, svgSymbolsPath
|
||||
@ -1597,7 +1599,7 @@ class PyQgsTextRenderer(unittest.TestCase):
|
||||
|
||||
def testDrawRectMixedHtml(self):
|
||||
"""
|
||||
Test drawing text in rect mode with cap height based line heights
|
||||
Test drawing text in rect mode with mixed html fonts
|
||||
"""
|
||||
format = QgsTextFormat()
|
||||
format.setFont(getTestFont('bold'))
|
||||
@ -1605,6 +1607,48 @@ class PyQgsTextRenderer(unittest.TestCase):
|
||||
format.setSize(30)
|
||||
assert self.checkRender(format, 'rect_html', rect=QRectF(100, 100, 100, 100), text=['first <span style="font-size:50pt">line</span>', 'second <span style="font-size:50pt">line</span>', 'third line'])
|
||||
|
||||
def testDrawDocumentRect(self):
|
||||
"""
|
||||
Test drawing text document in rect mode
|
||||
"""
|
||||
format = QgsTextFormat()
|
||||
format.setFont(getTestFont('bold'))
|
||||
format.setAllowHtmlFormatting(True)
|
||||
format.setSize(30)
|
||||
|
||||
image = QImage(400, 400, QImage.Format_RGB32)
|
||||
|
||||
painter = QPainter()
|
||||
ms = QgsMapSettings()
|
||||
ms.setExtent(QgsRectangle(0, 0, 50, 50))
|
||||
ms.setOutputSize(image.size())
|
||||
context = QgsRenderContext.fromMapSettings(ms)
|
||||
context.setPainter(painter)
|
||||
context.setScaleFactor(96 / 25.4) # 96 DPI
|
||||
context.setFlag(QgsRenderContext.ApplyScalingWorkaroundForTextRendering, True)
|
||||
|
||||
painter.begin(image)
|
||||
painter.setRenderHint(QPainter.Antialiasing)
|
||||
image.fill(QColor(152, 219, 249))
|
||||
|
||||
painter.setBrush(QBrush(QColor(182, 239, 255)))
|
||||
painter.setPen(Qt.NoPen)
|
||||
|
||||
doc = QgsTextDocument.fromHtml(['first <span style="font-size:50pt">line</span>', 'second <span style="font-size:50pt">line</span>', 'third line'])
|
||||
|
||||
metrics = QgsTextDocumentMetrics.calculateMetrics(doc, format, context, QgsTextRenderer.FONT_WORKAROUND_SCALE)
|
||||
|
||||
QgsTextRenderer.drawDocument(QRectF(100, 100, 100, 100),
|
||||
format,
|
||||
doc,
|
||||
metrics,
|
||||
context,
|
||||
mode=Qgis.TextLayoutMode.Rectangle)
|
||||
|
||||
painter.end()
|
||||
|
||||
self.assertTrue(self.imageCheck('draw_document_rect', 'draw_document_rect', image))
|
||||
|
||||
def testDrawRectCapHeightMode(self):
|
||||
"""
|
||||
Test drawing text in rect mode with cap height based line heights
|
||||
@ -1624,6 +1668,48 @@ class PyQgsTextRenderer(unittest.TestCase):
|
||||
format.setSize(30)
|
||||
assert self.checkRender(format, 'rect_cap_height_mode_html', rect=QRectF(100, 100, 100, 100), text=['first <span style="font-size:50pt">line</span>', 'second <span style="font-size:50pt">line</span>', 'third line'], mode=Qgis.TextLayoutMode.RectangleCapHeightBased)
|
||||
|
||||
def testDrawDocumentRectCapHeightMode(self):
|
||||
"""
|
||||
Test drawing text document in rect cap height mode
|
||||
"""
|
||||
format = QgsTextFormat()
|
||||
format.setFont(getTestFont('bold'))
|
||||
format.setAllowHtmlFormatting(True)
|
||||
format.setSize(30)
|
||||
|
||||
image = QImage(400, 400, QImage.Format_RGB32)
|
||||
|
||||
painter = QPainter()
|
||||
ms = QgsMapSettings()
|
||||
ms.setExtent(QgsRectangle(0, 0, 50, 50))
|
||||
ms.setOutputSize(image.size())
|
||||
context = QgsRenderContext.fromMapSettings(ms)
|
||||
context.setPainter(painter)
|
||||
context.setScaleFactor(96 / 25.4) # 96 DPI
|
||||
context.setFlag(QgsRenderContext.ApplyScalingWorkaroundForTextRendering, True)
|
||||
|
||||
painter.begin(image)
|
||||
painter.setRenderHint(QPainter.Antialiasing)
|
||||
image.fill(QColor(152, 219, 249))
|
||||
|
||||
painter.setBrush(QBrush(QColor(182, 239, 255)))
|
||||
painter.setPen(Qt.NoPen)
|
||||
|
||||
doc = QgsTextDocument.fromHtml(['first <span style="font-size:50pt">line</span>', 'second <span style="font-size:50pt">line</span>', 'third line'])
|
||||
|
||||
metrics = QgsTextDocumentMetrics.calculateMetrics(doc, format, context, QgsTextRenderer.FONT_WORKAROUND_SCALE)
|
||||
|
||||
QgsTextRenderer.drawDocument(QRectF(100, 100, 100, 100),
|
||||
format,
|
||||
doc,
|
||||
metrics,
|
||||
context,
|
||||
mode=Qgis.TextLayoutMode.RectangleCapHeightBased)
|
||||
|
||||
painter.end()
|
||||
|
||||
self.assertTrue(self.imageCheck('draw_document_rect_cap_height', 'draw_document_rect_cap_height', image))
|
||||
|
||||
def testDrawRectAscentMode(self):
|
||||
"""
|
||||
Test drawing text in rect mode with cap height based line heights
|
||||
@ -1643,6 +1729,48 @@ class PyQgsTextRenderer(unittest.TestCase):
|
||||
format.setSize(30)
|
||||
assert self.checkRender(format, 'rect_ascent_mode_html', rect=QRectF(100, 100, 100, 100), text=['first <span style="font-size:50pt">line</span>', 'second <span style="font-size:50pt">line</span>', 'third line'], mode=Qgis.TextLayoutMode.RectangleAscentBased)
|
||||
|
||||
def testDrawDocumentRectAscentMode(self):
|
||||
"""
|
||||
Test drawing text document in rect ascent mode
|
||||
"""
|
||||
format = QgsTextFormat()
|
||||
format.setFont(getTestFont('bold'))
|
||||
format.setAllowHtmlFormatting(True)
|
||||
format.setSize(30)
|
||||
|
||||
image = QImage(400, 400, QImage.Format_RGB32)
|
||||
|
||||
painter = QPainter()
|
||||
ms = QgsMapSettings()
|
||||
ms.setExtent(QgsRectangle(0, 0, 50, 50))
|
||||
ms.setOutputSize(image.size())
|
||||
context = QgsRenderContext.fromMapSettings(ms)
|
||||
context.setPainter(painter)
|
||||
context.setScaleFactor(96 / 25.4) # 96 DPI
|
||||
context.setFlag(QgsRenderContext.ApplyScalingWorkaroundForTextRendering, True)
|
||||
|
||||
painter.begin(image)
|
||||
painter.setRenderHint(QPainter.Antialiasing)
|
||||
image.fill(QColor(152, 219, 249))
|
||||
|
||||
painter.setBrush(QBrush(QColor(182, 239, 255)))
|
||||
painter.setPen(Qt.NoPen)
|
||||
|
||||
doc = QgsTextDocument.fromHtml(['first <span style="font-size:50pt">line</span>', 'second <span style="font-size:50pt">line</span>', 'third line'])
|
||||
|
||||
metrics = QgsTextDocumentMetrics.calculateMetrics(doc, format, context, QgsTextRenderer.FONT_WORKAROUND_SCALE)
|
||||
|
||||
QgsTextRenderer.drawDocument(QRectF(100, 100, 100, 100),
|
||||
format,
|
||||
doc,
|
||||
metrics,
|
||||
context,
|
||||
mode=Qgis.TextLayoutMode.RectangleAscentBased)
|
||||
|
||||
painter.end()
|
||||
|
||||
self.assertTrue(self.imageCheck('draw_document_rect_ascent', 'draw_document_rect_ascent', image))
|
||||
|
||||
def testDrawForcedItalic(self):
|
||||
"""
|
||||
Test drawing with forced italic
|
||||
|
BIN
tests/testdata/control_images/text_renderer/draw_document_rect/draw_document_rect.png
vendored
Normal file
BIN
tests/testdata/control_images/text_renderer/draw_document_rect/draw_document_rect.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
tests/testdata/control_images/text_renderer/draw_document_rect_ascent/draw_document_rect_ascent.png
vendored
Normal file
BIN
tests/testdata/control_images/text_renderer/draw_document_rect_ascent/draw_document_rect_ascent.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Loading…
x
Reference in New Issue
Block a user