1 /*
2  * Copyright 2020 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include <vector>
9 
10 #include "include/utils/SkNoDrawCanvas.h"
11 #include "modules/svg/src/SkSVGTextPriv.h"
12 #include "tests/Test.h"
13 
DEF_TEST(Svg_Text_PosProvider,r)14 DEF_TEST(Svg_Text_PosProvider, r) {
15     const auto L = [](float x) { return SkSVGLength(x); };
16     const float N = SkSVGTextContext::PosAttrs()[SkSVGTextContext::PosAttrs::kX];
17 
18     static const struct PosTestDesc {
19         size_t                   offseta;
20         std::vector<SkSVGLength> xa, ya;
21 
22         size_t                   offsetb;
23         std::vector<SkSVGLength> xb, yb;
24 
25         std::vector<SkPoint>     expected;
26     } gTests[] = {
27         {
28             0, {}, {},
29             0, {}, {},
30 
31             { {N,N} }
32         },
33 
34         {
35             0, { L(1) }, {},
36             0, {      }, {},
37 
38             { {1,N}, {N,N} }
39         },
40         {
41             0, {       }, {},
42             0, { L(10) }, {},
43 
44             { {10,N}, {N,N} }
45         },
46         {
47             0, { L( 1) }, {},
48             0, { L(10) }, {},
49 
50             { {10,N}, {N,N} }
51         },
52         {
53             0, { L( 1), L(2) }, {},
54             0, { L(10)       }, {},
55 
56             { {10,N}, {2,N}, {N,N} }
57         },
58         {
59             0, { L(1), L( 2) }, {},
60             1, {       L(20) }, {},
61 
62             { {1,N}, {20,N}, {N,N} }
63         },
64         {
65             0, { L(1), L( 2), L(3) }, {},
66             1, {       L(20)       }, {},
67 
68             { {1,N}, {20,N}, {3,N}, {N,N} }
69         },
70         {
71             0, { L(1), L(2), L( 3) }, {},
72             2, {             L(30) }, {},
73 
74             { {1,N}, {2,N}, {30,N}, {N,N} }
75         },
76         {
77             0, { L(1)              }, {},
78             2, {             L(30) }, {},
79 
80             { {1,N}, {N,N}, {30,N}, {N,N} }
81         },
82 
83 
84         {
85             0, {}, { L(4) },
86             0, {}, {      },
87 
88             { {N,4}, {N,N} }
89         },
90         {
91             0, {}, {       },
92             0, {}, { L(40) },
93 
94             { {N,40}, {N,N} }
95         },
96         {
97             0, {}, { L( 4) },
98             0, {}, { L(40) },
99 
100             { {N,40}, {N,N} }
101         },
102         {
103             0, {}, { L( 4), L(5) },
104             0, {}, { L(40)       },
105 
106             { {N,40}, {N,5}, {N,N} }
107         },
108         {
109             0, {}, { L(4), L( 5) },
110             1, {}, {       L(50) },
111 
112             { {N,4}, {N,50}, {N,N} }
113         },
114         {
115             0, {}, { L(4), L( 5), L(6) },
116             1, {}, {       L(50)       },
117 
118             { {N,4}, {N,50}, {N,6}, {N,N} }
119         },
120         {
121             0, {}, { L(4), L(5), L( 6) },
122             2, {}, {             L(60) },
123 
124             { {N,4}, {N,5}, {N,60}, {N,N} }
125         },
126         {
127             0, {}, { L(4)              },
128             2, {}, {             L(60) },
129 
130             { {N,4}, {N,N}, {N,60}, {N,N} }
131         },
132 
133         {
134             0, { L( 1), L(2)}, { L( 4)        },
135             0, { L(10)      }, { L(40), L(50) },
136 
137             { {10,40}, {2,50}, {N,N} }
138         },
139         {
140             0, { L(1), L( 2), L(3) }, { L(4), L( 5)        },
141             1, {       L(20)       }, {       L(50), L(60) },
142 
143             { {1,4}, {20,50}, {3,60}, {N,N} }
144         },
145     };
146 
147     const SkSVGTextContext::ShapedTextCallback mock_cb =
148         [](const SkSVGRenderContext&, const sk_sp<SkTextBlob>&, const SkPaint*, const SkPaint*) {};
149 
150     auto test = [&](const PosTestDesc& tst) {
151         auto a = SkSVGText::Make();
152         auto b = SkSVGTSpan::Make();
153         a->appendChild(b);
154 
155         a->setX(tst.xa);
156         a->setY(tst.ya);
157         b->setX(tst.xb);
158         b->setY(tst.yb);
159 
160         const SkSVGIDMapper mapper;
161         const SkSVGLengthContext lctx({0,0});
162         const SkSVGPresentationContext pctx;
163         SkNoDrawCanvas canvas(0, 0);
164         sk_sp<SkFontMgr> fmgr;
165         sk_sp<skresources::ResourceProvider> rp;
166         const SkSVGRenderContext ctx(&canvas, fmgr, rp, mapper, lctx, pctx, {nullptr, nullptr});
167 
168         SkSVGTextContext tctx(ctx, mock_cb);
169         SkSVGTextContext::ScopedPosResolver pa(*a, lctx, &tctx, tst.offseta);
170         SkSVGTextContext::ScopedPosResolver pb(*b, lctx, &tctx, tst.offsetb);
171 
172         for (size_t i = 0; i < tst.expected.size(); ++i) {
173             const auto& exp = tst.expected[i];
174             auto pos = i >= tst.offsetb ? pb.resolve(i) : pa.resolve(i);
175 
176             REPORTER_ASSERT(r, pos[SkSVGTextContext::PosAttrs::kX] == exp.fX);
177             REPORTER_ASSERT(r, pos[SkSVGTextContext::PosAttrs::kY] == exp.fY);
178         }
179     };
180 
181     for (const auto& tst : gTests) {
182         test(tst);
183     }
184 }
185