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