diff --git a/weasyprint/layout/inlines.py b/weasyprint/layout/inlines.py index 37a6dd053..65fc1fff2 100644 --- a/weasyprint/layout/inlines.py +++ b/weasyprint/layout/inlines.py @@ -246,6 +246,13 @@ def remove_last_whitespace(context, box): assert resume is None space_width = box.width - new_box.width box.width = new_box.width + if new_box.pango_layout.first_line_direction % 2: + # RTL line, the trailing space is at the left of the box. We have + # to translate the box to align the stripped text with the right + # edge of the box. + box.position_x -= space_width + for ancestor in ancestors: + ancestor.position_x -= space_width else: space_width = box.width box.width = 0 diff --git a/weasyprint/tests/test_draw/test_text.py b/weasyprint/tests/test_draw/test_text.py index ca057bd44..2391d4e47 100644 --- a/weasyprint/tests/test_draw/test_text.py +++ b/weasyprint/tests/test_draw/test_text.py @@ -88,3 +88,29 @@ def test_text_overflow_ellipsis():
abcde
abcde
''') + + +def test_text_align_rtl_trailing_whitespace(): + # Test text alignment for rtl text with trailing space. + # Test regression: https://github.com/Kozea/WeasyPrint/issues/1111 + assert_pixels('text_overflow', 9, 9, ''' + _________ + _rrrrBBB_ + _________ + _rrrrBBB_ + _________ + _________ + _________ + _________ + _________ + ''', ''' + +

abc

+ +

‏abc

+ ''') diff --git a/weasyprint/text.py b/weasyprint/text.py index 160507f6b..5c7c84c9d 100644 --- a/weasyprint/text.py +++ b/weasyprint/text.py @@ -110,7 +110,9 @@ PangoLayout *layout; gint start_index; gint length; - /* ... */ + void *runs; + guint is_paragraph_start : 1; + guint resolved_dir : 3; } PangoLayoutLine; typedef struct { @@ -654,6 +656,7 @@ def setup(self, context, font_size, style): self.context = context self.style = style + self.first_line_direction = 0 # Cairo crashes with font-size: 0 when using Win32 API # See https://github.com/Kozea/WeasyPrint/pull/599 @@ -739,6 +742,7 @@ def get_first_line(self): index = second_line.start_index else: index = None + self.first_line_direction = first_line.resolved_dir return first_line, index def set_text(self, text, justify=False):