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 14DEF_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