Skip to content

Commit

Permalink
Ensure that we handle text-anchor only on text content elements
Browse files Browse the repository at this point in the history
As asked by the SVG specification.

Fix #2375.
  • Loading branch information
liZe committed Feb 6, 2025
1 parent 9a8a71b commit 00dda6a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
20 changes: 20 additions & 0 deletions tests/draw/svg/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,26 @@ def test_text_anchor_middle_end_tspan(assert_pixels):
''')


@assert_no_logs
def test_text_tspan_anchor_non_text(assert_pixels):
# Regression test for https://github.com/Kozea/WeasyPrint/issues/2375
assert_pixels('''
_______BBBBBB_______
_______BBBBBB_______
''', '''
<style>
@page { size: 20px 2px }
svg { display: block }
</style>
<svg width="20px" height="2px" text-anchor="end"
xmlns="http://www.w3.org/2000/svg">
<text x="10" y="10" font-family="weasyprint" font-size="2" text-anchor="start">
<tspan x="10" y="1.5" text-anchor="middle" fill="blue">ABC</tspan>
</text>
</svg>
''')


@assert_no_logs
def test_text_rotate(assert_pixels):
assert_pixels('''
Expand Down
20 changes: 10 additions & 10 deletions weasyprint/svg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,14 +444,14 @@ def draw_node(self, node, font_size, fill_stroke=True):
if new_ctm.determinant:
self.stream.transform(*(old_ctm @ new_ctm.invert).values)

# Handle text anchor
if (text_anchor := node.get('text-anchor')) in ('middle', 'end'):
group = self.stream.add_group(0, 0, 0, 0) # BBox set after drawing
original_streams.append(self.stream)
self.stream = group

# Set text bounding box
# Handle text anchor and set text bounding box
text_anchor_shift = False
if node.display and TAGS.get(node.tag) == text:
if (text_anchor := node.get('text-anchor')) in ('middle', 'end'):
text_anchor_shift = True
group = self.stream.add_group(0, 0, 0, 0) # BBox set after drawing
original_streams.append(self.stream)
self.stream = group
node.text_bounding_box = EMPTY_BOUNDING_BOX

# Save concrete size of root svg tag
Expand All @@ -467,11 +467,11 @@ def draw_node(self, node, font_size, fill_stroke=True):
# Draw node children
if node.display and node.tag not in DEF_TYPES:
for child in node:
if text_anchor in ('middle', 'end'):
if text_anchor_shift:
new_stream = self.stream
self.stream = original_streams[-1]
self.draw_node(child, font_size, fill_stroke)
if text_anchor in ('middle', 'end'):
if text_anchor_shift:
self.stream = new_stream
visible_text_child = (
TAGS.get(node.tag) == text and
Expand All @@ -491,7 +491,7 @@ def draw_node(self, node, font_size, fill_stroke=True):
self.tree.set_svg_size(svg, concrete_width, concrete_height)

# Handle text anchor
if text_anchor in ('middle', 'end'):
if text_anchor_shift:
group_id = self.stream.id
self.stream = original_streams.pop()
self.stream.push_state()
Expand Down

0 comments on commit 00dda6a

Please sign in to comment.