Skip to content

Commit cfd8518

Browse files
committed
Fix data defined size in layout labels is not respected
Fixes qgis#55958
1 parent 40ff5bb commit cfd8518

File tree

3 files changed

+53
-33
lines changed

3 files changed

+53
-33
lines changed

src/core/textrenderer/qgstextrenderer.cpp

+38-33
Original file line numberDiff line numberDiff line change
@@ -82,33 +82,35 @@ int QgsTextRenderer::sizeToPixel( double size, const QgsRenderContext &c, Qgis::
8282
return static_cast< int >( c.convertToPainterUnits( size, unit, mapUnitScale ) + 0.5 ); //NOLINT
8383
}
8484

85-
void QgsTextRenderer::drawText( const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &text, QgsRenderContext &context, const QgsTextFormat &format, bool, Qgis::TextVerticalAlignment vAlignment, Qgis::TextRendererFlags flags,
85+
void QgsTextRenderer::drawText( const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &text, QgsRenderContext &context, const QgsTextFormat &_format, bool, Qgis::TextVerticalAlignment vAlignment, Qgis::TextRendererFlags flags,
8686
Qgis::TextLayoutMode mode )
8787
{
88-
QgsTextFormat tmpFormat = format;
89-
if ( format.dataDefinedProperties().hasActiveProperties() ) // note, we use format instead of tmpFormat here, it's const and potentially avoids a detach
90-
tmpFormat.updateDataDefinedProperties( context );
88+
QgsTextFormat lFormat = _format;
89+
if ( _format.dataDefinedProperties().hasActiveProperties() ) // note, we use format instead of tmpFormat here, it's const and potentially avoids a detach
90+
lFormat.updateDataDefinedProperties( context );
91+
92+
// DO NOT USE _format in the following code, always use lFormat!!
9193

9294
QStringList textLines;
9395
for ( const QString &line : text )
9496
{
95-
if ( flags & Qgis::TextRendererFlag::WrapLines && textRequiresWrapping( context, line, rect.width(), format ) )
97+
if ( flags & Qgis::TextRendererFlag::WrapLines && textRequiresWrapping( context, line, rect.width(), lFormat ) )
9698
{
97-
textLines.append( wrappedText( context, line, rect.width(), format ) );
99+
textLines.append( wrappedText( context, line, rect.width(), lFormat ) );
98100
}
99101
else
100102
{
101103
textLines.append( line );
102104
}
103105
}
104106

105-
QgsTextDocument document = format.allowHtmlFormatting() ? QgsTextDocument::fromHtml( textLines ) : QgsTextDocument::fromPlainText( textLines );
106-
document.applyCapitalization( format.capitalization() );
107+
QgsTextDocument document = lFormat.allowHtmlFormatting() ? QgsTextDocument::fromHtml( textLines ) : QgsTextDocument::fromPlainText( textLines );
108+
document.applyCapitalization( lFormat.capitalization() );
107109

108-
const double fontScale = calculateScaleFactorForFormat( context, format );
109-
const QgsTextDocumentMetrics metrics = QgsTextDocumentMetrics::calculateMetrics( document, format, context, fontScale );
110+
const double fontScale = calculateScaleFactorForFormat( context, lFormat );
111+
const QgsTextDocumentMetrics metrics = QgsTextDocumentMetrics::calculateMetrics( document, lFormat, context, fontScale );
110112

111-
drawDocument( rect, tmpFormat, document, metrics, context, alignment, vAlignment, rotation, mode, flags );
113+
drawDocument( rect, lFormat, document, metrics, context, alignment, vAlignment, rotation, mode, flags );
112114
}
113115

114116
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 )
@@ -128,43 +130,46 @@ void QgsTextRenderer::drawDocument( const QRectF &rect, const QgsTextFormat &for
128130
drawPart( rect, rotation, horizontalAlignment, verticalAlignment, document, metrics, context, tmpFormat, Qgis::TextComponent::Text, mode );
129131
}
130132

131-
void QgsTextRenderer::drawText( QPointF point, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool )
133+
void QgsTextRenderer::drawText( QPointF point, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &_format, bool )
132134
{
133-
QgsTextFormat tmpFormat = format;
134-
if ( format.dataDefinedProperties().hasActiveProperties() ) // note, we use format instead of tmpFormat here, it's const and potentially avoids a detach
135-
tmpFormat.updateDataDefinedProperties( context );
136-
tmpFormat = updateShadowPosition( tmpFormat );
135+
QgsTextFormat lFormat = _format;
136+
if ( _format.dataDefinedProperties().hasActiveProperties() ) // note, we use _format instead of tmpFormat here, it's const and potentially avoids a detach
137+
lFormat.updateDataDefinedProperties( context );
138+
lFormat = updateShadowPosition( lFormat );
137139

138-
QgsTextDocument document = format.allowHtmlFormatting() ? QgsTextDocument::fromHtml( textLines ) : QgsTextDocument::fromPlainText( textLines );
139-
document.applyCapitalization( format.capitalization() );
140-
const double fontScale = calculateScaleFactorForFormat( context, format );
141-
const QgsTextDocumentMetrics metrics = QgsTextDocumentMetrics::calculateMetrics( document, format, context, fontScale );
140+
// DO NOT USE _format in the following code, always use lFormat!!
141+
QgsTextDocument document = lFormat.allowHtmlFormatting() ? QgsTextDocument::fromHtml( textLines ) : QgsTextDocument::fromPlainText( textLines );
142+
document.applyCapitalization( lFormat.capitalization() );
143+
const double fontScale = calculateScaleFactorForFormat( context, lFormat );
144+
const QgsTextDocumentMetrics metrics = QgsTextDocumentMetrics::calculateMetrics( document, lFormat, context, fontScale );
142145

143-
if ( tmpFormat.background().enabled() )
146+
if ( lFormat.background().enabled() )
144147
{
145-
drawPart( point, rotation, alignment, document, metrics, context, tmpFormat, Qgis::TextComponent::Background, Qgis::TextLayoutMode::Point );
148+
drawPart( point, rotation, alignment, document, metrics, context, lFormat, Qgis::TextComponent::Background, Qgis::TextLayoutMode::Point );
146149
}
147150

148-
if ( tmpFormat.buffer().enabled() )
151+
if ( lFormat.buffer().enabled() )
149152
{
150-
drawPart( point, rotation, alignment, document, metrics, context, tmpFormat, Qgis::TextComponent::Buffer, Qgis::TextLayoutMode::Point );
153+
drawPart( point, rotation, alignment, document, metrics, context, lFormat, Qgis::TextComponent::Buffer, Qgis::TextLayoutMode::Point );
151154
}
152155

153-
drawPart( point, rotation, alignment, document, metrics, context, tmpFormat, Qgis::TextComponent::Text, Qgis::TextLayoutMode::Point );
156+
drawPart( point, rotation, alignment, document, metrics, context, lFormat, Qgis::TextComponent::Text, Qgis::TextLayoutMode::Point );
154157
}
155158

156-
void QgsTextRenderer::drawTextOnLine( const QPolygonF &line, const QString &text, QgsRenderContext &context, const QgsTextFormat &format, double offsetAlongLine, double offsetFromLine )
159+
void QgsTextRenderer::drawTextOnLine( const QPolygonF &line, const QString &text, QgsRenderContext &context, const QgsTextFormat &_format, double offsetAlongLine, double offsetFromLine )
157160
{
158-
QgsTextFormat tmpFormat = format;
159-
if ( format.dataDefinedProperties().hasActiveProperties() ) // note, we use format instead of tmpFormat here, it's const and potentially avoids a detach
160-
tmpFormat.updateDataDefinedProperties( context );
161-
tmpFormat = updateShadowPosition( tmpFormat );
161+
QgsTextFormat lFormat = _format;
162+
if ( _format.dataDefinedProperties().hasActiveProperties() ) // note, we use _format instead of tmpFormat here, it's const and potentially avoids a detach
163+
lFormat.updateDataDefinedProperties( context );
164+
lFormat = updateShadowPosition( lFormat );
165+
166+
// DO NOT USE _format in the following code, always use lFormat!!
162167

163168
// todo handle newlines??
164-
QgsTextDocument document = format.allowHtmlFormatting() ? QgsTextDocument::fromHtml( { text } ) : QgsTextDocument::fromPlainText( { text } );
165-
document.applyCapitalization( format.capitalization() );
169+
QgsTextDocument document = lFormat.allowHtmlFormatting() ? QgsTextDocument::fromHtml( { text } ) : QgsTextDocument::fromPlainText( { text } );
170+
document.applyCapitalization( lFormat.capitalization() );
166171

167-
drawDocumentOnLine( line, tmpFormat, document, context, offsetAlongLine, offsetFromLine );
172+
drawDocumentOnLine( line, lFormat, document, context, offsetAlongLine, offsetFromLine );
168173
}
169174

170175
void QgsTextRenderer::drawDocumentOnLine( const QPolygonF &line, const QgsTextFormat &format, const QgsTextDocument &document, QgsRenderContext &context, double offsetAlongLine, double offsetFromLine )

tests/src/python/test_qgstextrenderer.py

+15
Original file line numberDiff line numberDiff line change
@@ -4024,6 +4024,21 @@ def testDrawTextOnCurvedLineOffsetFromLinePositive(self):
40244024
painter.end()
40254025
self.assertTrue(self.image_check('text_on_curved_line_offset_line_positive', 'text_on_curved_line_offset_line_positive', image, 'text_on_curved_line_offset_line_positive'))
40264026

4027+
def testDrawTextDataDefinedProperties(self):
4028+
format = QgsTextFormat()
4029+
format.setFont(getTestFont('bold'))
4030+
format.setSize(16)
4031+
format.setSizeUnit(QgsUnitTypes.RenderUnit.RenderPoints)
4032+
4033+
format.dataDefinedProperties().setProperty(
4034+
QgsPalLayerSettings.Property.Size,
4035+
QgsProperty.fromExpression('90*1.5')
4036+
)
4037+
4038+
assert self.checkRender(format, 'datadefined_render', None,
4039+
text=['1234', '5678'], rect=QRectF(40, 20, 350, 350),
4040+
alignment=QgsTextRenderer.HAlignment.AlignRight)
4041+
40274042

40284043
if __name__ == '__main__':
40294044
unittest.main()
Loading

0 commit comments

Comments
 (0)