• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from __future__ import print_function, absolute_import, division
2
3from fontTools.misc.py23 import *
4from fontTools.svgLib.path import shapes
5from fontTools.misc import etree
6import pytest
7
8
9@pytest.mark.parametrize(
10    "svg_xml, expected_path, expected_transform",
11    [
12        # path: direct passthrough
13        (
14            "<path d='I love kittens'/>",
15            "I love kittens",
16            None
17        ),
18        # path no @d
19        (
20            "<path duck='Mallard'/>",
21            None,
22            None
23        ),
24        # line
25        (
26            '<line x1="10" x2="50" y1="110" y2="150"/>',
27            'M10,110 L50,150',
28            None
29        ),
30        # line, decimal positioning
31        (
32            '<line x1="10.0" x2="50.5" y1="110.2" y2="150.7"/>',
33            'M10,110.2 L50.5,150.7',
34            None
35        ),
36        # rect: minimal valid example
37        (
38            "<rect width='1' height='1'/>",
39            "M0,0 H1 V1 H0 V0 z",
40            None
41        ),
42        # rect: sharp corners
43        (
44            "<rect x='10' y='11' width='17' height='11'/>",
45            "M10,11 H27 V22 H10 V11 z",
46            None
47        ),
48        # rect: round corners
49        (
50            "<rect x='9' y='9' width='11' height='7' rx='2'/>",
51            "M11,9 H18 A2,2 0 0 1 20,11 V14 A2,2 0 0 1 18,16 H11"
52            " A2,2 0 0 1 9,14 V11 A2,2 0 0 1 11,9 z",
53            None
54        ),
55        # rect: simple
56        (
57            "<rect x='11.5' y='16' width='11' height='2'/>",
58            "M11.5,16 H22.5 V18 H11.5 V16 z",
59            None
60        ),
61        # rect: the one above plus a rotation
62        (
63            "<rect x='11.5' y='16' transform='matrix(0.7071 -0.7071 0.7071 0.7071 -7.0416 16.9999)' width='11' height='2'/>",
64            "M11.5,16 H22.5 V18 H11.5 V16 z",
65            (0.7071, -0.7071, 0.7071, 0.7071, -7.0416, 16.9999)
66        ),
67        # polygon
68        (
69            "<polygon points='30,10 50,30 10,30'/>",
70            "M30,10 50,30 10,30 z",
71            None
72        ),
73        # polyline
74        (
75            "<polyline points='30,10 50,30 10,30'/>",
76            "M30,10 50,30 10,30",
77            None
78        ),
79        # circle, minimal valid example
80        (
81            "<circle r='1'/>",
82            "M-1,0 A1,1 0 1 1 1,0 A1,1 0 1 1 -1,0",
83            None
84        ),
85        # circle
86        (
87            "<circle cx='600' cy='200' r='100'/>",
88            "M500,200 A100,100 0 1 1 700,200 A100,100 0 1 1 500,200",
89            None
90        ),
91        # circle, decimal positioning
92        (
93            "<circle cx='12' cy='6.5' r='1.5'></circle>",
94            "M10.5,6.5 A1.5,1.5 0 1 1 13.5,6.5 A1.5,1.5 0 1 1 10.5,6.5",
95            None
96        ),
97        # circle, with transform
98        (
99            '<circle transform="matrix(0.9871 -0.1602 0.1602 0.9871 -7.525 8.6516)" cx="49.9" cy="51" r="14.3"/>',
100            'M35.6,51 A14.3,14.3 0 1 1 64.2,51 A14.3,14.3 0 1 1 35.6,51',
101            (0.9871, -0.1602, 0.1602, 0.9871, -7.525, 8.6516)
102        ),
103        # ellipse
104        (
105            '<ellipse cx="100" cy="50" rx="100" ry="50"/>',
106            'M0,50 A100,50 0 1 1 200,50 A100,50 0 1 1 0,50',
107            None
108        ),
109        # ellipse, decimal positioning
110        (
111            '<ellipse cx="100.5" cy="50" rx="10" ry="50.5"/>',
112            'M90.5,50 A10,50.5 0 1 1 110.5,50 A10,50.5 0 1 1 90.5,50',
113            None
114        ),
115        # ellipse, with transform
116        (
117            '<ellipse transform="matrix(0.9557 -0.2945 0.2945 0.9557 -14.7694 20.1454)" cx="59.5" cy="59.1" rx="30.9" ry="11.9"/>',
118            'M28.6,59.1 A30.9,11.9 0 1 1 90.4,59.1 A30.9,11.9 0 1 1 28.6,59.1',
119            (0.9557, -0.2945, 0.2945, 0.9557, -14.7694, 20.1454)
120        ),
121    ]
122)
123def test_el_to_path(svg_xml, expected_path, expected_transform):
124    pb = shapes.PathBuilder()
125    pb.add_path_from_element(etree.fromstring(svg_xml))
126    if expected_path:
127        expected_paths = [expected_path]
128        expected_transforms = [expected_transform]
129    else:
130        expected_paths = []
131        expected_transforms = []
132    assert pb.paths == expected_paths
133    assert pb.transforms == expected_transforms
134