1#  Copyright (c) 2021, Manfred Moitzi
2#  License: MIT License
3
4import pytest
5
6pytest.importorskip('PyQt5')
7
8from PyQt5.QtGui import QPainterPath
9from PyQt5.QtCore import QPointF
10from ezdxf import path
11from ezdxf.math import quadratic_to_cubic_bezier, Bezier3P
12
13
14class TestToQPainterPath:
15    def test_no_paths(self):
16        with pytest.raises(ValueError):
17            path.to_qpainter_path([])
18
19    def test_line_to(self):
20        p = path.Path()
21        p.line_to((4, 5, 6))
22        p.line_to((7, 8, 6))
23        qpath = path.to_qpainter_path([p])
24        assert qpath.elementCount() == 3
25
26        m = qpath.elementAt(0)
27        assert m.isMoveTo() is True
28        assert (m.x, m.y) == (0, 0)
29
30        l1 = qpath.elementAt(1)
31        assert l1.isLineTo() is True
32        assert (l1.x, l1.y) == (4, 5)
33
34        l2 = qpath.elementAt(2)
35        assert l2.isLineTo() is True
36        assert (l2.x, l2.y) == (7, 8)
37
38    def test_curve3_to(self):
39        bez3 = Bezier3P([(0, 0), (2, 1), (4, 0)])
40        p = path.Path()
41        p.curve3_to(bez3.control_points[2], bez3.control_points[1])
42        qpath = path.to_qpainter_path([p])
43        # Qt converts quadratic bezier curves unto cubic bezier curves
44        assert qpath.elementCount() == 4
45        bez4 = quadratic_to_cubic_bezier(bez3)
46
47        q1 = qpath.elementAt(1)
48        assert q1.isCurveTo()  # start of cure
49        assert q1.x, q1.y == bez4.control_points[1]
50
51        q2 = qpath.elementAt(2)
52        assert q2.type == 3  # curve data element
53        assert q2.x, q2.y == bez4.control_points[2]
54
55        q3 = qpath.elementAt(3)
56        assert q3.type == 3  # curve data element
57        assert q3.x, q3.y == bez4.control_points[2]
58
59    def test_curve4_to(self):
60        bez4 = [(4, 0, 2), (1, 1, 7), (3, 1, 5)]
61        p = path.Path()
62        p.curve4_to(*bez4)
63        qpath = path.to_qpainter_path([p])
64        assert qpath.elementCount() == 4
65        q1 = qpath.elementAt(1)
66        assert q1.isCurveTo()  # start of cure
67        assert q1.x, q1.y == bez4[1]
68
69        q2 = qpath.elementAt(2)
70        assert q2.type == 3  # curve data element
71        assert q2.x, q2.y == bez4[2]
72
73        q3 = qpath.elementAt(3)
74        assert q3.type == 3  # curve data element
75        assert q3.x, q3.y == bez4[0]
76
77    def test_two_paths(self):
78        p1 = path.Path()
79        p1.line_to((4, 5, 6))
80        p2 = path.Path()
81        p2.line_to((7, 8, 6))
82        qpath = path.to_qpainter_path([p1, p2])
83        assert qpath.elementCount() == 4
84        assert qpath.elementAt(0).isMoveTo() is True
85        assert qpath.elementAt(1).isLineTo() is True
86        assert qpath.elementAt(2).isMoveTo() is True
87        assert qpath.elementAt(3).isLineTo() is True
88
89
90class TestFromQPainterPath:
91    def test_line_to(self):
92        qpath = QPainterPath(QPointF(1, 2))
93        qpath.lineTo(4, 5)
94
95        paths = list(path.from_qpainter_path(qpath))
96        p0 = paths[0]
97        assert p0.start == (1, 2)
98        assert p0[0].type == path.Command.LINE_TO
99        assert p0[0].end == (4, 5)
100
101    # Qt converts quadratic Bezier curves into cubic Bezier curves
102    # no need to test quadTo()
103    def test_cubic_to(self):
104        qpath = QPainterPath(QPointF(0, 0))
105        qpath.cubicTo(QPointF(1, 1), QPointF(3, 1), QPointF(4, 0), )
106
107        paths = list(path.from_qpainter_path(qpath))
108        p0 = paths[0]
109        assert p0.start == (0, 0)
110        assert p0[0].type == path.Command.CURVE4_TO
111        assert p0[0].ctrl1 == (1, 1)
112        assert p0[0].ctrl2 == (3, 1)
113        assert p0[0].end == (4, 0)
114
115    def test_two_lines(self):
116        qpath = QPainterPath(QPointF(1, 2))
117        qpath.lineTo(4, 5)
118        qpath.moveTo(3, 4)
119        qpath.lineTo(7, 9)
120        paths = list(path.from_qpainter_path(qpath))
121        assert len(paths) == 2
122
123        p0 = paths[0]
124        assert p0[0].type == path.Command.LINE_TO
125        assert p0.start == (1, 2)
126        assert p0[0].end == (4, 5)
127
128        p1 = paths[1]
129        assert p1[0].type == path.Command.LINE_TO
130        assert p1.start == (3, 4)
131        assert p1[0].end == (7, 9)
132
133
134if __name__ == '__main__':
135    pytest.main([__file__])
136