Skip to content

Commit

Permalink
Fix incorrect buffers drawn for html label items
Browse files Browse the repository at this point in the history
When a layout item uses a html enabled text format and has buffers
enabled, the buffers would be incorrectly horizontally placed
  • Loading branch information
nyalldawson committed May 24, 2024
1 parent b2a8801 commit f30ca52
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/core/textrenderer/qgstextrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ double QgsTextRenderer::drawBuffer( QgsRenderContext &context, const QgsTextRend
const double yOffset = metrics.fragmentVerticalOffset( component.blockIndex, fragmentIndex, mode );
path.addText( xOffset, yOffset, fragmentFont, fragment.text() );

xOffset += metrics.fragmentHorizontalAdvance( component.blockIndex, fragmentIndex, mode );
xOffset += metrics.fragmentHorizontalAdvance( component.blockIndex, fragmentIndex, mode ) * scaleFactor;

fragmentIndex++;
}
Expand Down Expand Up @@ -780,7 +780,7 @@ void QgsTextRenderer::drawMask( QgsRenderContext &context, const QgsTextRenderer
const double fragmentYOffset = metrics.fragmentVerticalOffset( component.blockIndex, fragmentIndex, mode );
path.addText( xOffset, fragmentYOffset, fragmentFont, fragment.text() );

xOffset += metrics.fragmentHorizontalAdvance( component.blockIndex, fragmentIndex, mode );
xOffset += metrics.fragmentHorizontalAdvance( component.blockIndex, fragmentIndex, mode ) * scaleFactor;
fragmentIndex++;
}

Expand Down
62 changes: 61 additions & 1 deletion tests/src/python/test_qgstextrenderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1563,7 +1563,9 @@ def checkRender(self, format, name, part=None, angle=0, alignment=QgsTextRendere
def checkRenderPoint(self, format, name, part=None, angle=0, alignment=QgsTextRenderer.HAlignment.AlignLeft,
text=['test'],
point=QPointF(100, 200),
image_size=400):
image_size=400,
enable_scale_workaround=False,
render_mask=False):
image = QImage(image_size, image_size, QImage.Format.Format_RGB32)

painter = QPainter()
Expand All @@ -1573,6 +1575,10 @@ def checkRenderPoint(self, format, name, part=None, angle=0, alignment=QgsTextRe
context = QgsRenderContext.fromMapSettings(ms)
context.setPainter(painter)
context.setScaleFactor(96 / 25.4) # 96 DPI
if render_mask:
context.setIsGuiPreview(True)

context.setFlag(QgsRenderContext.Flag.ApplyScalingWorkaroundForTextRendering, enable_scale_workaround)

painter.begin(image)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
Expand Down Expand Up @@ -3372,6 +3378,9 @@ def testHtmlFormatting(self):
point=QPointF(50, 200))

def testHtmlFormattingBuffer(self):
"""
Test drawing HTML with buffer
"""
format = QgsTextFormat()
format.setFont(getTestFont('bold'))
format.setSize(60)
Expand All @@ -3385,6 +3394,57 @@ def testHtmlFormattingBuffer(self):
'<s>t</s><span style="text-decoration: overline">e</span><span style="color: red">s<span style="text-decoration: underline">t</span></span>'],
point=QPointF(50, 200))

def testHtmlFormattingBufferScaleFactor(self):
"""
Test drawing HTML with scale factor workaround
"""
format = QgsTextFormat()
format.setFont(getTestFont('bold'))
# font sizes < 50 pixel trigger the scale factor workaround
format.setSize(49)
format.setSizeUnit(QgsUnitTypes.RenderUnit.RenderPixels)
format.setColor(QColor(0, 255, 0))
format.setAllowHtmlFormatting(True)
format.buffer().setEnabled(True)
format.buffer().setSize(5)
format.buffer().setColor(QColor(50, 150, 200))
assert self.checkRenderPoint(format, 'text_html_formatting_buffer_scale_workaround', None, text=[
't <span style="font-size:60pt">e</span> <span style="color: red">s</span>'],
point=QPointF(50, 200), enable_scale_workaround=True)

def testHtmlFormattingMask(self):
"""
Test drawing HTML with mask
"""
format = QgsTextFormat()
format.setFont(getTestFont('bold'))
format.setSize(60)
format.setSizeUnit(QgsUnitTypes.RenderUnit.RenderPoints)
format.setColor(QColor(0, 255, 0))
format.setAllowHtmlFormatting(True)
format.mask().setEnabled(True)
format.mask().setSize(5)
assert self.checkRenderPoint(format, 'text_html_formatting_mask', None, text=[
't <span style="font-size:60pt">e</span> <span style="color: red">s</span>'],
point=QPointF(50, 200), render_mask=True)

def testHtmlFormattingMaskScaleFactor(self):
"""
Test drawing HTML with mask with scale factor workaround
"""
format = QgsTextFormat()
format.setFont(getTestFont('bold'))
# font sizes < 50 pixel trigger the scale factor workaround
format.setSize(49)
format.setSizeUnit(QgsUnitTypes.RenderUnit.RenderPixels)
format.setColor(QColor(0, 255, 0))
format.setAllowHtmlFormatting(True)
format.mask().setEnabled(True)
format.mask().setSize(5)
assert self.checkRenderPoint(format, 'text_html_formatting_mask_scale_workaround', None, text=[
't <span style="font-size:60pt">e</span> <span style="color: red">s</span>'],
point=QPointF(50, 200), render_mask=True, enable_scale_workaround=True)

def testHtmlFormattingShadow(self):
format = QgsTextFormat()
format.setFont(getTestFont('bold'))
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f30ca52

Please sign in to comment.