diff --git a/pyproject.toml b/pyproject.toml index 430cdccf..b7564a4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,7 @@ build-backend = 'flit_core.buildapi' [project] name = 'weasyprint' +description = 'The Awesome Document Factory' keywords = ['html', 'css', 'pdf', 'converter'] authors = [{name = 'Simon Sapin', email = 'simon.sapin@exyr.org'}] maintainers = [{name = 'CourtBouillon', email = 'contact@courtbouillon.org'}] @@ -39,15 +40,15 @@ classifiers = [ 'Topic :: Multimedia :: Graphics :: Graphics Conversion', 'Topic :: Printing', ] -dynamic = ['version', 'description'] +dynamic = ['version'] [project.urls] -home-page = 'https://www.courtbouillon.org/weasyprint' -documentation = 'https://doc.courtbouillon.org/weasyprint/' -code = 'https://github.com/Kozea/WeasyPrint' -issues = 'https://github.com/Kozea/WeasyPrint/issues' -changelog = 'https://github.com/Kozea/WeasyPrint/releases' -donation = 'https://opencollective.com/courtbouillon' +Homepage = 'https://www.courtbouillon.org/weasyprint' +Documentation = 'https://doc.courtbouillon.org/weasyprint/' +Code = 'https://github.com/Kozea/WeasyPrint' +Issues = 'https://github.com/Kozea/WeasyPrint/issues' +Changelog = 'https://github.com/Kozea/WeasyPrint/releases' +Donation = 'https://opencollective.com/courtbouillon' [project.optional-dependencies] doc = ['sphinx', 'sphinx_rtd_theme'] diff --git a/tests/test_draw/svg/test_text.py b/tests/test_draw/svg/test_text.py index b853e8b7..c1dca3af 100644 --- a/tests/test_draw/svg/test_text.py +++ b/tests/test_draw/svg/test_text.py @@ -6,28 +6,201 @@ """ +import pytest + from ...testing_utils import assert_no_logs from .. import assert_pixels @assert_no_logs def test_text_fill(): - assert_pixels('text_fill', 20, 6, ''' + assert_pixels('text_fill', 20, 2, ''' BBBBBB__BBBBBB______ BBBBBB__BBBBBB______ - ____________________ - ____________________ - ____________________ - ____________________ ''', ''' - - + + ABC DEF ''') + + +@pytest.mark.xfail +@assert_no_logs +def test_text_stroke(): + assert_pixels('text_fill', 20, 4, ''' + BBBBBBBBBBBB________ + BBBBBBBBBBBB________ + BBBBBBBBBBBB________ + BBBBBBBBBBBB________ + ''', ''' + + + + A B C + + + ''') + + +@assert_no_logs +def test_text_x(): + assert_pixels('text_x', 20, 2, ''' + BB__BB_BBBB_________ + BB__BB_BBBB_________ + ''', ''' + + + + ABCD + + + ''') + + +@assert_no_logs +def test_text_y(): + assert_pixels('text_y', 30, 10, ''' + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + BBBBBBBBBB_____BBBBB__________ + BBBBBBBBBB_____BBBBB__________ + BBBBBBBBBB_____BBBBB__________ + BBBBBBBBBB_____BBBBB__________ + BBBBBBBBBB_____BBBBB__________ + ''', ''' + + + + ABCDEF + + + ''') + + +@assert_no_logs +def test_text_xy(): + assert_pixels('text_xy', 30, 10, ''' + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + BBBBB__________BBBBB__________ + BBBBB__________BBBBB__________ + BBBBB__________BBBBB__________ + BBBBB__________BBBBB__________ + BBBBB__________BBBBB__________ + ''', ''' + + + + ABCDE + + + ''') + + +@assert_no_logs +def test_text_dx(): + assert_pixels('text_dx', 20, 2, ''' + BB__BB_BBBB_________ + BB__BB_BBBB_________ + ''', ''' + + + + ABCD + + + ''') + + +@assert_no_logs +def test_text_dy(): + assert_pixels('text_dy', 30, 10, ''' + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + BBBBBBBBBB_____BBBBB__________ + BBBBBBBBBB_____BBBBB__________ + BBBBBBBBBB_____BBBBB__________ + BBBBBBBBBB_____BBBBB__________ + BBBBBBBBBB_____BBBBB__________ + ''', ''' + + + + ABCDEF + + + ''') + + +@assert_no_logs +def test_text_dx_dy(): + assert_pixels('text_dx_dy', 30, 10, ''' + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + __________BBBBB_____BBBBBBBBBB + BBBBB__________BBBBB__________ + BBBBB__________BBBBB__________ + BBBBB__________BBBBB__________ + BBBBB__________BBBBB__________ + BBBBB__________BBBBB__________ + ''', ''' + + + + ABCDE + + + ''') diff --git a/weasyprint/__init__.py b/weasyprint/__init__.py index 79c6636e..7da8c1c1 100644 --- a/weasyprint/__init__.py +++ b/weasyprint/__init__.py @@ -30,7 +30,7 @@ if hasattr(sys, 'frozen'): # pragma: no cover else: ROOT = Path(os.path.dirname(__file__)) -VERSION = __version__ = '53.0a0' +VERSION = __version__ = '53.0a1' __all__ = [ 'HTML', 'CSS', 'Attachment', 'Document', 'Page', 'default_url_fetcher', diff --git a/weasyprint/svg/text.py b/weasyprint/svg/text.py index 700f2c52..2e3b0688 100644 --- a/weasyprint/svg/text.py +++ b/weasyprint/svg/text.py @@ -68,18 +68,18 @@ def text(svg, node, font_size): # Get rotations and translations x, y, dx, dy, rotate = [], [], [], [], [0] - if 'x' in node: + if 'x' in node.attrib: x = [size(i, font_size, svg.concrete_width) - for i in normalize(node['x']).strip().split(' ')] - if 'y' in node: + for i in normalize(node.attrib['x']).strip().split(' ')] + if 'y' in node.attrib: y = [size(i, font_size, svg.concrete_height) - for i in normalize(node['y']).strip().split(' ')] - if 'dx' in node: + for i in normalize(node.attrib['y']).strip().split(' ')] + if 'dx' in node.attrib: dx = [size(i, font_size, svg.concrete_width) - for i in normalize(node['dx']).strip().split(' ')] - if 'dy' in node: + for i in normalize(node.attrib['dx']).strip().split(' ')] + if 'dy' in node.attrib: dy = [size(i, font_size, svg.concrete_height) - for i in normalize(node['dy']).strip().split(' ')] + for i in normalize(node.attrib['dy']).strip().split(' ')] if 'rotate' in node: rotate = [radians(float(i)) if i else 0 for i in normalize(node['rotate']).strip().split(' ')] @@ -191,7 +191,6 @@ def text(svg, node, font_size): svg.stream.transform( cos(angle), sin(angle), -sin(angle), cos(angle), 0, 0) svg.stream.transform(1, 0, 0, 1, 0, svg.cursor_d_position[1]) - svg.stream.move_to(0, 0) bounding_box = extend_bounding_box( bounding_box, ((end_point[0], width),)) else: @@ -200,9 +199,6 @@ def text(svg, node, font_size): y = svg.cursor_position[1] if y is None else y if i: x += letter_spacing - svg.stream.move_to( - x + svg.cursor_d_position[0] + x_align, - y + svg.cursor_d_position[1] + y_align) cursor_position = x + width, y angle = last_r if r is None else r svg.stream.transform( @@ -223,7 +219,8 @@ def text(svg, node, font_size): svg.stream.set_color_rgb(red, green, blue) svg.stream.set_alpha(alpha) draw_first_line( - svg.stream, TextBox(layout, style), 'none', 'none', x, y) + svg.stream, TextBox(layout, style), 'none', 'none', + x + svg.cursor_d_position[0], y + svg.cursor_d_position[1]) svg.stream.pop_state() if not text_path: svg.cursor_position = cursor_position