1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2019 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontMgr.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontStyle.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/encode/SkPngEncoder.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/DartTypes.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/FontCollection.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/Paragraph.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/ParagraphCache.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/ParagraphStyle.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/TextShadow.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/TextStyle.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/TypefaceFontProvider.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/OneLineShaper.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/ParagraphBuilderImpl.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/ParagraphImpl.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/Run.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/TextLine.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/tests/SkShaperJSONWriter.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/utils/TestFontCollection.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skshaper/utils/FactoryHelpers.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkTSort.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkOSFile.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/utils/SkOSPath.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "tools/Resources.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "tools/flags/CommandLineFlags.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
46*c8dee2aaSAndroid Build Coastguard Worker
47*c8dee2aaSAndroid Build Coastguard Worker #include <string.h>
48*c8dee2aaSAndroid Build Coastguard Worker #include <algorithm>
49*c8dee2aaSAndroid Build Coastguard Worker #include <limits>
50*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
51*c8dee2aaSAndroid Build Coastguard Worker #include <string>
52*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
53*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
54*c8dee2aaSAndroid Build Coastguard Worker #include <thread>
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode.h"
57*c8dee2aaSAndroid Build Coastguard Worker
58*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
59*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_icu.h"
60*c8dee2aaSAndroid Build Coastguard Worker #endif
61*c8dee2aaSAndroid Build Coastguard Worker
62*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION)
63*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_libgrapheme.h"
64*c8dee2aaSAndroid Build Coastguard Worker #endif
65*c8dee2aaSAndroid Build Coastguard Worker
66*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
67*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_icu4x.h"
68*c8dee2aaSAndroid Build Coastguard Worker #endif
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
73*c8dee2aaSAndroid Build Coastguard Worker
74*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_string(paragraph_fonts, "",
75*c8dee2aaSAndroid Build Coastguard Worker "subdirectory of //resources for fonts to use for these tests");
76*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_bool(run_paragraph_tests_needing_system_fonts, true,
77*c8dee2aaSAndroid Build Coastguard Worker "Some tests are finicky and need certain system fonts. "
78*c8dee2aaSAndroid Build Coastguard Worker "Set this to false to skip those.");
79*c8dee2aaSAndroid Build Coastguard Worker
80*c8dee2aaSAndroid Build Coastguard Worker #define VeryLongCanvasWidth 1000000
81*c8dee2aaSAndroid Build Coastguard Worker #define TestCanvasWidth 1000
82*c8dee2aaSAndroid Build Coastguard Worker #define TestCanvasHeight 600
83*c8dee2aaSAndroid Build Coastguard Worker
84*c8dee2aaSAndroid Build Coastguard Worker using namespace skia::textlayout;
85*c8dee2aaSAndroid Build Coastguard Worker namespace {
86*c8dee2aaSAndroid Build Coastguard Worker
87*c8dee2aaSAndroid Build Coastguard Worker SkScalar EPSILON100 = 0.01f;
88*c8dee2aaSAndroid Build Coastguard Worker SkScalar EPSILON50 = 0.02f;
89*c8dee2aaSAndroid Build Coastguard Worker SkScalar EPSILON20 = 0.05f;
90*c8dee2aaSAndroid Build Coastguard Worker SkScalar EPSILON10 = 0.1f;
91*c8dee2aaSAndroid Build Coastguard Worker SkScalar EPSILON5 = 0.20f;
92*c8dee2aaSAndroid Build Coastguard Worker SkScalar EPSILON2 = 0.50f;
93*c8dee2aaSAndroid Build Coastguard Worker
equal(const char * base,TextRange a,const char * b)94*c8dee2aaSAndroid Build Coastguard Worker bool equal(const char* base, TextRange a, const char* b) {
95*c8dee2aaSAndroid Build Coastguard Worker return std::strncmp(b, base + a.start, a.width()) == 0;
96*c8dee2aaSAndroid Build Coastguard Worker }
97*c8dee2aaSAndroid Build Coastguard Worker
mirror(const std::string & text)98*c8dee2aaSAndroid Build Coastguard Worker std::u16string mirror(const std::string& text) {
99*c8dee2aaSAndroid Build Coastguard Worker std::u16string result;
100*c8dee2aaSAndroid Build Coastguard Worker result += u"\u202E";
101*c8dee2aaSAndroid Build Coastguard Worker for (auto i = text.size(); i > 0; --i) {
102*c8dee2aaSAndroid Build Coastguard Worker result += text[i - 1];
103*c8dee2aaSAndroid Build Coastguard Worker }
104*c8dee2aaSAndroid Build Coastguard Worker //result += u"\u202C";
105*c8dee2aaSAndroid Build Coastguard Worker return result;
106*c8dee2aaSAndroid Build Coastguard Worker }
107*c8dee2aaSAndroid Build Coastguard Worker
straight(const std::string & text)108*c8dee2aaSAndroid Build Coastguard Worker std::u16string straight(const std::string& text) {
109*c8dee2aaSAndroid Build Coastguard Worker std::u16string result;
110*c8dee2aaSAndroid Build Coastguard Worker result += u"\u202D";
111*c8dee2aaSAndroid Build Coastguard Worker for (auto ch : text) {
112*c8dee2aaSAndroid Build Coastguard Worker result += ch;
113*c8dee2aaSAndroid Build Coastguard Worker }
114*c8dee2aaSAndroid Build Coastguard Worker return result;
115*c8dee2aaSAndroid Build Coastguard Worker }
116*c8dee2aaSAndroid Build Coastguard Worker
117*c8dee2aaSAndroid Build Coastguard Worker class ResourceFontCollection : public FontCollection {
getTypefaces()118*c8dee2aaSAndroid Build Coastguard Worker static const std::vector<sk_sp<SkTypeface>>& getTypefaces() {
119*c8dee2aaSAndroid Build Coastguard Worker static std::vector<sk_sp<SkTypeface>> typefaces = []() -> std::vector<sk_sp<SkTypeface>> {
120*c8dee2aaSAndroid Build Coastguard Worker if (FLAGS_paragraph_fonts.size() == 0) {
121*c8dee2aaSAndroid Build Coastguard Worker return {};
122*c8dee2aaSAndroid Build Coastguard Worker }
123*c8dee2aaSAndroid Build Coastguard Worker TArray<SkString> paths;
124*c8dee2aaSAndroid Build Coastguard Worker {
125*c8dee2aaSAndroid Build Coastguard Worker SkString fontResources = GetResourcePath(FLAGS_paragraph_fonts[0]);
126*c8dee2aaSAndroid Build Coastguard Worker const char* fontDir = fontResources.c_str();
127*c8dee2aaSAndroid Build Coastguard Worker SkOSFile::Iter iter(fontDir);
128*c8dee2aaSAndroid Build Coastguard Worker SkString path;
129*c8dee2aaSAndroid Build Coastguard Worker while (iter.next(&path)) {
130*c8dee2aaSAndroid Build Coastguard Worker if ((false)) {
131*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Found font file: %s\n", path.c_str());
132*c8dee2aaSAndroid Build Coastguard Worker }
133*c8dee2aaSAndroid Build Coastguard Worker SkString fullPath;
134*c8dee2aaSAndroid Build Coastguard Worker fullPath.printf("%s/%s", fontDir, path.c_str());
135*c8dee2aaSAndroid Build Coastguard Worker paths.emplace_back(fullPath);
136*c8dee2aaSAndroid Build Coastguard Worker }
137*c8dee2aaSAndroid Build Coastguard Worker if (paths.size()) {
138*c8dee2aaSAndroid Build Coastguard Worker SkTQSort(paths.begin(), paths.end(),
139*c8dee2aaSAndroid Build Coastguard Worker [](const SkString& a, const SkString& b) {
140*c8dee2aaSAndroid Build Coastguard Worker return strcmp(a.c_str(), b.c_str()) < 0;
141*c8dee2aaSAndroid Build Coastguard Worker });
142*c8dee2aaSAndroid Build Coastguard Worker }
143*c8dee2aaSAndroid Build Coastguard Worker }
144*c8dee2aaSAndroid Build Coastguard Worker
145*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFontMgr> mgr = ToolUtils::TestFontMgr();
146*c8dee2aaSAndroid Build Coastguard Worker std::vector<sk_sp<SkTypeface>> typefaces;
147*c8dee2aaSAndroid Build Coastguard Worker bool fontsFound = false;
148*c8dee2aaSAndroid Build Coastguard Worker for (auto&& path : paths) {
149*c8dee2aaSAndroid Build Coastguard Worker if ((false)) {
150*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Reading font: %s\n", path.c_str());
151*c8dee2aaSAndroid Build Coastguard Worker }
152*c8dee2aaSAndroid Build Coastguard Worker auto stream = SkStream::MakeFromFile(path.c_str());
153*c8dee2aaSAndroid Build Coastguard Worker SkASSERTF(stream, "%s not readable", path.c_str());
154*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> typeface = mgr->makeFromStream(std::move(stream), {});
155*c8dee2aaSAndroid Build Coastguard Worker // Without --nativeFonts, DM will use the portable test font manager which does
156*c8dee2aaSAndroid Build Coastguard Worker // not know how to read in fonts from bytes.
157*c8dee2aaSAndroid Build Coastguard Worker if (typeface) {
158*c8dee2aaSAndroid Build Coastguard Worker if ((false)) {
159*c8dee2aaSAndroid Build Coastguard Worker SkString familyName;
160*c8dee2aaSAndroid Build Coastguard Worker typeface->getFamilyName(&familyName);
161*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Creating: %s size: %zu\n",
162*c8dee2aaSAndroid Build Coastguard Worker familyName.c_str(),
163*c8dee2aaSAndroid Build Coastguard Worker typeface->openExistingStream(nullptr)->getLength());
164*c8dee2aaSAndroid Build Coastguard Worker }
165*c8dee2aaSAndroid Build Coastguard Worker if (path.endsWith("Roboto-Italic.ttf")) {
166*c8dee2aaSAndroid Build Coastguard Worker fontsFound = true;
167*c8dee2aaSAndroid Build Coastguard Worker }
168*c8dee2aaSAndroid Build Coastguard Worker typefaces.emplace_back(std::move(typeface));
169*c8dee2aaSAndroid Build Coastguard Worker } else {
170*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGF("%s was not turned into a Typeface. Did you set --nativeFonts?\n",
171*c8dee2aaSAndroid Build Coastguard Worker path.c_str());
172*c8dee2aaSAndroid Build Coastguard Worker }
173*c8dee2aaSAndroid Build Coastguard Worker }
174*c8dee2aaSAndroid Build Coastguard Worker SkASSERTF_RELEASE(typefaces.size(), "--paragraph_fonts set but no fonts found."
175*c8dee2aaSAndroid Build Coastguard Worker "Did you set --nativeFonts?");
176*c8dee2aaSAndroid Build Coastguard Worker SkASSERTF_RELEASE(fontsFound, "--paragraph_fonts set but Roboto-Italic.ttf not found");
177*c8dee2aaSAndroid Build Coastguard Worker return typefaces;
178*c8dee2aaSAndroid Build Coastguard Worker }();
179*c8dee2aaSAndroid Build Coastguard Worker return typefaces;
180*c8dee2aaSAndroid Build Coastguard Worker }
181*c8dee2aaSAndroid Build Coastguard Worker public:
ResourceFontCollection(bool testOnly=false)182*c8dee2aaSAndroid Build Coastguard Worker ResourceFontCollection(bool testOnly = false)
183*c8dee2aaSAndroid Build Coastguard Worker : fFontsFound(false)
184*c8dee2aaSAndroid Build Coastguard Worker , fResolvedFonts(0)
185*c8dee2aaSAndroid Build Coastguard Worker , fFontProvider(sk_make_sp<TypefaceFontProvider>()) {
186*c8dee2aaSAndroid Build Coastguard Worker const std::vector<sk_sp<SkTypeface>>& typefaces = getTypefaces();
187*c8dee2aaSAndroid Build Coastguard Worker fFontsFound = !typefaces.empty();
188*c8dee2aaSAndroid Build Coastguard Worker for (auto&& typeface : typefaces) {
189*c8dee2aaSAndroid Build Coastguard Worker fFontProvider->registerTypeface(typeface);
190*c8dee2aaSAndroid Build Coastguard Worker }
191*c8dee2aaSAndroid Build Coastguard Worker
192*c8dee2aaSAndroid Build Coastguard Worker if (testOnly) {
193*c8dee2aaSAndroid Build Coastguard Worker this->setTestFontManager(std::move(fFontProvider));
194*c8dee2aaSAndroid Build Coastguard Worker } else {
195*c8dee2aaSAndroid Build Coastguard Worker this->setAssetFontManager(std::move(fFontProvider));
196*c8dee2aaSAndroid Build Coastguard Worker }
197*c8dee2aaSAndroid Build Coastguard Worker this->disableFontFallback();
198*c8dee2aaSAndroid Build Coastguard Worker }
199*c8dee2aaSAndroid Build Coastguard Worker
resolvedFonts() const200*c8dee2aaSAndroid Build Coastguard Worker size_t resolvedFonts() const { return fResolvedFonts; }
201*c8dee2aaSAndroid Build Coastguard Worker
202*c8dee2aaSAndroid Build Coastguard Worker // TODO: temp solution until we check in fonts
fontsFound() const203*c8dee2aaSAndroid Build Coastguard Worker bool fontsFound() const { return fFontsFound; }
204*c8dee2aaSAndroid Build Coastguard Worker
205*c8dee2aaSAndroid Build Coastguard Worker private:
206*c8dee2aaSAndroid Build Coastguard Worker bool fFontsFound;
207*c8dee2aaSAndroid Build Coastguard Worker size_t fResolvedFonts;
208*c8dee2aaSAndroid Build Coastguard Worker sk_sp<TypefaceFontProvider> fFontProvider;
209*c8dee2aaSAndroid Build Coastguard Worker };
210*c8dee2aaSAndroid Build Coastguard Worker
211*c8dee2aaSAndroid Build Coastguard Worker class TestCanvas {
212*c8dee2aaSAndroid Build Coastguard Worker public:
TestCanvas(const char * testName)213*c8dee2aaSAndroid Build Coastguard Worker TestCanvas(const char* testName) : name(testName) {
214*c8dee2aaSAndroid Build Coastguard Worker bits.allocN32Pixels(TestCanvasWidth, TestCanvasHeight);
215*c8dee2aaSAndroid Build Coastguard Worker canvas = new SkCanvas(bits);
216*c8dee2aaSAndroid Build Coastguard Worker canvas->clear(SK_ColorWHITE);
217*c8dee2aaSAndroid Build Coastguard Worker }
218*c8dee2aaSAndroid Build Coastguard Worker
~TestCanvas()219*c8dee2aaSAndroid Build Coastguard Worker ~TestCanvas() {
220*c8dee2aaSAndroid Build Coastguard Worker SkString tmpDir = skiatest::GetTmpDir();
221*c8dee2aaSAndroid Build Coastguard Worker if (!tmpDir.isEmpty()) {
222*c8dee2aaSAndroid Build Coastguard Worker SkString path = SkOSPath::Join(tmpDir.c_str(), name);
223*c8dee2aaSAndroid Build Coastguard Worker SkFILEWStream file(path.c_str());
224*c8dee2aaSAndroid Build Coastguard Worker if (!SkPngEncoder::Encode(&file, bits.pixmap(), {})) {
225*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Cannot write a picture %s\n", name);
226*c8dee2aaSAndroid Build Coastguard Worker }
227*c8dee2aaSAndroid Build Coastguard Worker }
228*c8dee2aaSAndroid Build Coastguard Worker delete canvas;
229*c8dee2aaSAndroid Build Coastguard Worker }
230*c8dee2aaSAndroid Build Coastguard Worker
drawRects(SkColor color,std::vector<TextBox> & result,bool fill=false)231*c8dee2aaSAndroid Build Coastguard Worker void drawRects(SkColor color, std::vector<TextBox>& result, bool fill = false) {
232*c8dee2aaSAndroid Build Coastguard Worker
233*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
234*c8dee2aaSAndroid Build Coastguard Worker if (!fill) {
235*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
236*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
237*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1);
238*c8dee2aaSAndroid Build Coastguard Worker }
239*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(color);
240*c8dee2aaSAndroid Build Coastguard Worker for (auto& r : result) {
241*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(r.rect, paint);
242*c8dee2aaSAndroid Build Coastguard Worker }
243*c8dee2aaSAndroid Build Coastguard Worker }
244*c8dee2aaSAndroid Build Coastguard Worker
drawLine(SkColor color,SkRect rect,bool vertical=true)245*c8dee2aaSAndroid Build Coastguard Worker void drawLine(SkColor color, SkRect rect, bool vertical = true) {
246*c8dee2aaSAndroid Build Coastguard Worker
247*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
248*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
249*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
250*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1);
251*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(color);
252*c8dee2aaSAndroid Build Coastguard Worker if (vertical) {
253*c8dee2aaSAndroid Build Coastguard Worker canvas->drawLine(rect.fLeft, rect.fTop, rect.fLeft, rect.fBottom, paint);
254*c8dee2aaSAndroid Build Coastguard Worker } else {
255*c8dee2aaSAndroid Build Coastguard Worker canvas->drawLine(rect.fLeft, rect.fTop, rect.fRight, rect.fTop, paint);
256*c8dee2aaSAndroid Build Coastguard Worker }
257*c8dee2aaSAndroid Build Coastguard Worker }
258*c8dee2aaSAndroid Build Coastguard Worker
drawLines(SkColor color,std::vector<TextBox> & result)259*c8dee2aaSAndroid Build Coastguard Worker void drawLines(SkColor color, std::vector<TextBox>& result) {
260*c8dee2aaSAndroid Build Coastguard Worker
261*c8dee2aaSAndroid Build Coastguard Worker for (auto& r : result) {
262*c8dee2aaSAndroid Build Coastguard Worker drawLine(color, r.rect);
263*c8dee2aaSAndroid Build Coastguard Worker }
264*c8dee2aaSAndroid Build Coastguard Worker }
265*c8dee2aaSAndroid Build Coastguard Worker
get()266*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* get() { return canvas; }
267*c8dee2aaSAndroid Build Coastguard Worker private:
268*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bits;
269*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* canvas;
270*c8dee2aaSAndroid Build Coastguard Worker const char* name;
271*c8dee2aaSAndroid Build Coastguard Worker };
272*c8dee2aaSAndroid Build Coastguard Worker
get_unicode()273*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkUnicode> get_unicode() {
274*c8dee2aaSAndroid Build Coastguard Worker auto factory = SkShapers::BestAvailable();
275*c8dee2aaSAndroid Build Coastguard Worker return sk_ref_sp<SkUnicode>(factory->getUnicode());
276*c8dee2aaSAndroid Build Coastguard Worker }
277*c8dee2aaSAndroid Build Coastguard Worker
278*c8dee2aaSAndroid Build Coastguard Worker } // namespace
279*c8dee2aaSAndroid Build Coastguard Worker
280*c8dee2aaSAndroid Build Coastguard Worker // Skip tests which do not find the fonts, unless the user set --paragraph_fonts in which case
281*c8dee2aaSAndroid Build Coastguard Worker // we should make a loud error.
282*c8dee2aaSAndroid Build Coastguard Worker #define SKIP_IF_FONTS_NOT_FOUND(r, fontCollection) \
283*c8dee2aaSAndroid Build Coastguard Worker if (!fontCollection->fontsFound()) { \
284*c8dee2aaSAndroid Build Coastguard Worker if (FLAGS_paragraph_fonts.size() != 0) { \
285*c8dee2aaSAndroid Build Coastguard Worker ERRORF(r, "SkParagraphTests Fonts not found!\n"); \
286*c8dee2aaSAndroid Build Coastguard Worker } \
287*c8dee2aaSAndroid Build Coastguard Worker return; \
288*c8dee2aaSAndroid Build Coastguard Worker }
289*c8dee2aaSAndroid Build Coastguard Worker
290*c8dee2aaSAndroid Build Coastguard Worker #define NEED_SYSTEM_FONTS(fontCollection) \
291*c8dee2aaSAndroid Build Coastguard Worker if (!FLAGS_run_paragraph_tests_needing_system_fonts) { \
292*c8dee2aaSAndroid Build Coastguard Worker return; \
293*c8dee2aaSAndroid Build Coastguard Worker } \
294*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr()); \
295*c8dee2aaSAndroid Build Coastguard Worker fontCollection->enableFontFallback();
296*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_SimpleParagraph,reporter)297*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_SimpleParagraph, reporter) {
298*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
299*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
300*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Hello World Text Dialog";
301*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
302*c8dee2aaSAndroid Build Coastguard Worker
303*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
304*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
305*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
306*c8dee2aaSAndroid Build Coastguard Worker
307*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
308*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
309*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
310*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
311*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
312*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
313*c8dee2aaSAndroid Build Coastguard Worker
314*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
315*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
316*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
317*c8dee2aaSAndroid Build Coastguard Worker
318*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
319*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
320*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1); // paragraph style does not count
321*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
322*c8dee2aaSAndroid Build Coastguard Worker
323*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
324*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
325*c8dee2aaSAndroid Build Coastguard Worker line.scanStyles(StyleType::kDecorations,
326*c8dee2aaSAndroid Build Coastguard Worker [&index, reporter]
327*c8dee2aaSAndroid Build Coastguard Worker (TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
328*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 0);
329*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getColor() == SK_ColorBLACK);
330*c8dee2aaSAndroid Build Coastguard Worker ++index;
331*c8dee2aaSAndroid Build Coastguard Worker });
332*c8dee2aaSAndroid Build Coastguard Worker }
333*c8dee2aaSAndroid Build Coastguard Worker }
334*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Rounding_Off_LineBreaks,reporter)335*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Rounding_Off_LineBreaks, reporter) {
336*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
337*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
338*c8dee2aaSAndroid Build Coastguard Worker const char* text = "AAAAAAAAAA";
339*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
340*c8dee2aaSAndroid Build Coastguard Worker
341*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
342*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
343*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setApplyRoundingHack(false);
344*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
345*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
346*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
347*c8dee2aaSAndroid Build Coastguard Worker
348*c8dee2aaSAndroid Build Coastguard Worker auto testFontSize = {1.5f, 10.0f/3, 10.0f/6, 10.0f};
349*c8dee2aaSAndroid Build Coastguard Worker for (auto fontSize : testFontSize) {
350*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
351*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(fontSize);
352*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
353*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
354*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
355*c8dee2aaSAndroid Build Coastguard Worker
356*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
357*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(SK_ScalarInfinity);
358*c8dee2aaSAndroid Build Coastguard Worker // Slightly wider than the max intrinsic width.
359*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
360*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(paragraph->getMaxIntrinsicWidth());
361*c8dee2aaSAndroid Build Coastguard Worker
362*c8dee2aaSAndroid Build Coastguard Worker ParagraphImpl* impl = static_cast<ParagraphImpl*>(paragraph.get());
363*c8dee2aaSAndroid Build Coastguard Worker
364*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
365*c8dee2aaSAndroid Build Coastguard Worker auto& line = impl->lines()[0];
366*c8dee2aaSAndroid Build Coastguard Worker
367*c8dee2aaSAndroid Build Coastguard Worker const LineMetrics metrics = line.getMetrics();
368*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(metrics.fWidth, fontSize * len, EPSILON2));
369*c8dee2aaSAndroid Build Coastguard Worker }
370*c8dee2aaSAndroid Build Coastguard Worker }
371*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderParagraph,reporter)372*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderParagraph, reporter) {
373*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
374*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderParagraph.png");
375*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
376*c8dee2aaSAndroid Build Coastguard Worker
377*c8dee2aaSAndroid Build Coastguard Worker const char* text = "012 34";
378*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
379*c8dee2aaSAndroid Build Coastguard Worker
380*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
381*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
382*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
383*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
384*c8dee2aaSAndroid Build Coastguard Worker
385*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
386*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
387*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
388*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
389*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
390*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
391*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
392*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
393*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
394*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
395*c8dee2aaSAndroid Build Coastguard Worker
396*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder1(50, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 0);
397*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
398*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
399*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
400*c8dee2aaSAndroid Build Coastguard Worker
401*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder2(5, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 50);
402*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
403*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
404*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
405*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
406*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
407*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
408*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
409*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
410*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
411*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
412*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
413*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
414*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
415*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
416*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
417*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
418*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
419*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
420*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
421*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
422*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
423*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
424*c8dee2aaSAndroid Build Coastguard Worker
425*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
426*c8dee2aaSAndroid Build Coastguard Worker
427*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
428*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
429*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
430*c8dee2aaSAndroid Build Coastguard Worker
431*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
432*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
433*c8dee2aaSAndroid Build Coastguard Worker
434*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 3, rect_height_style, rect_width_style);
435*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
436*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
437*c8dee2aaSAndroid Build Coastguard Worker
438*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(0, 3, rect_height_style, rect_width_style);
439*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, boxes);
440*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
441*c8dee2aaSAndroid Build Coastguard Worker
442*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForPlaceholders();
443*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
444*c8dee2aaSAndroid Build Coastguard Worker
445*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(4, 17, rect_height_style, rect_width_style);
446*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
447*c8dee2aaSAndroid Build Coastguard Worker
448*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 7);
449*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 7) {
450*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.left(), 90.921f, EPSILON2));
451*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.top(), 50, EPSILON100));
452*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.right(), 90.921f + 50, EPSILON2));
453*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.bottom(), 100, EPSILON100));
454*c8dee2aaSAndroid Build Coastguard Worker
455*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[3].rect.left(), 231.343f, EPSILON2));
456*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[3].rect.top(), 50, EPSILON100));
457*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[3].rect.right(), 231.343f + 50, EPSILON2));
458*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[3].rect.bottom(), 100, EPSILON100));
459*c8dee2aaSAndroid Build Coastguard Worker
460*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[4].rect.left(), 281.343f, EPSILON2));
461*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[4].rect.top(), 0, EPSILON100));
462*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[4].rect.right(), 281.343f + 5, EPSILON2));
463*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[4].rect.bottom(), 50, EPSILON100));
464*c8dee2aaSAndroid Build Coastguard Worker
465*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[6].rect.left(), 336.343f, EPSILON2));
466*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[6].rect.top(), 0, EPSILON100));
467*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[6].rect.right(), 336.343f + 5, EPSILON2));
468*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[6].rect.bottom(), 50, EPSILON100));
469*c8dee2aaSAndroid Build Coastguard Worker }
470*c8dee2aaSAndroid Build Coastguard Worker }
471*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderBaselineParagraph,reporter)472*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderBaselineParagraph, reporter) {
473*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
474*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderBaselineParagraph.png");
475*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
476*c8dee2aaSAndroid Build Coastguard Worker
477*c8dee2aaSAndroid Build Coastguard Worker const char* text = "012 34";
478*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
479*c8dee2aaSAndroid Build Coastguard Worker
480*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
481*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
482*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
483*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
484*c8dee2aaSAndroid Build Coastguard Worker
485*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
486*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
487*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
488*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
489*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
490*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
491*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
492*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
493*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
494*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
495*c8dee2aaSAndroid Build Coastguard Worker
496*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 38.347f);
497*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder);
498*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
499*c8dee2aaSAndroid Build Coastguard Worker
500*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
501*c8dee2aaSAndroid Build Coastguard Worker
502*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
503*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
504*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
505*c8dee2aaSAndroid Build Coastguard Worker
506*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForPlaceholders();
507*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
508*c8dee2aaSAndroid Build Coastguard Worker
509*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
510*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
511*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 90.921f, EPSILON2));
512*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
513*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f + 55, EPSILON2));
514*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 50, EPSILON100));
515*c8dee2aaSAndroid Build Coastguard Worker }
516*c8dee2aaSAndroid Build Coastguard Worker
517*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
518*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
519*c8dee2aaSAndroid Build Coastguard Worker
520*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
521*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
522*c8dee2aaSAndroid Build Coastguard Worker
523*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
524*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
525*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 75.324f, EPSILON2));
526*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 14.226f, EPSILON100));
527*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f, EPSILON2));
528*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 44.694f, EPSILON100));
529*c8dee2aaSAndroid Build Coastguard Worker }
530*c8dee2aaSAndroid Build Coastguard Worker }
531*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderAboveBaselineParagraph,reporter)532*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderAboveBaselineParagraph, reporter) {
533*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
534*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderAboveBaselineParagraph.png");
535*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
536*c8dee2aaSAndroid Build Coastguard Worker
537*c8dee2aaSAndroid Build Coastguard Worker const char* text = "012 34";
538*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
539*c8dee2aaSAndroid Build Coastguard Worker
540*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
541*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
542*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
543*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
544*c8dee2aaSAndroid Build Coastguard Worker
545*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
546*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
547*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
548*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
549*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
550*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
551*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
552*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
553*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
554*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
555*c8dee2aaSAndroid Build Coastguard Worker
556*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kAboveBaseline, TextBaseline::kAlphabetic, 903129.129308f);
557*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder);
558*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
559*c8dee2aaSAndroid Build Coastguard Worker
560*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
561*c8dee2aaSAndroid Build Coastguard Worker
562*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
563*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
564*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
565*c8dee2aaSAndroid Build Coastguard Worker
566*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForPlaceholders();
567*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
568*c8dee2aaSAndroid Build Coastguard Worker
569*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
570*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
571*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 90.921f, EPSILON2));
572*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), -0.347f, EPSILON100));
573*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f + 55, EPSILON2));
574*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 49.652f, EPSILON100));
575*c8dee2aaSAndroid Build Coastguard Worker }
576*c8dee2aaSAndroid Build Coastguard Worker
577*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
578*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
579*c8dee2aaSAndroid Build Coastguard Worker
580*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
581*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
582*c8dee2aaSAndroid Build Coastguard Worker
583*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
584*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
585*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 75.324f, EPSILON2));
586*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 25.531f, EPSILON100));
587*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f, EPSILON2));
588*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 56, EPSILON100));
589*c8dee2aaSAndroid Build Coastguard Worker }
590*c8dee2aaSAndroid Build Coastguard Worker }
591*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderBelowBaselineParagraph,reporter)592*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderBelowBaselineParagraph, reporter) {
593*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
594*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderBelowBaselineParagraph.png");
595*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
596*c8dee2aaSAndroid Build Coastguard Worker
597*c8dee2aaSAndroid Build Coastguard Worker const char* text = "012 34";
598*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
599*c8dee2aaSAndroid Build Coastguard Worker
600*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
601*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
602*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
603*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
604*c8dee2aaSAndroid Build Coastguard Worker
605*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
606*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
607*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
608*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
609*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
610*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
611*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
612*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
613*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
614*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
615*c8dee2aaSAndroid Build Coastguard Worker
616*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kBelowBaseline, TextBaseline::kAlphabetic, 903129.129308f);
617*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder);
618*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
619*c8dee2aaSAndroid Build Coastguard Worker
620*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
621*c8dee2aaSAndroid Build Coastguard Worker
622*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
623*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
624*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
625*c8dee2aaSAndroid Build Coastguard Worker
626*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForPlaceholders();
627*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
628*c8dee2aaSAndroid Build Coastguard Worker
629*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
630*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
631*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 90.921f, EPSILON2));
632*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 24, EPSILON100));
633*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f + 55, EPSILON2));
634*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 74, EPSILON100));
635*c8dee2aaSAndroid Build Coastguard Worker }
636*c8dee2aaSAndroid Build Coastguard Worker
637*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
638*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
639*c8dee2aaSAndroid Build Coastguard Worker
640*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
641*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
642*c8dee2aaSAndroid Build Coastguard Worker
643*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
644*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
645*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 75.324f, EPSILON2));
646*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), -0.121f, EPSILON100));
647*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f, EPSILON2));
648*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 30.347f, EPSILON100));
649*c8dee2aaSAndroid Build Coastguard Worker }
650*c8dee2aaSAndroid Build Coastguard Worker }
651*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderBottomParagraph,reporter)652*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderBottomParagraph, reporter) {
653*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
654*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderBottomParagraph.png");
655*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
656*c8dee2aaSAndroid Build Coastguard Worker
657*c8dee2aaSAndroid Build Coastguard Worker const char* text = "012 34";
658*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
659*c8dee2aaSAndroid Build Coastguard Worker
660*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
661*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
662*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
663*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
664*c8dee2aaSAndroid Build Coastguard Worker
665*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
666*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
667*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
668*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
669*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
670*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
671*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
672*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
673*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
674*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
675*c8dee2aaSAndroid Build Coastguard Worker
676*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kBottom, TextBaseline::kAlphabetic, 0);
677*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder);
678*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
679*c8dee2aaSAndroid Build Coastguard Worker
680*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
681*c8dee2aaSAndroid Build Coastguard Worker
682*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
683*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
684*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
685*c8dee2aaSAndroid Build Coastguard Worker
686*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
687*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
688*c8dee2aaSAndroid Build Coastguard Worker
689*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForPlaceholders();
690*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
691*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
692*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
693*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 90.921f, EPSILON50));
694*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
695*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f + 55, EPSILON50));
696*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 50, EPSILON100));
697*c8dee2aaSAndroid Build Coastguard Worker }
698*c8dee2aaSAndroid Build Coastguard Worker
699*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
700*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
701*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
702*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
703*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0.5f, EPSILON50));
704*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 19.531f, EPSILON100));
705*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 16.097f, EPSILON50));
706*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 50, EPSILON100));
707*c8dee2aaSAndroid Build Coastguard Worker }
708*c8dee2aaSAndroid Build Coastguard Worker }
709*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderTopParagraph,reporter)710*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderTopParagraph, reporter) {
711*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
712*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderTopParagraph.png");
713*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
714*c8dee2aaSAndroid Build Coastguard Worker
715*c8dee2aaSAndroid Build Coastguard Worker const char* text = "012 34";
716*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
717*c8dee2aaSAndroid Build Coastguard Worker
718*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
719*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
720*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
721*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
722*c8dee2aaSAndroid Build Coastguard Worker
723*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
724*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
725*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
726*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
727*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
728*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
729*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
730*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
731*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
732*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
733*c8dee2aaSAndroid Build Coastguard Worker
734*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kTop, TextBaseline::kAlphabetic, 0);
735*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder);
736*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
737*c8dee2aaSAndroid Build Coastguard Worker
738*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
739*c8dee2aaSAndroid Build Coastguard Worker
740*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
741*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
742*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
743*c8dee2aaSAndroid Build Coastguard Worker
744*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
745*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
746*c8dee2aaSAndroid Build Coastguard Worker
747*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForPlaceholders();
748*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
749*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
750*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
751*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 90.921f, EPSILON50));
752*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
753*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f + 55, EPSILON50));
754*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 50, EPSILON100));
755*c8dee2aaSAndroid Build Coastguard Worker }
756*c8dee2aaSAndroid Build Coastguard Worker
757*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
758*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
759*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
760*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
761*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0.5f, EPSILON50));
762*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
763*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 16.097f, EPSILON50));
764*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 30.468f, EPSILON100));
765*c8dee2aaSAndroid Build Coastguard Worker }
766*c8dee2aaSAndroid Build Coastguard Worker }
767*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderMiddleParagraph,reporter)768*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderMiddleParagraph, reporter) {
769*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
770*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderMiddleParagraph.png");
771*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
772*c8dee2aaSAndroid Build Coastguard Worker
773*c8dee2aaSAndroid Build Coastguard Worker const char* text = "012 34";
774*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
775*c8dee2aaSAndroid Build Coastguard Worker
776*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
777*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
778*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
779*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
780*c8dee2aaSAndroid Build Coastguard Worker
781*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
782*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
783*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
784*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
785*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
786*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
787*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
788*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
789*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
790*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
791*c8dee2aaSAndroid Build Coastguard Worker
792*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kMiddle, TextBaseline::kAlphabetic, 0);
793*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder);
794*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
795*c8dee2aaSAndroid Build Coastguard Worker
796*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
797*c8dee2aaSAndroid Build Coastguard Worker
798*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
799*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
800*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
801*c8dee2aaSAndroid Build Coastguard Worker
802*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
803*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
804*c8dee2aaSAndroid Build Coastguard Worker
805*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForPlaceholders();
806*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
807*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
808*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
809*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 90.921f, EPSILON50));
810*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
811*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f + 55, EPSILON50));
812*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 50, EPSILON100));
813*c8dee2aaSAndroid Build Coastguard Worker }
814*c8dee2aaSAndroid Build Coastguard Worker
815*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
816*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
817*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
818*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
819*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 75.324f, EPSILON50));
820*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 9.765f, EPSILON100));
821*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f, EPSILON50));
822*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 40.234f, EPSILON100));
823*c8dee2aaSAndroid Build Coastguard Worker }
824*c8dee2aaSAndroid Build Coastguard Worker }
825*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderIdeographicBaselineParagraph,reporter)826*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderIdeographicBaselineParagraph, reporter) {
827*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
828*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderIdeographicBaselineParagraph.png");
829*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
830*c8dee2aaSAndroid Build Coastguard Worker
831*c8dee2aaSAndroid Build Coastguard Worker const char* text = "給能上目秘使";
832*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
833*c8dee2aaSAndroid Build Coastguard Worker
834*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
835*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
836*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
837*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
838*c8dee2aaSAndroid Build Coastguard Worker
839*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
840*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Source Han Serif CN")});
841*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
842*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
843*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
844*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
845*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
846*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
847*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
848*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
849*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kBaseline, TextBaseline::kIdeographic, 38.347f);
850*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder);
851*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
852*c8dee2aaSAndroid Build Coastguard Worker
853*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
854*c8dee2aaSAndroid Build Coastguard Worker
855*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
856*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
857*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
858*c8dee2aaSAndroid Build Coastguard Worker
859*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
860*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
861*c8dee2aaSAndroid Build Coastguard Worker
862*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForPlaceholders();
863*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
864*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
865*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
866*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 162.5f, EPSILON50));
867*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
868*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 162.5f + 55, EPSILON50));
869*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 50, EPSILON100));
870*c8dee2aaSAndroid Build Coastguard Worker }
871*c8dee2aaSAndroid Build Coastguard Worker
872*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
873*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
874*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
875*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
876*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 135.5f, EPSILON50));
877*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 4.703f, EPSILON100));
878*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 162.5f, EPSILON50));
879*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 42.065f, EPSILON100));
880*c8dee2aaSAndroid Build Coastguard Worker }
881*c8dee2aaSAndroid Build Coastguard Worker }
882*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderBreakParagraph,reporter)883*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderBreakParagraph, reporter) {
884*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
885*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderBreakParagraph.png");
886*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
887*c8dee2aaSAndroid Build Coastguard Worker
888*c8dee2aaSAndroid Build Coastguard Worker const char* text = "012 34";
889*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
890*c8dee2aaSAndroid Build Coastguard Worker
891*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
892*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
893*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
894*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
895*c8dee2aaSAndroid Build Coastguard Worker
896*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
897*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
898*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
899*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
900*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
901*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
902*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
903*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
904*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
905*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
906*c8dee2aaSAndroid Build Coastguard Worker
907*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder1(50, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 50);
908*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder2(25, 25, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 12.5f);
909*c8dee2aaSAndroid Build Coastguard Worker
910*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
911*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
912*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
913*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
914*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
915*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
916*c8dee2aaSAndroid Build Coastguard Worker
917*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
918*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
919*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
920*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
921*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2); // 4 + 1
922*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
923*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
924*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
925*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
926*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
927*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
928*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2); // 6 + 1
929*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
930*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
931*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
932*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
933*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
934*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
935*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
936*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2); // 7 + 1
937*c8dee2aaSAndroid Build Coastguard Worker
938*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
939*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
940*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
941*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
942*c8dee2aaSAndroid Build Coastguard Worker
943*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
944*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
945*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
946*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
947*c8dee2aaSAndroid Build Coastguard Worker
948*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
949*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
950*c8dee2aaSAndroid Build Coastguard Worker
951*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
952*c8dee2aaSAndroid Build Coastguard Worker
953*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
954*c8dee2aaSAndroid Build Coastguard Worker
955*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
956*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
957*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
958*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
959*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
960*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
961*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
962*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
963*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
964*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
965*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
966*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
967*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
968*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
969*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
970*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
971*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
972*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
973*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
974*c8dee2aaSAndroid Build Coastguard Worker
975*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
976*c8dee2aaSAndroid Build Coastguard Worker
977*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
978*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
979*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
980*c8dee2aaSAndroid Build Coastguard Worker
981*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
982*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
983*c8dee2aaSAndroid Build Coastguard Worker
984*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 3, rect_height_style, rect_width_style);
985*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
986*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
987*c8dee2aaSAndroid Build Coastguard Worker
988*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(175, 176, rect_height_style, rect_width_style);
989*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, boxes);
990*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
991*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
992*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 31.695f, EPSILON50));
993*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 218.531f, EPSILON100));
994*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 47.292f, EPSILON50));
995*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 249, EPSILON100));
996*c8dee2aaSAndroid Build Coastguard Worker }
997*c8dee2aaSAndroid Build Coastguard Worker
998*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForPlaceholders();
999*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
1000*c8dee2aaSAndroid Build Coastguard Worker
1001*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(4, 45, rect_height_style, rect_width_style);
1002*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
1003*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 30);
1004*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 30) {
1005*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 59.726f, EPSILON50));
1006*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 26.378f, EPSILON100));
1007*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 90.921f, EPSILON50));
1008*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 56.847f, EPSILON100));
1009*c8dee2aaSAndroid Build Coastguard Worker
1010*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[11].rect.left(), 606.343f, EPSILON20));
1011*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[11].rect.top(), 38, EPSILON100));
1012*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[11].rect.right(), 631.343f, EPSILON20));
1013*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[11].rect.bottom(), 63, EPSILON100));
1014*c8dee2aaSAndroid Build Coastguard Worker
1015*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[17].rect.left(), 0.5f, EPSILON50));
1016*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[17].rect.top(), 63.5f, EPSILON100));
1017*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[17].rect.right(), 50.5f, EPSILON50));
1018*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[17].rect.bottom(), 113.5f, EPSILON100));
1019*c8dee2aaSAndroid Build Coastguard Worker }
1020*c8dee2aaSAndroid Build Coastguard Worker }
1021*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderGetRectsParagraph,reporter)1022*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_InlinePlaceholderGetRectsParagraph, reporter) {
1023*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1024*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_InlinePlaceholderGetRectsParagraph.png");
1025*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1026*c8dee2aaSAndroid Build Coastguard Worker
1027*c8dee2aaSAndroid Build Coastguard Worker const char* text = "012 34";
1028*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1029*c8dee2aaSAndroid Build Coastguard Worker
1030*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1031*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
1032*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
1033*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1034*c8dee2aaSAndroid Build Coastguard Worker
1035*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1036*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1037*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
1038*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
1039*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
1040*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
1041*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
1042*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
1043*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1044*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1045*c8dee2aaSAndroid Build Coastguard Worker
1046*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder1(50, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 50);
1047*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder2(5, 20, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 10);
1048*c8dee2aaSAndroid Build Coastguard Worker
1049*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1050*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1051*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1052*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1053*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1054*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1055*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1056*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1057*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2); // 8 + 1
1058*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1059*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1060*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1061*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1062*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1063*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2); // 5 + 1
1064*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1065*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1066*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1067*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1068*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1069*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1070*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1071*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1); // 8 + 0
1072*c8dee2aaSAndroid Build Coastguard Worker
1073*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1074*c8dee2aaSAndroid Build Coastguard Worker
1075*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1076*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
1077*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2); // 1 + 2
1078*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1079*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
1080*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2); // 1 + 2
1081*c8dee2aaSAndroid Build Coastguard Worker
1082*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1083*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1084*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1085*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1086*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1087*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1088*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1089*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1090*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1091*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1092*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len); // 11
1093*c8dee2aaSAndroid Build Coastguard Worker
1094*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
1095*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1096*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
1097*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder1);
1098*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder2);
1099*c8dee2aaSAndroid Build Coastguard Worker
1100*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1101*c8dee2aaSAndroid Build Coastguard Worker
1102*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
1103*c8dee2aaSAndroid Build Coastguard Worker
1104*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1105*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
1106*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1107*c8dee2aaSAndroid Build Coastguard Worker
1108*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kMax;
1109*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1110*c8dee2aaSAndroid Build Coastguard Worker
1111*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForPlaceholders();
1112*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
1113*c8dee2aaSAndroid Build Coastguard Worker
1114*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 34);
1115*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 34) {
1116*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 90.921f, EPSILON50));
1117*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
1118*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 140.921f, EPSILON50));
1119*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 50, EPSILON100));
1120*c8dee2aaSAndroid Build Coastguard Worker
1121*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[16].rect.left(), 800.921f, EPSILON20));
1122*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[16].rect.top(), 0, EPSILON100));
1123*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[16].rect.right(), 850.921f, EPSILON20));
1124*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[16].rect.bottom(), 50, EPSILON100));
1125*c8dee2aaSAndroid Build Coastguard Worker
1126*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[33].rect.left(), 503.382f, EPSILON10));
1127*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[33].rect.top(), 160, EPSILON100));
1128*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[33].rect.right(), 508.382f, EPSILON10));
1129*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[33].rect.bottom(), 180, EPSILON100));
1130*c8dee2aaSAndroid Build Coastguard Worker }
1131*c8dee2aaSAndroid Build Coastguard Worker
1132*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(30, 50, rect_height_style, rect_width_style);
1133*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
1134*c8dee2aaSAndroid Build Coastguard Worker
1135*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 8);
1136*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 8) {
1137*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 216.097f, EPSILON50));
1138*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 60, EPSILON100));
1139*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 290.921f, EPSILON50));
1140*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 120, EPSILON100));
1141*c8dee2aaSAndroid Build Coastguard Worker
1142*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.left(), 290.921f, EPSILON20));
1143*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.top(), 60, EPSILON100));
1144*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.right(), 340.921f, EPSILON20));
1145*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.bottom(), 120, EPSILON100));
1146*c8dee2aaSAndroid Build Coastguard Worker
1147*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[2].rect.left(), 340.921f, EPSILON50));
1148*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[2].rect.top(), 60, EPSILON100));
1149*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[2].rect.right(), 345.921f, EPSILON50));
1150*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[2].rect.bottom(), 120, EPSILON100));
1151*c8dee2aaSAndroid Build Coastguard Worker }
1152*c8dee2aaSAndroid Build Coastguard Worker }
1153*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_SimpleRedParagraph,reporter)1154*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_SimpleRedParagraph, reporter) {
1155*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1156*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1157*c8dee2aaSAndroid Build Coastguard Worker const char* text = "I am RED";
1158*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1159*c8dee2aaSAndroid Build Coastguard Worker
1160*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1161*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
1162*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1163*c8dee2aaSAndroid Build Coastguard Worker
1164*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1165*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1166*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorRED);
1167*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1168*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1169*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
1170*c8dee2aaSAndroid Build Coastguard Worker
1171*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1172*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
1173*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
1174*c8dee2aaSAndroid Build Coastguard Worker
1175*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1176*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
1177*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1); // paragraph style does not count
1178*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
1179*c8dee2aaSAndroid Build Coastguard Worker
1180*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
1181*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
1182*c8dee2aaSAndroid Build Coastguard Worker line.scanStyles(StyleType::kDecorations,
1183*c8dee2aaSAndroid Build Coastguard Worker [reporter, &index](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
1184*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 0);
1185*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getColor() == SK_ColorRED);
1186*c8dee2aaSAndroid Build Coastguard Worker ++index;
1187*c8dee2aaSAndroid Build Coastguard Worker return true;
1188*c8dee2aaSAndroid Build Coastguard Worker });
1189*c8dee2aaSAndroid Build Coastguard Worker }
1190*c8dee2aaSAndroid Build Coastguard Worker }
1191*c8dee2aaSAndroid Build Coastguard Worker
1192*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF+ (Space between 1 & 2 style blocks)
UNIX_ONLY_TEST(SkParagraph_RainbowParagraph,reporter)1193*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RainbowParagraph, reporter) {
1194*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1195*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RainbowParagraph.png");
1196*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1197*c8dee2aaSAndroid Build Coastguard Worker const char* text1 = "Red Roboto"; // [0:10)
1198*c8dee2aaSAndroid Build Coastguard Worker const char* text2 = "big Greeen Default"; // [10:28)
1199*c8dee2aaSAndroid Build Coastguard Worker const char* text3 = "Defcolor Homemade Apple"; // [28:51)
1200*c8dee2aaSAndroid Build Coastguard Worker const char* text4 = "Small Blue Roboto"; // [51:68)
1201*c8dee2aaSAndroid Build Coastguard Worker const char* text41 = "Small Blue ";
1202*c8dee2aaSAndroid Build Coastguard Worker const char* text5 =
1203*c8dee2aaSAndroid Build Coastguard Worker "Continue Last Style With lots of words to check if it overlaps "
1204*c8dee2aaSAndroid Build Coastguard Worker "properly or not"; // [68:)
1205*c8dee2aaSAndroid Build Coastguard Worker const char* text42 =
1206*c8dee2aaSAndroid Build Coastguard Worker "Roboto"
1207*c8dee2aaSAndroid Build Coastguard Worker "Continue Last Style With lots of words to check if it overlaps "
1208*c8dee2aaSAndroid Build Coastguard Worker "properly or not";
1209*c8dee2aaSAndroid Build Coastguard Worker
1210*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1211*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
1212*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
1213*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(2);
1214*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1215*c8dee2aaSAndroid Build Coastguard Worker
1216*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style1;
1217*c8dee2aaSAndroid Build Coastguard Worker text_style1.setFontFamilies({SkString("Roboto")});
1218*c8dee2aaSAndroid Build Coastguard Worker
1219*c8dee2aaSAndroid Build Coastguard Worker text_style1.setColor(SK_ColorRED);
1220*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style1);
1221*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text1, strlen(text1));
1222*c8dee2aaSAndroid Build Coastguard Worker
1223*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style2;
1224*c8dee2aaSAndroid Build Coastguard Worker text_style2.setFontFamilies({SkString("Roboto")});
1225*c8dee2aaSAndroid Build Coastguard Worker text_style2.setFontSize(50);
1226*c8dee2aaSAndroid Build Coastguard Worker text_style2.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1227*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
1228*c8dee2aaSAndroid Build Coastguard Worker text_style2.setLetterSpacing(10);
1229*c8dee2aaSAndroid Build Coastguard Worker text_style2.setDecorationColor(SK_ColorBLACK);
1230*c8dee2aaSAndroid Build Coastguard Worker text_style2.setDecoration((TextDecoration)(
1231*c8dee2aaSAndroid Build Coastguard Worker TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
1232*c8dee2aaSAndroid Build Coastguard Worker text_style2.setWordSpacing(30);
1233*c8dee2aaSAndroid Build Coastguard Worker text_style2.setColor(SK_ColorGREEN);
1234*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style2);
1235*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text2, strlen(text2));
1236*c8dee2aaSAndroid Build Coastguard Worker
1237*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style3;
1238*c8dee2aaSAndroid Build Coastguard Worker text_style3.setFontFamilies({SkString("Homemade Apple")});
1239*c8dee2aaSAndroid Build Coastguard Worker text_style3.setColor(SK_ColorBLACK);
1240*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style3);
1241*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text3, strlen(text3));
1242*c8dee2aaSAndroid Build Coastguard Worker
1243*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style4;
1244*c8dee2aaSAndroid Build Coastguard Worker text_style4.setFontFamilies({SkString("Roboto")});
1245*c8dee2aaSAndroid Build Coastguard Worker text_style4.setFontSize(14);
1246*c8dee2aaSAndroid Build Coastguard Worker text_style4.setDecorationColor(SK_ColorBLACK);
1247*c8dee2aaSAndroid Build Coastguard Worker text_style4.setDecoration((TextDecoration)(
1248*c8dee2aaSAndroid Build Coastguard Worker TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
1249*c8dee2aaSAndroid Build Coastguard Worker text_style4.setColor(SK_ColorBLUE);
1250*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style4);
1251*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text4, strlen(text4));
1252*c8dee2aaSAndroid Build Coastguard Worker
1253*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text5, strlen(text5));
1254*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
1255*c8dee2aaSAndroid Build Coastguard Worker
1256*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1257*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(1000);
1258*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1259*c8dee2aaSAndroid Build Coastguard Worker
1260*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
1261*c8dee2aaSAndroid Build Coastguard Worker
1262*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1263*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 4);
1264*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 4);
1265*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 2);
1266*c8dee2aaSAndroid Build Coastguard Worker
1267*c8dee2aaSAndroid Build Coastguard Worker auto rects = paragraph->getRectsForRange(0, impl->text().size(), RectHeightStyle::kMax, RectWidthStyle::kTight);
1268*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorMAGENTA, rects);
1269*c8dee2aaSAndroid Build Coastguard Worker
1270*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
1271*c8dee2aaSAndroid Build Coastguard Worker impl->lines()[0].scanStyles(
1272*c8dee2aaSAndroid Build Coastguard Worker StyleType::kAllAttributes,
1273*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
1274*c8dee2aaSAndroid Build Coastguard Worker switch (index) {
1275*c8dee2aaSAndroid Build Coastguard Worker case 0:
1276*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.equals(text_style1));
1277*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, equal(impl->text().begin(), textRange, text1));
1278*c8dee2aaSAndroid Build Coastguard Worker break;
1279*c8dee2aaSAndroid Build Coastguard Worker case 1:
1280*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.equals(text_style2));
1281*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, equal(impl->text().begin(), textRange, text2));
1282*c8dee2aaSAndroid Build Coastguard Worker break;
1283*c8dee2aaSAndroid Build Coastguard Worker case 2:
1284*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.equals(text_style3));
1285*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, equal(impl->text().begin(), textRange, text3));
1286*c8dee2aaSAndroid Build Coastguard Worker break;
1287*c8dee2aaSAndroid Build Coastguard Worker case 3:
1288*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.equals(text_style4));
1289*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, equal(impl->text().begin(), textRange, text41));
1290*c8dee2aaSAndroid Build Coastguard Worker break;
1291*c8dee2aaSAndroid Build Coastguard Worker default:
1292*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, false);
1293*c8dee2aaSAndroid Build Coastguard Worker break;
1294*c8dee2aaSAndroid Build Coastguard Worker }
1295*c8dee2aaSAndroid Build Coastguard Worker ++index;
1296*c8dee2aaSAndroid Build Coastguard Worker return true;
1297*c8dee2aaSAndroid Build Coastguard Worker });
1298*c8dee2aaSAndroid Build Coastguard Worker impl->lines()[1].scanStyles(
1299*c8dee2aaSAndroid Build Coastguard Worker StyleType::kAllAttributes,
1300*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
1301*c8dee2aaSAndroid Build Coastguard Worker switch (index) {
1302*c8dee2aaSAndroid Build Coastguard Worker case 4:
1303*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.equals(text_style4));
1304*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, equal(impl->text().begin(), textRange, text42));
1305*c8dee2aaSAndroid Build Coastguard Worker break;
1306*c8dee2aaSAndroid Build Coastguard Worker default:
1307*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, false);
1308*c8dee2aaSAndroid Build Coastguard Worker break;
1309*c8dee2aaSAndroid Build Coastguard Worker }
1310*c8dee2aaSAndroid Build Coastguard Worker ++index;
1311*c8dee2aaSAndroid Build Coastguard Worker return true;
1312*c8dee2aaSAndroid Build Coastguard Worker });
1313*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 5);
1314*c8dee2aaSAndroid Build Coastguard Worker }
1315*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_DefaultStyleParagraph,reporter)1316*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_DefaultStyleParagraph, reporter) {
1317*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1318*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1319*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_DefaultStyleParagraph.png");
1320*c8dee2aaSAndroid Build Coastguard Worker const char* text = "No TextStyle! Uh Oh!";
1321*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1322*c8dee2aaSAndroid Build Coastguard Worker
1323*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1324*c8dee2aaSAndroid Build Coastguard Worker TextStyle defaultStyle;
1325*c8dee2aaSAndroid Build Coastguard Worker defaultStyle.setFontFamilies({SkString("Roboto")});
1326*c8dee2aaSAndroid Build Coastguard Worker defaultStyle.setColor(SK_ColorBLACK);
1327*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(defaultStyle);
1328*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
1329*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1330*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1331*c8dee2aaSAndroid Build Coastguard Worker
1332*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1333*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
1334*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 10.0, 15.0);
1335*c8dee2aaSAndroid Build Coastguard Worker
1336*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
1337*c8dee2aaSAndroid Build Coastguard Worker
1338*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1339*c8dee2aaSAndroid Build Coastguard Worker
1340*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
1341*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
1342*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
1343*c8dee2aaSAndroid Build Coastguard Worker
1344*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
1345*c8dee2aaSAndroid Build Coastguard Worker impl->lines()[0].scanStyles(
1346*c8dee2aaSAndroid Build Coastguard Worker StyleType::kAllAttributes,
1347*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
1348*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.equals(paragraph_style.getTextStyle()));
1349*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, equal(impl->text().begin(), textRange, text));
1350*c8dee2aaSAndroid Build Coastguard Worker ++index;
1351*c8dee2aaSAndroid Build Coastguard Worker return true;
1352*c8dee2aaSAndroid Build Coastguard Worker });
1353*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 1);
1354*c8dee2aaSAndroid Build Coastguard Worker }
1355*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_BoldParagraph,reporter)1356*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_BoldParagraph, reporter) {
1357*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1358*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1359*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_BoldParagraph.png");
1360*c8dee2aaSAndroid Build Coastguard Worker const char* text = "This is Red max bold text!";
1361*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1362*c8dee2aaSAndroid Build Coastguard Worker
1363*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1364*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
1365*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1366*c8dee2aaSAndroid Build Coastguard Worker
1367*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1368*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1369*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorRED);
1370*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(60);
1371*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
1372*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kBlack_Weight, SkFontStyle::kNormal_Width,
1373*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
1374*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1375*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1376*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
1377*c8dee2aaSAndroid Build Coastguard Worker
1378*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1379*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(VeryLongCanvasWidth);
1380*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 10.0, 60.0);
1381*c8dee2aaSAndroid Build Coastguard Worker
1382*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
1383*c8dee2aaSAndroid Build Coastguard Worker
1384*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1385*c8dee2aaSAndroid Build Coastguard Worker
1386*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
1387*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
1388*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
1389*c8dee2aaSAndroid Build Coastguard Worker
1390*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
1391*c8dee2aaSAndroid Build Coastguard Worker impl->lines()[0].scanStyles(
1392*c8dee2aaSAndroid Build Coastguard Worker StyleType::kAllAttributes,
1393*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
1394*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.equals(text_style));
1395*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, equal(impl->text().begin(), textRange, text));
1396*c8dee2aaSAndroid Build Coastguard Worker ++index;
1397*c8dee2aaSAndroid Build Coastguard Worker return true;
1398*c8dee2aaSAndroid Build Coastguard Worker });
1399*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 1);
1400*c8dee2aaSAndroid Build Coastguard Worker }
1401*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_HeightOverrideParagraph,reporter)1402*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_HeightOverrideParagraph, reporter) {
1403*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1404*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1405*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_HeightOverrideParagraph.png");
1406*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1407*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1408*c8dee2aaSAndroid Build Coastguard Worker
1409*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1410*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
1411*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(10);
1412*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1413*c8dee2aaSAndroid Build Coastguard Worker
1414*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1415*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1416*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
1417*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
1418*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(3.6345f);
1419*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeightOverride(true);
1420*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1421*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1422*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
1423*c8dee2aaSAndroid Build Coastguard Worker
1424*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1425*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
1426*c8dee2aaSAndroid Build Coastguard Worker
1427*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1428*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 5);
1429*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1); // paragraph style does not count
1430*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
1431*c8dee2aaSAndroid Build Coastguard Worker
1432*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1433*c8dee2aaSAndroid Build Coastguard Worker
1434*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
1435*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
1436*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
1437*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1);
1438*c8dee2aaSAndroid Build Coastguard Worker
1439*c8dee2aaSAndroid Build Coastguard Worker // Tests for GetRectsForRange()
1440*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kIncludeLineSpacingMiddle;
1441*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1442*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorRED);
1443*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
1444*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
1445*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 0ull);
1446*c8dee2aaSAndroid Build Coastguard Worker
1447*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(0, 40, rect_height_style, rect_width_style);
1448*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
1449*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 3ull);
1450*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 3) {
1451*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.left(), 0, EPSILON100));
1452*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.top(), 92.805f, EPSILON5));
1453*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.right(), 43.843f, EPSILON100));
1454*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.bottom(), 165.495f, EPSILON5));
1455*c8dee2aaSAndroid Build Coastguard Worker }
1456*c8dee2aaSAndroid Build Coastguard Worker }
1457*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_BasicHalfLeading,reporter)1458*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_BasicHalfLeading, reporter) {
1459*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1460*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1461*c8dee2aaSAndroid Build Coastguard Worker
1462*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1463*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1464*c8dee2aaSAndroid Build Coastguard Worker
1465*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_BasicHalfLeading.png");
1466*c8dee2aaSAndroid Build Coastguard Worker
1467*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1468*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1469*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1470*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20.0f);
1471*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
1472*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0.0f);
1473*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0.0f);
1474*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeightOverride(true);
1475*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(3.6345f);
1476*c8dee2aaSAndroid Build Coastguard Worker text_style.setHalfLeading(true);
1477*c8dee2aaSAndroid Build Coastguard Worker
1478*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1479*c8dee2aaSAndroid Build Coastguard Worker
1480*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1481*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
1482*c8dee2aaSAndroid Build Coastguard Worker
1483*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1484*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
1485*c8dee2aaSAndroid Build Coastguard Worker
1486*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1487*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1); // paragraph style does not count
1488*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
1489*c8dee2aaSAndroid Build Coastguard Worker
1490*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1491*c8dee2aaSAndroid Build Coastguard Worker
1492*c8dee2aaSAndroid Build Coastguard Worker const RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1493*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1494*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1495*c8dee2aaSAndroid Build Coastguard Worker
1496*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
1497*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 3ull);
1498*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineBoxes.size() == boxes.size());
1499*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 3) {
1500*c8dee2aaSAndroid Build Coastguard Worker const auto line_spacing1 = boxes[1].rect.top() - boxes[0].rect.bottom();
1501*c8dee2aaSAndroid Build Coastguard Worker const auto line_spacing2 = boxes[2].rect.top() - boxes[1].rect.bottom();
1502*c8dee2aaSAndroid Build Coastguard Worker
1503*c8dee2aaSAndroid Build Coastguard Worker // Uniform line spacing.
1504*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(line_spacing1, line_spacing2));
1505*c8dee2aaSAndroid Build Coastguard Worker
1506*c8dee2aaSAndroid Build Coastguard Worker // line spacing is distributed evenly over and under the text.
1507*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[0].rect.bottom() - boxes[0].rect.bottom(), boxes[0].rect.top() - lineBoxes[0].rect.top()));
1508*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[1].rect.bottom() - boxes[1].rect.bottom(), boxes[1].rect.top() - lineBoxes[1].rect.top()));
1509*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[2].rect.bottom() - boxes[2].rect.bottom(), boxes[2].rect.top() - lineBoxes[2].rect.top()));
1510*c8dee2aaSAndroid Build Coastguard Worker
1511*c8dee2aaSAndroid Build Coastguard Worker // Half leading does not move the text horizontally.
1512*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.left(), 0, EPSILON100));
1513*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.right(), 43.843f, EPSILON100));
1514*c8dee2aaSAndroid Build Coastguard Worker }
1515*c8dee2aaSAndroid Build Coastguard Worker }
1516*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_NearZeroHeightMixedDistribution,reporter)1517*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_NearZeroHeightMixedDistribution, reporter) {
1518*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1519*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1520*c8dee2aaSAndroid Build Coastguard Worker
1521*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Cookies need love";
1522*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1523*c8dee2aaSAndroid Build Coastguard Worker
1524*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_ZeroHeightHalfLeading.png");
1525*c8dee2aaSAndroid Build Coastguard Worker
1526*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1527*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextHeightBehavior(TextHeightBehavior::kAll);
1528*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1529*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1530*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20.0f);
1531*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
1532*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0.0f);
1533*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0.0f);
1534*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeightOverride(true);
1535*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(0.001f);
1536*c8dee2aaSAndroid Build Coastguard Worker
1537*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1538*c8dee2aaSAndroid Build Coastguard Worker
1539*c8dee2aaSAndroid Build Coastguard Worker // First run, half leading.
1540*c8dee2aaSAndroid Build Coastguard Worker text_style.setHalfLeading(true);
1541*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1542*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
1543*c8dee2aaSAndroid Build Coastguard Worker
1544*c8dee2aaSAndroid Build Coastguard Worker // Second run, no half leading.
1545*c8dee2aaSAndroid Build Coastguard Worker text_style.setHalfLeading(false);
1546*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1547*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
1548*c8dee2aaSAndroid Build Coastguard Worker
1549*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1550*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
1551*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1552*c8dee2aaSAndroid Build Coastguard Worker
1553*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1554*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 2);
1555*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 2); // paragraph style does not count
1556*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1ull);
1557*c8dee2aaSAndroid Build Coastguard Worker
1558*c8dee2aaSAndroid Build Coastguard Worker const RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1559*c8dee2aaSAndroid Build Coastguard Worker
1560*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1561*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1562*c8dee2aaSAndroid Build Coastguard Worker
1563*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
1564*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1ull);
1565*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineBoxes.size() == boxes.size());
1566*c8dee2aaSAndroid Build Coastguard Worker
1567*c8dee2aaSAndroid Build Coastguard Worker // From font metrics.
1568*c8dee2aaSAndroid Build Coastguard Worker const auto metricsAscent = -18.5546875f;
1569*c8dee2aaSAndroid Build Coastguard Worker const auto metricsDescent = 4.8828125f;
1570*c8dee2aaSAndroid Build Coastguard Worker
1571*c8dee2aaSAndroid Build Coastguard Worker // As the height multiplier converges to 0 (but not 0 since 0 is used as a
1572*c8dee2aaSAndroid Build Coastguard Worker // magic value to indicate there's no height multiplier), the `Run`s top
1573*c8dee2aaSAndroid Build Coastguard Worker // edge and bottom edge will converge to a horizontal line:
1574*c8dee2aaSAndroid Build Coastguard Worker // - When half leading is used the vertical line is roughly the center of
1575*c8dee2aaSAndroid Build Coastguard Worker // of the glyphs in the run ((fontMetrics.descent - fontMetrics.ascent) / 2)
1576*c8dee2aaSAndroid Build Coastguard Worker // - When half leading is disabled the line is the alphabetic baseline.
1577*c8dee2aaSAndroid Build Coastguard Worker
1578*c8dee2aaSAndroid Build Coastguard Worker // Expected values in baseline coordinate space:
1579*c8dee2aaSAndroid Build Coastguard Worker const auto run1_ascent = (metricsAscent + metricsDescent) / 2;
1580*c8dee2aaSAndroid Build Coastguard Worker const auto run1_descent = (metricsAscent + metricsDescent) / 2;
1581*c8dee2aaSAndroid Build Coastguard Worker const auto run2_ascent = 0.0f;
1582*c8dee2aaSAndroid Build Coastguard Worker const auto run2_descent = 0.0f;
1583*c8dee2aaSAndroid Build Coastguard Worker const auto line_top = std::min(run1_ascent, run2_ascent);
1584*c8dee2aaSAndroid Build Coastguard Worker const auto line_bottom = std::max(run1_descent, run2_descent);
1585*c8dee2aaSAndroid Build Coastguard Worker
1586*c8dee2aaSAndroid Build Coastguard Worker // Expected glyph height in linebox coordinate space:
1587*c8dee2aaSAndroid Build Coastguard Worker const auto glyphs_top = metricsAscent - line_top;
1588*c8dee2aaSAndroid Build Coastguard Worker const auto glyphs_bottom = metricsDescent - line_top;
1589*c8dee2aaSAndroid Build Coastguard Worker
1590*c8dee2aaSAndroid Build Coastguard Worker // kTight reports the glyphs' bounding box in the linebox's coordinate
1591*c8dee2aaSAndroid Build Coastguard Worker // space.
1592*c8dee2aaSAndroid Build Coastguard Worker const auto actual_glyphs_top = boxes[0].rect.top() - lineBoxes[0].rect.top();
1593*c8dee2aaSAndroid Build Coastguard Worker const auto actual_glyphs_bottom = boxes[0].rect.bottom() - lineBoxes[0].rect.top();
1594*c8dee2aaSAndroid Build Coastguard Worker
1595*c8dee2aaSAndroid Build Coastguard Worker // Use a relatively large epsilon since the heightMultiplier is not actually
1596*c8dee2aaSAndroid Build Coastguard Worker // 0.
1597*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(glyphs_top, actual_glyphs_top, EPSILON20));
1598*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(glyphs_bottom, actual_glyphs_bottom, EPSILON20));
1599*c8dee2aaSAndroid Build Coastguard Worker
1600*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[0].rect.height(), line_bottom - line_top, EPSILON2));
1601*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineBoxes[0].rect.height() > 1);
1602*c8dee2aaSAndroid Build Coastguard Worker
1603*c8dee2aaSAndroid Build Coastguard Worker // Half leading does not move the text horizontally.
1604*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
1605*c8dee2aaSAndroid Build Coastguard Worker }
1606*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_StrutHalfLeadingSimple,reporter)1607*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_StrutHalfLeadingSimple, reporter) {
1608*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1609*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1610*c8dee2aaSAndroid Build Coastguard Worker
1611*c8dee2aaSAndroid Build Coastguard Worker const char* text = "A";
1612*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1613*c8dee2aaSAndroid Build Coastguard Worker
1614*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_StrutHalfLeading.png");
1615*c8dee2aaSAndroid Build Coastguard Worker
1616*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1617*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1618*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1619*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(100.0f);
1620*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
1621*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0.0f);
1622*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0.0f);
1623*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeightOverride(true);
1624*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(2.0f);
1625*c8dee2aaSAndroid Build Coastguard Worker text_style.setHalfLeading(true);
1626*c8dee2aaSAndroid Build Coastguard Worker
1627*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
1628*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontFamilies({SkString("Roboto")});
1629*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontSize(100.0f);
1630*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeightOverride(true);
1631*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeight(2.0f);
1632*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHalfLeading(true);
1633*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(true);
1634*c8dee2aaSAndroid Build Coastguard Worker strut_style.setForceStrutHeight(true);
1635*c8dee2aaSAndroid Build Coastguard Worker
1636*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
1637*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
1638*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1639*c8dee2aaSAndroid Build Coastguard Worker
1640*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1641*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
1642*c8dee2aaSAndroid Build Coastguard Worker
1643*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1644*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
1645*c8dee2aaSAndroid Build Coastguard Worker
1646*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1647*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1); // paragraph style does not count
1648*c8dee2aaSAndroid Build Coastguard Worker
1649*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1650*c8dee2aaSAndroid Build Coastguard Worker
1651*c8dee2aaSAndroid Build Coastguard Worker const RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1652*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1653*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1654*c8dee2aaSAndroid Build Coastguard Worker
1655*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
1656*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineBoxes.size() == boxes.size());
1657*c8dee2aaSAndroid Build Coastguard Worker if (lineBoxes.size() >= 1 && boxes.size() >= 1) {
1658*c8dee2aaSAndroid Build Coastguard Worker // line spacing is distributed evenly over and under the text.
1659*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[0].rect.bottom() - boxes[0].rect.bottom(), boxes[0].rect.top() - lineBoxes[0].rect.top()));
1660*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[0].rect.top(), 0.0f));
1661*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[0].rect.left(), 0.0f));
1662*c8dee2aaSAndroid Build Coastguard Worker
1663*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> lineMetrics;
1664*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(lineMetrics);
1665*c8dee2aaSAndroid Build Coastguard Worker LineMetrics& firstLine = lineMetrics[0];
1666*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(firstLine.fHeight, 200.0f));
1667*c8dee2aaSAndroid Build Coastguard Worker
1668*c8dee2aaSAndroid Build Coastguard Worker // Half leading does not move the text horizontally.
1669*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
1670*c8dee2aaSAndroid Build Coastguard Worker }
1671*c8dee2aaSAndroid Build Coastguard Worker }
1672*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_StrutHalfLeadingMultiline,reporter)1673*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_StrutHalfLeadingMultiline, reporter) {
1674*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1675*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1676*c8dee2aaSAndroid Build Coastguard Worker
1677*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1678*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1679*c8dee2aaSAndroid Build Coastguard Worker
1680*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_StrutHalfLeading.png");
1681*c8dee2aaSAndroid Build Coastguard Worker
1682*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1683*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1684*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1685*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20.0f);
1686*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
1687*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0.0f);
1688*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0.0f);
1689*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeightOverride(true);
1690*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(3.0f);
1691*c8dee2aaSAndroid Build Coastguard Worker text_style.setHalfLeading(true);
1692*c8dee2aaSAndroid Build Coastguard Worker
1693*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
1694*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontFamilies({SkString("Roboto")});
1695*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontSize(20.0f);
1696*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeightOverride(true);
1697*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeight(3.0f);
1698*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHalfLeading(true);
1699*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(true);
1700*c8dee2aaSAndroid Build Coastguard Worker strut_style.setForceStrutHeight(true);
1701*c8dee2aaSAndroid Build Coastguard Worker
1702*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
1703*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
1704*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1705*c8dee2aaSAndroid Build Coastguard Worker
1706*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1707*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
1708*c8dee2aaSAndroid Build Coastguard Worker
1709*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1710*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
1711*c8dee2aaSAndroid Build Coastguard Worker
1712*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1713*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1); // paragraph style does not count
1714*c8dee2aaSAndroid Build Coastguard Worker
1715*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1716*c8dee2aaSAndroid Build Coastguard Worker
1717*c8dee2aaSAndroid Build Coastguard Worker const RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1718*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1719*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1720*c8dee2aaSAndroid Build Coastguard Worker
1721*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
1722*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 3ull);
1723*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineBoxes.size() == boxes.size());
1724*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 3) {
1725*c8dee2aaSAndroid Build Coastguard Worker const auto line_spacing1 = boxes[1].rect.top() - boxes[0].rect.bottom();
1726*c8dee2aaSAndroid Build Coastguard Worker const auto line_spacing2 = boxes[2].rect.top() - boxes[1].rect.bottom();
1727*c8dee2aaSAndroid Build Coastguard Worker
1728*c8dee2aaSAndroid Build Coastguard Worker // Uniform line spacing.
1729*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(line_spacing1, line_spacing2));
1730*c8dee2aaSAndroid Build Coastguard Worker
1731*c8dee2aaSAndroid Build Coastguard Worker // line spacing is distributed evenly over and under the text.
1732*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[0].rect.bottom() - boxes[0].rect.bottom(), boxes[0].rect.top() - lineBoxes[0].rect.top()));
1733*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[1].rect.bottom() - boxes[1].rect.bottom(), boxes[1].rect.top() - lineBoxes[1].rect.top()));
1734*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[2].rect.bottom() - boxes[2].rect.bottom(), boxes[2].rect.top() - lineBoxes[2].rect.top()));
1735*c8dee2aaSAndroid Build Coastguard Worker
1736*c8dee2aaSAndroid Build Coastguard Worker // Half leading does not move the text horizontally.
1737*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.left(), 0, EPSILON100));
1738*c8dee2aaSAndroid Build Coastguard Worker }
1739*c8dee2aaSAndroid Build Coastguard Worker }
1740*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_TrimLeadingDistribution,reporter)1741*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_TrimLeadingDistribution, reporter) {
1742*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1743*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1744*c8dee2aaSAndroid Build Coastguard Worker
1745*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1746*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1747*c8dee2aaSAndroid Build Coastguard Worker
1748*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_TrimHalfLeading.png");
1749*c8dee2aaSAndroid Build Coastguard Worker
1750*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1751*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextHeightBehavior(TextHeightBehavior::kDisableAll);
1752*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1753*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1754*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20.0f);
1755*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
1756*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0.0f);
1757*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0.0f);
1758*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeightOverride(true);
1759*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(3.6345f);
1760*c8dee2aaSAndroid Build Coastguard Worker text_style.setHalfLeading(true);
1761*c8dee2aaSAndroid Build Coastguard Worker
1762*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1763*c8dee2aaSAndroid Build Coastguard Worker
1764*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1765*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
1766*c8dee2aaSAndroid Build Coastguard Worker
1767*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1768*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
1769*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1770*c8dee2aaSAndroid Build Coastguard Worker
1771*c8dee2aaSAndroid Build Coastguard Worker const RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1772*c8dee2aaSAndroid Build Coastguard Worker
1773*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1774*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1775*c8dee2aaSAndroid Build Coastguard Worker
1776*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
1777*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 3ull);
1778*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineBoxes.size() == boxes.size());
1779*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 3) {
1780*c8dee2aaSAndroid Build Coastguard Worker const auto line_spacing1 = boxes[1].rect.top() - boxes[0].rect.bottom();
1781*c8dee2aaSAndroid Build Coastguard Worker const auto line_spacing2 = boxes[2].rect.top() - boxes[1].rect.bottom();
1782*c8dee2aaSAndroid Build Coastguard Worker
1783*c8dee2aaSAndroid Build Coastguard Worker // Uniform line spacing. The delta is introduced by the height rounding.
1784*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(line_spacing1, line_spacing2, 1));
1785*c8dee2aaSAndroid Build Coastguard Worker
1786*c8dee2aaSAndroid Build Coastguard Worker // Trim the first line's top leading.
1787*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[0].rect.top(), boxes[0].rect.top()));
1788*c8dee2aaSAndroid Build Coastguard Worker // Trim the last line's bottom leading.
1789*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[2].rect.bottom(), boxes[2].rect.bottom()));
1790*c8dee2aaSAndroid Build Coastguard Worker
1791*c8dee2aaSAndroid Build Coastguard Worker const auto halfLeading = lineBoxes[0].rect.bottom() - boxes[0].rect.bottom();
1792*c8dee2aaSAndroid Build Coastguard Worker // Large epsilon because of rounding.
1793*c8dee2aaSAndroid Build Coastguard Worker const auto epsilon = EPSILON10;
1794*c8dee2aaSAndroid Build Coastguard Worker // line spacing is distributed evenly over and under the text.
1795*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.top() - lineBoxes[1].rect.top(), halfLeading, epsilon));
1796*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(lineBoxes[1].rect.bottom() - boxes[1].rect.bottom(), halfLeading));
1797*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[2].rect.top() - lineBoxes[2].rect.top(), halfLeading, epsilon));
1798*c8dee2aaSAndroid Build Coastguard Worker
1799*c8dee2aaSAndroid Build Coastguard Worker // Half leading does not move the text horizontally.
1800*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.left(), 0, EPSILON100));
1801*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.right(), 43.843f, EPSILON100));
1802*c8dee2aaSAndroid Build Coastguard Worker }
1803*c8dee2aaSAndroid Build Coastguard Worker }
1804*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_LeftAlignParagraph,reporter)1805*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_LeftAlignParagraph, reporter) {
1806*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1807*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1808*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_LeftAlignParagraph.png");
1809*c8dee2aaSAndroid Build Coastguard Worker const char* text =
1810*c8dee2aaSAndroid Build Coastguard Worker "This is a very long sentence to test if the text will properly wrap "
1811*c8dee2aaSAndroid Build Coastguard Worker "around and go to the next line. Sometimes, short sentence. Longer "
1812*c8dee2aaSAndroid Build Coastguard Worker "sentences are okay too because they are nessecary. Very short. "
1813*c8dee2aaSAndroid Build Coastguard Worker "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1814*c8dee2aaSAndroid Build Coastguard Worker "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1815*c8dee2aaSAndroid Build Coastguard Worker "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1816*c8dee2aaSAndroid Build Coastguard Worker "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1817*c8dee2aaSAndroid Build Coastguard Worker "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1818*c8dee2aaSAndroid Build Coastguard Worker "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1819*c8dee2aaSAndroid Build Coastguard Worker "mollit anim id est laborum. "
1820*c8dee2aaSAndroid Build Coastguard Worker "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1821*c8dee2aaSAndroid Build Coastguard Worker "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1822*c8dee2aaSAndroid Build Coastguard Worker "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1823*c8dee2aaSAndroid Build Coastguard Worker "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1824*c8dee2aaSAndroid Build Coastguard Worker "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1825*c8dee2aaSAndroid Build Coastguard Worker "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1826*c8dee2aaSAndroid Build Coastguard Worker "mollit anim id est laborum.";
1827*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1828*c8dee2aaSAndroid Build Coastguard Worker
1829*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1830*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
1831*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
1832*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
1833*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1834*c8dee2aaSAndroid Build Coastguard Worker
1835*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1836*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1837*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
1838*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
1839*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
1840*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
1841*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
1842*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
1843*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
1844*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1845*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1846*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
1847*c8dee2aaSAndroid Build Coastguard Worker
1848*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1849*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
1850*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1851*c8dee2aaSAndroid Build Coastguard Worker
1852*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1853*c8dee2aaSAndroid Build Coastguard Worker
1854*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->text().size() == std::string{text}.length());
1855*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
1856*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
1857*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
1858*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == paragraph_style.getMaxLines());
1859*c8dee2aaSAndroid Build Coastguard Worker
1860*c8dee2aaSAndroid Build Coastguard Worker double expected_y = 0;
1861*c8dee2aaSAndroid Build Coastguard Worker double epsilon = 0.01f;
1862*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[0].baseline(), 24.121f, epsilon));
1863*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1864*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[0].offset().fY, expected_y, epsilon));
1865*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
1866*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1867*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[1].offset().fY, expected_y, epsilon));
1868*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
1869*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1870*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[2].offset().fY, expected_y, epsilon));
1871*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
1872*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1873*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[3].offset().fY, expected_y, epsilon));
1874*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30 * 10;
1875*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1876*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[13].offset().fY, expected_y, epsilon));
1877*c8dee2aaSAndroid Build Coastguard Worker
1878*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1879*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.getTextAlign() == impl->paragraphStyle().getTextAlign());
1880*c8dee2aaSAndroid Build Coastguard Worker
1881*c8dee2aaSAndroid Build Coastguard Worker // Tests for GetGlyphPositionAtCoordinate()
1882*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->getGlyphPositionAtCoordinate(0, 0).position == 0);
1883*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->getGlyphPositionAtCoordinate(1, 1).position == 0);
1884*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->getGlyphPositionAtCoordinate(1, 35).position == 68);
1885*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->getGlyphPositionAtCoordinate(1, 70).position == 134);
1886*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->getGlyphPositionAtCoordinate(2000, 35).position == 134);
1887*c8dee2aaSAndroid Build Coastguard Worker }
1888*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_RightAlignParagraph,reporter)1889*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RightAlignParagraph, reporter) {
1890*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1891*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1892*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RightAlignParagraph.png");
1893*c8dee2aaSAndroid Build Coastguard Worker const char* text =
1894*c8dee2aaSAndroid Build Coastguard Worker "This is a very long sentence to test if the text will properly wrap "
1895*c8dee2aaSAndroid Build Coastguard Worker "around and go to the next line. Sometimes, short sentence. Longer "
1896*c8dee2aaSAndroid Build Coastguard Worker "sentences are okay too because they are nessecary. Very short. "
1897*c8dee2aaSAndroid Build Coastguard Worker "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1898*c8dee2aaSAndroid Build Coastguard Worker "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1899*c8dee2aaSAndroid Build Coastguard Worker "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1900*c8dee2aaSAndroid Build Coastguard Worker "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1901*c8dee2aaSAndroid Build Coastguard Worker "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1902*c8dee2aaSAndroid Build Coastguard Worker "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1903*c8dee2aaSAndroid Build Coastguard Worker "mollit anim id est laborum. "
1904*c8dee2aaSAndroid Build Coastguard Worker "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1905*c8dee2aaSAndroid Build Coastguard Worker "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1906*c8dee2aaSAndroid Build Coastguard Worker "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1907*c8dee2aaSAndroid Build Coastguard Worker "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1908*c8dee2aaSAndroid Build Coastguard Worker "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1909*c8dee2aaSAndroid Build Coastguard Worker "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1910*c8dee2aaSAndroid Build Coastguard Worker "mollit anim id est laborum.";
1911*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1912*c8dee2aaSAndroid Build Coastguard Worker
1913*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
1914*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
1915*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kRight);
1916*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
1917*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
1918*c8dee2aaSAndroid Build Coastguard Worker
1919*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
1920*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
1921*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
1922*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
1923*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
1924*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
1925*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
1926*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
1927*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
1928*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
1929*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
1930*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
1931*c8dee2aaSAndroid Build Coastguard Worker
1932*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
1933*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
1934*c8dee2aaSAndroid Build Coastguard Worker
1935*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
1936*c8dee2aaSAndroid Build Coastguard Worker
1937*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
1938*c8dee2aaSAndroid Build Coastguard Worker
1939*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
1940*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
1941*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
1942*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == paragraph_style.getMaxLines());
1943*c8dee2aaSAndroid Build Coastguard Worker
1944*c8dee2aaSAndroid Build Coastguard Worker double expected_y = 0;
1945*c8dee2aaSAndroid Build Coastguard Worker double epsilon = 0.01f;
1946*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[0].baseline(), 24.121f, epsilon));
1947*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1948*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[0].offset().fY, expected_y, epsilon));
1949*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
1950*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1951*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[1].offset().fY, expected_y, epsilon));
1952*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
1953*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1954*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[2].offset().fY, expected_y, epsilon));
1955*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
1956*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1957*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[3].offset().fY, expected_y, epsilon));
1958*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30 * 10;
1959*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1960*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[13].offset().fY, expected_y, epsilon));
1961*c8dee2aaSAndroid Build Coastguard Worker
1962*c8dee2aaSAndroid Build Coastguard Worker auto calculate = [](const TextLine& line) -> SkScalar {
1963*c8dee2aaSAndroid Build Coastguard Worker return TestCanvasWidth - 100 - line.offset().fX - line.width();
1964*c8dee2aaSAndroid Build Coastguard Worker };
1965*c8dee2aaSAndroid Build Coastguard Worker
1966*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[0]), 0, epsilon));
1967*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[1]), 0, epsilon));
1968*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[2]), 0, epsilon));
1969*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[3]), 0, epsilon));
1970*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[13]), 0, epsilon));
1971*c8dee2aaSAndroid Build Coastguard Worker
1972*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1973*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.getTextAlign() == impl->paragraphStyle().getTextAlign());
1974*c8dee2aaSAndroid Build Coastguard Worker }
1975*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_CenterAlignParagraph,reporter)1976*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_CenterAlignParagraph, reporter) {
1977*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
1978*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
1979*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_CenterAlignParagraph.png");
1980*c8dee2aaSAndroid Build Coastguard Worker const char* text =
1981*c8dee2aaSAndroid Build Coastguard Worker "This is a very long sentence to test if the text will properly wrap "
1982*c8dee2aaSAndroid Build Coastguard Worker "around and go to the next line. Sometimes, short sentence. Longer "
1983*c8dee2aaSAndroid Build Coastguard Worker "sentences are okay too because they are nessecary. Very short. "
1984*c8dee2aaSAndroid Build Coastguard Worker "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1985*c8dee2aaSAndroid Build Coastguard Worker "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1986*c8dee2aaSAndroid Build Coastguard Worker "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1987*c8dee2aaSAndroid Build Coastguard Worker "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1988*c8dee2aaSAndroid Build Coastguard Worker "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1989*c8dee2aaSAndroid Build Coastguard Worker "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1990*c8dee2aaSAndroid Build Coastguard Worker "mollit anim id est laborum. "
1991*c8dee2aaSAndroid Build Coastguard Worker "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1992*c8dee2aaSAndroid Build Coastguard Worker "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1993*c8dee2aaSAndroid Build Coastguard Worker "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1994*c8dee2aaSAndroid Build Coastguard Worker "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1995*c8dee2aaSAndroid Build Coastguard Worker "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1996*c8dee2aaSAndroid Build Coastguard Worker "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1997*c8dee2aaSAndroid Build Coastguard Worker "mollit anim id est laborum.";
1998*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
1999*c8dee2aaSAndroid Build Coastguard Worker
2000*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2001*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2002*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kCenter);
2003*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2004*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2005*c8dee2aaSAndroid Build Coastguard Worker
2006*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2007*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
2008*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
2009*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(1);
2010*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
2011*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2012*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
2013*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
2014*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2015*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2016*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2017*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2018*c8dee2aaSAndroid Build Coastguard Worker
2019*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2020*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2021*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2022*c8dee2aaSAndroid Build Coastguard Worker
2023*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2024*c8dee2aaSAndroid Build Coastguard Worker
2025*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->text().size() == std::string{text}.length());
2026*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
2027*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
2028*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
2029*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == paragraph_style.getMaxLines());
2030*c8dee2aaSAndroid Build Coastguard Worker
2031*c8dee2aaSAndroid Build Coastguard Worker double expected_y = 0;
2032*c8dee2aaSAndroid Build Coastguard Worker double epsilon = 0.01f;
2033*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[0].baseline(), 24.121f, epsilon));
2034*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2035*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[0].offset().fY, expected_y, epsilon));
2036*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
2037*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2038*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[1].offset().fY, expected_y, epsilon));
2039*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
2040*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2041*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[2].offset().fY, expected_y, epsilon));
2042*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
2043*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2044*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[3].offset().fY, expected_y, epsilon));
2045*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30 * 10;
2046*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2047*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[13].offset().fY, expected_y, epsilon));
2048*c8dee2aaSAndroid Build Coastguard Worker
2049*c8dee2aaSAndroid Build Coastguard Worker auto calculate = [](const TextLine& line) -> SkScalar {
2050*c8dee2aaSAndroid Build Coastguard Worker return TestCanvasWidth - 100 - (line.offset().fX * 2 + line.width());
2051*c8dee2aaSAndroid Build Coastguard Worker };
2052*c8dee2aaSAndroid Build Coastguard Worker
2053*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[0]), 0, epsilon));
2054*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[1]), 0, epsilon));
2055*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[2]), 0, epsilon));
2056*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[3]), 0, epsilon));
2057*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[13]), 0, epsilon));
2058*c8dee2aaSAndroid Build Coastguard Worker
2059*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2060*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.getTextAlign() == impl->paragraphStyle().getTextAlign());
2061*c8dee2aaSAndroid Build Coastguard Worker }
2062*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_JustifyAlignParagraph,reporter)2063*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_JustifyAlignParagraph, reporter) {
2064*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2065*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2066*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_JustifyAlignParagraph.png");
2067*c8dee2aaSAndroid Build Coastguard Worker const char* text =
2068*c8dee2aaSAndroid Build Coastguard Worker "This is a very long sentence to test if the text will properly wrap "
2069*c8dee2aaSAndroid Build Coastguard Worker "around and go to the next line. Sometimes, short sentence. Longer "
2070*c8dee2aaSAndroid Build Coastguard Worker "sentences are okay too because they are nessecary. Very short. "
2071*c8dee2aaSAndroid Build Coastguard Worker "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
2072*c8dee2aaSAndroid Build Coastguard Worker "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
2073*c8dee2aaSAndroid Build Coastguard Worker "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
2074*c8dee2aaSAndroid Build Coastguard Worker "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
2075*c8dee2aaSAndroid Build Coastguard Worker "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
2076*c8dee2aaSAndroid Build Coastguard Worker "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
2077*c8dee2aaSAndroid Build Coastguard Worker "mollit anim id est laborum. "
2078*c8dee2aaSAndroid Build Coastguard Worker "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
2079*c8dee2aaSAndroid Build Coastguard Worker "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
2080*c8dee2aaSAndroid Build Coastguard Worker "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
2081*c8dee2aaSAndroid Build Coastguard Worker "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
2082*c8dee2aaSAndroid Build Coastguard Worker "velit esse cillum dolore eu fugiat.";
2083*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2084*c8dee2aaSAndroid Build Coastguard Worker
2085*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2086*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2087*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kJustify);
2088*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2089*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2090*c8dee2aaSAndroid Build Coastguard Worker
2091*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2092*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
2093*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
2094*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
2095*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
2096*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2097*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
2098*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
2099*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2100*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2101*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2102*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2103*c8dee2aaSAndroid Build Coastguard Worker
2104*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2105*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2106*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2107*c8dee2aaSAndroid Build Coastguard Worker
2108*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kMax;
2109*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
2110*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2111*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
2112*c8dee2aaSAndroid Build Coastguard Worker
2113*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2114*c8dee2aaSAndroid Build Coastguard Worker
2115*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->text().size() == std::string{text}.length());
2116*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
2117*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
2118*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
2119*c8dee2aaSAndroid Build Coastguard Worker
2120*c8dee2aaSAndroid Build Coastguard Worker double expected_y = 0;
2121*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[0].baseline(), 24.121f, EPSILON100));
2122*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2123*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[0].offset().fY, expected_y, EPSILON100));
2124*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
2125*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2126*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[1].offset().fY, expected_y, EPSILON100));
2127*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
2128*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2129*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[2].offset().fY, expected_y, EPSILON100));
2130*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30;
2131*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2132*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[3].offset().fY, expected_y, EPSILON100));
2133*c8dee2aaSAndroid Build Coastguard Worker expected_y += 30 * 9;
2134*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2135*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(impl->lines()[12].offset().fY, expected_y, EPSILON100));
2136*c8dee2aaSAndroid Build Coastguard Worker
2137*c8dee2aaSAndroid Build Coastguard Worker auto calculate = [](const TextLine& line) -> SkScalar {
2138*c8dee2aaSAndroid Build Coastguard Worker return line.offset().fX;
2139*c8dee2aaSAndroid Build Coastguard Worker };
2140*c8dee2aaSAndroid Build Coastguard Worker
2141*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[0]), 0, EPSILON100));
2142*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[1]), 0, EPSILON100));
2143*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[2]), 0, EPSILON100));
2144*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(impl->lines()[3]), 0, EPSILON100));
2145*c8dee2aaSAndroid Build Coastguard Worker
2146*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2147*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.getTextAlign() == impl->paragraphStyle().getTextAlign());
2148*c8dee2aaSAndroid Build Coastguard Worker }
2149*c8dee2aaSAndroid Build Coastguard Worker
2150*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF (ghost spaces as a separate box in TxtLib)
UNIX_ONLY_TEST(SkParagraph_JustifyRTL,reporter)2151*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_JustifyRTL, reporter) {
2152*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
2153*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2154*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_JustifyRTL.png");
2155*c8dee2aaSAndroid Build Coastguard Worker const char* text =
2156*c8dee2aaSAndroid Build Coastguard Worker "אאא בּבּבּבּ אאאא בּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ "
2157*c8dee2aaSAndroid Build Coastguard Worker "אאאאא בּבּבּבּבּ אאאבּבּבּבּבּבּאאאאא בּבּבּבּבּבּאאאאאבּבּבּבּבּבּ אאאאא בּבּבּבּבּ "
2158*c8dee2aaSAndroid Build Coastguard Worker "אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ "
2159*c8dee2aaSAndroid Build Coastguard Worker "אאאאאבּבּבּבּבּבּאאאאאבּבּבּבּבּבּאאאאאבּבּבּבּבּבּ "
2160*c8dee2aaSAndroid Build Coastguard Worker "אאאאא בּבּבּבּבּבּ";
2161*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2162*c8dee2aaSAndroid Build Coastguard Worker
2163*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2164*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2165*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kJustify);
2166*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
2167*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2168*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2169*c8dee2aaSAndroid Build Coastguard Worker
2170*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2171*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
2172*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
2173*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2174*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2175*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2176*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2177*c8dee2aaSAndroid Build Coastguard Worker
2178*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2179*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2180*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2181*c8dee2aaSAndroid Build Coastguard Worker
2182*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2183*c8dee2aaSAndroid Build Coastguard Worker
2184*c8dee2aaSAndroid Build Coastguard Worker auto calculate = [](const TextLine& line) -> SkScalar {
2185*c8dee2aaSAndroid Build Coastguard Worker return TestCanvasWidth - 100 - line.width();
2186*c8dee2aaSAndroid Build Coastguard Worker };
2187*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
2188*c8dee2aaSAndroid Build Coastguard Worker if (&line == &impl->lines().back() || &line == &impl->lines()[impl->lines().size() - 2]) {
2189*c8dee2aaSAndroid Build Coastguard Worker // Second-last line will be also right-aligned because it is only one cluster
2190*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, calculate(line) > EPSILON100);
2191*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, line.offset().fX > EPSILON100);
2192*c8dee2aaSAndroid Build Coastguard Worker } else {
2193*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(calculate(line), 0, EPSILON100));
2194*c8dee2aaSAndroid Build Coastguard Worker }
2195*c8dee2aaSAndroid Build Coastguard Worker }
2196*c8dee2aaSAndroid Build Coastguard Worker
2197*c8dee2aaSAndroid Build Coastguard Worker // Just make sure the the text is actually RTL
2198*c8dee2aaSAndroid Build Coastguard Worker for (auto& run : impl->runs()) {
2199*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !run.leftToRight());
2200*c8dee2aaSAndroid Build Coastguard Worker }
2201*c8dee2aaSAndroid Build Coastguard Worker
2202*c8dee2aaSAndroid Build Coastguard Worker // Tests for GetRectsForRange()
2203*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kMax;
2204*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
2205*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2206*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
2207*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 3);
2208*c8dee2aaSAndroid Build Coastguard Worker
2209*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(226, 278, rect_height_style, rect_width_style);
2210*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorYELLOW, boxes);
2211*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
2212*c8dee2aaSAndroid Build Coastguard Worker
2213*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 16, EPSILON100));
2214*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 130, EPSILON100));
2215*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 900, EPSILON100));
2216*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 156, EPSILON100));
2217*c8dee2aaSAndroid Build Coastguard Worker
2218*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(292, 296, rect_height_style, rect_width_style);
2219*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, boxes);
2220*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
2221*c8dee2aaSAndroid Build Coastguard Worker
2222*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 588, EPSILON100));
2223*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 156, EPSILON100));
2224*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 640, EPSILON100));
2225*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 182, EPSILON100));
2226*c8dee2aaSAndroid Build Coastguard Worker }
2227*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_JustifyRTLNewLine,reporter)2228*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_JustifyRTLNewLine, reporter) {
2229*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
2230*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2231*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_JustifyRTLNewLine.png");
2232*c8dee2aaSAndroid Build Coastguard Worker const char* text =
2233*c8dee2aaSAndroid Build Coastguard Worker "אאא בּבּבּבּ אאאא\nבּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ "
2234*c8dee2aaSAndroid Build Coastguard Worker "אאאאא בּבּבּבּבּ אאאבּבּבּבּבּבּאאאאא בּבּבּבּבּבּאאאאאבּבּבּבּבּבּ אאאאא בּבּבּבּבּ "
2235*c8dee2aaSAndroid Build Coastguard Worker "אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ";
2236*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2237*c8dee2aaSAndroid Build Coastguard Worker
2238*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2239*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2240*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kJustify);
2241*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
2242*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2243*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2244*c8dee2aaSAndroid Build Coastguard Worker
2245*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2246*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
2247*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
2248*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2249*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2250*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2251*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2252*c8dee2aaSAndroid Build Coastguard Worker
2253*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2254*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2255*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2256*c8dee2aaSAndroid Build Coastguard Worker
2257*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2258*c8dee2aaSAndroid Build Coastguard Worker
2259*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
2260*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
2261*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
2262*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1);
2263*c8dee2aaSAndroid Build Coastguard Worker
2264*c8dee2aaSAndroid Build Coastguard Worker // Tests for GetRectsForRange()
2265*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kMax;
2266*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
2267*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorRED);
2268*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 30, rect_height_style, rect_width_style);
2269*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < boxes.size(); ++i) {
2270*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(boxes[i].rect, paint);
2271*c8dee2aaSAndroid Build Coastguard Worker }
2272*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 2ull);
2273*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 2) {
2274*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 562, EPSILON100));
2275*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
2276*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 900, EPSILON100));
2277*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 26, EPSILON100));
2278*c8dee2aaSAndroid Build Coastguard Worker }
2279*c8dee2aaSAndroid Build Coastguard Worker
2280*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLUE);
2281*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(240, 250, rect_height_style, rect_width_style);
2282*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < boxes.size(); ++i) {
2283*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(boxes[i].rect, paint);
2284*c8dee2aaSAndroid Build Coastguard Worker }
2285*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1ull);
2286*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
2287*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 68, EPSILON100));
2288*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 130, EPSILON100));
2289*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 120, EPSILON100));
2290*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 156, EPSILON100));
2291*c8dee2aaSAndroid Build Coastguard Worker }
2292*c8dee2aaSAndroid Build Coastguard Worker
2293*c8dee2aaSAndroid Build Coastguard Worker // All lines should be justified to the width of the paragraph
2294*c8dee2aaSAndroid Build Coastguard Worker // except for #0 (new line) and #5 (the last one)
2295*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
2296*c8dee2aaSAndroid Build Coastguard Worker ptrdiff_t num = &line - impl->lines().data();
2297*c8dee2aaSAndroid Build Coastguard Worker if (num == 0 || num == 5) {
2298*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, line.width() < TestCanvasWidth - 100);
2299*c8dee2aaSAndroid Build Coastguard Worker } else {
2300*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2301*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(line.width(), TestCanvasWidth - 100, EPSILON100),
2302*c8dee2aaSAndroid Build Coastguard Worker "#%zd: %f <= %d\n", num, line.width(), TestCanvasWidth - 100);
2303*c8dee2aaSAndroid Build Coastguard Worker }
2304*c8dee2aaSAndroid Build Coastguard Worker }
2305*c8dee2aaSAndroid Build Coastguard Worker }
2306*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_LeadingSpaceRTL,reporter)2307*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_LeadingSpaceRTL, reporter) {
2308*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
2309*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2310*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_LeadingSpaceRTL.png");
2311*c8dee2aaSAndroid Build Coastguard Worker
2312*c8dee2aaSAndroid Build Coastguard Worker const char* text = " leading space";
2313*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2314*c8dee2aaSAndroid Build Coastguard Worker
2315*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2316*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2317*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kJustify);
2318*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
2319*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2320*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2321*c8dee2aaSAndroid Build Coastguard Worker
2322*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2323*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
2324*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
2325*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2326*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2327*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2328*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2329*c8dee2aaSAndroid Build Coastguard Worker
2330*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2331*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2332*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2333*c8dee2aaSAndroid Build Coastguard Worker
2334*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
2335*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
2336*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
2337*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1);
2338*c8dee2aaSAndroid Build Coastguard Worker
2339*c8dee2aaSAndroid Build Coastguard Worker // Tests for GetRectsForRange()
2340*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kMax;
2341*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
2342*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorRED);
2343*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2344*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < boxes.size(); ++i) {
2345*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(boxes[i].rect, paint);
2346*c8dee2aaSAndroid Build Coastguard Worker }
2347*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 2ull);
2348*c8dee2aaSAndroid Build Coastguard Worker }
2349*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_DecorationsParagraph,reporter)2350*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_DecorationsParagraph, reporter) {
2351*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2352*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2353*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_DecorationsParagraph.png");
2354*c8dee2aaSAndroid Build Coastguard Worker const char* text1 = "This text should be";
2355*c8dee2aaSAndroid Build Coastguard Worker const char* text2 = " decorated even when";
2356*c8dee2aaSAndroid Build Coastguard Worker const char* text3 = " wrapped around to";
2357*c8dee2aaSAndroid Build Coastguard Worker const char* text4 = " the next line.";
2358*c8dee2aaSAndroid Build Coastguard Worker const char* text5 = " Otherwise, bad things happen.";
2359*c8dee2aaSAndroid Build Coastguard Worker
2360*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2361*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2362*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
2363*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2364*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2365*c8dee2aaSAndroid Build Coastguard Worker
2366*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2367*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
2368*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
2369*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
2370*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
2371*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2372*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(2);
2373*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
2374*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2375*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration((TextDecoration)(
2376*c8dee2aaSAndroid Build Coastguard Worker TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
2377*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationStyle(TextDecorationStyle::kSolid);
2378*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2379*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationThicknessMultiplier(2.0);
2380*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2381*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text1, strlen(text1));
2382*c8dee2aaSAndroid Build Coastguard Worker
2383*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationStyle(TextDecorationStyle::kDouble);
2384*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLUE);
2385*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationThicknessMultiplier(1.0);
2386*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2387*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text2, strlen(text2));
2388*c8dee2aaSAndroid Build Coastguard Worker
2389*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationStyle(TextDecorationStyle::kDotted);
2390*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2391*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2392*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text3, strlen(text3));
2393*c8dee2aaSAndroid Build Coastguard Worker
2394*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationStyle(TextDecorationStyle::kDashed);
2395*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2396*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationThicknessMultiplier(3.0);
2397*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2398*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text4, strlen(text4));
2399*c8dee2aaSAndroid Build Coastguard Worker
2400*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationStyle(TextDecorationStyle::kWavy);
2401*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorRED);
2402*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationThicknessMultiplier(1.0);
2403*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2404*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text5, strlen(text5));
2405*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2406*c8dee2aaSAndroid Build Coastguard Worker
2407*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2408*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2409*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2410*c8dee2aaSAndroid Build Coastguard Worker
2411*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2412*c8dee2aaSAndroid Build Coastguard Worker
2413*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
2414*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
2415*c8dee2aaSAndroid Build Coastguard Worker line.scanStyles(
2416*c8dee2aaSAndroid Build Coastguard Worker StyleType::kDecorations,
2417*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
2418*c8dee2aaSAndroid Build Coastguard Worker auto decoration = (TextDecoration)(TextDecoration::kUnderline |
2419*c8dee2aaSAndroid Build Coastguard Worker TextDecoration::kOverline |
2420*c8dee2aaSAndroid Build Coastguard Worker TextDecoration::kLineThrough);
2421*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationType() == decoration);
2422*c8dee2aaSAndroid Build Coastguard Worker switch (index) {
2423*c8dee2aaSAndroid Build Coastguard Worker case 0:
2424*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationStyle() ==
2425*c8dee2aaSAndroid Build Coastguard Worker TextDecorationStyle::kSolid);
2426*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationColor() == SK_ColorBLACK);
2427*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2428*c8dee2aaSAndroid Build Coastguard Worker style.getDecorationThicknessMultiplier() == 2.0);
2429*c8dee2aaSAndroid Build Coastguard Worker break;
2430*c8dee2aaSAndroid Build Coastguard Worker case 1: // The style appears on 2 lines so it has 2 pieces
2431*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationStyle() ==
2432*c8dee2aaSAndroid Build Coastguard Worker TextDecorationStyle::kDouble);
2433*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationColor() == SK_ColorBLUE);
2434*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2435*c8dee2aaSAndroid Build Coastguard Worker style.getDecorationThicknessMultiplier() == 1.0);
2436*c8dee2aaSAndroid Build Coastguard Worker break;
2437*c8dee2aaSAndroid Build Coastguard Worker case 2:
2438*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationStyle() ==
2439*c8dee2aaSAndroid Build Coastguard Worker TextDecorationStyle::kDotted);
2440*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationColor() == SK_ColorBLACK);
2441*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2442*c8dee2aaSAndroid Build Coastguard Worker style.getDecorationThicknessMultiplier() == 1.0);
2443*c8dee2aaSAndroid Build Coastguard Worker break;
2444*c8dee2aaSAndroid Build Coastguard Worker case 3:
2445*c8dee2aaSAndroid Build Coastguard Worker case 4:
2446*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationStyle() ==
2447*c8dee2aaSAndroid Build Coastguard Worker TextDecorationStyle::kDashed);
2448*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationColor() == SK_ColorBLACK);
2449*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2450*c8dee2aaSAndroid Build Coastguard Worker style.getDecorationThicknessMultiplier() == 3.0);
2451*c8dee2aaSAndroid Build Coastguard Worker break;
2452*c8dee2aaSAndroid Build Coastguard Worker case 5:
2453*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationStyle() ==
2454*c8dee2aaSAndroid Build Coastguard Worker TextDecorationStyle::kWavy);
2455*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getDecorationColor() == SK_ColorRED);
2456*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2457*c8dee2aaSAndroid Build Coastguard Worker style.getDecorationThicknessMultiplier() == 1.0);
2458*c8dee2aaSAndroid Build Coastguard Worker break;
2459*c8dee2aaSAndroid Build Coastguard Worker default:
2460*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, false);
2461*c8dee2aaSAndroid Build Coastguard Worker break;
2462*c8dee2aaSAndroid Build Coastguard Worker }
2463*c8dee2aaSAndroid Build Coastguard Worker ++index;
2464*c8dee2aaSAndroid Build Coastguard Worker return true;
2465*c8dee2aaSAndroid Build Coastguard Worker });
2466*c8dee2aaSAndroid Build Coastguard Worker }
2467*c8dee2aaSAndroid Build Coastguard Worker }
2468*c8dee2aaSAndroid Build Coastguard Worker
2469*c8dee2aaSAndroid Build Coastguard Worker // TODO: Add test for wavy decorations.
2470*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_ItalicsParagraph,reporter)2471*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ItalicsParagraph, reporter) {
2472*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2473*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2474*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_ItalicsParagraph.png");
2475*c8dee2aaSAndroid Build Coastguard Worker const char* text1 = "No italic ";
2476*c8dee2aaSAndroid Build Coastguard Worker const char* text2 = "Yes Italic ";
2477*c8dee2aaSAndroid Build Coastguard Worker const char* text3 = "No Italic again.";
2478*c8dee2aaSAndroid Build Coastguard Worker
2479*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2480*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2481*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2482*c8dee2aaSAndroid Build Coastguard Worker
2483*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2484*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
2485*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10);
2486*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorRED);
2487*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2488*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text1, strlen(text1));
2489*c8dee2aaSAndroid Build Coastguard Worker
2490*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
2491*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kItalic_Slant));
2492*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2493*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text2, strlen(text2));
2494*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2495*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text3, strlen(text3));
2496*c8dee2aaSAndroid Build Coastguard Worker
2497*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2498*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
2499*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2500*c8dee2aaSAndroid Build Coastguard Worker
2501*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2502*c8dee2aaSAndroid Build Coastguard Worker
2503*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 3);
2504*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 3);
2505*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
2506*c8dee2aaSAndroid Build Coastguard Worker auto& line = impl->lines()[0];
2507*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
2508*c8dee2aaSAndroid Build Coastguard Worker line.scanStyles(
2509*c8dee2aaSAndroid Build Coastguard Worker StyleType::kForeground,
2510*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
2511*c8dee2aaSAndroid Build Coastguard Worker switch (index) {
2512*c8dee2aaSAndroid Build Coastguard Worker case 0:
2513*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(
2514*c8dee2aaSAndroid Build Coastguard Worker reporter,
2515*c8dee2aaSAndroid Build Coastguard Worker style.getFontStyle().slant() == SkFontStyle::kUpright_Slant);
2516*c8dee2aaSAndroid Build Coastguard Worker break;
2517*c8dee2aaSAndroid Build Coastguard Worker case 1:
2518*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2519*c8dee2aaSAndroid Build Coastguard Worker style.getFontStyle().slant() == SkFontStyle::kItalic_Slant);
2520*c8dee2aaSAndroid Build Coastguard Worker break;
2521*c8dee2aaSAndroid Build Coastguard Worker case 2:
2522*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(
2523*c8dee2aaSAndroid Build Coastguard Worker reporter,
2524*c8dee2aaSAndroid Build Coastguard Worker style.getFontStyle().slant() == SkFontStyle::kUpright_Slant);
2525*c8dee2aaSAndroid Build Coastguard Worker break;
2526*c8dee2aaSAndroid Build Coastguard Worker default:
2527*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, false);
2528*c8dee2aaSAndroid Build Coastguard Worker break;
2529*c8dee2aaSAndroid Build Coastguard Worker }
2530*c8dee2aaSAndroid Build Coastguard Worker ++index;
2531*c8dee2aaSAndroid Build Coastguard Worker return true;
2532*c8dee2aaSAndroid Build Coastguard Worker });
2533*c8dee2aaSAndroid Build Coastguard Worker }
2534*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_ChineseParagraph,reporter)2535*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ChineseParagraph, reporter) {
2536*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2537*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2538*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_ChineseParagraph.png");
2539*c8dee2aaSAndroid Build Coastguard Worker const char* text =
2540*c8dee2aaSAndroid Build Coastguard Worker " 左線読設重説切後碁給能上目秘使約。満毎冠行来昼本可必図将発確年。今属場育"
2541*c8dee2aaSAndroid Build Coastguard Worker "図情闘陰野高備込制詩西校客。審対江置講今固残必託地集済決維駆年策。立得庭"
2542*c8dee2aaSAndroid Build Coastguard Worker "際輝求佐抗蒼提夜合逃表。注統天言件自謙雅載報紙喪。作画稿愛器灯女書利変探"
2543*c8dee2aaSAndroid Build Coastguard Worker "訃第金線朝開化建。子戦年帝励害表月幕株漠新期刊人秘。図的海力生禁挙保天戦"
2544*c8dee2aaSAndroid Build Coastguard Worker "聞条年所在口。";
2545*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2546*c8dee2aaSAndroid Build Coastguard Worker
2547*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2548*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2549*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kJustify);
2550*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2551*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2552*c8dee2aaSAndroid Build Coastguard Worker
2553*c8dee2aaSAndroid Build Coastguard Worker auto decoration = (TextDecoration)(TextDecoration::kUnderline | TextDecoration::kOverline |
2554*c8dee2aaSAndroid Build Coastguard Worker TextDecoration::kLineThrough);
2555*c8dee2aaSAndroid Build Coastguard Worker
2556*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2557*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Source Han Serif CN")});
2558*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(35);
2559*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2560*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(2);
2561*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
2562*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(decoration);
2563*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2564*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationStyle(TextDecorationStyle::kSolid);
2565*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2566*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2567*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2568*c8dee2aaSAndroid Build Coastguard Worker
2569*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2570*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2571*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2572*c8dee2aaSAndroid Build Coastguard Worker
2573*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
2574*c8dee2aaSAndroid Build Coastguard Worker
2575*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2576*c8dee2aaSAndroid Build Coastguard Worker
2577*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
2578*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 7);
2579*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
2580*c8dee2aaSAndroid Build Coastguard Worker if (impl->styles().size() >= 1) {
2581*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
2582*c8dee2aaSAndroid Build Coastguard Worker }
2583*c8dee2aaSAndroid Build Coastguard Worker }
2584*c8dee2aaSAndroid Build Coastguard Worker
2585*c8dee2aaSAndroid Build Coastguard Worker // Checked: disabled for TxtLib
UNIX_ONLY_TEST(SkParagraph_ArabicParagraph,reporter)2586*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ArabicParagraph, reporter) {
2587*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2588*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2589*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_ArabicParagraph.png");
2590*c8dee2aaSAndroid Build Coastguard Worker const char* text =
2591*c8dee2aaSAndroid Build Coastguard Worker "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
2592*c8dee2aaSAndroid Build Coastguard Worker "بمباركة التقليدية قام عن. تصفح";
2593*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2594*c8dee2aaSAndroid Build Coastguard Worker
2595*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2596*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2597*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kJustify);
2598*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2599*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2600*c8dee2aaSAndroid Build Coastguard Worker
2601*c8dee2aaSAndroid Build Coastguard Worker auto decoration = (TextDecoration)(TextDecoration::kUnderline | TextDecoration::kOverline |
2602*c8dee2aaSAndroid Build Coastguard Worker TextDecoration::kLineThrough);
2603*c8dee2aaSAndroid Build Coastguard Worker
2604*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2605*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Katibeh")});
2606*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(35);
2607*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2608*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(2);
2609*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(decoration);
2610*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2611*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationStyle(TextDecorationStyle::kSolid);
2612*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2613*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2614*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2615*c8dee2aaSAndroid Build Coastguard Worker
2616*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2617*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2618*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2619*c8dee2aaSAndroid Build Coastguard Worker
2620*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
2621*c8dee2aaSAndroid Build Coastguard Worker
2622*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2623*c8dee2aaSAndroid Build Coastguard Worker
2624*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
2625*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 2);
2626*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
2627*c8dee2aaSAndroid Build Coastguard Worker if (impl->styles().size() >= 1) {
2628*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
2629*c8dee2aaSAndroid Build Coastguard Worker }
2630*c8dee2aaSAndroid Build Coastguard Worker }
2631*c8dee2aaSAndroid Build Coastguard Worker
2632*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF (2 boxes and each space is a word)
UNIX_ONLY_TEST(SkParagraph_ArabicRectsParagraph,reporter)2633*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ArabicRectsParagraph, reporter) {
2634*c8dee2aaSAndroid Build Coastguard Worker
2635*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2636*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2637*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_ArabicRectsParagraph.png");
2638*c8dee2aaSAndroid Build Coastguard Worker const char* text = "بمباركة التقليدية قام عن. تصفح يد ";
2639*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2640*c8dee2aaSAndroid Build Coastguard Worker
2641*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2642*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2643*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2644*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kRight);
2645*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
2646*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2647*c8dee2aaSAndroid Build Coastguard Worker
2648*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2649*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Naskh Arabic")});
2650*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
2651*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
2652*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2653*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
2654*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2655*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2656*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2657*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2658*c8dee2aaSAndroid Build Coastguard Worker
2659*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2660*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2661*c8dee2aaSAndroid Build Coastguard Worker
2662*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2663*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
2664*c8dee2aaSAndroid Build Coastguard Worker
2665*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2666*c8dee2aaSAndroid Build Coastguard Worker
2667*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kMax;
2668*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
2669*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2670*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
2671*c8dee2aaSAndroid Build Coastguard Worker
2672*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1ull);
2673*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
2674*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 538.120f, EPSILON100)); // DIFF: 510.09375
2675*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), -0.280f, EPSILON100));
2676*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 900, EPSILON100));
2677*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 44, EPSILON100));
2678*c8dee2aaSAndroid Build Coastguard Worker }
2679*c8dee2aaSAndroid Build Coastguard Worker }
2680*c8dee2aaSAndroid Build Coastguard Worker
2681*c8dee2aaSAndroid Build Coastguard Worker // Checked DIFF+
2682*c8dee2aaSAndroid Build Coastguard Worker // This test shows now 2 boxes for [36:40) range:
2683*c8dee2aaSAndroid Build Coastguard Worker // [36:38) for arabic text and [38:39) for the last space
2684*c8dee2aaSAndroid Build Coastguard Worker // that has default paragraph direction (LTR) and is placed at the end of the paragraph
UNIX_ONLY_TEST(SkParagraph_ArabicRectsLTRLeftAlignParagraph,reporter)2685*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ArabicRectsLTRLeftAlignParagraph, reporter) {
2686*c8dee2aaSAndroid Build Coastguard Worker
2687*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2688*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2689*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_ArabicRectsLTRLeftAlignParagraph.png");
2690*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Helloبمباركة التقليدية قام عن. تصفح يد ";
2691*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2692*c8dee2aaSAndroid Build Coastguard Worker
2693*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2694*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2695*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2696*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
2697*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kLtr);
2698*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2699*c8dee2aaSAndroid Build Coastguard Worker
2700*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2701*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Naskh Arabic")});
2702*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
2703*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
2704*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2705*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
2706*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2707*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2708*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2709*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2710*c8dee2aaSAndroid Build Coastguard Worker
2711*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2712*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2713*c8dee2aaSAndroid Build Coastguard Worker
2714*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2715*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 3);
2716*c8dee2aaSAndroid Build Coastguard Worker
2717*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2718*c8dee2aaSAndroid Build Coastguard Worker
2719*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kMax;
2720*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
2721*c8dee2aaSAndroid Build Coastguard Worker // There are 39 codepoints: [0:39); asking for [36:40) would give the same as for [36:39)
2722*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> boxes = paragraph->getRectsForRange(36, 40, rect_height_style, rect_width_style);
2723*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
2724*c8dee2aaSAndroid Build Coastguard Worker
2725*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 2ull);
2726*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 2) {
2727*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 65.65f, EPSILON100)); // DIFF: 89.40625
2728*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), -0.27f, EPSILON100));
2729*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 86.89f, EPSILON100)); // DIFF: 121.87891
2730*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 44.0f, EPSILON100));
2731*c8dee2aaSAndroid Build Coastguard Worker }
2732*c8dee2aaSAndroid Build Coastguard Worker }
2733*c8dee2aaSAndroid Build Coastguard Worker
2734*c8dee2aaSAndroid Build Coastguard Worker // Checked DIFF+
UNIX_ONLY_TEST(SkParagraph_ArabicRectsLTRRightAlignParagraph,reporter)2735*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ArabicRectsLTRRightAlignParagraph, reporter) {
2736*c8dee2aaSAndroid Build Coastguard Worker
2737*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2738*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2739*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_ArabicRectsLTRRightAlignParagraph.png");
2740*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Helloبمباركة التقليدية قام عن. تصفح يد ";
2741*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2742*c8dee2aaSAndroid Build Coastguard Worker
2743*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
2744*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
2745*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
2746*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kRight);
2747*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kLtr);
2748*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
2749*c8dee2aaSAndroid Build Coastguard Worker
2750*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
2751*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Naskh Arabic")});
2752*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
2753*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(5);
2754*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
2755*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
2756*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
2757*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
2758*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2759*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2760*c8dee2aaSAndroid Build Coastguard Worker
2761*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2762*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
2763*c8dee2aaSAndroid Build Coastguard Worker
2764*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2765*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 3);
2766*c8dee2aaSAndroid Build Coastguard Worker
2767*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2768*c8dee2aaSAndroid Build Coastguard Worker
2769*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kMax;
2770*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
2771*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextBox> boxes =
2772*c8dee2aaSAndroid Build Coastguard Worker paragraph->getRectsForRange(36, 40, rect_height_style, rect_width_style);
2773*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
2774*c8dee2aaSAndroid Build Coastguard Worker
2775*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 2ull); // DIFF
2776*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 2) {
2777*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 561.1f, EPSILON100)); // DIFF
2778*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), -0.27f, EPSILON100));
2779*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 582.34f, EPSILON100)); // DIFF
2780*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 44, EPSILON100));
2781*c8dee2aaSAndroid Build Coastguard Worker }
2782*c8dee2aaSAndroid Build Coastguard Worker }
2783*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GetGlyphPositionAtCoordinateParagraph,reporter)2784*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetGlyphPositionAtCoordinateParagraph, reporter) {
2785*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2786*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2787*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetGlyphPositionAtCoordinateParagraph.png");
2788*c8dee2aaSAndroid Build Coastguard Worker const char* text =
2789*c8dee2aaSAndroid Build Coastguard Worker "12345 67890 12345 67890 12345 67890 12345 67890 12345 67890 12345 "
2790*c8dee2aaSAndroid Build Coastguard Worker "67890 12345";
2791*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2792*c8dee2aaSAndroid Build Coastguard Worker
2793*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
2794*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kLeft);
2795*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
2796*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
2797*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
2798*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
2799*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
2800*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
2801*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
2802*c8dee2aaSAndroid Build Coastguard Worker textStyle.setLetterSpacing(1);
2803*c8dee2aaSAndroid Build Coastguard Worker textStyle.setWordSpacing(5);
2804*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeight(1);
2805*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
2806*c8dee2aaSAndroid Build Coastguard Worker
2807*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
2808*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
2809*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2810*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2811*c8dee2aaSAndroid Build Coastguard Worker
2812*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2813*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
2814*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2815*c8dee2aaSAndroid Build Coastguard Worker
2816*c8dee2aaSAndroid Build Coastguard Worker // Tests for getGlyphPositionAtCoordinate()
2817*c8dee2aaSAndroid Build Coastguard Worker // NOTE: resulting values can be a few off from their respective positions in
2818*c8dee2aaSAndroid Build Coastguard Worker // the original text because the final trailing whitespaces are sometimes not
2819*c8dee2aaSAndroid Build Coastguard Worker // drawn (namely, when using "justify" alignment) and therefore are not active
2820*c8dee2aaSAndroid Build Coastguard Worker // glyphs.
2821*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2822*c8dee2aaSAndroid Build Coastguard Worker paragraph->getGlyphPositionAtCoordinate(-10000, -10000).position == 0);
2823*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(-1, -1).position == 0);
2824*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(0, 0).position == 0);
2825*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(3, 3).position == 0);
2826*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(35, 1).position == 1);
2827*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2828*c8dee2aaSAndroid Build Coastguard Worker paragraph->getGlyphPositionAtCoordinate(300, 2).position == 11);
2829*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(301, 2.2f).position == 11);
2830*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(302, 2.6f).position == 11);
2831*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(301, 2.1f).position == 11);
2832*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(100000, 20).position == 18);
2833*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(450, 20).position == 16);
2834*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(100000, 90).position == 36);
2835*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(-100000, 90).position == 18);
2836*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
2837*c8dee2aaSAndroid Build Coastguard Worker paragraph->getGlyphPositionAtCoordinate(20, -80).position == 1);
2838*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(1, 90).position == 18);
2839*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(1, 170).position == 36);
2840*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(10000, 180).position == 72);
2841*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(70, 180).position == 56);
2842*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(1, 270).position == 72);
2843*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(35, 90).position == 19);
2844*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(10000, 10000).position == 77);
2845*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphPositionAtCoordinate(85, 10000).position == 75);
2846*c8dee2aaSAndroid Build Coastguard Worker }
2847*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeParagraph,reporter)2848*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeParagraph, reporter) {
2849*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2850*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2851*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeParagraph.png");
2852*c8dee2aaSAndroid Build Coastguard Worker const char* text =
2853*c8dee2aaSAndroid Build Coastguard Worker "12345, \"67890\" 12345 67890 12345 67890 12345 67890 12345 67890 12345 "
2854*c8dee2aaSAndroid Build Coastguard Worker "67890 12345";
2855*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2856*c8dee2aaSAndroid Build Coastguard Worker
2857*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
2858*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kLeft);
2859*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
2860*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
2861*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
2862*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
2863*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
2864*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
2865*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
2866*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
2867*c8dee2aaSAndroid Build Coastguard Worker
2868*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
2869*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
2870*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2871*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2872*c8dee2aaSAndroid Build Coastguard Worker
2873*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2874*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
2875*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2876*c8dee2aaSAndroid Build Coastguard Worker
2877*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kMax;
2878*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kTight;
2879*c8dee2aaSAndroid Build Coastguard Worker
2880*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
2881*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
2882*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
2883*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1);
2884*c8dee2aaSAndroid Build Coastguard Worker
2885*c8dee2aaSAndroid Build Coastguard Worker {
2886*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
2887*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
2888*c8dee2aaSAndroid Build Coastguard Worker }
2889*c8dee2aaSAndroid Build Coastguard Worker {
2890*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
2891*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
2892*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
2893*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
2894*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 0, EPSILON100));
2895*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
2896*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 28.417f, EPSILON100));
2897*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
2898*c8dee2aaSAndroid Build Coastguard Worker }
2899*c8dee2aaSAndroid Build Coastguard Worker }
2900*c8dee2aaSAndroid Build Coastguard Worker {
2901*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
2902*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
2903*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
2904*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
2905*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 56.835f, EPSILON100));
2906*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
2907*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 177.97f, EPSILON100));
2908*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
2909*c8dee2aaSAndroid Build Coastguard Worker }
2910*c8dee2aaSAndroid Build Coastguard Worker }
2911*c8dee2aaSAndroid Build Coastguard Worker {
2912*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
2913*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
2914*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
2915*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
2916*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 177.97f, EPSILON100));
2917*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
2918*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 507.031f, EPSILON100));
2919*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
2920*c8dee2aaSAndroid Build Coastguard Worker }
2921*c8dee2aaSAndroid Build Coastguard Worker }
2922*c8dee2aaSAndroid Build Coastguard Worker {
2923*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(30, 100, heightStyle, widthStyle);
2924*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
2925*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 4);
2926*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 4) {
2927*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 211.375f, EPSILON100));
2928*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 59.40625f, EPSILON100));
2929*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 463.623f, EPSILON100));
2930*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 118, EPSILON100));
2931*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.left(), 0, EPSILON100));
2932*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.top(), 236.406f, EPSILON100));
2933*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.right(), 142.089f, EPSILON100));
2934*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.bottom(), 295, EPSILON100));
2935*c8dee2aaSAndroid Build Coastguard Worker }
2936*c8dee2aaSAndroid Build Coastguard Worker }
2937*c8dee2aaSAndroid Build Coastguard Worker {
2938*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
2939*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
2940*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
2941*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
2942*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 450.1875f, EPSILON20));
2943*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
2944*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 519.47266f, EPSILON20));
2945*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
2946*c8dee2aaSAndroid Build Coastguard Worker }
2947*c8dee2aaSAndroid Build Coastguard Worker }
2948*c8dee2aaSAndroid Build Coastguard Worker {
2949*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
2950*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
2951*c8dee2aaSAndroid Build Coastguard Worker }
2952*c8dee2aaSAndroid Build Coastguard Worker }
2953*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeTight,reporter)2954*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeTight, reporter) {
2955*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
2956*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
2957*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeTight.png");
2958*c8dee2aaSAndroid Build Coastguard Worker const char* text =
2959*c8dee2aaSAndroid Build Coastguard Worker "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
2960*c8dee2aaSAndroid Build Coastguard Worker " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
2961*c8dee2aaSAndroid Build Coastguard Worker " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
2962*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
2963*c8dee2aaSAndroid Build Coastguard Worker /*
2964*c8dee2aaSAndroid Build Coastguard Worker ( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)
2965*c8dee2aaSAndroid Build Coastguard Worker S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S
2966*c8dee2aaSAndroid Build Coastguard Worker G G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GGG G G G G G GG
2967*c8dee2aaSAndroid Build Coastguard Worker W W W W W W W W W W W W W W W W W W W W
2968*c8dee2aaSAndroid Build Coastguard Worker
2969*c8dee2aaSAndroid Build Coastguard Worker */
2970*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
2971*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kLeft);
2972*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
2973*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
2974*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
2975*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Noto Sans CJK JP")});
2976*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
2977*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
2978*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
2979*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
2980*c8dee2aaSAndroid Build Coastguard Worker
2981*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
2982*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
2983*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
2984*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
2985*c8dee2aaSAndroid Build Coastguard Worker
2986*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
2987*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
2988*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
2989*c8dee2aaSAndroid Build Coastguard Worker
2990*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kTight;
2991*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kTight;
2992*c8dee2aaSAndroid Build Coastguard Worker {
2993*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
2994*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
2995*c8dee2aaSAndroid Build Coastguard Worker }
2996*c8dee2aaSAndroid Build Coastguard Worker {
2997*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
2998*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
2999*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3000*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3001*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 0, EPSILON100));
3002*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0, EPSILON100));
3003*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 16.898f, EPSILON100));
3004*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 74, EPSILON100));
3005*c8dee2aaSAndroid Build Coastguard Worker }
3006*c8dee2aaSAndroid Build Coastguard Worker }
3007*c8dee2aaSAndroid Build Coastguard Worker {
3008*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3009*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
3010*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3011*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3012*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 66.899f, EPSILON100));
3013*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0, EPSILON100));
3014*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 264.099f, EPSILON100));
3015*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 74, EPSILON100));
3016*c8dee2aaSAndroid Build Coastguard Worker }
3017*c8dee2aaSAndroid Build Coastguard Worker }
3018*c8dee2aaSAndroid Build Coastguard Worker {
3019*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3020*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
3021*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 2);
3022*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 2) {
3023*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 264.099f, EPSILON100));
3024*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0, EPSILON100));
3025*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 595.085f, EPSILON50));
3026*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 74, EPSILON100));
3027*c8dee2aaSAndroid Build Coastguard Worker }
3028*c8dee2aaSAndroid Build Coastguard Worker }
3029*c8dee2aaSAndroid Build Coastguard Worker }
3030*c8dee2aaSAndroid Build Coastguard Worker
3031*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF+
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeIncludeLineSpacingMiddle,reporter)3032*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeIncludeLineSpacingMiddle, reporter) {
3033*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3034*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3035*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeIncludeLineSpacingMiddle.png");
3036*c8dee2aaSAndroid Build Coastguard Worker const char* text =
3037*c8dee2aaSAndroid Build Coastguard Worker "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3038*c8dee2aaSAndroid Build Coastguard Worker " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3039*c8dee2aaSAndroid Build Coastguard Worker " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
3040*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3041*c8dee2aaSAndroid Build Coastguard Worker
3042*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3043*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kLeft);
3044*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
3045*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
3046*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3047*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3048*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
3049*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeight(1.6f);
3050*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeightOverride(true);
3051*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3052*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
3053*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
3054*c8dee2aaSAndroid Build Coastguard Worker
3055*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3056*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3057*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3058*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3059*c8dee2aaSAndroid Build Coastguard Worker
3060*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3061*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3062*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3063*c8dee2aaSAndroid Build Coastguard Worker
3064*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kIncludeLineSpacingMiddle;
3065*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kMax;
3066*c8dee2aaSAndroid Build Coastguard Worker {
3067*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3068*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3069*c8dee2aaSAndroid Build Coastguard Worker }
3070*c8dee2aaSAndroid Build Coastguard Worker
3071*c8dee2aaSAndroid Build Coastguard Worker {
3072*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3073*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
3074*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3075*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3076*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 0, EPSILON100));
3077*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946615f, EPSILON100));
3078*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 17.4296889f, EPSILON100));
3079*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 88.473305f, EPSILON100));
3080*c8dee2aaSAndroid Build Coastguard Worker }
3081*c8dee2aaSAndroid Build Coastguard Worker }
3082*c8dee2aaSAndroid Build Coastguard Worker {
3083*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3084*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
3085*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3086*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3087*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 67.429688f, EPSILON100));
3088*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946615f, EPSILON100));
3089*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 190.00781f, EPSILON100));
3090*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 88.473305f, EPSILON100));
3091*c8dee2aaSAndroid Build Coastguard Worker }
3092*c8dee2aaSAndroid Build Coastguard Worker }
3093*c8dee2aaSAndroid Build Coastguard Worker {
3094*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3095*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
3096*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3097*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3098*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 190.00781f, EPSILON20));
3099*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946615f, EPSILON100));
3100*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 508.0625f, EPSILON20));
3101*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 88.473305f, EPSILON100));
3102*c8dee2aaSAndroid Build Coastguard Worker }
3103*c8dee2aaSAndroid Build Coastguard Worker }
3104*c8dee2aaSAndroid Build Coastguard Worker {
3105*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(30, 150, heightStyle, widthStyle);
3106*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
3107*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 8);
3108*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 8) {
3109*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 190.00781f, EPSILON20));
3110*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 88.473305f, EPSILON100));
3111*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 525.687f, EPSILON20));
3112*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 168.47331f, EPSILON100));
3113*c8dee2aaSAndroid Build Coastguard Worker
3114*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.left(), 525.687f, EPSILON20));
3115*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.top(), 88.473305f, EPSILON100));
3116*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.right(), 570.02344f, EPSILON20));
3117*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.bottom(), 168.47331f, EPSILON100));
3118*c8dee2aaSAndroid Build Coastguard Worker
3119*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.left(), 0, EPSILON100));
3120*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.top(), 168.47331f, EPSILON100));
3121*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.right(), 531.574f, EPSILON20));
3122*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.bottom(), 248.47331f, EPSILON100));
3123*c8dee2aaSAndroid Build Coastguard Worker
3124*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.left(), 531.574f, EPSILON20));
3125*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.top(), 168.47331f, EPSILON100));
3126*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.right(), 570.02344f, EPSILON20));
3127*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.bottom(), 248.47331f, EPSILON100));
3128*c8dee2aaSAndroid Build Coastguard Worker
3129*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.left(), 0, EPSILON100));
3130*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.top(), 248.47331f, EPSILON100));
3131*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.right(), 570.02344f, EPSILON20));
3132*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.bottom(), 328.47333f, EPSILON100));
3133*c8dee2aaSAndroid Build Coastguard Worker
3134*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.left(), 0, EPSILON100));
3135*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.top(), 328.47333f, EPSILON100));
3136*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.right(), 570.02344f, EPSILON20));
3137*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.bottom(), 408.4733f, EPSILON100));
3138*c8dee2aaSAndroid Build Coastguard Worker }
3139*c8dee2aaSAndroid Build Coastguard Worker }
3140*c8dee2aaSAndroid Build Coastguard Worker {
3141*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
3142*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
3143*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 2); // DIFF
3144*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 2) {
3145*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 463.72656f, EPSILON20));
3146*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946615f, EPSILON100));
3147*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 530.23047f, EPSILON20));
3148*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 88.473305f, EPSILON100));
3149*c8dee2aaSAndroid Build Coastguard Worker
3150*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.left(), 530.23047f, EPSILON20));
3151*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.top(), 16.946615f, EPSILON100));
3152*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.right(), 570.02344f, EPSILON20));
3153*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.bottom(), 88.473305f, EPSILON100));
3154*c8dee2aaSAndroid Build Coastguard Worker }
3155*c8dee2aaSAndroid Build Coastguard Worker }
3156*c8dee2aaSAndroid Build Coastguard Worker {
3157*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3158*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3159*c8dee2aaSAndroid Build Coastguard Worker }
3160*c8dee2aaSAndroid Build Coastguard Worker }
3161*c8dee2aaSAndroid Build Coastguard Worker
3162*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF+
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeIncludeLineSpacingTop,reporter)3163*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeIncludeLineSpacingTop, reporter) {
3164*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3165*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3166*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeIncludeLineSpacingTop.png");
3167*c8dee2aaSAndroid Build Coastguard Worker const char* text =
3168*c8dee2aaSAndroid Build Coastguard Worker "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3169*c8dee2aaSAndroid Build Coastguard Worker " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3170*c8dee2aaSAndroid Build Coastguard Worker " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
3171*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3172*c8dee2aaSAndroid Build Coastguard Worker
3173*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3174*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kLeft);
3175*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
3176*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
3177*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3178*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3179*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
3180*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeight(1.6f);
3181*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeightOverride(true);
3182*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3183*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
3184*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
3185*c8dee2aaSAndroid Build Coastguard Worker
3186*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3187*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3188*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3189*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3190*c8dee2aaSAndroid Build Coastguard Worker
3191*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3192*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3193*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3194*c8dee2aaSAndroid Build Coastguard Worker
3195*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kIncludeLineSpacingTop;
3196*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kMax;
3197*c8dee2aaSAndroid Build Coastguard Worker {
3198*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3199*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3200*c8dee2aaSAndroid Build Coastguard Worker }
3201*c8dee2aaSAndroid Build Coastguard Worker
3202*c8dee2aaSAndroid Build Coastguard Worker {
3203*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3204*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
3205*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3206*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3207*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 0, EPSILON100));
3208*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946615f, EPSILON100));
3209*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 17.4296889f, EPSILON100));
3210*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 80, EPSILON100));
3211*c8dee2aaSAndroid Build Coastguard Worker }
3212*c8dee2aaSAndroid Build Coastguard Worker }
3213*c8dee2aaSAndroid Build Coastguard Worker {
3214*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3215*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
3216*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3217*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3218*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 67.429688f, EPSILON100));
3219*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946615f, EPSILON100));
3220*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 190.00781f, EPSILON100));
3221*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 80, EPSILON100));
3222*c8dee2aaSAndroid Build Coastguard Worker }
3223*c8dee2aaSAndroid Build Coastguard Worker }
3224*c8dee2aaSAndroid Build Coastguard Worker {
3225*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3226*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
3227*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3228*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3229*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 190.00781f, EPSILON100));
3230*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946615f, EPSILON100));
3231*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 508.0625f, EPSILON50));
3232*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 80, EPSILON100));
3233*c8dee2aaSAndroid Build Coastguard Worker }
3234*c8dee2aaSAndroid Build Coastguard Worker }
3235*c8dee2aaSAndroid Build Coastguard Worker {
3236*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(30, 150, heightStyle, widthStyle);
3237*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorMAGENTA, result);
3238*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 8);
3239*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 8) {
3240*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 190.00781f, EPSILON100));
3241*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 80, EPSILON100));
3242*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 525.687f, EPSILON20));
3243*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 160, EPSILON100));
3244*c8dee2aaSAndroid Build Coastguard Worker
3245*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.left(), 525.687f, EPSILON20));
3246*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.top(), 80, EPSILON100));
3247*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.right(), 570.02344f, EPSILON20));
3248*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.bottom(), 160, EPSILON100));
3249*c8dee2aaSAndroid Build Coastguard Worker
3250*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.left(), 0, EPSILON100));
3251*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.top(), 160, EPSILON100));
3252*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.right(), 531.574f, EPSILON20));
3253*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.bottom(), 240, EPSILON100));
3254*c8dee2aaSAndroid Build Coastguard Worker
3255*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.left(), 531.574f, EPSILON20));
3256*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.top(), 160, EPSILON100));
3257*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.right(), 570.02344f, EPSILON20));
3258*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.bottom(), 240, EPSILON100));
3259*c8dee2aaSAndroid Build Coastguard Worker
3260*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.left(), 0, EPSILON100));
3261*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.top(), 240, EPSILON100));
3262*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.right(), 570.02344f, EPSILON20));
3263*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.bottom(), 320, EPSILON100));
3264*c8dee2aaSAndroid Build Coastguard Worker
3265*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.left(), 0, EPSILON100));
3266*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.top(), 320, EPSILON100));
3267*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.right(), 570.02344f, EPSILON20));
3268*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.bottom(), 400, EPSILON100));
3269*c8dee2aaSAndroid Build Coastguard Worker }
3270*c8dee2aaSAndroid Build Coastguard Worker }
3271*c8dee2aaSAndroid Build Coastguard Worker {
3272*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
3273*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLACK, result);
3274*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 2); // DIFF
3275*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 2) {
3276*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 463.72656f, EPSILON20));
3277*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946615f, EPSILON100));
3278*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 530.23047f, EPSILON20));
3279*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 80, EPSILON100));
3280*c8dee2aaSAndroid Build Coastguard Worker
3281*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.left(), 530.23047f, EPSILON50));
3282*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.top(), 16.946615f, EPSILON100));
3283*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.right(), 570.02344f, EPSILON20));
3284*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.bottom(), 80, EPSILON100));
3285*c8dee2aaSAndroid Build Coastguard Worker }
3286*c8dee2aaSAndroid Build Coastguard Worker }
3287*c8dee2aaSAndroid Build Coastguard Worker {
3288*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3289*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3290*c8dee2aaSAndroid Build Coastguard Worker }
3291*c8dee2aaSAndroid Build Coastguard Worker }
3292*c8dee2aaSAndroid Build Coastguard Worker
3293*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF+
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeIncludeLineSpacingBottom,reporter)3294*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeIncludeLineSpacingBottom, reporter) {
3295*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3296*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3297*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeIncludeLineSpacingBottom.png");
3298*c8dee2aaSAndroid Build Coastguard Worker const char* text =
3299*c8dee2aaSAndroid Build Coastguard Worker "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3300*c8dee2aaSAndroid Build Coastguard Worker " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3301*c8dee2aaSAndroid Build Coastguard Worker " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
3302*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3303*c8dee2aaSAndroid Build Coastguard Worker
3304*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3305*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kLeft);
3306*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
3307*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
3308*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3309*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3310*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
3311*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeight(1.6f);
3312*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeightOverride(true);
3313*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3314*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
3315*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
3316*c8dee2aaSAndroid Build Coastguard Worker
3317*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3318*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3319*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3320*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3321*c8dee2aaSAndroid Build Coastguard Worker
3322*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3323*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3324*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3325*c8dee2aaSAndroid Build Coastguard Worker
3326*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kIncludeLineSpacingBottom;
3327*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kMax;
3328*c8dee2aaSAndroid Build Coastguard Worker {
3329*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3330*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3331*c8dee2aaSAndroid Build Coastguard Worker }
3332*c8dee2aaSAndroid Build Coastguard Worker
3333*c8dee2aaSAndroid Build Coastguard Worker {
3334*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3335*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
3336*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3337*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3338*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 0, EPSILON100));
3339*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946f, EPSILON100));
3340*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 17.429f, EPSILON100));
3341*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 96.946f, EPSILON100));
3342*c8dee2aaSAndroid Build Coastguard Worker }
3343*c8dee2aaSAndroid Build Coastguard Worker }
3344*c8dee2aaSAndroid Build Coastguard Worker {
3345*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3346*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
3347*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3348*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3349*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 67.4298f, EPSILON100));
3350*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946f, EPSILON100));
3351*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 190.007f, EPSILON100));
3352*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 96.946f, EPSILON100));
3353*c8dee2aaSAndroid Build Coastguard Worker }
3354*c8dee2aaSAndroid Build Coastguard Worker }
3355*c8dee2aaSAndroid Build Coastguard Worker {
3356*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3357*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
3358*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3359*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3360*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 190.007f, EPSILON100));
3361*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946f, EPSILON100));
3362*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 508.062f, EPSILON50));
3363*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 96.946f, EPSILON100));
3364*c8dee2aaSAndroid Build Coastguard Worker }
3365*c8dee2aaSAndroid Build Coastguard Worker }
3366*c8dee2aaSAndroid Build Coastguard Worker {
3367*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(30, 150, heightStyle, widthStyle);
3368*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorMAGENTA, result);
3369*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 8);
3370*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 8) {
3371*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 190.007f, EPSILON20));
3372*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 96.946f, EPSILON100));
3373*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 525.687f, EPSILON20));
3374*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 176.946f, EPSILON100));
3375*c8dee2aaSAndroid Build Coastguard Worker
3376*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.left(), 525.687f, EPSILON20));
3377*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.top(), 96.946f, EPSILON100));
3378*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.right(), 570.023f, EPSILON20));
3379*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.bottom(), 176.946f, EPSILON100));
3380*c8dee2aaSAndroid Build Coastguard Worker
3381*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.left(), 0, EPSILON20));
3382*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.top(), 176.946f, EPSILON100));
3383*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.right(), 531.574f, EPSILON20));
3384*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[2].rect.bottom(), 256.946f, EPSILON100));
3385*c8dee2aaSAndroid Build Coastguard Worker
3386*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.left(), 531.574f, EPSILON20));
3387*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.top(), 176.946f, EPSILON100));
3388*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.right(), 570.023f, EPSILON20));
3389*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[3].rect.bottom(), 256.946f, EPSILON100));
3390*c8dee2aaSAndroid Build Coastguard Worker
3391*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.left(), 0, EPSILON20));
3392*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.top(), 256.946f, EPSILON100));
3393*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.right(), 570.023f, EPSILON20));
3394*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[4].rect.bottom(), 336.946f, EPSILON100));
3395*c8dee2aaSAndroid Build Coastguard Worker
3396*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.left(), 0, EPSILON20));
3397*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.top(), 336.946f, EPSILON100));
3398*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.right(), 570.023f, EPSILON20));
3399*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[5].rect.bottom(), 416.946f, EPSILON100));
3400*c8dee2aaSAndroid Build Coastguard Worker }
3401*c8dee2aaSAndroid Build Coastguard Worker }
3402*c8dee2aaSAndroid Build Coastguard Worker {
3403*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
3404*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLACK, result);
3405*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 2); // DIFF
3406*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 2) {
3407*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 463.726f, EPSILON20));
3408*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 16.946f, EPSILON100));
3409*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 530.230f, EPSILON20));
3410*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 96.946f, EPSILON100));
3411*c8dee2aaSAndroid Build Coastguard Worker
3412*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.left(), 530.230f, EPSILON20));
3413*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.top(), 16.946f, EPSILON100));
3414*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.right(), 570.023f, EPSILON20));
3415*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[1].rect.bottom(), 96.946f, EPSILON100));
3416*c8dee2aaSAndroid Build Coastguard Worker }
3417*c8dee2aaSAndroid Build Coastguard Worker }
3418*c8dee2aaSAndroid Build Coastguard Worker {
3419*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3420*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3421*c8dee2aaSAndroid Build Coastguard Worker }
3422*c8dee2aaSAndroid Build Coastguard Worker }
3423*c8dee2aaSAndroid Build Coastguard Worker
3424*c8dee2aaSAndroid Build Coastguard Worker // This is the test I cannot accommodate
3425*c8dee2aaSAndroid Build Coastguard Worker // Any text range gets a smallest glyph rectangle
DEF_TEST_DISABLED(SkParagraph_GetRectsForRangeIncludeCombiningCharacter,reporter)3426*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_DISABLED(SkParagraph_GetRectsForRangeIncludeCombiningCharacter, reporter) {
3427*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3428*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3429*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeIncludeCombiningCharacter.png");
3430*c8dee2aaSAndroid Build Coastguard Worker const char* text = "ดีสวัสดีชาวโลกที่น่ารัก";
3431*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3432*c8dee2aaSAndroid Build Coastguard Worker
3433*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3434*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kLeft);
3435*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
3436*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
3437*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3438*c8dee2aaSAndroid Build Coastguard Worker
3439*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3440*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3441*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
3442*c8dee2aaSAndroid Build Coastguard Worker textStyle.setLetterSpacing(1);
3443*c8dee2aaSAndroid Build Coastguard Worker textStyle.setWordSpacing(5);
3444*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeight(1);
3445*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3446*c8dee2aaSAndroid Build Coastguard Worker
3447*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3448*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3449*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3450*c8dee2aaSAndroid Build Coastguard Worker
3451*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3452*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
3453*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3454*c8dee2aaSAndroid Build Coastguard Worker
3455*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
3456*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
3457*c8dee2aaSAndroid Build Coastguard Worker
3458*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kTight;
3459*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kTight;
3460*c8dee2aaSAndroid Build Coastguard Worker {
3461*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3462*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3463*c8dee2aaSAndroid Build Coastguard Worker }
3464*c8dee2aaSAndroid Build Coastguard Worker {
3465*c8dee2aaSAndroid Build Coastguard Worker auto first = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3466*c8dee2aaSAndroid Build Coastguard Worker auto second = paragraph->getRectsForRange(1, 2, heightStyle, widthStyle);
3467*c8dee2aaSAndroid Build Coastguard Worker auto last = paragraph->getRectsForRange(0, 2, heightStyle, widthStyle);
3468*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, first.size() == 0 && second.size() == 1 && last.size() == 1);
3469*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, second[0].rect == last[0].rect);
3470*c8dee2aaSAndroid Build Coastguard Worker }
3471*c8dee2aaSAndroid Build Coastguard Worker {
3472*c8dee2aaSAndroid Build Coastguard Worker auto first = paragraph->getRectsForRange(3, 4, heightStyle, widthStyle);
3473*c8dee2aaSAndroid Build Coastguard Worker auto second = paragraph->getRectsForRange(4, 5, heightStyle, widthStyle);
3474*c8dee2aaSAndroid Build Coastguard Worker auto last = paragraph->getRectsForRange(3, 5, heightStyle, widthStyle);
3475*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, first.size() == 0 && second.size() == 1 && last.size() == 1);
3476*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, second[0].rect == last[0].rect);
3477*c8dee2aaSAndroid Build Coastguard Worker }
3478*c8dee2aaSAndroid Build Coastguard Worker {
3479*c8dee2aaSAndroid Build Coastguard Worker auto first = paragraph->getRectsForRange(14, 15, heightStyle, widthStyle);
3480*c8dee2aaSAndroid Build Coastguard Worker auto second = paragraph->getRectsForRange(15, 16, heightStyle, widthStyle);
3481*c8dee2aaSAndroid Build Coastguard Worker auto third = paragraph->getRectsForRange(16, 17, heightStyle, widthStyle);
3482*c8dee2aaSAndroid Build Coastguard Worker auto last = paragraph->getRectsForRange(14, 17, heightStyle, widthStyle);
3483*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, first.size() == 0 && second.size() == 0 && third.size() == 1 && last.size() == 1);
3484*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, third[0].rect == last[0].rect);
3485*c8dee2aaSAndroid Build Coastguard Worker }
3486*c8dee2aaSAndroid Build Coastguard Worker }
3487*c8dee2aaSAndroid Build Coastguard Worker
3488*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeCenterParagraph,reporter)3489*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeCenterParagraph, reporter) {
3490*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3491*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3492*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeCenterParagraph.png");
3493*c8dee2aaSAndroid Build Coastguard Worker // Minikin uses a hard coded list of unicode characters that he treats as invisible - as spaces.
3494*c8dee2aaSAndroid Build Coastguard Worker // It's absolutely wrong - invisibility is a glyph attribute, not character/grapheme.
3495*c8dee2aaSAndroid Build Coastguard Worker // Any attempt to substitute one for another leads to errors
3496*c8dee2aaSAndroid Build Coastguard Worker // (for instance, some fonts can use these hard coded characters for something that is visible)
3497*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234 "; // includes ideographic space and english space.
3498*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3499*c8dee2aaSAndroid Build Coastguard Worker
3500*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3501*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kCenter);
3502*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
3503*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
3504*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3505*c8dee2aaSAndroid Build Coastguard Worker
3506*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3507*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3508*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
3509*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeight(1);
3510*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3511*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
3512*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
3513*c8dee2aaSAndroid Build Coastguard Worker
3514*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3515*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3516*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3517*c8dee2aaSAndroid Build Coastguard Worker
3518*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3519*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3520*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3521*c8dee2aaSAndroid Build Coastguard Worker
3522*c8dee2aaSAndroid Build Coastguard Worker // Some of the formatting lazily done on paint
3523*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kMax;
3524*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kTight;
3525*c8dee2aaSAndroid Build Coastguard Worker {
3526*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3527*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3528*c8dee2aaSAndroid Build Coastguard Worker }
3529*c8dee2aaSAndroid Build Coastguard Worker
3530*c8dee2aaSAndroid Build Coastguard Worker {
3531*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3532*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
3533*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3534*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3535*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 203.955f, EPSILON100));
3536*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
3537*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 232.373f, EPSILON100));
3538*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
3539*c8dee2aaSAndroid Build Coastguard Worker }
3540*c8dee2aaSAndroid Build Coastguard Worker }
3541*c8dee2aaSAndroid Build Coastguard Worker
3542*c8dee2aaSAndroid Build Coastguard Worker {
3543*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(2, 4, heightStyle, widthStyle);
3544*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
3545*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3546*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3547*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 260.791f, EPSILON100));
3548*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
3549*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 317.626f, EPSILON100));
3550*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
3551*c8dee2aaSAndroid Build Coastguard Worker }
3552*c8dee2aaSAndroid Build Coastguard Worker }
3553*c8dee2aaSAndroid Build Coastguard Worker
3554*c8dee2aaSAndroid Build Coastguard Worker {
3555*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(4, 5, heightStyle, widthStyle);
3556*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
3557*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3558*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3559*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 317.626f, EPSILON100));
3560*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
3561*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 346.044f, EPSILON100));
3562*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
3563*c8dee2aaSAndroid Build Coastguard Worker }
3564*c8dee2aaSAndroid Build Coastguard Worker }
3565*c8dee2aaSAndroid Build Coastguard Worker
3566*c8dee2aaSAndroid Build Coastguard Worker {
3567*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(4, 6, heightStyle, widthStyle);
3568*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLACK, result);
3569*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1); // DIFF
3570*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3571*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 317.626f, EPSILON100));
3572*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
3573*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 358.494f, EPSILON100));
3574*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
3575*c8dee2aaSAndroid Build Coastguard Worker }
3576*c8dee2aaSAndroid Build Coastguard Worker }
3577*c8dee2aaSAndroid Build Coastguard Worker
3578*c8dee2aaSAndroid Build Coastguard Worker {
3579*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(5, 6, heightStyle, widthStyle);
3580*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
3581*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3582*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3583*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 346.044f, EPSILON100));
3584*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
3585*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 358.494f, EPSILON100));
3586*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
3587*c8dee2aaSAndroid Build Coastguard Worker }
3588*c8dee2aaSAndroid Build Coastguard Worker }
3589*c8dee2aaSAndroid Build Coastguard Worker
3590*c8dee2aaSAndroid Build Coastguard Worker {
3591*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3592*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3593*c8dee2aaSAndroid Build Coastguard Worker }
3594*c8dee2aaSAndroid Build Coastguard Worker }
3595*c8dee2aaSAndroid Build Coastguard Worker
3596*c8dee2aaSAndroid Build Coastguard Worker // Checked DIFF+
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeCenterParagraphNewlineCentered,reporter)3597*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeCenterParagraphNewlineCentered, reporter) {
3598*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3599*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3600*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeCenterParagraphNewlineCentered.png");
3601*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234\n";
3602*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3603*c8dee2aaSAndroid Build Coastguard Worker
3604*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3605*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kCenter);
3606*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
3607*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
3608*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3609*c8dee2aaSAndroid Build Coastguard Worker
3610*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3611*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3612*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
3613*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeight(1);
3614*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3615*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
3616*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
3617*c8dee2aaSAndroid Build Coastguard Worker
3618*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3619*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3620*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3621*c8dee2aaSAndroid Build Coastguard Worker
3622*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3623*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3624*c8dee2aaSAndroid Build Coastguard Worker
3625*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3626*c8dee2aaSAndroid Build Coastguard Worker
3627*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
3628*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 2);
3629*c8dee2aaSAndroid Build Coastguard Worker
3630*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kMax;
3631*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kTight;
3632*c8dee2aaSAndroid Build Coastguard Worker {
3633*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3634*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3635*c8dee2aaSAndroid Build Coastguard Worker }
3636*c8dee2aaSAndroid Build Coastguard Worker
3637*c8dee2aaSAndroid Build Coastguard Worker {
3638*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3639*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
3640*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3641*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3642*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 203.955f, EPSILON100));
3643*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, EPSILON100));
3644*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 232.373f, EPSILON100));
3645*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, EPSILON100));
3646*c8dee2aaSAndroid Build Coastguard Worker }
3647*c8dee2aaSAndroid Build Coastguard Worker }
3648*c8dee2aaSAndroid Build Coastguard Worker
3649*c8dee2aaSAndroid Build Coastguard Worker {
3650*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(6, 7, heightStyle, widthStyle);
3651*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
3652*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3653*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3654*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 275.0f, EPSILON100));
3655*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 59.406f, EPSILON100));
3656*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 275.0f, EPSILON100));
3657*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 118, EPSILON100));
3658*c8dee2aaSAndroid Build Coastguard Worker }
3659*c8dee2aaSAndroid Build Coastguard Worker }
3660*c8dee2aaSAndroid Build Coastguard Worker }
3661*c8dee2aaSAndroid Build Coastguard Worker
3662*c8dee2aaSAndroid Build Coastguard Worker // Checked NO DIFF
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeCenterMultiLineParagraph,reporter)3663*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeCenterMultiLineParagraph, reporter) {
3664*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3665*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3666*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeCenterMultiLineParagraph.png");
3667*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234 \n0123 "; // includes ideographic space and english space.
3668*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3669*c8dee2aaSAndroid Build Coastguard Worker
3670*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3671*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kCenter);
3672*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
3673*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
3674*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3675*c8dee2aaSAndroid Build Coastguard Worker
3676*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3677*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3678*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(50);
3679*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeight(1);
3680*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3681*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
3682*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
3683*c8dee2aaSAndroid Build Coastguard Worker
3684*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3685*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3686*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3687*c8dee2aaSAndroid Build Coastguard Worker
3688*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3689*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3690*c8dee2aaSAndroid Build Coastguard Worker
3691*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3692*c8dee2aaSAndroid Build Coastguard Worker
3693*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
3694*c8dee2aaSAndroid Build Coastguard Worker
3695*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 2);
3696*c8dee2aaSAndroid Build Coastguard Worker
3697*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kMax;
3698*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kTight;
3699*c8dee2aaSAndroid Build Coastguard Worker SkScalar epsilon = 0.01f;
3700*c8dee2aaSAndroid Build Coastguard Worker {
3701*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3702*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3703*c8dee2aaSAndroid Build Coastguard Worker }
3704*c8dee2aaSAndroid Build Coastguard Worker {
3705*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3706*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
3707*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3708*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3709*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 203.955f, epsilon));
3710*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, epsilon));
3711*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 232.373f, epsilon));
3712*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, epsilon));
3713*c8dee2aaSAndroid Build Coastguard Worker }
3714*c8dee2aaSAndroid Build Coastguard Worker }
3715*c8dee2aaSAndroid Build Coastguard Worker {
3716*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(2, 4, heightStyle, widthStyle);
3717*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
3718*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3719*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3720*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 260.791f, epsilon));
3721*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, epsilon));
3722*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 317.626f, epsilon));
3723*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, epsilon));
3724*c8dee2aaSAndroid Build Coastguard Worker }
3725*c8dee2aaSAndroid Build Coastguard Worker }
3726*c8dee2aaSAndroid Build Coastguard Worker {
3727*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(4, 6, heightStyle, widthStyle);
3728*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
3729*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3730*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3731*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 317.626f, epsilon));
3732*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, epsilon));
3733*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 358.494f, epsilon));
3734*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, epsilon));
3735*c8dee2aaSAndroid Build Coastguard Worker }
3736*c8dee2aaSAndroid Build Coastguard Worker }
3737*c8dee2aaSAndroid Build Coastguard Worker {
3738*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(5, 6, heightStyle, widthStyle);
3739*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorYELLOW, result);
3740*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3741*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3742*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 346.044f, epsilon));
3743*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 0.40625f, epsilon));
3744*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 358.494f, epsilon));
3745*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 59, epsilon));
3746*c8dee2aaSAndroid Build Coastguard Worker }
3747*c8dee2aaSAndroid Build Coastguard Worker }
3748*c8dee2aaSAndroid Build Coastguard Worker {
3749*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(10, 12, heightStyle, widthStyle);
3750*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorCYAN, result);
3751*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3752*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3753*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 218.164f, epsilon));
3754*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 59.40625f, epsilon));
3755*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 275, epsilon));
3756*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 118, epsilon));
3757*c8dee2aaSAndroid Build Coastguard Worker }
3758*c8dee2aaSAndroid Build Coastguard Worker }
3759*c8dee2aaSAndroid Build Coastguard Worker {
3760*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(14, 18, heightStyle, widthStyle);
3761*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLACK, result);
3762*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3763*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3764*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 331.835f, epsilon));
3765*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 59.40625f, epsilon));
3766*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 419.189f, epsilon));
3767*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 118, epsilon));
3768*c8dee2aaSAndroid Build Coastguard Worker }
3769*c8dee2aaSAndroid Build Coastguard Worker }
3770*c8dee2aaSAndroid Build Coastguard Worker {
3771*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3772*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.empty());
3773*c8dee2aaSAndroid Build Coastguard Worker }
3774*c8dee2aaSAndroid Build Coastguard Worker }
3775*c8dee2aaSAndroid Build Coastguard Worker
3776*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF (line height rounding error)
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeStrut,reporter)3777*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeStrut, reporter) {
3778*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3779*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3780*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeStrut.png");
3781*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Chinese 字典";
3782*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3783*c8dee2aaSAndroid Build Coastguard Worker
3784*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strutStyle;
3785*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setStrutEnabled(true);
3786*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setFontFamilies({SkString("Roboto")});
3787*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setFontSize(14.0);
3788*c8dee2aaSAndroid Build Coastguard Worker
3789*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3790*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setStrutStyle(strutStyle);
3791*c8dee2aaSAndroid Build Coastguard Worker
3792*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3793*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Noto Sans CJK JP")});
3794*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(20);
3795*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3796*c8dee2aaSAndroid Build Coastguard Worker
3797*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3798*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3799*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3800*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3801*c8dee2aaSAndroid Build Coastguard Worker
3802*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3803*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3804*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3805*c8dee2aaSAndroid Build Coastguard Worker
3806*c8dee2aaSAndroid Build Coastguard Worker {
3807*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 10, RectHeightStyle::kTight, RectWidthStyle::kMax);
3808*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
3809*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3810*c8dee2aaSAndroid Build Coastguard Worker }
3811*c8dee2aaSAndroid Build Coastguard Worker
3812*c8dee2aaSAndroid Build Coastguard Worker {
3813*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 10, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3814*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
3815*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3816*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3817*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.left(), 0, EPSILON100));
3818*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 10.611f, EPSILON2));
3819*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.right(), 118.605f, EPSILON50));
3820*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.bottom(), 27.017f, EPSILON2));
3821*c8dee2aaSAndroid Build Coastguard Worker }
3822*c8dee2aaSAndroid Build Coastguard Worker }
3823*c8dee2aaSAndroid Build Coastguard Worker }
3824*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeStrutWithHeight,reporter)3825*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeStrutWithHeight, reporter) {
3826*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3827*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3828*c8dee2aaSAndroid Build Coastguard Worker const char* text = "A";
3829*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3830*c8dee2aaSAndroid Build Coastguard Worker
3831*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strutStyle;
3832*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setStrutEnabled(true);
3833*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setFontFamilies({SkString("Roboto")});
3834*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setFontSize(14.0);
3835*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setHeightOverride(true);
3836*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setHeight(2.0);
3837*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setLeading(3.0);
3838*c8dee2aaSAndroid Build Coastguard Worker
3839*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3840*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setStrutStyle(strutStyle);
3841*c8dee2aaSAndroid Build Coastguard Worker
3842*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3843*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3844*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(10);
3845*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3846*c8dee2aaSAndroid Build Coastguard Worker
3847*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3848*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3849*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3850*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3851*c8dee2aaSAndroid Build Coastguard Worker
3852*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3853*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3854*c8dee2aaSAndroid Build Coastguard Worker
3855*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3856*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3857*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3858*c8dee2aaSAndroid Build Coastguard Worker // Half of the strut leading: 3.0 * 14.0 / 2
3859*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 21.0, EPSILON100));
3860*c8dee2aaSAndroid Build Coastguard Worker // Strut height 2.0 * 14.0
3861*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.height(), 28.0, EPSILON100));
3862*c8dee2aaSAndroid Build Coastguard Worker }
3863*c8dee2aaSAndroid Build Coastguard Worker }
3864*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeStrutWithHeightAndHalfLeading,reporter)3865*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeStrutWithHeightAndHalfLeading, reporter) {
3866*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3867*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3868*c8dee2aaSAndroid Build Coastguard Worker const char* text = "A";
3869*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3870*c8dee2aaSAndroid Build Coastguard Worker
3871*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strutStyle;
3872*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setStrutEnabled(true);
3873*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setFontFamilies({SkString("Roboto")});
3874*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setFontSize(14.0);
3875*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setHeightOverride(true);
3876*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setHeight(2.0);
3877*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setLeading(3.0);
3878*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setHalfLeading(true);
3879*c8dee2aaSAndroid Build Coastguard Worker
3880*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3881*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setStrutStyle(strutStyle);
3882*c8dee2aaSAndroid Build Coastguard Worker
3883*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3884*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3885*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(10);
3886*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3887*c8dee2aaSAndroid Build Coastguard Worker
3888*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3889*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3890*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3891*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3892*c8dee2aaSAndroid Build Coastguard Worker
3893*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3894*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3895*c8dee2aaSAndroid Build Coastguard Worker
3896*c8dee2aaSAndroid Build Coastguard Worker // Produces the same results as halfLeading = false.
3897*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 1, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3898*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
3899*c8dee2aaSAndroid Build Coastguard Worker if (result.size() >= 1) {
3900*c8dee2aaSAndroid Build Coastguard Worker // Half of the strut leading: 3.0 * 14.0 / 2
3901*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.top(), 21.0, EPSILON100));
3902*c8dee2aaSAndroid Build Coastguard Worker // Strut height 2.0 * 14.0
3903*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(result[0].rect.height(), 28.0, EPSILON100));
3904*c8dee2aaSAndroid Build Coastguard Worker }
3905*c8dee2aaSAndroid Build Coastguard Worker }
3906*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeStrutFallback,reporter)3907*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeStrutFallback, reporter) {
3908*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3909*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3910*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetRectsForRangeStrutFallback.png");
3911*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Chinese 字典";
3912*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3913*c8dee2aaSAndroid Build Coastguard Worker
3914*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strutStyle;
3915*c8dee2aaSAndroid Build Coastguard Worker strutStyle.setStrutEnabled(false);
3916*c8dee2aaSAndroid Build Coastguard Worker
3917*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3918*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setStrutStyle(strutStyle);
3919*c8dee2aaSAndroid Build Coastguard Worker
3920*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3921*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Noto Sans CJK JP")});
3922*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(20);
3923*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3924*c8dee2aaSAndroid Build Coastguard Worker
3925*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3926*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3927*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3928*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3929*c8dee2aaSAndroid Build Coastguard Worker
3930*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3931*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3932*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3933*c8dee2aaSAndroid Build Coastguard Worker
3934*c8dee2aaSAndroid Build Coastguard Worker auto result1 = paragraph->getRectsForRange(0, 10, RectHeightStyle::kTight, RectWidthStyle::kMax);
3935*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result1);
3936*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result1.size() == 1);
3937*c8dee2aaSAndroid Build Coastguard Worker
3938*c8dee2aaSAndroid Build Coastguard Worker auto result2 = paragraph->getRectsForRange(0, 10, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3939*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result2);
3940*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result2.size() == 1);
3941*c8dee2aaSAndroid Build Coastguard Worker
3942*c8dee2aaSAndroid Build Coastguard Worker if (result1.size() >= 1 && result2.size() >= 1) {
3943*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result1[0].rect == result2[0].rect);
3944*c8dee2aaSAndroid Build Coastguard Worker }
3945*c8dee2aaSAndroid Build Coastguard Worker }
3946*c8dee2aaSAndroid Build Coastguard Worker
3947*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF (small in numbers)
UNIX_ONLY_TEST(SkParagraph_GetWordBoundaryParagraph,reporter)3948*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetWordBoundaryParagraph, reporter) {
3949*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
3950*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
3951*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GetWordBoundaryParagraph.png");
3952*c8dee2aaSAndroid Build Coastguard Worker const char* text = "12345 67890 12345 67890 12345 67890 12345 "
3953*c8dee2aaSAndroid Build Coastguard Worker "67890 12345 67890 12345 67890 12345";
3954*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
3955*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
3956*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(TextAlign::kLeft);
3957*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setMaxLines(10);
3958*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.turnHintingOff();
3959*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
3960*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
3961*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(52);
3962*c8dee2aaSAndroid Build Coastguard Worker textStyle.setLetterSpacing(1.19039f);
3963*c8dee2aaSAndroid Build Coastguard Worker textStyle.setWordSpacing(5);
3964*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeight(1.5);
3965*c8dee2aaSAndroid Build Coastguard Worker textStyle.setHeightOverride(true);
3966*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
3967*c8dee2aaSAndroid Build Coastguard Worker
3968*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
3969*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
3970*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
3971*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
3972*c8dee2aaSAndroid Build Coastguard Worker
3973*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
3974*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
3975*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
3976*c8dee2aaSAndroid Build Coastguard Worker
3977*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(0) == SkRange<size_t>(0, 5));
3978*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(1) == SkRange<size_t>(0, 5));
3979*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(2) == SkRange<size_t>(0, 5));
3980*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(3) == SkRange<size_t>(0, 5));
3981*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(4) == SkRange<size_t>(0, 5));
3982*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(5, 6, RectHeightStyle::kMax, RectWidthStyle::kTight);
3983*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
3984*c8dee2aaSAndroid Build Coastguard Worker
3985*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(5) == SkRange<size_t>(5, 7));
3986*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(6, 7, RectHeightStyle::kMax, RectWidthStyle::kTight);
3987*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
3988*c8dee2aaSAndroid Build Coastguard Worker
3989*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(6) == SkRange<size_t>(5, 7));
3990*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(7, 8, RectHeightStyle::kMax, RectWidthStyle::kTight);
3991*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
3992*c8dee2aaSAndroid Build Coastguard Worker
3993*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(7) == SkRange<size_t>(7, 12));
3994*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(8) == SkRange<size_t>(7, 12));
3995*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(9) == SkRange<size_t>(7, 12));
3996*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(10) == SkRange<size_t>(7, 12));
3997*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(11) == SkRange<size_t>(7, 12));
3998*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(12) == SkRange<size_t>(12, 13));
3999*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(13) == SkRange<size_t>(13, 18));
4000*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(30) == SkRange<size_t>(30, 31));
4001*c8dee2aaSAndroid Build Coastguard Worker
4002*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(12, 13, RectHeightStyle::kMax, RectWidthStyle::kTight);
4003*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
4004*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(13, 14, RectHeightStyle::kMax, RectWidthStyle::kTight);
4005*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
4006*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(18, 19, RectHeightStyle::kMax, RectWidthStyle::kTight);
4007*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
4008*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(19, 20, RectHeightStyle::kMax, RectWidthStyle::kTight);
4009*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
4010*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(24, 25, RectHeightStyle::kMax, RectWidthStyle::kTight);
4011*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
4012*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(25, 26, RectHeightStyle::kMax, RectWidthStyle::kTight);
4013*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
4014*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(30, 31, RectHeightStyle::kMax, RectWidthStyle::kTight);
4015*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
4016*c8dee2aaSAndroid Build Coastguard Worker boxes = paragraph->getRectsForRange(31, 32, RectHeightStyle::kMax, RectWidthStyle::kTight);
4017*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLines(SK_ColorRED, boxes);
4018*c8dee2aaSAndroid Build Coastguard Worker
4019*c8dee2aaSAndroid Build Coastguard Worker auto outLen = static_cast<ParagraphImpl*>(paragraph.get())->text().size();
4020*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getWordBoundary(outLen - 1) == SkRange<size_t>(outLen - 5, outLen));
4021*c8dee2aaSAndroid Build Coastguard Worker }
4022*c8dee2aaSAndroid Build Coastguard Worker
4023*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF (unclear)
UNIX_ONLY_TEST(SkParagraph_SpacingParagraph,reporter)4024*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_SpacingParagraph, reporter) {
4025*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4026*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4027*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_SpacingParagraph.png");
4028*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4029*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(10);
4030*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
4031*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4032*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4033*c8dee2aaSAndroid Build Coastguard Worker
4034*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4035*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
4036*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
4037*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(20);
4038*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0);
4039*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4040*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4041*c8dee2aaSAndroid Build Coastguard Worker builder.addText("H", 1);
4042*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4043*c8dee2aaSAndroid Build Coastguard Worker
4044*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(10);
4045*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0);
4046*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4047*c8dee2aaSAndroid Build Coastguard Worker builder.addText("H", 1);
4048*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4049*c8dee2aaSAndroid Build Coastguard Worker
4050*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(20);
4051*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0);
4052*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4053*c8dee2aaSAndroid Build Coastguard Worker builder.addText("H", 1);
4054*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4055*c8dee2aaSAndroid Build Coastguard Worker
4056*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
4057*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0);
4058*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4059*c8dee2aaSAndroid Build Coastguard Worker builder.addText("|", 1);
4060*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4061*c8dee2aaSAndroid Build Coastguard Worker
4062*c8dee2aaSAndroid Build Coastguard Worker const char* hSpace = "H ";
4063*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(hSpace);
4064*c8dee2aaSAndroid Build Coastguard Worker
4065*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
4066*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(20);
4067*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4068*c8dee2aaSAndroid Build Coastguard Worker builder.addText(hSpace, len);
4069*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4070*c8dee2aaSAndroid Build Coastguard Worker
4071*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
4072*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0);
4073*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4074*c8dee2aaSAndroid Build Coastguard Worker builder.addText(hSpace, len);
4075*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4076*c8dee2aaSAndroid Build Coastguard Worker
4077*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
4078*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
4079*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(20);
4080*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4081*c8dee2aaSAndroid Build Coastguard Worker builder.addText(hSpace, len);
4082*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4083*c8dee2aaSAndroid Build Coastguard Worker
4084*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4085*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
4086*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4087*c8dee2aaSAndroid Build Coastguard Worker
4088*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4089*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
4090*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
4091*c8dee2aaSAndroid Build Coastguard Worker impl->lines().begin()->scanStyles(StyleType::kLetterSpacing,
4092*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
4093*c8dee2aaSAndroid Build Coastguard Worker ++index;
4094*c8dee2aaSAndroid Build Coastguard Worker return true;
4095*c8dee2aaSAndroid Build Coastguard Worker });
4096*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 4);
4097*c8dee2aaSAndroid Build Coastguard Worker index = 0;
4098*c8dee2aaSAndroid Build Coastguard Worker impl->lines().begin()->scanStyles(StyleType::kWordSpacing,
4099*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
4100*c8dee2aaSAndroid Build Coastguard Worker ++index;
4101*c8dee2aaSAndroid Build Coastguard Worker return true;
4102*c8dee2aaSAndroid Build Coastguard Worker });
4103*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 4);
4104*c8dee2aaSAndroid Build Coastguard Worker }
4105*c8dee2aaSAndroid Build Coastguard Worker
4106*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_LongWordParagraph,reporter)4107*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_LongWordParagraph, reporter) {
4108*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4109*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4110*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_LongWordParagraph.png");
4111*c8dee2aaSAndroid Build Coastguard Worker const char* text =
4112*c8dee2aaSAndroid Build Coastguard Worker "A "
4113*c8dee2aaSAndroid Build Coastguard Worker "veryverylongwordtoseewherethiswillwraporifitwillatallandifitdoesthenthat"
4114*c8dee2aaSAndroid Build Coastguard Worker "wouldbeagoodthingbecausethebreakingisworking.";
4115*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4116*c8dee2aaSAndroid Build Coastguard Worker
4117*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4118*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4119*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4120*c8dee2aaSAndroid Build Coastguard Worker
4121*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4122*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
4123*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorRED);
4124*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(31);
4125*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
4126*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(0);
4127*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4128*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
4129*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4130*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4131*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4132*c8dee2aaSAndroid Build Coastguard Worker
4133*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4134*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth / 2);
4135*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4136*c8dee2aaSAndroid Build Coastguard Worker
4137*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4138*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->text().size() == std::string{text}.length());
4139*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
4140*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
4141*c8dee2aaSAndroid Build Coastguard Worker if (impl->styles().size() >= 1) {
4142*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
4143*c8dee2aaSAndroid Build Coastguard Worker }
4144*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 4);
4145*c8dee2aaSAndroid Build Coastguard Worker if (impl->lines().size() >= 4) {
4146*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[0].width() > TestCanvasWidth / 2 - 20);
4147*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[1].width() > TestCanvasWidth / 2 - 20);
4148*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[2].width() > TestCanvasWidth / 2 - 20);
4149*c8dee2aaSAndroid Build Coastguard Worker }
4150*c8dee2aaSAndroid Build Coastguard Worker }
4151*c8dee2aaSAndroid Build Coastguard Worker
4152*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF?
UNIX_ONLY_TEST(SkParagraph_KernScaleParagraph,reporter)4153*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_KernScaleParagraph, reporter) {
4154*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4155*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4156*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_KernScaleParagraph.png");
4157*c8dee2aaSAndroid Build Coastguard Worker
4158*c8dee2aaSAndroid Build Coastguard Worker const char* text1 = "AVAVAWAH A0 V0 VA To The Lo";
4159*c8dee2aaSAndroid Build Coastguard Worker const char* text2 = " Dialog Text List lots of words to see "
4160*c8dee2aaSAndroid Build Coastguard Worker "if kerning works on a bigger set of characters AVAVAW";
4161*c8dee2aaSAndroid Build Coastguard Worker float scale = 3.0f;
4162*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4163*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4164*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4165*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Droid Serif")});
4166*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(100 / scale);
4167*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4168*c8dee2aaSAndroid Build Coastguard Worker
4169*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4170*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text1, strlen(text1));
4171*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4172*c8dee2aaSAndroid Build Coastguard Worker builder.addText("A", 1);
4173*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4174*c8dee2aaSAndroid Build Coastguard Worker builder.addText("V", 1);
4175*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(14 / scale);
4176*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4177*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text2, strlen(text2));
4178*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4179*c8dee2aaSAndroid Build Coastguard Worker
4180*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4181*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth / scale);
4182*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->scale(scale, scale);
4183*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4184*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->scale(1, 1);
4185*c8dee2aaSAndroid Build Coastguard Worker
4186*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4187*c8dee2aaSAndroid Build Coastguard Worker
4188*c8dee2aaSAndroid Build Coastguard Worker // First and second lines must have the same width, the third one must be bigger
4189*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 3);
4190*c8dee2aaSAndroid Build Coastguard Worker if (impl->lines().size() >= 3) {
4191*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[0].width(), 285.858f, EPSILON100));
4192*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[1].width(), 329.709f, EPSILON100));
4193*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[2].width(), 120.619f, EPSILON100));
4194*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[0].height(), 39.00f, EPSILON100));
4195*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[1].height(), 39.00f, EPSILON100));
4196*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->lines()[2].height(), 05.00f, EPSILON100));
4197*c8dee2aaSAndroid Build Coastguard Worker }
4198*c8dee2aaSAndroid Build Coastguard Worker }
4199*c8dee2aaSAndroid Build Coastguard Worker
4200*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF+
UNIX_ONLY_TEST(SkParagraph_NewlineParagraph,reporter)4201*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_NewlineParagraph, reporter) {
4202*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4203*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4204*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_NewlineParagraph.png");
4205*c8dee2aaSAndroid Build Coastguard Worker const char* text =
4206*c8dee2aaSAndroid Build Coastguard Worker "line1\nline2 test1 test2 test3 test4 test5 test6 test7\nline3\n\nline4 "
4207*c8dee2aaSAndroid Build Coastguard Worker "test1 test2 test3 test4";
4208*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4209*c8dee2aaSAndroid Build Coastguard Worker
4210*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4211*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4212*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4213*c8dee2aaSAndroid Build Coastguard Worker
4214*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4215*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
4216*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorRED);
4217*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(60);
4218*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4219*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
4220*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4221*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4222*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4223*c8dee2aaSAndroid Build Coastguard Worker
4224*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4225*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 300);
4226*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4227*c8dee2aaSAndroid Build Coastguard Worker
4228*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4229*c8dee2aaSAndroid Build Coastguard Worker // Minikin does not count empty lines but SkParagraph does
4230*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 7);
4231*c8dee2aaSAndroid Build Coastguard Worker
4232*c8dee2aaSAndroid Build Coastguard Worker if (impl->lines().size() >= 7) {
4233*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[0].offset().fY == 0);
4234*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[1].offset().fY == 70);
4235*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[2].offset().fY == 140);
4236*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[3].offset().fY == 210);
4237*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[4].offset().fY == 280); // Empty line
4238*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[5].offset().fY == 350);
4239*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines()[6].offset().fY == 420);
4240*c8dee2aaSAndroid Build Coastguard Worker }
4241*c8dee2aaSAndroid Build Coastguard Worker }
4242*c8dee2aaSAndroid Build Coastguard Worker
4243*c8dee2aaSAndroid Build Coastguard Worker // TODO: Fix underline
UNIX_ONLY_TEST(SkParagraph_EmojiParagraph,reporter)4244*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_EmojiParagraph, reporter) {
4245*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4246*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4247*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_EmojiParagraph.png");
4248*c8dee2aaSAndroid Build Coastguard Worker const char* text =
4249*c8dee2aaSAndroid Build Coastguard Worker "☺♂️\
4250*c8dee2aaSAndroid Build Coastguard Worker ☂\
4251*c8dee2aaSAndroid Build Coastguard Worker ❄⚽♀️⚓⏰\
4252*c8dee2aaSAndroid Build Coastguard Worker ❤♠♣❗️";
4253*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4254*c8dee2aaSAndroid Build Coastguard Worker
4255*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4256*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4257*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4258*c8dee2aaSAndroid Build Coastguard Worker
4259*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4260*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Color Emoji")});
4261*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
4262*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
4263*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4264*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4265*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4266*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4267*c8dee2aaSAndroid Build Coastguard Worker
4268*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4269*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
4270*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4271*c8dee2aaSAndroid Build Coastguard Worker
4272*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
4273*c8dee2aaSAndroid Build Coastguard Worker
4274*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4275*c8dee2aaSAndroid Build Coastguard Worker
4276*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 8);
4277*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
4278*c8dee2aaSAndroid Build Coastguard Worker if (&line != impl->lines().end() - 1) {
4279*c8dee2aaSAndroid Build Coastguard Worker // The actual value is 50_size / 109_ppemX * 136_advance = ~62.385319
4280*c8dee2aaSAndroid Build Coastguard Worker // FreeType reports advances in 24.6 fixed point, so each is 62.390625
4281*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
4282*c8dee2aaSAndroid Build Coastguard Worker line.width() == 998.25f ||
4283*c8dee2aaSAndroid Build Coastguard Worker (998.1 < line.width() && line.width() < 998.2),
4284*c8dee2aaSAndroid Build Coastguard Worker "width: %f", line.width());
4285*c8dee2aaSAndroid Build Coastguard Worker } else {
4286*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, line.width() < 998.25f, "width: %f", line.width());
4287*c8dee2aaSAndroid Build Coastguard Worker }
4288*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, line.height() == 59, "height: %f", line.height());
4289*c8dee2aaSAndroid Build Coastguard Worker }
4290*c8dee2aaSAndroid Build Coastguard Worker }
4291*c8dee2aaSAndroid Build Coastguard Worker
4292*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF+
UNIX_ONLY_TEST(SkParagraph_EmojiMultiLineRectsParagraph,reporter)4293*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_EmojiMultiLineRectsParagraph, reporter) {
4294*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4295*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4296*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_EmojiMultiLineRectsParagraph.png");
4297*c8dee2aaSAndroid Build Coastguard Worker const char* text =
4298*c8dee2aaSAndroid Build Coastguard Worker "i"
4299*c8dee2aaSAndroid Build Coastguard Worker ""
4300*c8dee2aaSAndroid Build Coastguard Worker ""
4301*c8dee2aaSAndroid Build Coastguard Worker ""
4302*c8dee2aaSAndroid Build Coastguard Worker "❄⚽♀️⚓⏰"
4303*c8dee2aaSAndroid Build Coastguard Worker "❤♠♣❗️";
4304*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4305*c8dee2aaSAndroid Build Coastguard Worker
4306*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4307*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4308*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4309*c8dee2aaSAndroid Build Coastguard Worker
4310*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4311*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Color Emoji")});
4312*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
4313*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4314*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4315*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4316*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4317*c8dee2aaSAndroid Build Coastguard Worker
4318*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4319*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 300);
4320*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4321*c8dee2aaSAndroid Build Coastguard Worker
4322*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
4323*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
4324*c8dee2aaSAndroid Build Coastguard Worker
4325*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4326*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 0);
4327*c8dee2aaSAndroid Build Coastguard Worker
4328*c8dee2aaSAndroid Build Coastguard Worker result = paragraph->getRectsForRange(0, 119, rect_height_style, rect_width_style);
4329*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 2);
4330*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, result);
4331*c8dee2aaSAndroid Build Coastguard Worker
4332*c8dee2aaSAndroid Build Coastguard Worker result = paragraph->getRectsForRange(122, 132, rect_height_style, rect_width_style);
4333*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 0);
4334*c8dee2aaSAndroid Build Coastguard Worker // We changed the selection algorithm and now the selection is empty
4335*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorBLUE, result);
4336*c8dee2aaSAndroid Build Coastguard Worker
4337*c8dee2aaSAndroid Build Coastguard Worker auto pos = paragraph->getGlyphPositionAtCoordinate(610, 100).position;
4338*c8dee2aaSAndroid Build Coastguard Worker result = paragraph->getRectsForRange(0, pos, rect_height_style, rect_width_style);
4339*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 2);
4340*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
4341*c8dee2aaSAndroid Build Coastguard Worker
4342*c8dee2aaSAndroid Build Coastguard Worker pos = paragraph->getGlyphPositionAtCoordinate(580, 100).position;
4343*c8dee2aaSAndroid Build Coastguard Worker result = paragraph->getRectsForRange(0, pos, rect_height_style, rect_width_style);
4344*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 2);
4345*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
4346*c8dee2aaSAndroid Build Coastguard Worker
4347*c8dee2aaSAndroid Build Coastguard Worker pos = paragraph->getGlyphPositionAtCoordinate(560, 100).position;
4348*c8dee2aaSAndroid Build Coastguard Worker result = paragraph->getRectsForRange(0, pos, rect_height_style, rect_width_style);
4349*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 2);
4350*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorGREEN, result);
4351*c8dee2aaSAndroid Build Coastguard Worker }
4352*c8dee2aaSAndroid Build Coastguard Worker
4353*c8dee2aaSAndroid Build Coastguard Worker // Checked: DIFF (line breaking)
UNIX_ONLY_TEST(SkParagraph_RepeatLayoutParagraph,reporter)4354*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RepeatLayoutParagraph, reporter) {
4355*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4356*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4357*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RepeatLayoutParagraph.png");
4358*c8dee2aaSAndroid Build Coastguard Worker const char* text =
4359*c8dee2aaSAndroid Build Coastguard Worker "Sentence to layout at diff widths to get diff line counts. short words "
4360*c8dee2aaSAndroid Build Coastguard Worker "short words short words short words short words short words short words "
4361*c8dee2aaSAndroid Build Coastguard Worker "short words short words short words short words short words short words "
4362*c8dee2aaSAndroid Build Coastguard Worker "end";
4363*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4364*c8dee2aaSAndroid Build Coastguard Worker
4365*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4366*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4367*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4368*c8dee2aaSAndroid Build Coastguard Worker
4369*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4370*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
4371*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(31);
4372*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4373*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4374*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4375*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4376*c8dee2aaSAndroid Build Coastguard Worker
4377*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4378*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(300);
4379*c8dee2aaSAndroid Build Coastguard Worker
4380*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4381*c8dee2aaSAndroid Build Coastguard Worker // Some of the formatting lazily done on paint
4382*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
4383*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
4384*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 12);
4385*c8dee2aaSAndroid Build Coastguard Worker
4386*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(600);
4387*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4388*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
4389*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
4390*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 6);
4391*c8dee2aaSAndroid Build Coastguard Worker }
4392*c8dee2aaSAndroid Build Coastguard Worker
4393*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_Ellipsize,reporter)4394*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Ellipsize, reporter) {
4395*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4396*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4397*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_Ellipsize.png");
4398*c8dee2aaSAndroid Build Coastguard Worker const char* text =
4399*c8dee2aaSAndroid Build Coastguard Worker "This is a very long sentence to test if the text will properly wrap "
4400*c8dee2aaSAndroid Build Coastguard Worker "around and go to the next line. Sometimes, short sentence. Longer "
4401*c8dee2aaSAndroid Build Coastguard Worker "sentences are okay too because they are nessecary. Very short. ";
4402*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4403*c8dee2aaSAndroid Build Coastguard Worker
4404*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4405*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(1);
4406*c8dee2aaSAndroid Build Coastguard Worker std::u16string ellipsis = u"\u2026";
4407*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setEllipsis(ellipsis);
4408*c8dee2aaSAndroid Build Coastguard Worker std::u16string e = paragraph_style.getEllipsisUtf16();
4409*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4410*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4411*c8dee2aaSAndroid Build Coastguard Worker
4412*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4413*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
4414*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4415*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4416*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4417*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4418*c8dee2aaSAndroid Build Coastguard Worker
4419*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4420*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
4421*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4422*c8dee2aaSAndroid Build Coastguard Worker
4423*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4424*c8dee2aaSAndroid Build Coastguard Worker
4425*c8dee2aaSAndroid Build Coastguard Worker // Check that the ellipsizer limited the text to one line and did not wrap to a second line.
4426*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
4427*c8dee2aaSAndroid Build Coastguard Worker if (impl->lines().size() >= 1) {
4428*c8dee2aaSAndroid Build Coastguard Worker auto& line = impl->lines()[0];
4429*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, line.ellipsis() != nullptr);
4430*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
4431*c8dee2aaSAndroid Build Coastguard Worker }
4432*c8dee2aaSAndroid Build Coastguard Worker }
4433*c8dee2aaSAndroid Build Coastguard Worker
4434*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_UnderlineShiftParagraph,reporter)4435*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_UnderlineShiftParagraph, reporter) {
4436*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4437*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4438*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_UnderlineShiftParagraph.png");
4439*c8dee2aaSAndroid Build Coastguard Worker const char* text1 = "fluttser ";
4440*c8dee2aaSAndroid Build Coastguard Worker const char* text2 = "mdje";
4441*c8dee2aaSAndroid Build Coastguard Worker const char* text3 = "fluttser mdje";
4442*c8dee2aaSAndroid Build Coastguard Worker
4443*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4444*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4445*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
4446*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(2);
4447*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4448*c8dee2aaSAndroid Build Coastguard Worker
4449*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4450*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
4451*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4452*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4453*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text1, strlen(text1));
4454*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kUnderline);
4455*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
4456*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4457*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text2, strlen(text2));
4458*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4459*c8dee2aaSAndroid Build Coastguard Worker
4460*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4461*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
4462*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4463*c8dee2aaSAndroid Build Coastguard Worker
4464*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4465*c8dee2aaSAndroid Build Coastguard Worker
4466*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder1(paragraph_style, fontCollection, get_unicode());
4467*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecoration(TextDecoration::kNoDecoration);
4468*c8dee2aaSAndroid Build Coastguard Worker builder1.pushStyle(text_style);
4469*c8dee2aaSAndroid Build Coastguard Worker builder1.addText(text3, strlen(text3));
4470*c8dee2aaSAndroid Build Coastguard Worker builder1.pop();
4471*c8dee2aaSAndroid Build Coastguard Worker
4472*c8dee2aaSAndroid Build Coastguard Worker auto paragraph1 = builder1.Build();
4473*c8dee2aaSAndroid Build Coastguard Worker paragraph1->layout(TestCanvasWidth);
4474*c8dee2aaSAndroid Build Coastguard Worker paragraph1->paint(canvas.get(), 0, 25);
4475*c8dee2aaSAndroid Build Coastguard Worker
4476*c8dee2aaSAndroid Build Coastguard Worker auto impl1 = static_cast<ParagraphImpl*>(paragraph1.get());
4477*c8dee2aaSAndroid Build Coastguard Worker
4478*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
4479*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl1->lines().size() == 1);
4480*c8dee2aaSAndroid Build Coastguard Worker
4481*c8dee2aaSAndroid Build Coastguard Worker auto rect = paragraph->getRectsForRange(0, 12, RectHeightStyle::kMax, RectWidthStyle::kTight)
4482*c8dee2aaSAndroid Build Coastguard Worker .front()
4483*c8dee2aaSAndroid Build Coastguard Worker .rect;
4484*c8dee2aaSAndroid Build Coastguard Worker auto rect1 = paragraph1->getRectsForRange(0, 12, RectHeightStyle::kMax, RectWidthStyle::kTight)
4485*c8dee2aaSAndroid Build Coastguard Worker .front()
4486*c8dee2aaSAndroid Build Coastguard Worker .rect;
4487*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, rect.fLeft == rect1.fLeft);
4488*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, rect.fRight == rect1.fRight);
4489*c8dee2aaSAndroid Build Coastguard Worker
4490*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < 12; ++i) {
4491*c8dee2aaSAndroid Build Coastguard Worker // Not all ranges produce a rectangle ("fl" goes into one cluster so [0:1) is empty)
4492*c8dee2aaSAndroid Build Coastguard Worker auto r1 = paragraph->getRectsForRange(i, i + 1, RectHeightStyle::kMax, RectWidthStyle::kTight);
4493*c8dee2aaSAndroid Build Coastguard Worker auto r2 = paragraph1->getRectsForRange(i, i + 1, RectHeightStyle::kMax, RectWidthStyle::kTight);
4494*c8dee2aaSAndroid Build Coastguard Worker
4495*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, r1.size() == r2.size());
4496*c8dee2aaSAndroid Build Coastguard Worker if (!r1.empty() && !r2.empty()) {
4497*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, r1.front().rect.fLeft == r2.front().rect.fLeft);
4498*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, r1.front().rect.fRight == r2.front().rect.fRight);
4499*c8dee2aaSAndroid Build Coastguard Worker }
4500*c8dee2aaSAndroid Build Coastguard Worker }
4501*c8dee2aaSAndroid Build Coastguard Worker }
4502*c8dee2aaSAndroid Build Coastguard Worker
4503*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_SimpleShadow,reporter)4504*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_SimpleShadow, reporter) {
4505*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4506*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4507*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_SimpleShadow.png");
4508*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Hello World Text Dialog";
4509*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4510*c8dee2aaSAndroid Build Coastguard Worker
4511*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4512*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4513*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4514*c8dee2aaSAndroid Build Coastguard Worker
4515*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4516*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
4517*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4518*c8dee2aaSAndroid Build Coastguard Worker text_style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(2.0f, 2.0f), 1.0));
4519*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4520*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4521*c8dee2aaSAndroid Build Coastguard Worker
4522*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4523*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
4524*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 10.0, 15.0);
4525*c8dee2aaSAndroid Build Coastguard Worker
4526*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4527*c8dee2aaSAndroid Build Coastguard Worker
4528*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
4529*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1);
4530*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
4531*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
4532*c8dee2aaSAndroid Build Coastguard Worker line.scanStyles(StyleType::kShadow,
4533*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
4534*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 0 && style.equals(text_style));
4535*c8dee2aaSAndroid Build Coastguard Worker ++index;
4536*c8dee2aaSAndroid Build Coastguard Worker return true;
4537*c8dee2aaSAndroid Build Coastguard Worker });
4538*c8dee2aaSAndroid Build Coastguard Worker }
4539*c8dee2aaSAndroid Build Coastguard Worker }
4540*c8dee2aaSAndroid Build Coastguard Worker
4541*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_ComplexShadow,reporter)4542*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ComplexShadow, reporter) {
4543*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4544*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4545*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_ComplexShadow.png");
4546*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Text Chunk ";
4547*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4548*c8dee2aaSAndroid Build Coastguard Worker
4549*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4550*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4551*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4552*c8dee2aaSAndroid Build Coastguard Worker
4553*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4554*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
4555*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4556*c8dee2aaSAndroid Build Coastguard Worker text_style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(2.0f, 2.0f), 1.0f));
4557*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4558*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4559*c8dee2aaSAndroid Build Coastguard Worker
4560*c8dee2aaSAndroid Build Coastguard Worker text_style.addShadow(TextShadow(SK_ColorRED, SkPoint::Make(2.0f, 2.0f), 5.0f));
4561*c8dee2aaSAndroid Build Coastguard Worker text_style.addShadow(TextShadow(SK_ColorGREEN, SkPoint::Make(10.0f, -5.0f), 3.0f));
4562*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4563*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4564*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4565*c8dee2aaSAndroid Build Coastguard Worker
4566*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4567*c8dee2aaSAndroid Build Coastguard Worker
4568*c8dee2aaSAndroid Build Coastguard Worker text_style.addShadow(TextShadow(SK_ColorRED, SkPoint::Make(0.0f, 1.0f), 0.0f));
4569*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4570*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4571*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4572*c8dee2aaSAndroid Build Coastguard Worker
4573*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4574*c8dee2aaSAndroid Build Coastguard Worker
4575*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4576*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
4577*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 10.0, 15.0);
4578*c8dee2aaSAndroid Build Coastguard Worker
4579*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4580*c8dee2aaSAndroid Build Coastguard Worker
4581*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
4582*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
4583*c8dee2aaSAndroid Build Coastguard Worker line.scanStyles(StyleType::kShadow,
4584*c8dee2aaSAndroid Build Coastguard Worker [&](TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
4585*c8dee2aaSAndroid Build Coastguard Worker ++index;
4586*c8dee2aaSAndroid Build Coastguard Worker switch (index) {
4587*c8dee2aaSAndroid Build Coastguard Worker case 1:
4588*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getShadowNumber() == 1);
4589*c8dee2aaSAndroid Build Coastguard Worker break;
4590*c8dee2aaSAndroid Build Coastguard Worker case 2:
4591*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getShadowNumber() == 3);
4592*c8dee2aaSAndroid Build Coastguard Worker break;
4593*c8dee2aaSAndroid Build Coastguard Worker case 3:
4594*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getShadowNumber() == 1);
4595*c8dee2aaSAndroid Build Coastguard Worker break;
4596*c8dee2aaSAndroid Build Coastguard Worker case 4:
4597*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getShadowNumber() == 4);
4598*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.equals(text_style));
4599*c8dee2aaSAndroid Build Coastguard Worker break;
4600*c8dee2aaSAndroid Build Coastguard Worker case 5:
4601*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getShadowNumber() == 1);
4602*c8dee2aaSAndroid Build Coastguard Worker break;
4603*c8dee2aaSAndroid Build Coastguard Worker default:
4604*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, false);
4605*c8dee2aaSAndroid Build Coastguard Worker }
4606*c8dee2aaSAndroid Build Coastguard Worker return true;
4607*c8dee2aaSAndroid Build Coastguard Worker });
4608*c8dee2aaSAndroid Build Coastguard Worker }
4609*c8dee2aaSAndroid Build Coastguard Worker }
4610*c8dee2aaSAndroid Build Coastguard Worker
4611*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_BaselineParagraph,reporter)4612*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_BaselineParagraph, reporter) {
4613*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4614*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4615*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_BaselineParagraph.png");
4616*c8dee2aaSAndroid Build Coastguard Worker const char* text =
4617*c8dee2aaSAndroid Build Coastguard Worker "左線読設Byg後碁給能上目秘使約。満毎冠行来昼本可必図将発確年。今属場育"
4618*c8dee2aaSAndroid Build Coastguard Worker "図情闘陰野高備込制詩西校客。審対江置講今固残必託地集済決維駆年策。立得";
4619*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4620*c8dee2aaSAndroid Build Coastguard Worker
4621*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4622*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4623*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
4624*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kJustify);
4625*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setHeight(1.5);
4626*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4627*c8dee2aaSAndroid Build Coastguard Worker
4628*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4629*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Source Han Serif CN")});
4630*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4631*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(55);
4632*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(2);
4633*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationStyle(TextDecorationStyle::kSolid);
4634*c8dee2aaSAndroid Build Coastguard Worker text_style.setDecorationColor(SK_ColorBLACK);
4635*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4636*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4637*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4638*c8dee2aaSAndroid Build Coastguard Worker
4639*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4640*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth - 100);
4641*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4642*c8dee2aaSAndroid Build Coastguard Worker
4643*c8dee2aaSAndroid Build Coastguard Worker SkRect rect1 = SkRect::MakeXYWH(0, paragraph->getIdeographicBaseline(),
4644*c8dee2aaSAndroid Build Coastguard Worker paragraph->getMaxWidth(),
4645*c8dee2aaSAndroid Build Coastguard Worker paragraph->getIdeographicBaseline());
4646*c8dee2aaSAndroid Build Coastguard Worker SkRect rect2 = SkRect::MakeXYWH(0, paragraph->getAlphabeticBaseline(),
4647*c8dee2aaSAndroid Build Coastguard Worker paragraph->getMaxWidth(),
4648*c8dee2aaSAndroid Build Coastguard Worker paragraph->getAlphabeticBaseline());
4649*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLine(SK_ColorRED, rect1, false);
4650*c8dee2aaSAndroid Build Coastguard Worker canvas.drawLine(SK_ColorGREEN, rect2, false);
4651*c8dee2aaSAndroid Build Coastguard Worker
4652*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
4653*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(paragraph->getIdeographicBaseline(), 79.035f, EPSILON100));
4654*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
4655*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(paragraph->getAlphabeticBaseline(), 63.305f, EPSILON100));
4656*c8dee2aaSAndroid Build Coastguard Worker }
4657*c8dee2aaSAndroid Build Coastguard Worker
4658*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF (number of runs only)
UNIX_ONLY_TEST(SkParagraph_FontFallbackParagraph,reporter)4659*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_FontFallbackParagraph, reporter) {
4660*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4661*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4662*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_FontFallbackParagraph.png");
4663*c8dee2aaSAndroid Build Coastguard Worker
4664*c8dee2aaSAndroid Build Coastguard Worker const char* text1 = "Roboto 字典 "; // Roboto + unresolved
4665*c8dee2aaSAndroid Build Coastguard Worker const char* text2 = "Homemade Apple 字典"; // Homemade Apple + Noto Sans...
4666*c8dee2aaSAndroid Build Coastguard Worker const char* text3 = "Chinese 字典"; // Homemade Apple + Source Han
4667*c8dee2aaSAndroid Build Coastguard Worker
4668*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4669*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4670*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4671*c8dee2aaSAndroid Build Coastguard Worker
4672*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4673*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({
4674*c8dee2aaSAndroid Build Coastguard Worker SkString("Not a real font"),
4675*c8dee2aaSAndroid Build Coastguard Worker SkString("Also a fake font"),
4676*c8dee2aaSAndroid Build Coastguard Worker SkString("So fake it is obvious"),
4677*c8dee2aaSAndroid Build Coastguard Worker SkString("Next one should be a real font..."),
4678*c8dee2aaSAndroid Build Coastguard Worker SkString("Roboto"),
4679*c8dee2aaSAndroid Build Coastguard Worker SkString("another fake one in between"),
4680*c8dee2aaSAndroid Build Coastguard Worker SkString("Homemade Apple"),
4681*c8dee2aaSAndroid Build Coastguard Worker });
4682*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4683*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4684*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text1, strlen(text1));
4685*c8dee2aaSAndroid Build Coastguard Worker
4686*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({
4687*c8dee2aaSAndroid Build Coastguard Worker SkString("Not a real font"),
4688*c8dee2aaSAndroid Build Coastguard Worker SkString("Also a fake font"),
4689*c8dee2aaSAndroid Build Coastguard Worker SkString("So fake it is obvious"),
4690*c8dee2aaSAndroid Build Coastguard Worker SkString("Homemade Apple"),
4691*c8dee2aaSAndroid Build Coastguard Worker SkString("Next one should be a real font..."),
4692*c8dee2aaSAndroid Build Coastguard Worker SkString("Roboto"),
4693*c8dee2aaSAndroid Build Coastguard Worker SkString("another fake one in between"),
4694*c8dee2aaSAndroid Build Coastguard Worker SkString("Noto Sans CJK JP"),
4695*c8dee2aaSAndroid Build Coastguard Worker SkString("Source Han Serif CN"),
4696*c8dee2aaSAndroid Build Coastguard Worker });
4697*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4698*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text2, strlen(text2));
4699*c8dee2aaSAndroid Build Coastguard Worker
4700*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({
4701*c8dee2aaSAndroid Build Coastguard Worker SkString("Not a real font"),
4702*c8dee2aaSAndroid Build Coastguard Worker SkString("Also a fake font"),
4703*c8dee2aaSAndroid Build Coastguard Worker SkString("So fake it is obvious"),
4704*c8dee2aaSAndroid Build Coastguard Worker SkString("Homemade Apple"),
4705*c8dee2aaSAndroid Build Coastguard Worker SkString("Next one should be a real font..."),
4706*c8dee2aaSAndroid Build Coastguard Worker SkString("Roboto"),
4707*c8dee2aaSAndroid Build Coastguard Worker SkString("another fake one in between"),
4708*c8dee2aaSAndroid Build Coastguard Worker SkString("Source Han Serif CN"),
4709*c8dee2aaSAndroid Build Coastguard Worker SkString("Noto Sans CJK JP"),
4710*c8dee2aaSAndroid Build Coastguard Worker });
4711*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4712*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text3, strlen(text3));
4713*c8dee2aaSAndroid Build Coastguard Worker
4714*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4715*c8dee2aaSAndroid Build Coastguard Worker
4716*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4717*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == -1); // Not shaped yet
4718*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
4719*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 10.0, 15.0);
4720*c8dee2aaSAndroid Build Coastguard Worker
4721*c8dee2aaSAndroid Build Coastguard Worker size_t spaceRun = 1;
4722*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 2); // From the text1 ("字典" - excluding the last space)
4723*c8dee2aaSAndroid Build Coastguard Worker
4724*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4725*c8dee2aaSAndroid Build Coastguard Worker
4726*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 6 + spaceRun);
4727*c8dee2aaSAndroid Build Coastguard Worker if (impl->runs().size() == 6 + spaceRun) {
4728*c8dee2aaSAndroid Build Coastguard Worker // Font resolution in Skia produces 6 runs because 2 parts of "Roboto 字典 " have different
4729*c8dee2aaSAndroid Build Coastguard Worker // script (Minikin merges the first 2 into one because of unresolved)
4730*c8dee2aaSAndroid Build Coastguard Worker // [Apple + Unresolved + ' '] 0, 1, 2
4731*c8dee2aaSAndroid Build Coastguard Worker // [Apple + Noto] 3, 4
4732*c8dee2aaSAndroid Build Coastguard Worker // [Apple + Han] 5, 6
4733*c8dee2aaSAndroid Build Coastguard Worker auto robotoAdvance = impl->runs()[0].advance().fX +
4734*c8dee2aaSAndroid Build Coastguard Worker impl->runs()[1].advance().fX;
4735*c8dee2aaSAndroid Build Coastguard Worker robotoAdvance += impl->runs()[2].advance().fX;
4736*c8dee2aaSAndroid Build Coastguard Worker
4737*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(robotoAdvance, 64.199f, EPSILON50));
4738*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->runs()[2 + spaceRun].advance().fX, 139.125f, EPSILON100));
4739*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->runs()[3 + spaceRun].advance().fX, 27.999f, EPSILON100));
4740*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->runs()[4 + spaceRun].advance().fX, 62.248f, EPSILON100));
4741*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(impl->runs()[5 + spaceRun].advance().fX, 27.999f, EPSILON100));
4742*c8dee2aaSAndroid Build Coastguard Worker
4743*c8dee2aaSAndroid Build Coastguard Worker // When a different font is resolved, then the metrics are different.
4744*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs()[3 + spaceRun].correctAscent() != impl->runs()[5 + spaceRun].correctAscent());
4745*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs()[3 + spaceRun].correctDescent() != impl->runs()[5 + spaceRun].correctDescent());
4746*c8dee2aaSAndroid Build Coastguard Worker }
4747*c8dee2aaSAndroid Build Coastguard Worker }
4748*c8dee2aaSAndroid Build Coastguard Worker
4749*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_StrutParagraph1,reporter)4750*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_StrutParagraph1, reporter) {
4751*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4752*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4753*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_StrutParagraph1.png");
4754*c8dee2aaSAndroid Build Coastguard Worker // The chinese extra height should be absorbed by the strut.
4755*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234満毎冠p来É本可\nabcd\n満毎É行p昼本可";
4756*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4757*c8dee2aaSAndroid Build Coastguard Worker
4758*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4759*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(10);
4760*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
4761*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4762*c8dee2aaSAndroid Build Coastguard Worker
4763*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
4764*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(true);
4765*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontFamilies({SkString("BlahFake"), SkString("Ahem")});
4766*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontSize(50);
4767*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeight(1.8f);
4768*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeightOverride(true);
4769*c8dee2aaSAndroid Build Coastguard Worker strut_style.setLeading(0.1f);
4770*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
4771*c8dee2aaSAndroid Build Coastguard Worker
4772*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4773*c8dee2aaSAndroid Build Coastguard Worker
4774*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4775*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
4776*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
4777*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width, SkFontStyle::kUpright_Slant));
4778*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4779*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(0.5f);
4780*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4781*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4782*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4783*c8dee2aaSAndroid Build Coastguard Worker
4784*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4785*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
4786*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4787*c8dee2aaSAndroid Build Coastguard Worker
4788*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4789*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 4);
4790*c8dee2aaSAndroid Build Coastguard Worker
4791*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
4792*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_max_style = RectHeightStyle::kMax;
4793*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
4794*c8dee2aaSAndroid Build Coastguard Worker {
4795*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4796*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.empty());
4797*c8dee2aaSAndroid Build Coastguard Worker }
4798*c8dee2aaSAndroid Build Coastguard Worker {
4799*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
4800*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4801*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4802*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4803*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
4804*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 34.5f, EPSILON100));
4805*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 50, EPSILON100));
4806*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 84.5f, EPSILON100));
4807*c8dee2aaSAndroid Build Coastguard Worker }
4808*c8dee2aaSAndroid Build Coastguard Worker }
4809*c8dee2aaSAndroid Build Coastguard Worker {
4810*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
4811*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4812*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4813*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4814*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
4815*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
4816*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 50, EPSILON100));
4817*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 95, EPSILON100));
4818*c8dee2aaSAndroid Build Coastguard Worker }
4819*c8dee2aaSAndroid Build Coastguard Worker }
4820*c8dee2aaSAndroid Build Coastguard Worker {
4821*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
4822*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4823*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4824*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4825*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 300, EPSILON100));
4826*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 34.5f, EPSILON100));
4827*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 500, EPSILON100));
4828*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 84.5f, EPSILON100));
4829*c8dee2aaSAndroid Build Coastguard Worker }
4830*c8dee2aaSAndroid Build Coastguard Worker }
4831*c8dee2aaSAndroid Build Coastguard Worker {
4832*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
4833*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4834*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4835*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4836*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 300, EPSILON100));
4837*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
4838*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 500, EPSILON100));
4839*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 95, EPSILON100));
4840*c8dee2aaSAndroid Build Coastguard Worker }
4841*c8dee2aaSAndroid Build Coastguard Worker }
4842*c8dee2aaSAndroid Build Coastguard Worker {
4843*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
4844*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4845*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4846*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4847*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
4848*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 190, EPSILON100));
4849*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 100, EPSILON100));
4850*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 285, EPSILON100));
4851*c8dee2aaSAndroid Build Coastguard Worker }
4852*c8dee2aaSAndroid Build Coastguard Worker }
4853*c8dee2aaSAndroid Build Coastguard Worker {
4854*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
4855*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4856*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4857*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4858*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 50, EPSILON100));
4859*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 285, EPSILON100));
4860*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 300, EPSILON100));
4861*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 380, EPSILON100));
4862*c8dee2aaSAndroid Build Coastguard Worker }
4863*c8dee2aaSAndroid Build Coastguard Worker }
4864*c8dee2aaSAndroid Build Coastguard Worker }
4865*c8dee2aaSAndroid Build Coastguard Worker
4866*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_StrutParagraph2,reporter)4867*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_StrutParagraph2, reporter) {
4868*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4869*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4870*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_StrutParagraph2.png");
4871*c8dee2aaSAndroid Build Coastguard Worker // The chinese extra height should be absorbed by the strut.
4872*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234ABCDEFGH\nabcd\nABCDEFGH";
4873*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4874*c8dee2aaSAndroid Build Coastguard Worker
4875*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4876*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(10);
4877*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
4878*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4879*c8dee2aaSAndroid Build Coastguard Worker
4880*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
4881*c8dee2aaSAndroid Build Coastguard Worker
4882*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(true);
4883*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontFamilies({SkString("Ahem")});
4884*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontSize(50);
4885*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeight(1.6f);
4886*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeightOverride(true);
4887*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
4888*c8dee2aaSAndroid Build Coastguard Worker
4889*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
4890*c8dee2aaSAndroid Build Coastguard Worker
4891*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
4892*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
4893*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
4894*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
4895*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
4896*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
4897*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
4898*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
4899*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
4900*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
4901*c8dee2aaSAndroid Build Coastguard Worker
4902*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
4903*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
4904*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
4905*c8dee2aaSAndroid Build Coastguard Worker
4906*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
4907*c8dee2aaSAndroid Build Coastguard Worker // Font is not resolved and the first line does not fit
4908*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 4);
4909*c8dee2aaSAndroid Build Coastguard Worker
4910*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
4911*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_max_style = RectHeightStyle::kMax;
4912*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
4913*c8dee2aaSAndroid Build Coastguard Worker {
4914*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4915*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.empty());
4916*c8dee2aaSAndroid Build Coastguard Worker }
4917*c8dee2aaSAndroid Build Coastguard Worker {
4918*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
4919*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4920*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4921*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4922*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
4923*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 24, EPSILON100));
4924*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 50, EPSILON100));
4925*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 74, EPSILON100));
4926*c8dee2aaSAndroid Build Coastguard Worker }
4927*c8dee2aaSAndroid Build Coastguard Worker }
4928*c8dee2aaSAndroid Build Coastguard Worker {
4929*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
4930*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4931*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4932*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4933*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
4934*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
4935*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 50, EPSILON100));
4936*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 80, EPSILON100));
4937*c8dee2aaSAndroid Build Coastguard Worker }
4938*c8dee2aaSAndroid Build Coastguard Worker }
4939*c8dee2aaSAndroid Build Coastguard Worker {
4940*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
4941*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4942*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4943*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4944*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 300, EPSILON100));
4945*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 24, EPSILON100));
4946*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 500, EPSILON100));
4947*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 74, EPSILON100));
4948*c8dee2aaSAndroid Build Coastguard Worker }
4949*c8dee2aaSAndroid Build Coastguard Worker }
4950*c8dee2aaSAndroid Build Coastguard Worker {
4951*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
4952*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4953*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4954*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4955*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 300, EPSILON100));
4956*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, EPSILON100));
4957*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 500, EPSILON100));
4958*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 80, EPSILON100));
4959*c8dee2aaSAndroid Build Coastguard Worker }
4960*c8dee2aaSAndroid Build Coastguard Worker }
4961*c8dee2aaSAndroid Build Coastguard Worker {
4962*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
4963*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4964*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4965*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4966*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
4967*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 160, EPSILON100));
4968*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 100, EPSILON100));
4969*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 240, EPSILON100));
4970*c8dee2aaSAndroid Build Coastguard Worker }
4971*c8dee2aaSAndroid Build Coastguard Worker }
4972*c8dee2aaSAndroid Build Coastguard Worker {
4973*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
4974*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
4975*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
4976*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
4977*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 50, EPSILON100));
4978*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 240, EPSILON100));
4979*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 300, EPSILON100));
4980*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 320, EPSILON100));
4981*c8dee2aaSAndroid Build Coastguard Worker }
4982*c8dee2aaSAndroid Build Coastguard Worker }
4983*c8dee2aaSAndroid Build Coastguard Worker }
4984*c8dee2aaSAndroid Build Coastguard Worker
4985*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_StrutParagraph3,reporter)4986*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_StrutParagraph3, reporter) {
4987*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
4988*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
4989*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_StrutParagraph3.png");
4990*c8dee2aaSAndroid Build Coastguard Worker
4991*c8dee2aaSAndroid Build Coastguard Worker // The chinese extra height should be absorbed by the strut.
4992*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234満毎p行来昼本可\nabcd\n満毎冠行来昼本可";
4993*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
4994*c8dee2aaSAndroid Build Coastguard Worker
4995*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
4996*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(10);
4997*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
4998*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
4999*c8dee2aaSAndroid Build Coastguard Worker
5000*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
5001*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(true);
5002*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontFamilies({SkString("Ahem")});
5003*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontSize(50);
5004*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeight(1.2f);
5005*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeightOverride(true);
5006*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
5007*c8dee2aaSAndroid Build Coastguard Worker
5008*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5009*c8dee2aaSAndroid Build Coastguard Worker
5010*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5011*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
5012*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
5013*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
5014*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
5015*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5016*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
5017*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5018*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
5019*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5020*c8dee2aaSAndroid Build Coastguard Worker
5021*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5022*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
5023*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5024*c8dee2aaSAndroid Build Coastguard Worker
5025*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5026*c8dee2aaSAndroid Build Coastguard Worker // Font is not resolved and the first line does not fit
5027*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 4);
5028*c8dee2aaSAndroid Build Coastguard Worker
5029*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
5030*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_max_style = RectHeightStyle::kMax;
5031*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
5032*c8dee2aaSAndroid Build Coastguard Worker SkScalar epsilon = 0.001f;
5033*c8dee2aaSAndroid Build Coastguard Worker {
5034*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
5035*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.empty());
5036*c8dee2aaSAndroid Build Coastguard Worker }
5037*c8dee2aaSAndroid Build Coastguard Worker {
5038*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
5039*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
5040*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
5041*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
5042*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, epsilon));
5043*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 8, epsilon));
5044*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 50, epsilon));
5045*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 58, epsilon));
5046*c8dee2aaSAndroid Build Coastguard Worker }
5047*c8dee2aaSAndroid Build Coastguard Worker }
5048*c8dee2aaSAndroid Build Coastguard Worker {
5049*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
5050*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
5051*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
5052*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
5053*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, epsilon));
5054*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, epsilon));
5055*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 50, epsilon));
5056*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 60, epsilon));
5057*c8dee2aaSAndroid Build Coastguard Worker }
5058*c8dee2aaSAndroid Build Coastguard Worker }
5059*c8dee2aaSAndroid Build Coastguard Worker {
5060*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
5061*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
5062*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
5063*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
5064*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 300, epsilon));
5065*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 8, epsilon));
5066*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 500, epsilon));
5067*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 58, epsilon));
5068*c8dee2aaSAndroid Build Coastguard Worker }
5069*c8dee2aaSAndroid Build Coastguard Worker }
5070*c8dee2aaSAndroid Build Coastguard Worker {
5071*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
5072*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
5073*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
5074*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
5075*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 300, epsilon));
5076*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 0, epsilon));
5077*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 500, epsilon));
5078*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 60, epsilon));
5079*c8dee2aaSAndroid Build Coastguard Worker }
5080*c8dee2aaSAndroid Build Coastguard Worker }
5081*c8dee2aaSAndroid Build Coastguard Worker {
5082*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
5083*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
5084*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
5085*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
5086*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, epsilon));
5087*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 120, epsilon));
5088*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 100, epsilon));
5089*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 180, epsilon));
5090*c8dee2aaSAndroid Build Coastguard Worker }
5091*c8dee2aaSAndroid Build Coastguard Worker }
5092*c8dee2aaSAndroid Build Coastguard Worker {
5093*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
5094*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
5095*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
5096*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
5097*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 50, epsilon));
5098*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 180, epsilon));
5099*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 300, epsilon));
5100*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 240, epsilon));
5101*c8dee2aaSAndroid Build Coastguard Worker }
5102*c8dee2aaSAndroid Build Coastguard Worker }
5103*c8dee2aaSAndroid Build Coastguard Worker }
5104*c8dee2aaSAndroid Build Coastguard Worker
5105*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_StrutForceParagraph,reporter)5106*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_StrutForceParagraph, reporter) {
5107*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5108*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5109*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_StrutForceParagraph.png");
5110*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
5111*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
5112*c8dee2aaSAndroid Build Coastguard Worker
5113*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5114*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(10);
5115*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
5116*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5117*c8dee2aaSAndroid Build Coastguard Worker
5118*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
5119*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(true);
5120*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontFamilies({SkString("Ahem")});
5121*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontSize(50);
5122*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeight(1.5f);
5123*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeightOverride(true);
5124*c8dee2aaSAndroid Build Coastguard Worker strut_style.setLeading(0.1f);
5125*c8dee2aaSAndroid Build Coastguard Worker strut_style.setForceStrutHeight(true);
5126*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
5127*c8dee2aaSAndroid Build Coastguard Worker
5128*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5129*c8dee2aaSAndroid Build Coastguard Worker
5130*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5131*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
5132*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
5133*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(0);
5134*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5135*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(1);
5136*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5137*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
5138*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5139*c8dee2aaSAndroid Build Coastguard Worker
5140*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5141*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
5142*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5143*c8dee2aaSAndroid Build Coastguard Worker
5144*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5145*c8dee2aaSAndroid Build Coastguard Worker // Font is not resolved and the first line does not fit
5146*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 4);
5147*c8dee2aaSAndroid Build Coastguard Worker
5148*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
5149*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_max_style = RectHeightStyle::kMax;
5150*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
5151*c8dee2aaSAndroid Build Coastguard Worker
5152*c8dee2aaSAndroid Build Coastguard Worker auto boxes1 = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
5153*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes1.empty());
5154*c8dee2aaSAndroid Build Coastguard Worker
5155*c8dee2aaSAndroid Build Coastguard Worker auto boxes2 = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
5156*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes2);
5157*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes2.size() == 1);
5158*c8dee2aaSAndroid Build Coastguard Worker if (boxes2.size() >= 1) {
5159*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes2[0].rect.left(), 0, EPSILON100));
5160*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes2[0].rect.top(), 22.5f, EPSILON100));
5161*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes2[0].rect.right(), 50, EPSILON100));
5162*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes2[0].rect.bottom(), 72.5f, EPSILON100));
5163*c8dee2aaSAndroid Build Coastguard Worker }
5164*c8dee2aaSAndroid Build Coastguard Worker
5165*c8dee2aaSAndroid Build Coastguard Worker auto boxes3 = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
5166*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes3);
5167*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes3.size() == 1);
5168*c8dee2aaSAndroid Build Coastguard Worker if (boxes3.size() >= 1) {
5169*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes3[0].rect.left(), 0, EPSILON100));
5170*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes3[0].rect.top(), 0, EPSILON100));
5171*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes3[0].rect.right(), 50, EPSILON100));
5172*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes3[0].rect.bottom(), 80, EPSILON100));
5173*c8dee2aaSAndroid Build Coastguard Worker }
5174*c8dee2aaSAndroid Build Coastguard Worker
5175*c8dee2aaSAndroid Build Coastguard Worker auto boxes4 = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
5176*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes4);
5177*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes4.size() == 1);
5178*c8dee2aaSAndroid Build Coastguard Worker if (boxes4.size() >= 1) {
5179*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes4[0].rect.left(), 300, EPSILON100));
5180*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes4[0].rect.top(), 22.5f, EPSILON100));
5181*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes4[0].rect.right(), 500, EPSILON100));
5182*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes4[0].rect.bottom(), 72.5f, EPSILON100));
5183*c8dee2aaSAndroid Build Coastguard Worker }
5184*c8dee2aaSAndroid Build Coastguard Worker
5185*c8dee2aaSAndroid Build Coastguard Worker auto boxes5 = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
5186*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes5);
5187*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes5.size() == 1);
5188*c8dee2aaSAndroid Build Coastguard Worker if (boxes5.size() >= 1) {
5189*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes5[0].rect.left(), 300, EPSILON100));
5190*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes5[0].rect.top(), 0, EPSILON100));
5191*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes5[0].rect.right(), 500, EPSILON100));
5192*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes5[0].rect.bottom(), 80, EPSILON100));
5193*c8dee2aaSAndroid Build Coastguard Worker }
5194*c8dee2aaSAndroid Build Coastguard Worker
5195*c8dee2aaSAndroid Build Coastguard Worker auto boxes6 = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
5196*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes6);
5197*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes6.size() == 1);
5198*c8dee2aaSAndroid Build Coastguard Worker if (boxes6.size() >= 1) {
5199*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes6[0].rect.left(), 0, EPSILON100));
5200*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes6[0].rect.top(), 160, EPSILON100));
5201*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes6[0].rect.right(), 100, EPSILON100));
5202*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes6[0].rect.bottom(), 240, EPSILON100));
5203*c8dee2aaSAndroid Build Coastguard Worker }
5204*c8dee2aaSAndroid Build Coastguard Worker
5205*c8dee2aaSAndroid Build Coastguard Worker auto boxes7 = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
5206*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes7);
5207*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes7.size() == 1);
5208*c8dee2aaSAndroid Build Coastguard Worker if (boxes7.size() >= 1) {
5209*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes7[0].rect.left(), 50, EPSILON100));
5210*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes7[0].rect.top(), 240, EPSILON100));
5211*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes7[0].rect.right(), 300, EPSILON100));
5212*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes7[0].rect.bottom(), 320, EPSILON100));
5213*c8dee2aaSAndroid Build Coastguard Worker }
5214*c8dee2aaSAndroid Build Coastguard Worker }
5215*c8dee2aaSAndroid Build Coastguard Worker
5216*c8dee2aaSAndroid Build Coastguard Worker // Checked: NO DIFF
UNIX_ONLY_TEST(SkParagraph_StrutDefaultParagraph,reporter)5217*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_StrutDefaultParagraph, reporter) {
5218*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5219*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5220*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_StrutDefaultParagraph.png");
5221*c8dee2aaSAndroid Build Coastguard Worker
5222*c8dee2aaSAndroid Build Coastguard Worker const char* text = "01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
5223*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
5224*c8dee2aaSAndroid Build Coastguard Worker
5225*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5226*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(10);
5227*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kLeft);
5228*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5229*c8dee2aaSAndroid Build Coastguard Worker
5230*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
5231*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(true);
5232*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontFamilies({SkString("Ahem")});
5233*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontSize(50);
5234*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeight(1.5f);
5235*c8dee2aaSAndroid Build Coastguard Worker strut_style.setLeading(0.1f);
5236*c8dee2aaSAndroid Build Coastguard Worker strut_style.setForceStrutHeight(false);
5237*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
5238*c8dee2aaSAndroid Build Coastguard Worker
5239*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5240*c8dee2aaSAndroid Build Coastguard Worker
5241*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5242*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
5243*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
5244*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5245*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5246*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
5247*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5248*c8dee2aaSAndroid Build Coastguard Worker
5249*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5250*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(550);
5251*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5252*c8dee2aaSAndroid Build Coastguard Worker
5253*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_style = RectHeightStyle::kTight;
5254*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle rect_height_strut_style = RectHeightStyle::kStrut;
5255*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle rect_width_style = RectWidthStyle::kTight;
5256*c8dee2aaSAndroid Build Coastguard Worker {
5257*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
5258*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.empty());
5259*c8dee2aaSAndroid Build Coastguard Worker }
5260*c8dee2aaSAndroid Build Coastguard Worker {
5261*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
5262*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
5263*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
5264*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
5265*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
5266*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 26.5f, EPSILON100));
5267*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 20, EPSILON100));
5268*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 46.5f, EPSILON100));
5269*c8dee2aaSAndroid Build Coastguard Worker }
5270*c8dee2aaSAndroid Build Coastguard Worker }
5271*c8dee2aaSAndroid Build Coastguard Worker {
5272*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 2, rect_height_strut_style, rect_width_style);
5273*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes);
5274*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
5275*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 1) {
5276*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.left(), 0, EPSILON100));
5277*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.top(), 2.5f, EPSILON100));
5278*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.right(), 40, EPSILON100));
5279*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.bottom(), 52.5f, EPSILON100));
5280*c8dee2aaSAndroid Build Coastguard Worker }
5281*c8dee2aaSAndroid Build Coastguard Worker }
5282*c8dee2aaSAndroid Build Coastguard Worker }
5283*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_FontFeaturesParagraph,reporter)5284*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_FontFeaturesParagraph, reporter) {
5285*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5286*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5287*c8dee2aaSAndroid Build Coastguard Worker
5288*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_FontFeaturesParagraph.png");
5289*c8dee2aaSAndroid Build Coastguard Worker
5290*c8dee2aaSAndroid Build Coastguard Worker const char* text = "12ab\n";
5291*c8dee2aaSAndroid Build Coastguard Worker
5292*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5293*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5294*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5295*c8dee2aaSAndroid Build Coastguard Worker
5296*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5297*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle::Italic()); // Regular Roboto doesn't have font features
5298*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5299*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5300*c8dee2aaSAndroid Build Coastguard Worker
5301*c8dee2aaSAndroid Build Coastguard Worker text_style.addFontFeature(SkString("tnum"), 1);
5302*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5303*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
5304*c8dee2aaSAndroid Build Coastguard Worker
5305*c8dee2aaSAndroid Build Coastguard Worker text_style.resetFontFeatures();
5306*c8dee2aaSAndroid Build Coastguard Worker text_style.addFontFeature(SkString("tnum"), 0);
5307*c8dee2aaSAndroid Build Coastguard Worker text_style.addFontFeature(SkString("pnum"), 1);
5308*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5309*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
5310*c8dee2aaSAndroid Build Coastguard Worker
5311*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5312*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5313*c8dee2aaSAndroid Build Coastguard Worker
5314*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5315*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
5316*c8dee2aaSAndroid Build Coastguard Worker
5317*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 10.0, 15.0);
5318*c8dee2aaSAndroid Build Coastguard Worker
5319*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5320*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->lineNumber() == 3ull);
5321*c8dee2aaSAndroid Build Coastguard Worker if (paragraph->lineNumber() >= 3) {
5322*c8dee2aaSAndroid Build Coastguard Worker auto& tnum_line = impl->lines()[0];
5323*c8dee2aaSAndroid Build Coastguard Worker auto& pnum_line = impl->lines()[1];
5324*c8dee2aaSAndroid Build Coastguard Worker
5325*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, tnum_line.clusters().width() == 4ull);
5326*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pnum_line.clusters().width() == 4ull);
5327*c8dee2aaSAndroid Build Coastguard Worker // Tabular numbers should have equal widths.
5328*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->clusters()[0].width() == impl->clusters()[1].width());
5329*c8dee2aaSAndroid Build Coastguard Worker // Proportional numbers should have variable widths.
5330*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->clusters()[5].width() != impl->clusters()[6].width());
5331*c8dee2aaSAndroid Build Coastguard Worker // Alphabetic characters should be unaffected.
5332*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->clusters()[2].width() == impl->clusters()[7].width());
5333*c8dee2aaSAndroid Build Coastguard Worker }
5334*c8dee2aaSAndroid Build Coastguard Worker }
5335*c8dee2aaSAndroid Build Coastguard Worker
5336*c8dee2aaSAndroid Build Coastguard Worker // Not in Minikin
UNIX_ONLY_TEST(SkParagraph_WhitespacesInMultipleFonts,reporter)5337*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_WhitespacesInMultipleFonts, reporter) {
5338*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5339*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5340*c8dee2aaSAndroid Build Coastguard Worker const char* text = "English English 字典 字典 ";
5341*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
5342*c8dee2aaSAndroid Build Coastguard Worker
5343*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5344*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5345*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5346*c8dee2aaSAndroid Build Coastguard Worker
5347*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5348*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies(
5349*c8dee2aaSAndroid Build Coastguard Worker {SkString("Roboto"), SkString("Noto Color Emoji"), SkString("Source Han Serif CN")});
5350*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(60);
5351*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5352*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
5353*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5354*c8dee2aaSAndroid Build Coastguard Worker
5355*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5356*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
5357*c8dee2aaSAndroid Build Coastguard Worker
5358*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
5359*c8dee2aaSAndroid Build Coastguard Worker
5360*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5361*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < impl->runs().size() - 1; ++i) {
5362*c8dee2aaSAndroid Build Coastguard Worker auto first = impl->runs()[i].textRange();
5363*c8dee2aaSAndroid Build Coastguard Worker auto next = impl->runs()[i + 1].textRange();
5364*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, first.end == next.start);
5365*c8dee2aaSAndroid Build Coastguard Worker }
5366*c8dee2aaSAndroid Build Coastguard Worker }
5367*c8dee2aaSAndroid Build Coastguard Worker
5368*c8dee2aaSAndroid Build Coastguard Worker // Disable until I sort out fonts
DEF_TEST_DISABLED(SkParagraph_JSON1,reporter)5369*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_DISABLED(SkParagraph_JSON1, reporter) {
5370*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5371*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5372*c8dee2aaSAndroid Build Coastguard Worker const char* text = "";
5373*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
5374*c8dee2aaSAndroid Build Coastguard Worker
5375*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5376*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5377*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5378*c8dee2aaSAndroid Build Coastguard Worker
5379*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5380*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Color Emoji")});
5381*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5382*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
5383*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5384*c8dee2aaSAndroid Build Coastguard Worker
5385*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5386*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
5387*c8dee2aaSAndroid Build Coastguard Worker
5388*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5389*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
5390*c8dee2aaSAndroid Build Coastguard Worker auto& run = impl->runs().front();
5391*c8dee2aaSAndroid Build Coastguard Worker
5392*c8dee2aaSAndroid Build Coastguard Worker auto cluster = 0;
5393*c8dee2aaSAndroid Build Coastguard Worker SkShaperJSONWriter::VisualizeClusters(
5394*c8dee2aaSAndroid Build Coastguard Worker text, 0, std::strlen(text), run.glyphs(), run.clusterIndexes(),
5395*c8dee2aaSAndroid Build Coastguard Worker [&](int codePointCount, SkSpan<const char> utf1to1, SkSpan<const SkGlyphID> glyph1to1) {
5396*c8dee2aaSAndroid Build Coastguard Worker if (cluster == 0) {
5397*c8dee2aaSAndroid Build Coastguard Worker std::string toCheckUtf8{utf1to1.data(), utf1to1.size()};
5398*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(std::strcmp(text, utf1to1.data()) == 0);
5399*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(glyph1to1.size() == 1);
5400*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(*glyph1to1.begin() == 1611);
5401*c8dee2aaSAndroid Build Coastguard Worker }
5402*c8dee2aaSAndroid Build Coastguard Worker ++cluster;
5403*c8dee2aaSAndroid Build Coastguard Worker });
5404*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, cluster <= 2);
5405*c8dee2aaSAndroid Build Coastguard Worker }
5406*c8dee2aaSAndroid Build Coastguard Worker
5407*c8dee2aaSAndroid Build Coastguard Worker // Disable until I sort out fonts
DEF_TEST_DISABLED(SkParagraph_JSON2,reporter)5408*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_DISABLED(SkParagraph_JSON2, reporter) {
5409*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5410*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5411*c8dee2aaSAndroid Build Coastguard Worker const char* text = "p〠q";
5412*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
5413*c8dee2aaSAndroid Build Coastguard Worker
5414*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5415*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5416*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5417*c8dee2aaSAndroid Build Coastguard Worker
5418*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5419*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Sans CJK JP")});
5420*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5421*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
5422*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5423*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
5424*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5425*c8dee2aaSAndroid Build Coastguard Worker
5426*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5427*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
5428*c8dee2aaSAndroid Build Coastguard Worker
5429*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5430*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
5431*c8dee2aaSAndroid Build Coastguard Worker
5432*c8dee2aaSAndroid Build Coastguard Worker auto cluster = 0;
5433*c8dee2aaSAndroid Build Coastguard Worker for (auto& run : impl->runs()) {
5434*c8dee2aaSAndroid Build Coastguard Worker SkShaperJSONWriter::VisualizeClusters(
5435*c8dee2aaSAndroid Build Coastguard Worker impl->text().begin() + run.textRange().start, 0, run.textRange().width(),
5436*c8dee2aaSAndroid Build Coastguard Worker run.glyphs(), run.clusterIndexes(),
5437*c8dee2aaSAndroid Build Coastguard Worker [&](int codePointCount, SkSpan<const char> utf1to1,
5438*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const SkGlyphID> glyph1to1) {
5439*c8dee2aaSAndroid Build Coastguard Worker if (cluster == 0) {
5440*c8dee2aaSAndroid Build Coastguard Worker std::string toCheckUtf8{utf1to1.data(), utf1to1.size()};
5441*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(std::strcmp(text, utf1to1.data()) == 0);
5442*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(glyph1to1.size() == 3);
5443*c8dee2aaSAndroid Build Coastguard Worker }
5444*c8dee2aaSAndroid Build Coastguard Worker ++cluster;
5445*c8dee2aaSAndroid Build Coastguard Worker });
5446*c8dee2aaSAndroid Build Coastguard Worker }
5447*c8dee2aaSAndroid Build Coastguard Worker
5448*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, cluster <= 2);
5449*c8dee2aaSAndroid Build Coastguard Worker }
5450*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_CacheText,reporter)5451*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_CacheText, reporter) {
5452*c8dee2aaSAndroid Build Coastguard Worker ParagraphCache cache;
5453*c8dee2aaSAndroid Build Coastguard Worker cache.turnOn(true);
5454*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5455*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5456*c8dee2aaSAndroid Build Coastguard Worker
5457*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5458*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5459*c8dee2aaSAndroid Build Coastguard Worker
5460*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5461*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5462*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5463*c8dee2aaSAndroid Build Coastguard Worker
5464*c8dee2aaSAndroid Build Coastguard Worker auto test = [&](const char* text, int count, bool expectedToBeFound) {
5465*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5466*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5467*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, strlen(text));
5468*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5469*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5470*c8dee2aaSAndroid Build Coastguard Worker
5471*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5472*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, count == cache.count());
5473*c8dee2aaSAndroid Build Coastguard Worker auto found = cache.findParagraph(impl);
5474*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, found == expectedToBeFound);
5475*c8dee2aaSAndroid Build Coastguard Worker auto added = cache.updateParagraph(impl);
5476*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, added != expectedToBeFound);
5477*c8dee2aaSAndroid Build Coastguard Worker };
5478*c8dee2aaSAndroid Build Coastguard Worker
5479*c8dee2aaSAndroid Build Coastguard Worker test("text1", 0, false);
5480*c8dee2aaSAndroid Build Coastguard Worker test("text1", 1, true);
5481*c8dee2aaSAndroid Build Coastguard Worker test("text2", 1, false);
5482*c8dee2aaSAndroid Build Coastguard Worker test("text2", 2, true);
5483*c8dee2aaSAndroid Build Coastguard Worker test("text3", 2, false);
5484*c8dee2aaSAndroid Build Coastguard Worker }
5485*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_CacheFonts,reporter)5486*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_CacheFonts, reporter) {
5487*c8dee2aaSAndroid Build Coastguard Worker ParagraphCache cache;
5488*c8dee2aaSAndroid Build Coastguard Worker cache.turnOn(true);
5489*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5490*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5491*c8dee2aaSAndroid Build Coastguard Worker
5492*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5493*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5494*c8dee2aaSAndroid Build Coastguard Worker
5495*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5496*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5497*c8dee2aaSAndroid Build Coastguard Worker
5498*c8dee2aaSAndroid Build Coastguard Worker const char* text = "text";
5499*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
5500*c8dee2aaSAndroid Build Coastguard Worker
5501*c8dee2aaSAndroid Build Coastguard Worker auto test = [&](int count, bool expectedToBeFound) {
5502*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5503*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5504*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
5505*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5506*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5507*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5508*c8dee2aaSAndroid Build Coastguard Worker
5509*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, count == cache.count());
5510*c8dee2aaSAndroid Build Coastguard Worker auto found = cache.findParagraph(impl);
5511*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, found == expectedToBeFound);
5512*c8dee2aaSAndroid Build Coastguard Worker auto added = cache.updateParagraph(impl);
5513*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, added != expectedToBeFound);
5514*c8dee2aaSAndroid Build Coastguard Worker };
5515*c8dee2aaSAndroid Build Coastguard Worker
5516*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5517*c8dee2aaSAndroid Build Coastguard Worker test(0, false);
5518*c8dee2aaSAndroid Build Coastguard Worker test(1, true);
5519*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Homemade Apple")});
5520*c8dee2aaSAndroid Build Coastguard Worker test(1, false);
5521*c8dee2aaSAndroid Build Coastguard Worker test(2, true);
5522*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Color Emoji")});
5523*c8dee2aaSAndroid Build Coastguard Worker test(2, false);
5524*c8dee2aaSAndroid Build Coastguard Worker }
5525*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_CacheFontRanges,reporter)5526*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_CacheFontRanges, reporter) {
5527*c8dee2aaSAndroid Build Coastguard Worker ParagraphCache cache;
5528*c8dee2aaSAndroid Build Coastguard Worker cache.turnOn(true);
5529*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5530*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5531*c8dee2aaSAndroid Build Coastguard Worker
5532*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5533*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5534*c8dee2aaSAndroid Build Coastguard Worker
5535*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5536*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5537*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5538*c8dee2aaSAndroid Build Coastguard Worker
5539*c8dee2aaSAndroid Build Coastguard Worker auto test = [&](const char* text1,
5540*c8dee2aaSAndroid Build Coastguard Worker const char* text2,
5541*c8dee2aaSAndroid Build Coastguard Worker const char* font1,
5542*c8dee2aaSAndroid Build Coastguard Worker const char* font2,
5543*c8dee2aaSAndroid Build Coastguard Worker int count,
5544*c8dee2aaSAndroid Build Coastguard Worker bool expectedToBeFound) {
5545*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5546*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString(font1)});
5547*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5548*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text1, strlen(text1));
5549*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5550*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString(font2)});
5551*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5552*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text2, strlen(text2));
5553*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5554*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5555*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5556*c8dee2aaSAndroid Build Coastguard Worker
5557*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, count == cache.count());
5558*c8dee2aaSAndroid Build Coastguard Worker auto found = cache.findParagraph(impl);
5559*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, found == expectedToBeFound);
5560*c8dee2aaSAndroid Build Coastguard Worker auto added = cache.updateParagraph(impl);
5561*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, added != expectedToBeFound);
5562*c8dee2aaSAndroid Build Coastguard Worker };
5563*c8dee2aaSAndroid Build Coastguard Worker
5564*c8dee2aaSAndroid Build Coastguard Worker test("text", "", "Roboto", "Homemade Apple", 0, false);
5565*c8dee2aaSAndroid Build Coastguard Worker test("t", "ext", "Roboto", "Homemade Apple", 1, false);
5566*c8dee2aaSAndroid Build Coastguard Worker test("te", "xt", "Roboto", "Homemade Apple", 2, false);
5567*c8dee2aaSAndroid Build Coastguard Worker test("tex", "t", "Roboto", "Homemade Apple", 3, false);
5568*c8dee2aaSAndroid Build Coastguard Worker test("text", "", "Roboto", "Homemade Apple", 4, true);
5569*c8dee2aaSAndroid Build Coastguard Worker }
5570*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_CacheStyles,reporter)5571*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_CacheStyles, reporter) {
5572*c8dee2aaSAndroid Build Coastguard Worker ParagraphCache cache;
5573*c8dee2aaSAndroid Build Coastguard Worker cache.turnOn(true);
5574*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5575*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5576*c8dee2aaSAndroid Build Coastguard Worker
5577*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5578*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
5579*c8dee2aaSAndroid Build Coastguard Worker
5580*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5581*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5582*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5583*c8dee2aaSAndroid Build Coastguard Worker
5584*c8dee2aaSAndroid Build Coastguard Worker const char* text = "text";
5585*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
5586*c8dee2aaSAndroid Build Coastguard Worker
5587*c8dee2aaSAndroid Build Coastguard Worker auto test = [&](int count, bool expectedToBeFound) {
5588*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5589*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5590*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
5591*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5592*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5593*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5594*c8dee2aaSAndroid Build Coastguard Worker
5595*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, count == cache.count());
5596*c8dee2aaSAndroid Build Coastguard Worker auto found = cache.findParagraph(impl);
5597*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, found == expectedToBeFound);
5598*c8dee2aaSAndroid Build Coastguard Worker auto added = cache.updateParagraph(impl);
5599*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, added != expectedToBeFound);
5600*c8dee2aaSAndroid Build Coastguard Worker };
5601*c8dee2aaSAndroid Build Coastguard Worker
5602*c8dee2aaSAndroid Build Coastguard Worker test(0, false);
5603*c8dee2aaSAndroid Build Coastguard Worker test(1, true);
5604*c8dee2aaSAndroid Build Coastguard Worker text_style.setLetterSpacing(10);
5605*c8dee2aaSAndroid Build Coastguard Worker test(1, false);
5606*c8dee2aaSAndroid Build Coastguard Worker test(2, true);
5607*c8dee2aaSAndroid Build Coastguard Worker text_style.setWordSpacing(10);
5608*c8dee2aaSAndroid Build Coastguard Worker test(2, false);
5609*c8dee2aaSAndroid Build Coastguard Worker }
5610*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_ParagraphWithLineBreak,reporter)5611*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ParagraphWithLineBreak, reporter) {
5612*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5613*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5614*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
5615*c8dee2aaSAndroid Build Coastguard Worker fontCollection->enableFontFallback();
5616*c8dee2aaSAndroid Build Coastguard Worker
5617*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_ParagraphWithLineBreak.png");
5618*c8dee2aaSAndroid Build Coastguard Worker
5619*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5620*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5621*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(16);
5622*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5623*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5624*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5625*c8dee2aaSAndroid Build Coastguard Worker builder.addText("abc\n\ndef");
5626*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5627*c8dee2aaSAndroid Build Coastguard Worker
5628*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5629*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
5630*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5631*c8dee2aaSAndroid Build Coastguard Worker
5632*c8dee2aaSAndroid Build Coastguard Worker // Select a position at the second (empty) line
5633*c8dee2aaSAndroid Build Coastguard Worker auto pos = paragraph->getGlyphPositionAtCoordinate(0, 21);
5634*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pos.affinity == Affinity::kDownstream && pos.position == 4);
5635*c8dee2aaSAndroid Build Coastguard Worker auto rect = paragraph->getRectsForRange(4, 5, RectHeightStyle::kTight, RectWidthStyle::kTight);
5636*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, rect.size() == 1 && rect[0].rect.width() == 0);
5637*c8dee2aaSAndroid Build Coastguard Worker }
5638*c8dee2aaSAndroid Build Coastguard Worker
5639*c8dee2aaSAndroid Build Coastguard Worker // This test does not produce an image
UNIX_ONLY_TEST(SkParagraph_NullInMiddleOfText,reporter)5640*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_NullInMiddleOfText, reporter) {
5641*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5642*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5643*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
5644*c8dee2aaSAndroid Build Coastguard Worker
5645*c8dee2aaSAndroid Build Coastguard Worker const SkString text("null terminator ->\u0000<- on purpose did you see it?");
5646*c8dee2aaSAndroid Build Coastguard Worker
5647*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5648*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5649*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5650*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(16);
5651*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5652*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5653*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text.c_str(), text.size());
5654*c8dee2aaSAndroid Build Coastguard Worker
5655*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5656*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
5657*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getHeight() > 0);
5658*c8dee2aaSAndroid Build Coastguard Worker }
5659*c8dee2aaSAndroid Build Coastguard Worker
5660*c8dee2aaSAndroid Build Coastguard Worker // This test does not produce an image
UNIX_ONLY_TEST(SkParagraph_PlaceholderOnly,reporter)5661*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_PlaceholderOnly, reporter) {
5662*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5663*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5664*c8dee2aaSAndroid Build Coastguard Worker
5665*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5666*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5667*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5668*c8dee2aaSAndroid Build Coastguard Worker text_style.setBackgroundColor(SkPaint(SkColors::kRed));
5669*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5670*c8dee2aaSAndroid Build Coastguard Worker
5671*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder(0, 0, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 0);
5672*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder);
5673*c8dee2aaSAndroid Build Coastguard Worker
5674*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5675*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
5676*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForPlaceholders();
5677*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.size() == 1);
5678*c8dee2aaSAndroid Build Coastguard Worker }
5679*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Fallbacks,reporter)5680*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Fallbacks, reporter) {
5681*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5682*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5683*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr(), "Arial");
5684*c8dee2aaSAndroid Build Coastguard Worker fontCollection->enableFontFallback();
5685*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_Fallbacks.png");
5686*c8dee2aaSAndroid Build Coastguard Worker
5687*c8dee2aaSAndroid Build Coastguard Worker const char* multiScript = "A1!aÀàĀāƁƀḂⱠꜲꬰəͲἀἏЀЖԠꙐꙮՁخࡔࠇܦআਉઐଘஇఘಧൺඣᭆᯔᮯ᳇ꠈᜅᩌꪈ༇ꥄꡙꫤ᧰៘꧁꧂ᜰᨏᯤᢆᣭᗗꗃⵞ߷ጩꬤ‡₩℻Ⅷ↹⋇⏳ⓖ╋▒◛⚧⑆שׁ㊼龜ポ䷤\n";
5688*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(multiScript);
5689*c8dee2aaSAndroid Build Coastguard Worker
5690*c8dee2aaSAndroid Build Coastguard Worker const char* androidFonts[] = {
5691*c8dee2aaSAndroid Build Coastguard Worker "sans-serif",
5692*c8dee2aaSAndroid Build Coastguard Worker "sans-serif-condensed",
5693*c8dee2aaSAndroid Build Coastguard Worker "serif",
5694*c8dee2aaSAndroid Build Coastguard Worker "monospace",
5695*c8dee2aaSAndroid Build Coastguard Worker "serif-monospace",
5696*c8dee2aaSAndroid Build Coastguard Worker "casual",
5697*c8dee2aaSAndroid Build Coastguard Worker "cursive",
5698*c8dee2aaSAndroid Build Coastguard Worker "sans-serif-smallcaps",
5699*c8dee2aaSAndroid Build Coastguard Worker };
5700*c8dee2aaSAndroid Build Coastguard Worker
5701*c8dee2aaSAndroid Build Coastguard Worker for (auto& font : androidFonts) {
5702*c8dee2aaSAndroid Build Coastguard Worker
5703*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5704*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5705*c8dee2aaSAndroid Build Coastguard Worker
5706*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5707*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5708*c8dee2aaSAndroid Build Coastguard Worker text_style.setLocale(SkString("en_US"));
5709*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
5710*c8dee2aaSAndroid Build Coastguard Worker
5711*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({ SkString(font) });
5712*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5713*c8dee2aaSAndroid Build Coastguard Worker builder.addText(multiScript, len);
5714*c8dee2aaSAndroid Build Coastguard Worker
5715*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5716*c8dee2aaSAndroid Build Coastguard Worker
5717*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5718*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
5719*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5720*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, paragraph->getHeight() + 10);
5721*c8dee2aaSAndroid Build Coastguard Worker }
5722*c8dee2aaSAndroid Build Coastguard Worker }
5723*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Bidi1,reporter)5724*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Bidi1, reporter) {
5725*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5726*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5727*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
5728*c8dee2aaSAndroid Build Coastguard Worker fontCollection->enableFontFallback();
5729*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_Bidi1.png");
5730*c8dee2aaSAndroid Build Coastguard Worker
5731*c8dee2aaSAndroid Build Coastguard Worker std::u16string abc = u"\u202Dabc";
5732*c8dee2aaSAndroid Build Coastguard Worker std::u16string DEF = u"\u202EDEF";
5733*c8dee2aaSAndroid Build Coastguard Worker std::u16string ghi = u"\u202Dghi";
5734*c8dee2aaSAndroid Build Coastguard Worker std::u16string JKL = u"\u202EJKL";
5735*c8dee2aaSAndroid Build Coastguard Worker std::u16string mno = u"\u202Dmno";
5736*c8dee2aaSAndroid Build Coastguard Worker
5737*c8dee2aaSAndroid Build Coastguard Worker std::u16string abcDEFghiJKLmno = u"\u202Dabc\u202EDEF\u202Dghi\u202EJKL\u202Dmno";
5738*c8dee2aaSAndroid Build Coastguard Worker
5739*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5740*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5741*c8dee2aaSAndroid Build Coastguard Worker
5742*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5743*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({ SkString("sans-serif")});
5744*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(40);
5745*c8dee2aaSAndroid Build Coastguard Worker
5746*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorCYAN);
5747*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kThin_Weight, SkFontStyle::kNormal_Width, SkFontStyle::kUpright_Slant));
5748*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5749*c8dee2aaSAndroid Build Coastguard Worker builder.addText(abc);
5750*c8dee2aaSAndroid Build Coastguard Worker
5751*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorGREEN);
5752*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kLight_Weight, SkFontStyle::kNormal_Width, SkFontStyle::kUpright_Slant));
5753*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5754*c8dee2aaSAndroid Build Coastguard Worker builder.addText(DEF);
5755*c8dee2aaSAndroid Build Coastguard Worker
5756*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorYELLOW);
5757*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width, SkFontStyle::kUpright_Slant));
5758*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5759*c8dee2aaSAndroid Build Coastguard Worker builder.addText(ghi);
5760*c8dee2aaSAndroid Build Coastguard Worker
5761*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorMAGENTA);
5762*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width, SkFontStyle::kUpright_Slant));
5763*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5764*c8dee2aaSAndroid Build Coastguard Worker builder.addText(JKL);
5765*c8dee2aaSAndroid Build Coastguard Worker
5766*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLUE);
5767*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(SkFontStyle(SkFontStyle::kBlack_Weight, SkFontStyle::kNormal_Width, SkFontStyle::kUpright_Slant));
5768*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5769*c8dee2aaSAndroid Build Coastguard Worker builder.addText(mno);
5770*c8dee2aaSAndroid Build Coastguard Worker
5771*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5772*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(400);
5773*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5774*c8dee2aaSAndroid Build Coastguard Worker }
5775*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Bidi2,reporter)5776*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Bidi2, reporter) {
5777*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5778*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5779*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
5780*c8dee2aaSAndroid Build Coastguard Worker fontCollection->enableFontFallback();
5781*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_Bidi2.png");
5782*c8dee2aaSAndroid Build Coastguard Worker
5783*c8dee2aaSAndroid Build Coastguard Worker std::u16string abcD = u"\u202Dabc\u202ED";
5784*c8dee2aaSAndroid Build Coastguard Worker std::u16string EFgh = u"EF\u202Dgh";
5785*c8dee2aaSAndroid Build Coastguard Worker std::u16string iJKLmno = u"i\u202EJKL\u202Dmno";
5786*c8dee2aaSAndroid Build Coastguard Worker
5787*c8dee2aaSAndroid Build Coastguard Worker std::u16string abcDEFghiJKLmno = u"\u202Dabc\u202EDEF\u202Dghi\u202EJKL\u202Dmno";
5788*c8dee2aaSAndroid Build Coastguard Worker
5789*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5790*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5791*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({ SkString("sans-serif")});
5792*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(40);
5793*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5794*c8dee2aaSAndroid Build Coastguard Worker {
5795*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5796*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5797*c8dee2aaSAndroid Build Coastguard Worker builder.addText(abcD);
5798*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5799*c8dee2aaSAndroid Build Coastguard Worker builder.addText(EFgh);
5800*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5801*c8dee2aaSAndroid Build Coastguard Worker builder.addText(iJKLmno);
5802*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5803*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(360);
5804*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5805*c8dee2aaSAndroid Build Coastguard Worker }
5806*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, 400);
5807*c8dee2aaSAndroid Build Coastguard Worker {
5808*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5809*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5810*c8dee2aaSAndroid Build Coastguard Worker builder.addText(abcDEFghiJKLmno);
5811*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5812*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(360);
5813*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5814*c8dee2aaSAndroid Build Coastguard Worker }
5815*c8dee2aaSAndroid Build Coastguard Worker }
5816*c8dee2aaSAndroid Build Coastguard Worker
5817*c8dee2aaSAndroid Build Coastguard Worker // This test does not produce an image
UNIX_ONLY_TEST(SkParagraph_NewlineOnly,reporter)5818*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_NewlineOnly, reporter) {
5819*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5820*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5821*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
5822*c8dee2aaSAndroid Build Coastguard Worker
5823*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5824*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
5825*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5826*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
5827*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(false);
5828*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5829*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
5830*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
5831*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5832*c8dee2aaSAndroid Build Coastguard Worker builder.addText("\n");
5833*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5834*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(1000);
5835*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getHeight() == 28);
5836*c8dee2aaSAndroid Build Coastguard Worker }
5837*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_FontResolutions,reporter)5838*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_FontResolutions, reporter) {
5839*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_FontResolutions.png");
5840*c8dee2aaSAndroid Build Coastguard Worker
5841*c8dee2aaSAndroid Build Coastguard Worker sk_sp<TestFontCollection> fontCollection =
5842*c8dee2aaSAndroid Build Coastguard Worker sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false);
5843*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5844*c8dee2aaSAndroid Build Coastguard Worker
5845*c8dee2aaSAndroid Build Coastguard Worker if (!fontCollection->addFontFromFile("abc/abc.ttf", "abc")) {
5846*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "abc/abc.ttf not found");
5847*c8dee2aaSAndroid Build Coastguard Worker return;
5848*c8dee2aaSAndroid Build Coastguard Worker }
5849*c8dee2aaSAndroid Build Coastguard Worker if (!fontCollection->addFontFromFile("abc/abc+grave.ttf", "abc+grave")) {
5850*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "abc/abc+grave.ttf not found");
5851*c8dee2aaSAndroid Build Coastguard Worker return;
5852*c8dee2aaSAndroid Build Coastguard Worker }
5853*c8dee2aaSAndroid Build Coastguard Worker if (!fontCollection->addFontFromFile("abc/abc+agrave.ttf", "abc+agrave")) {
5854*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "abc/abc+agrave.ttf not found");
5855*c8dee2aaSAndroid Build Coastguard Worker return;
5856*c8dee2aaSAndroid Build Coastguard Worker }
5857*c8dee2aaSAndroid Build Coastguard Worker
5858*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5859*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("abc")});
5860*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
5861*c8dee2aaSAndroid Build Coastguard Worker
5862*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5863*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5864*c8dee2aaSAndroid Build Coastguard Worker
5865*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("abc"), SkString("abc+grave")});
5866*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLUE);
5867*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5868*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"a\u0300");
5869*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorMAGENTA);
5870*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5871*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"à");
5872*c8dee2aaSAndroid Build Coastguard Worker
5873*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("abc"), SkString("abc+agrave")});
5874*c8dee2aaSAndroid Build Coastguard Worker
5875*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorRED);
5876*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5877*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"a\u0300");
5878*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorGREEN);
5879*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5880*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"à");
5881*c8dee2aaSAndroid Build Coastguard Worker
5882*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5883*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
5884*c8dee2aaSAndroid Build Coastguard Worker
5885*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
5886*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 2);
5887*c8dee2aaSAndroid Build Coastguard Worker if (impl->runs().size() >= 2) {
5888*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().front().size() == 4);
5889*c8dee2aaSAndroid Build Coastguard Worker if (impl->runs().front().size() >= 4) {
5890*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().front().glyphs()[0] == impl->runs().front().glyphs()[2]);
5891*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().front().glyphs()[1] == impl->runs().front().glyphs()[3]);
5892*c8dee2aaSAndroid Build Coastguard Worker }
5893*c8dee2aaSAndroid Build Coastguard Worker
5894*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().back().size() == 2);
5895*c8dee2aaSAndroid Build Coastguard Worker if (impl->runs().back().size() >= 2) {
5896*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().back().glyphs()[0] == impl->runs().back().glyphs()[1]);
5897*c8dee2aaSAndroid Build Coastguard Worker }
5898*c8dee2aaSAndroid Build Coastguard Worker }
5899*c8dee2aaSAndroid Build Coastguard Worker
5900*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 100, 100);
5901*c8dee2aaSAndroid Build Coastguard Worker }
5902*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_FontStyle,reporter)5903*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_FontStyle, reporter) {
5904*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_FontStyle.png");
5905*c8dee2aaSAndroid Build Coastguard Worker
5906*c8dee2aaSAndroid Build Coastguard Worker sk_sp<TestFontCollection> fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
5907*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5908*c8dee2aaSAndroid Build Coastguard Worker
5909*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5910*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5911*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5912*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
5913*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle fs = SkFontStyle(
5914*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Weight::kLight_Weight,
5915*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Width::kNormal_Width,
5916*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Slant::kUpright_Slant
5917*c8dee2aaSAndroid Build Coastguard Worker );
5918*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(fs);
5919*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5920*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
5921*c8dee2aaSAndroid Build Coastguard Worker TextStyle boldItalic;
5922*c8dee2aaSAndroid Build Coastguard Worker boldItalic.setFontFamilies({SkString("Roboto")});
5923*c8dee2aaSAndroid Build Coastguard Worker boldItalic.setColor(SK_ColorRED);
5924*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle bi = SkFontStyle(
5925*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Weight::kBold_Weight,
5926*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Width::kNormal_Width,
5927*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Slant::kItalic_Slant
5928*c8dee2aaSAndroid Build Coastguard Worker );
5929*c8dee2aaSAndroid Build Coastguard Worker boldItalic.setFontStyle(bi);
5930*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5931*c8dee2aaSAndroid Build Coastguard Worker builder.addText("Default text\n");
5932*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(boldItalic);
5933*c8dee2aaSAndroid Build Coastguard Worker builder.addText("Bold and Italic\n");
5934*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
5935*c8dee2aaSAndroid Build Coastguard Worker builder.addText("back to normal");
5936*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5937*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(250);
5938*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5939*c8dee2aaSAndroid Build Coastguard Worker }
5940*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Shaping,reporter)5941*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Shaping, reporter) {
5942*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_Shaping.png");
5943*c8dee2aaSAndroid Build Coastguard Worker
5944*c8dee2aaSAndroid Build Coastguard Worker sk_sp<TestFontCollection> fontCollection =
5945*c8dee2aaSAndroid Build Coastguard Worker sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), true);
5946*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5947*c8dee2aaSAndroid Build Coastguard Worker
5948*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5949*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
5950*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorGRAY);
5951*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(14);
5952*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle b = SkFontStyle(
5953*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Weight::kNormal_Weight,
5954*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Width::kNormal_Width,
5955*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Slant::kUpright_Slant
5956*c8dee2aaSAndroid Build Coastguard Worker );
5957*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontStyle(b);
5958*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5959*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5960*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
5961*c8dee2aaSAndroid Build Coastguard Worker builder.addText("Eat0 apple0 pies0 | Eat1 apple1 pies1 | Eat2 apple2 pies2");
5962*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5963*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(380);
5964*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5965*c8dee2aaSAndroid Build Coastguard Worker }
5966*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Ellipsis,reporter)5967*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Ellipsis, reporter) {
5968*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
5969*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
5970*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
5971*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_Ellipsis.png");
5972*c8dee2aaSAndroid Build Coastguard Worker
5973*c8dee2aaSAndroid Build Coastguard Worker const char* text = "This\n"
5974*c8dee2aaSAndroid Build Coastguard Worker "is a wrapping test. It should wrap at manual newlines, and if softWrap is true, also at spaces.";
5975*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
5976*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
5977*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
5978*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10);
5979*c8dee2aaSAndroid Build Coastguard Worker
5980*c8dee2aaSAndroid Build Coastguard Worker auto relayout = [&](size_t lines, bool ellipsis,
5981*c8dee2aaSAndroid Build Coastguard Worker SkScalar width, SkScalar height, SkScalar minWidth, SkScalar maxWidth, SkColor bg) {
5982*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
5983*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
5984*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(bg);
5985*c8dee2aaSAndroid Build Coastguard Worker text_style.setForegroundColor(paint);
5986*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
5987*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(lines);
5988*c8dee2aaSAndroid Build Coastguard Worker if (ellipsis) {
5989*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setEllipsis(u"\u2026");
5990*c8dee2aaSAndroid Build Coastguard Worker }
5991*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
5992*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
5993*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
5994*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(50);
5995*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
5996*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(50, paragraph->getHeight() + 10);
5997*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, strlen(text), RectHeightStyle::kTight, RectWidthStyle::kTight);
5998*c8dee2aaSAndroid Build Coastguard Worker SkPaint background;
5999*c8dee2aaSAndroid Build Coastguard Worker background.setColor(SK_ColorRED);
6000*c8dee2aaSAndroid Build Coastguard Worker background.setStyle(SkPaint::kStroke_Style);
6001*c8dee2aaSAndroid Build Coastguard Worker background.setAntiAlias(true);
6002*c8dee2aaSAndroid Build Coastguard Worker background.setStrokeWidth(1);
6003*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(result.front().rect, background);
6004*c8dee2aaSAndroid Build Coastguard Worker
6005*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(width == paragraph->getMaxWidth());
6006*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(height == paragraph->getHeight());
6007*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(minWidth, paragraph->getMinIntrinsicWidth(), EPSILON100));
6008*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(maxWidth, paragraph->getMaxIntrinsicWidth(), EPSILON100));
6009*c8dee2aaSAndroid Build Coastguard Worker };
6010*c8dee2aaSAndroid Build Coastguard Worker
6011*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
6012*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorLTGRAY);
6013*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(SkRect::MakeXYWH(0, 0, 50, 500), paint);
6014*c8dee2aaSAndroid Build Coastguard Worker
6015*c8dee2aaSAndroid Build Coastguard Worker relayout(1, false, 50, 10, 950, 950, SK_ColorRED);
6016*c8dee2aaSAndroid Build Coastguard Worker relayout(3, false, 50, 30, 90, 950, SK_ColorBLUE);
6017*c8dee2aaSAndroid Build Coastguard Worker relayout(std::numeric_limits<size_t>::max(), false, 50, 200, 90, 950, SK_ColorGREEN);
6018*c8dee2aaSAndroid Build Coastguard Worker
6019*c8dee2aaSAndroid Build Coastguard Worker relayout(1, true, 50, 10, 950, 950, SK_ColorYELLOW);
6020*c8dee2aaSAndroid Build Coastguard Worker relayout(3, true, 50, 30, 90, 950, SK_ColorMAGENTA);
6021*c8dee2aaSAndroid Build Coastguard Worker relayout(std::numeric_limits<size_t>::max(), true, 50, 20, 950, 950, SK_ColorCYAN);
6022*c8dee2aaSAndroid Build Coastguard Worker
6023*c8dee2aaSAndroid Build Coastguard Worker relayout(1, false, 50, 10, 950, 950, SK_ColorRED);
6024*c8dee2aaSAndroid Build Coastguard Worker relayout(3, false, 50, 30, 90, 950, SK_ColorBLUE);
6025*c8dee2aaSAndroid Build Coastguard Worker relayout(std::numeric_limits<size_t>::max(), false, 50, 200, 90, 950, SK_ColorGREEN);
6026*c8dee2aaSAndroid Build Coastguard Worker }
6027*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_MemoryLeak,reporter)6028*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_MemoryLeak, reporter) {
6029*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6030*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6031*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
6032*c8dee2aaSAndroid Build Coastguard Worker
6033*c8dee2aaSAndroid Build Coastguard Worker std::string text;
6034*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < 10; i++)
6035*c8dee2aaSAndroid Build Coastguard Worker {
6036*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
6037*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
6038*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLACK);
6039*c8dee2aaSAndroid Build Coastguard Worker
6040*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
6041*c8dee2aaSAndroid Build Coastguard Worker textStyle.setForegroundColor(paint);
6042*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({ SkString("Roboto") });
6043*c8dee2aaSAndroid Build Coastguard Worker
6044*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
6045*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextStyle(textStyle);
6046*c8dee2aaSAndroid Build Coastguard Worker
6047*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
6048*c8dee2aaSAndroid Build Coastguard Worker text += "Text ";
6049*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text.c_str());
6050*c8dee2aaSAndroid Build Coastguard Worker
6051*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6052*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(100);
6053*c8dee2aaSAndroid Build Coastguard Worker
6054*c8dee2aaSAndroid Build Coastguard Worker //used to add a delay so I can monitor memory usage
6055*c8dee2aaSAndroid Build Coastguard Worker //std::this_thread::sleep_for(std::chrono::milliseconds(1000));
6056*c8dee2aaSAndroid Build Coastguard Worker }
6057*c8dee2aaSAndroid Build Coastguard Worker };
6058*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_FormattingInfinity,reporter)6059*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_FormattingInfinity, reporter) {
6060*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6061*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6062*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
6063*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_FormattingInfinity.png");
6064*c8dee2aaSAndroid Build Coastguard Worker
6065*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Some text\nAnother line";
6066*c8dee2aaSAndroid Build Coastguard Worker
6067*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
6068*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
6069*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLACK);
6070*c8dee2aaSAndroid Build Coastguard Worker
6071*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
6072*c8dee2aaSAndroid Build Coastguard Worker textStyle.setForegroundColor(paint);
6073*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({ SkString("Roboto") });
6074*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
6075*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextStyle(textStyle);
6076*c8dee2aaSAndroid Build Coastguard Worker
6077*c8dee2aaSAndroid Build Coastguard Worker auto draw = [&](const char* prefix, TextAlign textAlign, TextDirection textDirection) {
6078*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextAlign(textAlign);
6079*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle.setTextDirection(textDirection);
6080*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
6081*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
6082*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6083*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(SK_ScalarInfinity);
6084*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6085*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, 100);
6086*c8dee2aaSAndroid Build Coastguard Worker };
6087*c8dee2aaSAndroid Build Coastguard Worker
6088*c8dee2aaSAndroid Build Coastguard Worker draw("left", TextAlign::kLeft, TextDirection::kLtr);
6089*c8dee2aaSAndroid Build Coastguard Worker draw("right", TextAlign::kRight, TextDirection::kLtr);
6090*c8dee2aaSAndroid Build Coastguard Worker draw("center", TextAlign::kCenter, TextDirection::kLtr);
6091*c8dee2aaSAndroid Build Coastguard Worker draw("justify LTR", TextAlign::kJustify, TextDirection::kLtr);
6092*c8dee2aaSAndroid Build Coastguard Worker draw("justify RTL", TextAlign::kJustify, TextDirection::kRtl);
6093*c8dee2aaSAndroid Build Coastguard Worker };
6094*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Infinity,reporter)6095*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Infinity, reporter) {
6096*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(1, SK_ScalarInfinity) == false);
6097*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(1, SK_ScalarNegativeInfinity) == false);
6098*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(1, SK_ScalarNaN) == false);
6099*c8dee2aaSAndroid Build Coastguard Worker
6100*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(SK_ScalarInfinity, SK_ScalarInfinity) == true);
6101*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(SK_ScalarInfinity, SK_ScalarNegativeInfinity) == false);
6102*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(SK_ScalarInfinity, SK_ScalarNaN) == false);
6103*c8dee2aaSAndroid Build Coastguard Worker
6104*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(SK_ScalarNegativeInfinity, SK_ScalarInfinity) == false);
6105*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(SK_ScalarNegativeInfinity, SK_ScalarNegativeInfinity) == true);
6106*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(SK_ScalarNegativeInfinity, SK_ScalarNaN) == false);
6107*c8dee2aaSAndroid Build Coastguard Worker
6108*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(SK_ScalarNaN, SK_ScalarInfinity) == false);
6109*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(SK_ScalarNaN, SK_ScalarNegativeInfinity) == false);
6110*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nearlyEqual(SK_ScalarNaN, SK_ScalarNaN) == false);
6111*c8dee2aaSAndroid Build Coastguard Worker };
6112*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_LineMetrics,reporter)6113*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_LineMetrics, reporter) {
6114*c8dee2aaSAndroid Build Coastguard Worker
6115*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6116*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6117*c8dee2aaSAndroid Build Coastguard Worker
6118*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_LineMetrics.png");
6119*c8dee2aaSAndroid Build Coastguard Worker
6120*c8dee2aaSAndroid Build Coastguard Worker const char* text = "One line of text\n";
6121*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
6122*c8dee2aaSAndroid Build Coastguard Worker
6123*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6124*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
6125*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6126*c8dee2aaSAndroid Build Coastguard Worker
6127*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6128*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
6129*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6130*c8dee2aaSAndroid Build Coastguard Worker
6131*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(8);
6132*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6133*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
6134*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6135*c8dee2aaSAndroid Build Coastguard Worker
6136*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(12);
6137*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6138*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
6139*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6140*c8dee2aaSAndroid Build Coastguard Worker
6141*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(18);
6142*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6143*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
6144*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6145*c8dee2aaSAndroid Build Coastguard Worker
6146*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(30);
6147*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6148*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len - 1); // Skip the last \n
6149*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6150*c8dee2aaSAndroid Build Coastguard Worker
6151*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6152*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
6153*c8dee2aaSAndroid Build Coastguard Worker
6154*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> metrics;
6155*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(metrics);
6156*c8dee2aaSAndroid Build Coastguard Worker
6157*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(auto impl = static_cast<ParagraphImpl*>(paragraph.get());)
6158*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(metrics.size() == impl->lines().size());
6159*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < metrics.size(); ++i) {
6160*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(auto& line = impl->lines()[i];)
6161*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(auto baseline = metrics[i].fBaseline;)
6162*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(auto top = line.offset().fY;)
6163*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(auto bottom = line.offset().fY + line.height();)
6164*c8dee2aaSAndroid Build Coastguard Worker SkASSERT( baseline > top && baseline <= bottom);
6165*c8dee2aaSAndroid Build Coastguard Worker }
6166*c8dee2aaSAndroid Build Coastguard Worker
6167*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6168*c8dee2aaSAndroid Build Coastguard Worker auto rects = paragraph->getRectsForRange(0, len * 4, RectHeightStyle::kMax, RectWidthStyle::kTight);
6169*c8dee2aaSAndroid Build Coastguard Worker
6170*c8dee2aaSAndroid Build Coastguard Worker SkPaint red;
6171*c8dee2aaSAndroid Build Coastguard Worker red.setColor(SK_ColorRED);
6172*c8dee2aaSAndroid Build Coastguard Worker red.setStyle(SkPaint::kStroke_Style);
6173*c8dee2aaSAndroid Build Coastguard Worker red.setAntiAlias(true);
6174*c8dee2aaSAndroid Build Coastguard Worker red.setStrokeWidth(1);
6175*c8dee2aaSAndroid Build Coastguard Worker
6176*c8dee2aaSAndroid Build Coastguard Worker for (auto& rect : rects) {
6177*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(rect.rect, red);
6178*c8dee2aaSAndroid Build Coastguard Worker }
6179*c8dee2aaSAndroid Build Coastguard Worker
6180*c8dee2aaSAndroid Build Coastguard Worker SkPaint green;
6181*c8dee2aaSAndroid Build Coastguard Worker green.setColor(SK_ColorGREEN);
6182*c8dee2aaSAndroid Build Coastguard Worker green.setStyle(SkPaint::kStroke_Style);
6183*c8dee2aaSAndroid Build Coastguard Worker green.setAntiAlias(true);
6184*c8dee2aaSAndroid Build Coastguard Worker green.setStrokeWidth(1);
6185*c8dee2aaSAndroid Build Coastguard Worker for (auto& metric : metrics) {
6186*c8dee2aaSAndroid Build Coastguard Worker auto x0 = 0.0;
6187*c8dee2aaSAndroid Build Coastguard Worker auto x1 = metric.fWidth;
6188*c8dee2aaSAndroid Build Coastguard Worker auto y = metric.fBaseline;
6189*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawLine(x0, y, x1, y, green);
6190*c8dee2aaSAndroid Build Coastguard Worker }
6191*c8dee2aaSAndroid Build Coastguard Worker };
6192*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST_DISABLED(SkParagraph_PlaceholderHeightInf,reporter)6193*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_DISABLED(SkParagraph_PlaceholderHeightInf, reporter) {
6194*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_PlaceholderHeightInf.png");
6195*c8dee2aaSAndroid Build Coastguard Worker
6196*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6197*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6198*c8dee2aaSAndroid Build Coastguard Worker
6199*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6200*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
6201*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6202*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(14);
6203*c8dee2aaSAndroid Build Coastguard Worker
6204*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder_style;
6205*c8dee2aaSAndroid Build Coastguard Worker placeholder_style.fWidth = 16.0f;
6206*c8dee2aaSAndroid Build Coastguard Worker placeholder_style.fHeight = SK_ScalarInfinity;
6207*c8dee2aaSAndroid Build Coastguard Worker placeholder_style.fAlignment = PlaceholderAlignment::kBottom;
6208*c8dee2aaSAndroid Build Coastguard Worker placeholder_style.fBaseline = TextBaseline::kAlphabetic;
6209*c8dee2aaSAndroid Build Coastguard Worker placeholder_style.fBaselineOffset = SK_ScalarInfinity;
6210*c8dee2aaSAndroid Build Coastguard Worker
6211*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6212*c8dee2aaSAndroid Build Coastguard Worker //paragraph_style.setDrawOptions(DrawOptions::kRecord);
6213*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6214*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6215*c8dee2aaSAndroid Build Coastguard Worker builder.addText("Limited by budget");
6216*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder_style);
6217*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6218*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(SK_ScalarInfinity);
6219*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6220*c8dee2aaSAndroid Build Coastguard Worker
6221*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
6222*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkIsFinite(impl->getPicture()->cullRect().height()));
6223*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkIsFinite(impl->getPicture()->cullRect().width()));
6224*c8dee2aaSAndroid Build Coastguard Worker }
6225*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_LineMetricsTextAlign,reporter)6226*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_LineMetricsTextAlign, reporter) {
6227*c8dee2aaSAndroid Build Coastguard Worker
6228*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6229*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6230*c8dee2aaSAndroid Build Coastguard Worker
6231*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_LineMetricsTextAlign.png");
6232*c8dee2aaSAndroid Build Coastguard Worker
6233*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6234*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
6235*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6236*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
6237*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6238*c8dee2aaSAndroid Build Coastguard Worker
6239*c8dee2aaSAndroid Build Coastguard Worker auto layout = [&](TextAlign text_align) -> std::pair<SkScalar, SkScalar> {
6240*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(text_align);
6241*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6242*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6243*c8dee2aaSAndroid Build Coastguard Worker builder.addText("Some text that takes more than 200 px");
6244*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6245*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(200);
6246*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6247*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, paragraph->getHeight());
6248*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> metrics;
6249*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(metrics);
6250*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, metrics.size() > 0);
6251*c8dee2aaSAndroid Build Coastguard Worker return { metrics[0].fLeft, metrics[0].fWidth };
6252*c8dee2aaSAndroid Build Coastguard Worker };
6253*c8dee2aaSAndroid Build Coastguard Worker
6254*c8dee2aaSAndroid Build Coastguard Worker SkScalar left[4];
6255*c8dee2aaSAndroid Build Coastguard Worker SkScalar width[4];
6256*c8dee2aaSAndroid Build Coastguard Worker std::tie(left[0], width[0]) = layout(TextAlign::kLeft);
6257*c8dee2aaSAndroid Build Coastguard Worker std::tie(left[1], width[1]) = layout(TextAlign::kCenter);
6258*c8dee2aaSAndroid Build Coastguard Worker std::tie(left[2], width[2]) = layout(TextAlign::kRight);
6259*c8dee2aaSAndroid Build Coastguard Worker std::tie(left[3], width[3]) = layout(TextAlign::kJustify);
6260*c8dee2aaSAndroid Build Coastguard Worker
6261*c8dee2aaSAndroid Build Coastguard Worker // delta = line_width - text_width
6262*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, left[0] == 0); // Starts from 0
6263*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, left[1] > left[0]); // Starts from delta / 2
6264*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, left[2] > left[1]); // Starts from delta
6265*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, left[3] == left[0]); // Starts from 0
6266*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, width[1] == width[0]);
6267*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, width[2] == width[0]);
6268*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, width[3] > width[0]); // delta == 0
6269*c8dee2aaSAndroid Build Coastguard Worker }
6270*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_FontResolutionInRTL,reporter)6271*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_FontResolutionInRTL, reporter) {
6272*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
6273*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6274*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_FontResolutionInRTL.png");
6275*c8dee2aaSAndroid Build Coastguard Worker const char* text = " אאא בּבּבּבּ אאאא בּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ ";
6276*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
6277*c8dee2aaSAndroid Build Coastguard Worker
6278*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6279*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
6280*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kRight);
6281*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
6282*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
6283*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6284*c8dee2aaSAndroid Build Coastguard Worker
6285*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6286*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
6287*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
6288*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6289*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6290*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
6291*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6292*c8dee2aaSAndroid Build Coastguard Worker
6293*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6294*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
6295*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6296*c8dee2aaSAndroid Build Coastguard Worker
6297*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
6298*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == (10 + 11));
6299*c8dee2aaSAndroid Build Coastguard Worker }
6300*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_FontResolutionInLTR,reporter)6301*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_FontResolutionInLTR, reporter) {
6302*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
6303*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6304*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_FontResolutionInLTR.png");
6305*c8dee2aaSAndroid Build Coastguard Worker auto text = u"abc \u01A2 \u01A2 def";
6306*c8dee2aaSAndroid Build Coastguard Worker
6307*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6308*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(14);
6309*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
6310*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6311*c8dee2aaSAndroid Build Coastguard Worker
6312*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6313*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
6314*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(26);
6315*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6316*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6317*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
6318*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6319*c8dee2aaSAndroid Build Coastguard Worker
6320*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6321*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
6322*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6323*c8dee2aaSAndroid Build Coastguard Worker
6324*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
6325*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 5);
6326*c8dee2aaSAndroid Build Coastguard Worker if (impl->runs().size() >= 5) {
6327*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs()[0].textRange().width() == 4); // "abc "
6328*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs()[1].textRange().width() == 2); // "{unresolved}"
6329*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs()[2].textRange().width() == 1); // " "
6330*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs()[3].textRange().width() == 2); // "{unresolved}"
6331*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs()[4].textRange().width() == 4); // " def"
6332*c8dee2aaSAndroid Build Coastguard Worker }
6333*c8dee2aaSAndroid Build Coastguard Worker }
6334*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Intrinsic,reporter)6335*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Intrinsic, reporter) {
6336*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6337*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6338*c8dee2aaSAndroid Build Coastguard Worker SkString text(std::string(3000, 'a'));
6339*c8dee2aaSAndroid Build Coastguard Worker
6340*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6341*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
6342*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6343*c8dee2aaSAndroid Build Coastguard Worker
6344*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6345*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Google Sans")});
6346*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(12.0f);
6347*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6348*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6349*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text.c_str());
6350*c8dee2aaSAndroid Build Coastguard Worker
6351*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6352*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(300000.0f);
6353*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getMinIntrinsicWidth() <= paragraph->getMaxIntrinsicWidth());
6354*c8dee2aaSAndroid Build Coastguard Worker }
6355*c8dee2aaSAndroid Build Coastguard Worker
6356*c8dee2aaSAndroid Build Coastguard Worker // This test does not produce an image
UNIX_ONLY_TEST(SkParagraph_NoCache1,reporter)6357*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_NoCache1, reporter) {
6358*c8dee2aaSAndroid Build Coastguard Worker
6359*c8dee2aaSAndroid Build Coastguard Worker ParagraphCache cache;
6360*c8dee2aaSAndroid Build Coastguard Worker cache.turnOn(true);
6361*c8dee2aaSAndroid Build Coastguard Worker
6362*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
6363*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6364*c8dee2aaSAndroid Build Coastguard Worker // Long arabic text with english spaces
6365*c8dee2aaSAndroid Build Coastguard Worker const char* text =
6366*c8dee2aaSAndroid Build Coastguard Worker "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6367*c8dee2aaSAndroid Build Coastguard Worker "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6368*c8dee2aaSAndroid Build Coastguard Worker "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6369*c8dee2aaSAndroid Build Coastguard Worker "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6370*c8dee2aaSAndroid Build Coastguard Worker "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6371*c8dee2aaSAndroid Build Coastguard Worker "عل بمباركة التقليدية قام عن. تصفح";
6372*c8dee2aaSAndroid Build Coastguard Worker
6373*c8dee2aaSAndroid Build Coastguard Worker SkString str;
6374*c8dee2aaSAndroid Build Coastguard Worker
6375*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6376*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kLtr);
6377*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6378*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
6379*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(14);
6380*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6381*c8dee2aaSAndroid Build Coastguard Worker
6382*c8dee2aaSAndroid Build Coastguard Worker auto test = [&](const char* test, const char* text, bool editing) {
6383*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6384*c8dee2aaSAndroid Build Coastguard Worker //SkDebugf("test %s:\n", test);
6385*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6386*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
6387*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6388*c8dee2aaSAndroid Build Coastguard Worker
6389*c8dee2aaSAndroid Build Coastguard Worker auto cache = fontCollection->getParagraphCache();
6390*c8dee2aaSAndroid Build Coastguard Worker auto countBefore = cache->count();
6391*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6392*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
6393*c8dee2aaSAndroid Build Coastguard Worker auto countAfter = cache->count();
6394*c8dee2aaSAndroid Build Coastguard Worker
6395*c8dee2aaSAndroid Build Coastguard Worker if (test == nullptr) {
6396*c8dee2aaSAndroid Build Coastguard Worker return;
6397*c8dee2aaSAndroid Build Coastguard Worker }
6398*c8dee2aaSAndroid Build Coastguard Worker
6399*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, (countBefore == countAfter) == editing);
6400*c8dee2aaSAndroid Build Coastguard Worker };
6401*c8dee2aaSAndroid Build Coastguard Worker
6402*c8dee2aaSAndroid Build Coastguard Worker str.append(text);
6403*c8dee2aaSAndroid Build Coastguard Worker test("Long arabic text", str.c_str(), false);
6404*c8dee2aaSAndroid Build Coastguard Worker
6405*c8dee2aaSAndroid Build Coastguard Worker str.append("عل");
6406*c8dee2aaSAndroid Build Coastguard Worker test("+2 character at the end", str.c_str(), true);
6407*c8dee2aaSAndroid Build Coastguard Worker
6408*c8dee2aaSAndroid Build Coastguard Worker str = SkString(text);
6409*c8dee2aaSAndroid Build Coastguard Worker test("-2 characters from the end", str.c_str(), true);
6410*c8dee2aaSAndroid Build Coastguard Worker
6411*c8dee2aaSAndroid Build Coastguard Worker str.insert(0, "عل");
6412*c8dee2aaSAndroid Build Coastguard Worker test("+2 character at the start", str.c_str(), true);
6413*c8dee2aaSAndroid Build Coastguard Worker
6414*c8dee2aaSAndroid Build Coastguard Worker test("-2 characters from the start", text, true);
6415*c8dee2aaSAndroid Build Coastguard Worker
6416*c8dee2aaSAndroid Build Coastguard Worker // Make sure that different strings are not flagged as editing
6417*c8dee2aaSAndroid Build Coastguard Worker test("different strings", "0123456789 0123456789 0123456789 0123456789 0123456789", false);
6418*c8dee2aaSAndroid Build Coastguard Worker }
6419*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_HeightCalculations,reporter)6420*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_HeightCalculations, reporter) {
6421*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6422*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6423*c8dee2aaSAndroid Build Coastguard Worker
6424*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_HeightCalculations.png");
6425*c8dee2aaSAndroid Build Coastguard Worker
6426*c8dee2aaSAndroid Build Coastguard Worker auto draw = [&](TextHeightBehavior hb, const char* text, SkScalar height) {
6427*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6428*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextHeightBehavior(hb);
6429*c8dee2aaSAndroid Build Coastguard Worker
6430*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6431*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6432*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
6433*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(14.0f);
6434*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(5.0f);
6435*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeightOverride(true);
6436*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6437*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6438*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
6439*c8dee2aaSAndroid Build Coastguard Worker
6440*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6441*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(500);
6442*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6443*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, paragraph->getHeight());
6444*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(paragraph->getHeight(), height));
6445*c8dee2aaSAndroid Build Coastguard Worker };
6446*c8dee2aaSAndroid Build Coastguard Worker
6447*c8dee2aaSAndroid Build Coastguard Worker draw(TextHeightBehavior::kAll, "Hello\nLine 2\nLine 3", 210);
6448*c8dee2aaSAndroid Build Coastguard Worker draw(TextHeightBehavior::kDisableAll, "Hello\nLine 2\nLine 3", 157);
6449*c8dee2aaSAndroid Build Coastguard Worker draw(TextHeightBehavior::kDisableFirstAscent, "Hello", 28);
6450*c8dee2aaSAndroid Build Coastguard Worker }
6451*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_RTL_With_Styles,reporter)6452*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RTL_With_Styles, reporter) {
6453*c8dee2aaSAndroid Build Coastguard Worker
6454*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6455*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6456*c8dee2aaSAndroid Build Coastguard Worker
6457*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RTL_With_Styles.png");
6458*c8dee2aaSAndroid Build Coastguard Worker
6459*c8dee2aaSAndroid Build Coastguard Worker SkPaint whiteSpaces;
6460*c8dee2aaSAndroid Build Coastguard Worker whiteSpaces.setColor(SK_ColorLTGRAY);
6461*c8dee2aaSAndroid Build Coastguard Worker
6462*c8dee2aaSAndroid Build Coastguard Worker SkPaint breakingSpace;
6463*c8dee2aaSAndroid Build Coastguard Worker breakingSpace.setColor(SK_ColorYELLOW);
6464*c8dee2aaSAndroid Build Coastguard Worker
6465*c8dee2aaSAndroid Build Coastguard Worker SkPaint text;
6466*c8dee2aaSAndroid Build Coastguard Worker text.setColor(SK_ColorWHITE);
6467*c8dee2aaSAndroid Build Coastguard Worker
6468*c8dee2aaSAndroid Build Coastguard Worker const char* arabic = "قففغغغغقففغغغغقففغغغ";
6469*c8dee2aaSAndroid Build Coastguard Worker
6470*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6471*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kRight);
6472*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6473*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6474*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
6475*c8dee2aaSAndroid Build Coastguard Worker
6476*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
6477*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kRight);
6478*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
6479*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6480*c8dee2aaSAndroid Build Coastguard Worker text_style.setBackgroundColor(whiteSpaces);
6481*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6482*c8dee2aaSAndroid Build Coastguard Worker builder.addText(" ");
6483*c8dee2aaSAndroid Build Coastguard Worker text_style.setBackgroundColor(text);
6484*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6485*c8dee2aaSAndroid Build Coastguard Worker builder.addText(arabic);
6486*c8dee2aaSAndroid Build Coastguard Worker
6487*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6488*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(300);
6489*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6490*c8dee2aaSAndroid Build Coastguard Worker }
6491*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_PositionInsideEmoji,reporter)6492*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_PositionInsideEmoji, reporter) {
6493*c8dee2aaSAndroid Build Coastguard Worker
6494*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6495*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6496*c8dee2aaSAndroid Build Coastguard Worker
6497*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_PositionInsideEmoji.png");
6498*c8dee2aaSAndroid Build Coastguard Worker
6499*c8dee2aaSAndroid Build Coastguard Worker std::u16string text = u"\U0001f469\u200D\U0001f469\u200D\U0001f467\u200D\U0001f467\U0001f469\U0001f469\U0001f467\U0001f467";
6500*c8dee2aaSAndroid Build Coastguard Worker
6501*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6502*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6503*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6504*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Color Emoji")});
6505*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6506*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6507*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
6508*c8dee2aaSAndroid Build Coastguard Worker
6509*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6510*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
6511*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6512*c8dee2aaSAndroid Build Coastguard Worker
6513*c8dee2aaSAndroid Build Coastguard Worker // UTF8 UTF16
6514*c8dee2aaSAndroid Build Coastguard Worker // 4 [0:2)
6515*c8dee2aaSAndroid Build Coastguard Worker // 3 + 4 [2:5)
6516*c8dee2aaSAndroid Build Coastguard Worker // 3 + 4 [5:8)
6517*c8dee2aaSAndroid Build Coastguard Worker // 3 + 4 [8:11)
6518*c8dee2aaSAndroid Build Coastguard Worker // 4 [11:13)
6519*c8dee2aaSAndroid Build Coastguard Worker // 4 [13:15)
6520*c8dee2aaSAndroid Build Coastguard Worker // 4 [15:17)
6521*c8dee2aaSAndroid Build Coastguard Worker // 4 [17:19)
6522*c8dee2aaSAndroid Build Coastguard Worker
6523*c8dee2aaSAndroid Build Coastguard Worker auto family = paragraph->getRectsForRange(0, 11, RectHeightStyle::kTight, RectWidthStyle::kTight); // 00.0000000 + 17.4699993
6524*c8dee2aaSAndroid Build Coastguard Worker auto face01 = paragraph->getRectsForRange(11, 13, RectHeightStyle::kTight, RectWidthStyle::kTight); // 17.4699993 + 17.4699993
6525*c8dee2aaSAndroid Build Coastguard Worker auto face02 = paragraph->getRectsForRange(13, 15, RectHeightStyle::kTight, RectWidthStyle::kTight); // 34.9399986 + 17.4699993
6526*c8dee2aaSAndroid Build Coastguard Worker auto face03 = paragraph->getRectsForRange(15, 17, RectHeightStyle::kTight, RectWidthStyle::kTight); // 52.4099998 + 17.4699993
6527*c8dee2aaSAndroid Build Coastguard Worker auto face04 = paragraph->getRectsForRange(17, 19, RectHeightStyle::kTight, RectWidthStyle::kTight); // 69.8799973 + 17.4699993
6528*c8dee2aaSAndroid Build Coastguard Worker
6529*c8dee2aaSAndroid Build Coastguard Worker int32_t words[] = { 11, 13, 15, 17, 19, 21};
6530*c8dee2aaSAndroid Build Coastguard Worker auto j = 0;
6531*c8dee2aaSAndroid Build Coastguard Worker for (auto i : words) {
6532*c8dee2aaSAndroid Build Coastguard Worker auto rects = paragraph->getRectsForRange(j, i, RectHeightStyle::kTight, RectWidthStyle::kTight);
6533*c8dee2aaSAndroid Build Coastguard Worker if (rects.empty()) {
6534*c8dee2aaSAndroid Build Coastguard Worker continue;
6535*c8dee2aaSAndroid Build Coastguard Worker }
6536*c8dee2aaSAndroid Build Coastguard Worker auto X = rects[0].rect.centerX();
6537*c8dee2aaSAndroid Build Coastguard Worker auto Y = rects[0].rect.centerY();
6538*c8dee2aaSAndroid Build Coastguard Worker auto res1 = paragraph->getGlyphPositionAtCoordinate(X - 5, Y);
6539*c8dee2aaSAndroid Build Coastguard Worker //SkDebugf("[%d:%d) @%f,%f: %d %s\n", j, i, X - 5, Y, res1.position, res1.affinity == Affinity::kDownstream ? "D" : "U");
6540*c8dee2aaSAndroid Build Coastguard Worker auto res2 = paragraph->getGlyphPositionAtCoordinate(X + 5, Y);
6541*c8dee2aaSAndroid Build Coastguard Worker //SkDebugf("[%d:%d) @%f,%f: %d %s\n\n", j, i, X + 5, Y, res2.position, res2.affinity == Affinity::kDownstream ? "D" : "U");
6542*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, i == res2.position && res1.position == j);
6543*c8dee2aaSAndroid Build Coastguard Worker j = i;
6544*c8dee2aaSAndroid Build Coastguard Worker }
6545*c8dee2aaSAndroid Build Coastguard Worker }
6546*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_SingleLineHeight1,reporter)6547*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_SingleLineHeight1, reporter) {
6548*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6549*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6550*c8dee2aaSAndroid Build Coastguard Worker
6551*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_SingleLineHeight1.png");
6552*c8dee2aaSAndroid Build Coastguard Worker
6553*c8dee2aaSAndroid Build Coastguard Worker auto paint = [&](const char* text) {
6554*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6555*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextHeightBehavior(TextHeightBehavior::kDisableAll);
6556*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(1);
6557*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6558*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6559*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6560*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
6561*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(14);
6562*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(2);
6563*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeightOverride(true);
6564*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6565*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
6566*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6567*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(80);
6568*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6569*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getHeight() == 14.0f);
6570*c8dee2aaSAndroid Build Coastguard Worker };
6571*c8dee2aaSAndroid Build Coastguard Worker
6572*c8dee2aaSAndroid Build Coastguard Worker paint("Loooooooooooooooooooooooooooooooooooong text");
6573*c8dee2aaSAndroid Build Coastguard Worker paint("");
6574*c8dee2aaSAndroid Build Coastguard Worker }
6575*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_SingleLineHeight2,reporter)6576*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_SingleLineHeight2, reporter) {
6577*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6578*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6579*c8dee2aaSAndroid Build Coastguard Worker
6580*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_SingleLineHeight2.png");
6581*c8dee2aaSAndroid Build Coastguard Worker
6582*c8dee2aaSAndroid Build Coastguard Worker auto paint = [&](const char* text) {
6583*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6584*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(1);
6585*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6586*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6587*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6588*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
6589*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(14);
6590*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeight(2);
6591*c8dee2aaSAndroid Build Coastguard Worker text_style.setHeightOverride(true);
6592*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6593*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
6594*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6595*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(80);
6596*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6597*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getHeight() == 28.0f);
6598*c8dee2aaSAndroid Build Coastguard Worker };
6599*c8dee2aaSAndroid Build Coastguard Worker
6600*c8dee2aaSAndroid Build Coastguard Worker paint("Loooooooooooooooooooooooooooooooooooong text");
6601*c8dee2aaSAndroid Build Coastguard Worker paint("");
6602*c8dee2aaSAndroid Build Coastguard Worker }
6603*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_PlaceholderWidth,reporter)6604*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_PlaceholderWidth, reporter) {
6605*c8dee2aaSAndroid Build Coastguard Worker
6606*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6607*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6608*c8dee2aaSAndroid Build Coastguard Worker
6609*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_PlaceholderWidth.png");
6610*c8dee2aaSAndroid Build Coastguard Worker
6611*c8dee2aaSAndroid Build Coastguard Worker const char* text = "1 23 456 7890"; // 13 * 50 = 650
6612*c8dee2aaSAndroid Build Coastguard Worker
6613*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6614*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6615*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6616*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
6617*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
6618*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder(300, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 0);
6619*c8dee2aaSAndroid Build Coastguard Worker
6620*c8dee2aaSAndroid Build Coastguard Worker auto draw = [&](bool withPlaceholder) {
6621*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6622*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6623*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
6624*c8dee2aaSAndroid Build Coastguard Worker if (withPlaceholder) {
6625*c8dee2aaSAndroid Build Coastguard Worker SkPaint red;
6626*c8dee2aaSAndroid Build Coastguard Worker red.setColor(SK_ColorRED);
6627*c8dee2aaSAndroid Build Coastguard Worker text_style.setBackgroundColor(red);
6628*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6629*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder);
6630*c8dee2aaSAndroid Build Coastguard Worker }
6631*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
6632*c8dee2aaSAndroid Build Coastguard Worker
6633*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6634*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(950);
6635*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6636*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, paragraph->getHeight());
6637*c8dee2aaSAndroid Build Coastguard Worker return paragraph->getMinIntrinsicWidth();
6638*c8dee2aaSAndroid Build Coastguard Worker };
6639*c8dee2aaSAndroid Build Coastguard Worker
6640*c8dee2aaSAndroid Build Coastguard Worker auto len1 = draw(true);
6641*c8dee2aaSAndroid Build Coastguard Worker auto len2 = draw(false);
6642*c8dee2aaSAndroid Build Coastguard Worker
6643*c8dee2aaSAndroid Build Coastguard Worker // placeholder: 300 "78901": 250
6644*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(len1, 300.0f, EPSILON100));
6645*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(len2, 250.0f, EPSILON100));
6646*c8dee2aaSAndroid Build Coastguard Worker }
6647*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GlyphPositionsInEmptyLines,reporter)6648*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GlyphPositionsInEmptyLines, reporter) {
6649*c8dee2aaSAndroid Build Coastguard Worker
6650*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6651*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6652*c8dee2aaSAndroid Build Coastguard Worker
6653*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_GlyphPositionsInEmptyLines.png");
6654*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6655*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6656*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6657*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto") });
6658*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
6659*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6660*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6661*c8dee2aaSAndroid Build Coastguard Worker builder.addText("A\n\n");
6662*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6663*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6664*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(300);
6665*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6666*c8dee2aaSAndroid Build Coastguard Worker
6667*c8dee2aaSAndroid Build Coastguard Worker auto res1 = paragraph->
6668*c8dee2aaSAndroid Build Coastguard Worker getGlyphPositionAtCoordinate(paragraph->getMinIntrinsicWidth(),1);
6669*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, res1.position == 1 && res1.affinity == Affinity::kUpstream);
6670*c8dee2aaSAndroid Build Coastguard Worker
6671*c8dee2aaSAndroid Build Coastguard Worker auto res2 = paragraph->
6672*c8dee2aaSAndroid Build Coastguard Worker getGlyphPositionAtCoordinate(0,paragraph->getHeight() * 0.5);
6673*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, res2.position == 2 && res2.affinity == Affinity::kDownstream);
6674*c8dee2aaSAndroid Build Coastguard Worker
6675*c8dee2aaSAndroid Build Coastguard Worker auto res3 = paragraph->
6676*c8dee2aaSAndroid Build Coastguard Worker getGlyphPositionAtCoordinate(0,paragraph->getHeight() - 1);
6677*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, res3.position == 3 && res3.affinity == Affinity::kDownstream);
6678*c8dee2aaSAndroid Build Coastguard Worker }
6679*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_RTLGlyphPositions,reporter)6680*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RTLGlyphPositions, reporter) {
6681*c8dee2aaSAndroid Build Coastguard Worker
6682*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6683*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6684*c8dee2aaSAndroid Build Coastguard Worker
6685*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RTLGlyphPositions.png");
6686*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6687*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
6688*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6689*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6690*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto") });
6691*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
6692*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6693*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6694*c8dee2aaSAndroid Build Coastguard Worker builder.addText("אאאא");
6695*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6696*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6697*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(500);
6698*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6699*c8dee2aaSAndroid Build Coastguard Worker
6700*c8dee2aaSAndroid Build Coastguard Worker std::vector<std::pair<SkScalar, PositionWithAffinity>> checks = {
6701*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(550, PositionWithAffinity(0, Affinity::kDownstream)),
6702*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(500, PositionWithAffinity(0, Affinity::kDownstream)),
6703*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(494, PositionWithAffinity(1, Affinity::kUpstream)),
6704*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(488, PositionWithAffinity(1, Affinity::kDownstream)),
6705*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(485, PositionWithAffinity(2, Affinity::kUpstream)),
6706*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(480, PositionWithAffinity(2, Affinity::kDownstream)),
6707*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(475, PositionWithAffinity(3, Affinity::kUpstream)),
6708*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(471, PositionWithAffinity(3, Affinity::kDownstream)),
6709*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(467, PositionWithAffinity(4, Affinity::kUpstream)),
6710*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 0, PositionWithAffinity(4, Affinity::kUpstream)),
6711*c8dee2aaSAndroid Build Coastguard Worker };
6712*c8dee2aaSAndroid Build Coastguard Worker
6713*c8dee2aaSAndroid Build Coastguard Worker for (auto check : checks) {
6714*c8dee2aaSAndroid Build Coastguard Worker auto pos = paragraph->getGlyphPositionAtCoordinate(check.first, 0);
6715*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pos.affinity == check.second.affinity);
6716*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pos.position == check.second.position);
6717*c8dee2aaSAndroid Build Coastguard Worker }
6718*c8dee2aaSAndroid Build Coastguard Worker }
6719*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_RTLGlyphPositionsInEmptyLines,reporter)6720*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RTLGlyphPositionsInEmptyLines, reporter) {
6721*c8dee2aaSAndroid Build Coastguard Worker
6722*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6723*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6724*c8dee2aaSAndroid Build Coastguard Worker
6725*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RTLGlyphPositionsInEmptyLines.png");
6726*c8dee2aaSAndroid Build Coastguard Worker
6727*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6728*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
6729*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6730*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6731*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto") });
6732*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
6733*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6734*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6735*c8dee2aaSAndroid Build Coastguard Worker //builder.addText("בבבב\n\nאאאא");
6736*c8dee2aaSAndroid Build Coastguard Worker builder.addText("בבבב\n\nאאאא");
6737*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6738*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6739*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(500);
6740*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6741*c8dee2aaSAndroid Build Coastguard Worker
6742*c8dee2aaSAndroid Build Coastguard Worker auto height = paragraph->getHeight();
6743*c8dee2aaSAndroid Build Coastguard Worker auto res1 = paragraph->getGlyphPositionAtCoordinate(0, 0);
6744*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, res1.position == 4 && res1.affinity == Affinity::kUpstream);
6745*c8dee2aaSAndroid Build Coastguard Worker auto res2 = paragraph->getGlyphPositionAtCoordinate(0, height / 2);
6746*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, res2.position == 5 && res2.affinity == Affinity::kDownstream);
6747*c8dee2aaSAndroid Build Coastguard Worker auto res3 = paragraph->getGlyphPositionAtCoordinate(0, height);
6748*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, res3.position == 10 && res3.affinity == Affinity::kUpstream);
6749*c8dee2aaSAndroid Build Coastguard Worker }
6750*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_LTRGlyphPositionsForTrailingSpaces,reporter)6751*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_LTRGlyphPositionsForTrailingSpaces, reporter) {
6752*c8dee2aaSAndroid Build Coastguard Worker
6753*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6754*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6755*c8dee2aaSAndroid Build Coastguard Worker
6756*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_LTRGlyphPositionsForTrailingSpaces.png");
6757*c8dee2aaSAndroid Build Coastguard Worker
6758*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6759*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6760*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem") });
6761*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10);
6762*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6763*c8dee2aaSAndroid Build Coastguard Worker
6764*c8dee2aaSAndroid Build Coastguard Worker auto test = [&](const char* text) {
6765*c8dee2aaSAndroid Build Coastguard Worker auto str = straight(text);
6766*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6767*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6768*c8dee2aaSAndroid Build Coastguard Worker builder.addText(str);
6769*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6770*c8dee2aaSAndroid Build Coastguard Worker SkPaint gray; gray.setColor(SK_ColorGRAY);
6771*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6772*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(100);
6773*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, 20);
6774*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(SkRect::MakeXYWH(0, 0, paragraph->getMaxIntrinsicWidth(), paragraph->getHeight()), gray);
6775*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6776*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, paragraph->getHeight());
6777*c8dee2aaSAndroid Build Coastguard Worker
6778*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < str.size(); ++i) {
6779*c8dee2aaSAndroid Build Coastguard Worker auto res = paragraph->getGlyphPositionAtCoordinate(i * 10, 2);
6780*c8dee2aaSAndroid Build Coastguard Worker //SkDebugf("@%f[%d]: %d %s\n", i * 10.0f, i, res.position, res.affinity == Affinity::kDownstream ? "D" : "U");
6781*c8dee2aaSAndroid Build Coastguard Worker // There is a hidden codepoint at the beginning (to make it symmetric to RTL)
6782*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, res.position == SkToInt(i) + (i > 0 ? 1 : 0));
6783*c8dee2aaSAndroid Build Coastguard Worker // The ending looks slightly different...
6784*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, res.affinity == (res.position == SkToInt(str.size()) ? Affinity::kUpstream : Affinity::kDownstream));
6785*c8dee2aaSAndroid Build Coastguard Worker }
6786*c8dee2aaSAndroid Build Coastguard Worker };
6787*c8dee2aaSAndroid Build Coastguard Worker
6788*c8dee2aaSAndroid Build Coastguard Worker test(" ");
6789*c8dee2aaSAndroid Build Coastguard Worker test("hello ");
6790*c8dee2aaSAndroid Build Coastguard Worker }
6791*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_RTLGlyphPositionsForTrailingSpaces,reporter)6792*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RTLGlyphPositionsForTrailingSpaces, reporter) {
6793*c8dee2aaSAndroid Build Coastguard Worker
6794*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6795*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6796*c8dee2aaSAndroid Build Coastguard Worker
6797*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RTLGlyphPositionsForTrailingSpaces.png");
6798*c8dee2aaSAndroid Build Coastguard Worker
6799*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6800*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
6801*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kRight);
6802*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6803*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem") });
6804*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10);
6805*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6806*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(200, 0);
6807*c8dee2aaSAndroid Build Coastguard Worker
6808*c8dee2aaSAndroid Build Coastguard Worker auto test = [&](const char* text, int whitespaces) {
6809*c8dee2aaSAndroid Build Coastguard Worker auto str = mirror(text);
6810*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6811*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6812*c8dee2aaSAndroid Build Coastguard Worker builder.addText(str);
6813*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6814*c8dee2aaSAndroid Build Coastguard Worker SkPaint gray; gray.setColor(SK_ColorGRAY);
6815*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6816*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(100);
6817*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, 20);
6818*c8dee2aaSAndroid Build Coastguard Worker auto res = paragraph->getRectsForRange(0, str.size(), RectHeightStyle::kTight, RectWidthStyle::kTight);
6819*c8dee2aaSAndroid Build Coastguard Worker bool even = true;
6820*c8dee2aaSAndroid Build Coastguard Worker for (auto& r : res) {
6821*c8dee2aaSAndroid Build Coastguard Worker if (even) {
6822*c8dee2aaSAndroid Build Coastguard Worker gray.setColor(SK_ColorGRAY);
6823*c8dee2aaSAndroid Build Coastguard Worker } else {
6824*c8dee2aaSAndroid Build Coastguard Worker gray.setColor(SK_ColorLTGRAY);
6825*c8dee2aaSAndroid Build Coastguard Worker }
6826*c8dee2aaSAndroid Build Coastguard Worker even = !even;
6827*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(r.rect, gray);
6828*c8dee2aaSAndroid Build Coastguard Worker }
6829*c8dee2aaSAndroid Build Coastguard Worker gray.setColor(SK_ColorRED);
6830*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(SkRect::MakeXYWH(0, 0, 1, paragraph->getHeight()), gray);
6831*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6832*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(0, paragraph->getHeight());
6833*c8dee2aaSAndroid Build Coastguard Worker
6834*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < SkToInt(str.size()); ++i) {
6835*c8dee2aaSAndroid Build Coastguard Worker // Additional 1.0f to make sure the offset is not too close to the
6836*c8dee2aaSAndroid Build Coastguard Worker // edge of glyphs.
6837*c8dee2aaSAndroid Build Coastguard Worker auto pointX = (whitespaces + i) * 10.0f + 1.0f;
6838*c8dee2aaSAndroid Build Coastguard Worker auto pos = paragraph->getGlyphPositionAtCoordinate(pointX, 2);
6839*c8dee2aaSAndroid Build Coastguard Worker //SkDebugf("@%f[%d]: %d %s\n", pointX, i, pos.position, pos.affinity == Affinity::kDownstream ? "D" : "U");
6840*c8dee2aaSAndroid Build Coastguard Worker // At the beginning there is a control codepoint that makes the string RTL
6841*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, (pos.position + i) == SkToInt(str.size()) - (pos.affinity == Affinity::kDownstream ? 1 : 0));
6842*c8dee2aaSAndroid Build Coastguard Worker }
6843*c8dee2aaSAndroid Build Coastguard Worker };
6844*c8dee2aaSAndroid Build Coastguard Worker
6845*c8dee2aaSAndroid Build Coastguard Worker test(" ", 6);
6846*c8dee2aaSAndroid Build Coastguard Worker test(" hello", -10);
6847*c8dee2aaSAndroid Build Coastguard Worker }
6848*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_LTRLineMetricsDoesNotIncludeNewLine,reporter)6849*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_LTRLineMetricsDoesNotIncludeNewLine, reporter) {
6850*c8dee2aaSAndroid Build Coastguard Worker
6851*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6852*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6853*c8dee2aaSAndroid Build Coastguard Worker
6854*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_LTRLineMetricsDoesNotIncludeNewLine.png");
6855*c8dee2aaSAndroid Build Coastguard Worker
6856*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6857*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
6858*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6859*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6860*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto") });
6861*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
6862*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6863*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6864*c8dee2aaSAndroid Build Coastguard Worker builder.addText("one two\n\nthree four\nwith spaces \n \n______________________");
6865*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6866*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6867*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(190);
6868*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6869*c8dee2aaSAndroid Build Coastguard Worker
6870*c8dee2aaSAndroid Build Coastguard Worker std::vector<std::tuple<size_t, size_t, size_t, size_t>> expected = {
6871*c8dee2aaSAndroid Build Coastguard Worker { 0, 7, 7, 8 }, // one two\n
6872*c8dee2aaSAndroid Build Coastguard Worker { 8, 8, 8, 9 }, // \n
6873*c8dee2aaSAndroid Build Coastguard Worker { 9, 19, 19, 20 }, // three four\n
6874*c8dee2aaSAndroid Build Coastguard Worker { 20, 31, 36, 37 }, // with spaces \n
6875*c8dee2aaSAndroid Build Coastguard Worker { 37, 37, 41, 42 }, // { just spaces }\n
6876*c8dee2aaSAndroid Build Coastguard Worker { 42, 63, 63, 63 }, // _____________________
6877*c8dee2aaSAndroid Build Coastguard Worker { 63, 64, 64, 64 }, // _
6878*c8dee2aaSAndroid Build Coastguard Worker };
6879*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> metrics;
6880*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(metrics);
6881*c8dee2aaSAndroid Build Coastguard Worker for (auto& metric : metrics) {
6882*c8dee2aaSAndroid Build Coastguard Worker //SkDebugf("Line[%d:%d <= %d <=%d)\n", metric.fStartIndex, metric.fEndExcludingWhitespaces, metric.fEndIndex, metric.fEndIncludingNewline);
6883*c8dee2aaSAndroid Build Coastguard Worker auto result = expected[metric.fLineNumber];
6884*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, metric.fStartIndex ==std::get<0>(result));
6885*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, metric.fEndExcludingWhitespaces == std::get<1>(result));
6886*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, metric.fEndIndex == std::get<2>(result));
6887*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, metric.fEndIncludingNewline == std::get<3>(result));
6888*c8dee2aaSAndroid Build Coastguard Worker }
6889*c8dee2aaSAndroid Build Coastguard Worker }
6890*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_RTLLineMetricsDoesNotIncludeNewLine,reporter)6891*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RTLLineMetricsDoesNotIncludeNewLine, reporter) {
6892*c8dee2aaSAndroid Build Coastguard Worker
6893*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6894*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6895*c8dee2aaSAndroid Build Coastguard Worker
6896*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RTLLineMetricsDoesNotIncludeNewLine.png");
6897*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(100, 100);
6898*c8dee2aaSAndroid Build Coastguard Worker
6899*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6900*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
6901*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kRight);
6902*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6903*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6904*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto") });
6905*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
6906*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6907*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6908*c8dee2aaSAndroid Build Coastguard Worker builder.addText(mirror("______________________\none two\n\nthree four\nwith spaces \n "));
6909*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
6910*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6911*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(190);
6912*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6913*c8dee2aaSAndroid Build Coastguard Worker //auto impl = static_cast<ParagraphImpl*>(paragraph.get());
6914*c8dee2aaSAndroid Build Coastguard Worker
6915*c8dee2aaSAndroid Build Coastguard Worker SkPaint gray;
6916*c8dee2aaSAndroid Build Coastguard Worker gray.setColor(SK_ColorGRAY);
6917*c8dee2aaSAndroid Build Coastguard Worker gray.setStyle(SkPaint::kStroke_Style);
6918*c8dee2aaSAndroid Build Coastguard Worker gray.setAntiAlias(true);
6919*c8dee2aaSAndroid Build Coastguard Worker gray.setStrokeWidth(1);
6920*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(SkRect::MakeXYWH(0, 0, paragraph->getMaxWidth(), paragraph->getHeight()), gray);
6921*c8dee2aaSAndroid Build Coastguard Worker
6922*c8dee2aaSAndroid Build Coastguard Worker SkPaint red;
6923*c8dee2aaSAndroid Build Coastguard Worker red.setColor(SK_ColorRED);
6924*c8dee2aaSAndroid Build Coastguard Worker red.setStyle(SkPaint::kStroke_Style);
6925*c8dee2aaSAndroid Build Coastguard Worker red.setAntiAlias(true);
6926*c8dee2aaSAndroid Build Coastguard Worker red.setStrokeWidth(1);
6927*c8dee2aaSAndroid Build Coastguard Worker
6928*c8dee2aaSAndroid Build Coastguard Worker SkPaint blue;
6929*c8dee2aaSAndroid Build Coastguard Worker blue.setColor(SK_ColorRED);
6930*c8dee2aaSAndroid Build Coastguard Worker blue.setStyle(SkPaint::kStroke_Style);
6931*c8dee2aaSAndroid Build Coastguard Worker blue.setAntiAlias(true);
6932*c8dee2aaSAndroid Build Coastguard Worker blue.setStrokeWidth(1);
6933*c8dee2aaSAndroid Build Coastguard Worker
6934*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 100, RectHeightStyle::kTight, RectWidthStyle::kTight);
6935*c8dee2aaSAndroid Build Coastguard Worker bool even = false;
6936*c8dee2aaSAndroid Build Coastguard Worker for (auto& box : boxes) {
6937*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(box.rect, even ? red : blue);
6938*c8dee2aaSAndroid Build Coastguard Worker even = !even;
6939*c8dee2aaSAndroid Build Coastguard Worker }
6940*c8dee2aaSAndroid Build Coastguard Worker
6941*c8dee2aaSAndroid Build Coastguard Worker // RTL codepoint u"\u202E" messes everything up
6942*c8dee2aaSAndroid Build Coastguard Worker // (adds one invisible codepoint to the first line
6943*c8dee2aaSAndroid Build Coastguard Worker // and shift all the indexes by 1 right)
6944*c8dee2aaSAndroid Build Coastguard Worker std::vector<std::tuple<int, int, int, int>> expected = {
6945*c8dee2aaSAndroid Build Coastguard Worker { 0, 1, 5, 6 }, // { just spaces; the end of the text considered as a new line in libtxt?!? }
6946*c8dee2aaSAndroid Build Coastguard Worker { 6, 22, 22, 23 }, // with spaces \n
6947*c8dee2aaSAndroid Build Coastguard Worker { 23, 33, 33, 34 }, // three four\n
6948*c8dee2aaSAndroid Build Coastguard Worker { 34, 34, 34, 35 }, // \n
6949*c8dee2aaSAndroid Build Coastguard Worker { 35, 42, 42, 43 }, // one two\n
6950*c8dee2aaSAndroid Build Coastguard Worker { 43, 64, 64, 64 }, // _____________________
6951*c8dee2aaSAndroid Build Coastguard Worker { 64, 65, 65, 65 } // _
6952*c8dee2aaSAndroid Build Coastguard Worker };
6953*c8dee2aaSAndroid Build Coastguard Worker
6954*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> metrics;
6955*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(metrics);
6956*c8dee2aaSAndroid Build Coastguard Worker for (auto& metric : metrics) {
6957*c8dee2aaSAndroid Build Coastguard Worker //SkDebugf("Line[%d:%d <= %d <=%d]\n", metric.fStartIndex, metric.fEndExcludingWhitespaces, metric.fEndIndex, metric.fEndIncludingNewline);
6958*c8dee2aaSAndroid Build Coastguard Worker auto result = expected[metric.fLineNumber];
6959*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, metric.fStartIndex == SkToU32(std::get<0>(result)));
6960*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, metric.fEndExcludingWhitespaces == SkToU32(std::get<1>(result)));
6961*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, metric.fEndIndex == SkToU32(std::get<2>(result)));
6962*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, metric.fEndIncludingNewline == SkToU32(std::get<3>(result)));
6963*c8dee2aaSAndroid Build Coastguard Worker }
6964*c8dee2aaSAndroid Build Coastguard Worker }
6965*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_PlaceholderPosition,reporter)6966*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_PlaceholderPosition, reporter) {
6967*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
6968*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
6969*c8dee2aaSAndroid Build Coastguard Worker
6970*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_PlaceholderPosition.png");
6971*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(100, 100);
6972*c8dee2aaSAndroid Build Coastguard Worker
6973*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
6974*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
6975*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
6976*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10.0f);
6977*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
6978*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
6979*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
6980*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
6981*c8dee2aaSAndroid Build Coastguard Worker builder.addText("abcd");
6982*c8dee2aaSAndroid Build Coastguard Worker
6983*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle placeholder_style;
6984*c8dee2aaSAndroid Build Coastguard Worker placeholder_style.fHeight = 10;
6985*c8dee2aaSAndroid Build Coastguard Worker placeholder_style.fWidth = 10;
6986*c8dee2aaSAndroid Build Coastguard Worker placeholder_style.fBaseline = TextBaseline::kAlphabetic;
6987*c8dee2aaSAndroid Build Coastguard Worker placeholder_style.fAlignment = PlaceholderAlignment::kBottom;
6988*c8dee2aaSAndroid Build Coastguard Worker builder.addPlaceholder(placeholder_style);
6989*c8dee2aaSAndroid Build Coastguard Worker
6990*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
6991*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(500);
6992*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
6993*c8dee2aaSAndroid Build Coastguard Worker
6994*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getGlyphPositionAtCoordinate(41.0f, 0.0f);
6995*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result.position == 4 && result.affinity == Affinity::kDownstream);
6996*c8dee2aaSAndroid Build Coastguard Worker }
6997*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_LineEnd,reporter)6998*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_LineEnd, reporter) {
6999*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7000*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7001*c8dee2aaSAndroid Build Coastguard Worker
7002*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_LineEnd.png");
7003*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(100, 100);
7004*c8dee2aaSAndroid Build Coastguard Worker
7005*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7006*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7007*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
7008*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10.0f);
7009*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7010*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7011*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7012*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7013*c8dee2aaSAndroid Build Coastguard Worker builder.addText("Hello ");
7014*c8dee2aaSAndroid Build Coastguard Worker builder.addText("hello ");
7015*c8dee2aaSAndroid Build Coastguard Worker builder.addText("hello\n");
7016*c8dee2aaSAndroid Build Coastguard Worker builder.addText("hello \n");
7017*c8dee2aaSAndroid Build Coastguard Worker builder.addText("world");
7018*c8dee2aaSAndroid Build Coastguard Worker
7019*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7020*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(60.0f);
7021*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7022*c8dee2aaSAndroid Build Coastguard Worker
7023*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> lm;
7024*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(lm);
7025*c8dee2aaSAndroid Build Coastguard Worker /*
7026*c8dee2aaSAndroid Build Coastguard Worker for (auto& lm : lm) {
7027*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%d %d %d\n", (int)lm.fEndExcludingWhitespaces, (int)lm.fEndIndex, (int)lm.fEndIncludingNewline);
7028*c8dee2aaSAndroid Build Coastguard Worker }
7029*c8dee2aaSAndroid Build Coastguard Worker */
7030*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm.size() >= 4);
7031*c8dee2aaSAndroid Build Coastguard Worker if (lm.size() >= 4) {
7032*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm[0].fEndExcludingWhitespaces == 05 && lm[0].fEndIndex == 06 && lm[0].fEndIncludingNewline == 06);
7033*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm[1].fEndExcludingWhitespaces == 11 && lm[1].fEndIndex == 14 && lm[1].fEndIncludingNewline == 14);
7034*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm[2].fEndExcludingWhitespaces == 19 && lm[2].fEndIndex == 19 && lm[2].fEndIncludingNewline == 20);
7035*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm[3].fEndExcludingWhitespaces == 25 && lm[3].fEndIndex == 28 && lm[3].fEndIncludingNewline == 29);
7036*c8dee2aaSAndroid Build Coastguard Worker }
7037*c8dee2aaSAndroid Build Coastguard Worker }
7038*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Utf16Indexes,reporter)7039*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Utf16Indexes, reporter) {
7040*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7041*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7042*c8dee2aaSAndroid Build Coastguard Worker
7043*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_Utf16Indexes.png");
7044*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(100, 100);
7045*c8dee2aaSAndroid Build Coastguard Worker
7046*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7047*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7048*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
7049*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10.0f);
7050*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7051*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7052*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7053*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7054*c8dee2aaSAndroid Build Coastguard Worker builder.addText("áéíóú\nxxxx");
7055*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7056*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(60.0f);
7057*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7058*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> lm;
7059*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(lm);
7060*c8dee2aaSAndroid Build Coastguard Worker //for (auto& lm : lm) {
7061*c8dee2aaSAndroid Build Coastguard Worker // SkDebugf("%d %d %d\n", (int)lm.fEndExcludingWhitespaces, (int)lm.fEndIndex, (int)lm.fEndIncludingNewline);
7062*c8dee2aaSAndroid Build Coastguard Worker //}
7063*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm.size() == 2);
7064*c8dee2aaSAndroid Build Coastguard Worker if (lm.size() >= 2) {
7065*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm[0].fEndExcludingWhitespaces == 05 && lm[0].fEndIndex == 05 && lm[0].fEndIncludingNewline == 06);
7066*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm[1].fEndExcludingWhitespaces == 10 && lm[1].fEndIndex == 10 && lm[1].fEndIncludingNewline == 10);
7067*c8dee2aaSAndroid Build Coastguard Worker }
7068*c8dee2aaSAndroid Build Coastguard Worker }
7069*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_RTLFollowedByLTR,reporter)7070*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RTLFollowedByLTR, reporter) {
7071*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7072*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7073*c8dee2aaSAndroid Build Coastguard Worker
7074*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RTLFollowedByLTR.png");
7075*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->translate(100, 100);
7076*c8dee2aaSAndroid Build Coastguard Worker
7077*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7078*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
7079*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10);
7080*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7081*c8dee2aaSAndroid Build Coastguard Worker
7082*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7083*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7084*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kLtr);
7085*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7086*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7087*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"\u05D0\u05D0\u05D0ABC");
7088*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7089*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(100);
7090*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7091*c8dee2aaSAndroid Build Coastguard Worker
7092*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(
7093*c8dee2aaSAndroid Build Coastguard Worker 0, paragraph->getMaxWidth(), RectHeightStyle::kTight, RectWidthStyle::kTight);
7094*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 2);
7095*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(
7096*c8dee2aaSAndroid Build Coastguard Worker reporter,
7097*c8dee2aaSAndroid Build Coastguard Worker boxes[0].direction == TextDirection::kRtl && boxes[1].direction == TextDirection::kLtr);
7098*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.fLeft, 0.0f));
7099*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.fRight, boxes[1].rect.fLeft));
7100*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
7101*c8dee2aaSAndroid Build Coastguard Worker SkScalarNearlyEqual(boxes[1].rect.fRight, paragraph->getMaxIntrinsicWidth()));
7102*c8dee2aaSAndroid Build Coastguard Worker
7103*c8dee2aaSAndroid Build Coastguard Worker std::vector<std::pair<SkScalar, PositionWithAffinity>> checks = {
7104*c8dee2aaSAndroid Build Coastguard Worker std::make_pair(-10, PositionWithAffinity(3, Affinity::kUpstream)),
7105*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 0, PositionWithAffinity(3, Affinity::kUpstream)),
7106*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 5, PositionWithAffinity(2, Affinity::kDownstream)),
7107*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 10, PositionWithAffinity(2, Affinity::kUpstream)),
7108*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 15, PositionWithAffinity(1, Affinity::kDownstream)),
7109*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 20, PositionWithAffinity(1, Affinity::kUpstream)),
7110*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 25, PositionWithAffinity(0, Affinity::kDownstream)),
7111*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 30, PositionWithAffinity(3, Affinity::kDownstream)),
7112*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 35, PositionWithAffinity(4, Affinity::kUpstream)),
7113*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 40, PositionWithAffinity(4, Affinity::kDownstream)),
7114*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 45, PositionWithAffinity(5, Affinity::kUpstream)),
7115*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 50, PositionWithAffinity(5, Affinity::kDownstream)),
7116*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 55, PositionWithAffinity(6, Affinity::kUpstream)),
7117*c8dee2aaSAndroid Build Coastguard Worker std::make_pair( 60, PositionWithAffinity(6, Affinity::kUpstream)),
7118*c8dee2aaSAndroid Build Coastguard Worker };
7119*c8dee2aaSAndroid Build Coastguard Worker
7120*c8dee2aaSAndroid Build Coastguard Worker for (auto check : checks) {
7121*c8dee2aaSAndroid Build Coastguard Worker auto pos = paragraph->getGlyphPositionAtCoordinate(check.first, 0);
7122*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pos.affinity == check.second.affinity);
7123*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pos.position == check.second.position);
7124*c8dee2aaSAndroid Build Coastguard Worker }
7125*c8dee2aaSAndroid Build Coastguard Worker }
7126*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_StrutTopLine,reporter)7127*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_StrutTopLine, reporter) {
7128*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7129*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7130*c8dee2aaSAndroid Build Coastguard Worker
7131*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_StrutTopLine.png");
7132*c8dee2aaSAndroid Build Coastguard Worker
7133*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7134*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
7135*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10);
7136*c8dee2aaSAndroid Build Coastguard Worker SkPaint black;
7137*c8dee2aaSAndroid Build Coastguard Worker black.setColor(SK_ColorBLACK);
7138*c8dee2aaSAndroid Build Coastguard Worker text_style.setForegroundColor(black);
7139*c8dee2aaSAndroid Build Coastguard Worker
7140*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7141*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7142*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kLtr);
7143*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
7144*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(true);
7145*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontFamilies({SkString("Ahem")});
7146*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontSize(16);
7147*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeight(4.0f);
7148*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeightOverride(true);
7149*c8dee2aaSAndroid Build Coastguard Worker strut_style.setLeading(-1.0f);
7150*c8dee2aaSAndroid Build Coastguard Worker strut_style.setForceStrutHeight(true);
7151*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
7152*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7153*c8dee2aaSAndroid Build Coastguard Worker
7154*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7155*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"Atwater Peel Sherbrooke Bonaventure\nhi\nwasssup!");
7156*c8dee2aaSAndroid Build Coastguard Worker
7157*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7158*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(797);
7159*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7160*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 60, RectHeightStyle::kIncludeLineSpacingTop, RectWidthStyle::kMax);
7161*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 4);
7162*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 4) {
7163*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.fTop, 38.4f));
7164*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.fBottom, 64.0f));
7165*c8dee2aaSAndroid Build Coastguard Worker
7166*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.fTop, 64.0f));
7167*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.fBottom, 128.0f));
7168*c8dee2aaSAndroid Build Coastguard Worker
7169*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[2].rect.fTop, 64.0f));
7170*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[2].rect.fBottom, 128.0f));
7171*c8dee2aaSAndroid Build Coastguard Worker
7172*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[3].rect.fTop, 128.0f));
7173*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[3].rect.fBottom, 192.0f));
7174*c8dee2aaSAndroid Build Coastguard Worker }
7175*c8dee2aaSAndroid Build Coastguard Worker }
7176*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_DifferentFontsTopLine,reporter)7177*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_DifferentFontsTopLine, reporter) {
7178*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7179*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7180*c8dee2aaSAndroid Build Coastguard Worker
7181*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_DifferentFontsTopLine.png");
7182*c8dee2aaSAndroid Build Coastguard Worker
7183*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7184*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
7185*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10);
7186*c8dee2aaSAndroid Build Coastguard Worker SkPaint black;
7187*c8dee2aaSAndroid Build Coastguard Worker black.setColor(SK_ColorBLACK);
7188*c8dee2aaSAndroid Build Coastguard Worker text_style.setForegroundColor(black);
7189*c8dee2aaSAndroid Build Coastguard Worker
7190*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7191*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7192*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kLtr);
7193*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7194*c8dee2aaSAndroid Build Coastguard Worker
7195*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(30.0);
7196*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7197*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"Atwater Peel ");
7198*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(15.0);
7199*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7200*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"Sherbrooke Bonaventure ");
7201*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10.0);
7202*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7203*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"hi wassup!");
7204*c8dee2aaSAndroid Build Coastguard Worker
7205*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7206*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(797);
7207*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7208*c8dee2aaSAndroid Build Coastguard Worker auto boxes = paragraph->getRectsForRange(0, 60, RectHeightStyle::kIncludeLineSpacingTop, RectWidthStyle::kMax);
7209*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 4);
7210*c8dee2aaSAndroid Build Coastguard Worker if (boxes.size() >= 4) {
7211*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.fTop, 00.0f));
7212*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[0].rect.fBottom, 30.0f));
7213*c8dee2aaSAndroid Build Coastguard Worker
7214*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.fTop, 00.0f));
7215*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[1].rect.fBottom, 30.0f));
7216*c8dee2aaSAndroid Build Coastguard Worker
7217*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[2].rect.fTop, 00.0f));
7218*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[2].rect.fBottom, 30.0f));
7219*c8dee2aaSAndroid Build Coastguard Worker
7220*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[3].rect.fTop, 30.0f));
7221*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(boxes[3].rect.fBottom, 40.0f));
7222*c8dee2aaSAndroid Build Coastguard Worker }
7223*c8dee2aaSAndroid Build Coastguard Worker }
7224*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_SimpleParagraphReset,reporter)7225*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_SimpleParagraphReset, reporter) {
7226*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7227*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7228*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Hello World Text Dialog";
7229*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
7230*c8dee2aaSAndroid Build Coastguard Worker
7231*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7232*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
7233*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7234*c8dee2aaSAndroid Build Coastguard Worker
7235*c8dee2aaSAndroid Build Coastguard Worker for (int iteration = 0; iteration < 2; iteration += 1) {
7236*c8dee2aaSAndroid Build Coastguard Worker builder.Reset();
7237*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, builder.peekStyle().equals(paragraph_style.getTextStyle()));
7238*c8dee2aaSAndroid Build Coastguard Worker
7239*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7240*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
7241*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7242*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7243*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
7244*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
7245*c8dee2aaSAndroid Build Coastguard Worker
7246*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7247*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
7248*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->unresolvedGlyphs() == 0);
7249*c8dee2aaSAndroid Build Coastguard Worker
7250*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
7251*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1);
7252*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles().size() == 1); // paragraph style does not count
7253*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->styles()[0].fStyle.equals(text_style));
7254*c8dee2aaSAndroid Build Coastguard Worker
7255*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
7256*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
7257*c8dee2aaSAndroid Build Coastguard Worker line.scanStyles(StyleType::kDecorations,
7258*c8dee2aaSAndroid Build Coastguard Worker [&index, reporter]
7259*c8dee2aaSAndroid Build Coastguard Worker (TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
7260*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 0);
7261*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getColor() == SK_ColorBLACK);
7262*c8dee2aaSAndroid Build Coastguard Worker ++index;
7263*c8dee2aaSAndroid Build Coastguard Worker });
7264*c8dee2aaSAndroid Build Coastguard Worker }
7265*c8dee2aaSAndroid Build Coastguard Worker }
7266*c8dee2aaSAndroid Build Coastguard Worker }
7267*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_EllipsisGetRectForRange,reporter)7268*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_EllipsisGetRectForRange, reporter) {
7269*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7270*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7271*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_EllipsisGetRectForRange.png");
7272*c8dee2aaSAndroid Build Coastguard Worker const char* text =
7273*c8dee2aaSAndroid Build Coastguard Worker "This is a very long sentence to test if the text will properly wrap "
7274*c8dee2aaSAndroid Build Coastguard Worker "around and go to the next line. Sometimes, short sentence. Longer "
7275*c8dee2aaSAndroid Build Coastguard Worker "sentences are okay too because they are nessecary. Very short. ";
7276*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
7277*c8dee2aaSAndroid Build Coastguard Worker
7278*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7279*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(1);
7280*c8dee2aaSAndroid Build Coastguard Worker std::u16string ellipsis = u"\u2026";
7281*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setEllipsis(ellipsis);
7282*c8dee2aaSAndroid Build Coastguard Worker std::u16string e = paragraph_style.getEllipsisUtf16();
7283*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
7284*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7285*c8dee2aaSAndroid Build Coastguard Worker
7286*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7287*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
7288*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7289*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7290*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
7291*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
7292*c8dee2aaSAndroid Build Coastguard Worker
7293*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7294*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
7295*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7296*c8dee2aaSAndroid Build Coastguard Worker
7297*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
7298*c8dee2aaSAndroid Build Coastguard Worker
7299*c8dee2aaSAndroid Build Coastguard Worker // Check that the ellipsizer limited the text to one line and did not wrap to a second line.
7300*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
7301*c8dee2aaSAndroid Build Coastguard Worker
7302*c8dee2aaSAndroid Build Coastguard Worker auto boxes1 = impl->getRectsForRange(0, 2, RectHeightStyle::kTight, RectWidthStyle::kTight);
7303*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes1.size() == 1);
7304*c8dee2aaSAndroid Build Coastguard Worker
7305*c8dee2aaSAndroid Build Coastguard Worker auto boxes2 = impl->getRectsForRange(0, 3, RectHeightStyle::kTight, RectWidthStyle::kTight);
7306*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes2.size() == 1);
7307*c8dee2aaSAndroid Build Coastguard Worker
7308*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes1);
7309*c8dee2aaSAndroid Build Coastguard Worker canvas.drawRects(SK_ColorRED, boxes2);
7310*c8dee2aaSAndroid Build Coastguard Worker }
7311*c8dee2aaSAndroid Build Coastguard Worker
7312*c8dee2aaSAndroid Build Coastguard Worker // This test does not produce an image
UNIX_ONLY_TEST(SkParagraph_StrutAndTextBehavior,reporter)7313*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_StrutAndTextBehavior, reporter) {
7314*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7315*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7316*c8dee2aaSAndroid Build Coastguard Worker const char* text = "";
7317*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
7318*c8dee2aaSAndroid Build Coastguard Worker
7319*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7320*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
7321*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(16.0);
7322*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7323*c8dee2aaSAndroid Build Coastguard Worker StrutStyle strut_style;
7324*c8dee2aaSAndroid Build Coastguard Worker strut_style.setStrutEnabled(true);
7325*c8dee2aaSAndroid Build Coastguard Worker strut_style.setForceStrutHeight(true);
7326*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeight(1.5);
7327*c8dee2aaSAndroid Build Coastguard Worker strut_style.setHeightOverride(true);
7328*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontFamilies({SkString("Ahem")});
7329*c8dee2aaSAndroid Build Coastguard Worker strut_style.setFontSize(16.0);
7330*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7331*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setStrutStyle(strut_style);
7332*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7333*c8dee2aaSAndroid Build Coastguard Worker
7334*c8dee2aaSAndroid Build Coastguard Worker auto layout = [&](TextHeightBehavior tb) {
7335*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextHeightBehavior(tb);
7336*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7337*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7338*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
7339*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7340*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(SK_ScalarInfinity);
7341*c8dee2aaSAndroid Build Coastguard Worker return paragraph->getHeight();
7342*c8dee2aaSAndroid Build Coastguard Worker };
7343*c8dee2aaSAndroid Build Coastguard Worker
7344*c8dee2aaSAndroid Build Coastguard Worker auto height1 = layout(TextHeightBehavior::kDisableAll);
7345*c8dee2aaSAndroid Build Coastguard Worker auto height2 = layout(TextHeightBehavior::kAll);
7346*c8dee2aaSAndroid Build Coastguard Worker
7347*c8dee2aaSAndroid Build Coastguard Worker // Regardless of TextHeightBehavior strut sets the line height
7348*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(height1, 24.0f));
7349*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(height2, 24.0f));
7350*c8dee2aaSAndroid Build Coastguard Worker }
7351*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_NonMonotonicGlyphsLTR,reporter)7352*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_NonMonotonicGlyphsLTR, reporter) {
7353*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7354*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7355*c8dee2aaSAndroid Build Coastguard Worker NEED_SYSTEM_FONTS(fontCollection)
7356*c8dee2aaSAndroid Build Coastguard Worker
7357*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_NonMonotonicGlyphsLTR.png");
7358*c8dee2aaSAndroid Build Coastguard Worker std::u16string text =
7359*c8dee2aaSAndroid Build Coastguard Worker u"\u0068\u0301\u0350\u0312\u0357\u030C\u0369\u0305\u036C\u0304\u0310\u033F\u0366\u0350 ";
7360*c8dee2aaSAndroid Build Coastguard Worker /*
7361*c8dee2aaSAndroid Build Coastguard Worker u"\u0343\u0364\u0369\u0311\u0309\u030E\u0365\u031B\u0340\u0337\u0335\u035E\u0334\u0328"
7362*c8dee2aaSAndroid Build Coastguard Worker u"\u0360\u0360\u0315\u035F\u0340\u0340\u0362\u0360\u0322\u031B\u031B\u0337\u0340\u031E"
7363*c8dee2aaSAndroid Build Coastguard Worker u"\u031F\u032A\u0331\u0345\u032F\u0332\u032E\u0333\u0353\u0320\u0345\u031C\u031F\u033C"
7364*c8dee2aaSAndroid Build Coastguard Worker u"\u0325\u0355\u032C\u0325\u033Aa\u0307\u0312\u034B\u0308\u0312\u0346\u0313\u0346\u0304"
7365*c8dee2aaSAndroid Build Coastguard Worker u"\u0307\u0344\u0305\u0342\u0368\u0346\u036A\u035B\u030F\u0365\u0307\u0340\u0328\u0322"
7366*c8dee2aaSAndroid Build Coastguard Worker u"\u0361\u0489\u034F\u0328\u0334\u035F\u0335\u0362\u0489\u0360\u0358\u035E\u0360\u035D"
7367*c8dee2aaSAndroid Build Coastguard Worker u"\u0341\u0337\u0337\u032E\u0326\u032D\u0359\u0318\u033C\u032F\u0333\u035A\u034D\u0319"
7368*c8dee2aaSAndroid Build Coastguard Worker u"\u031C\u0353\u033C\u0345\u0359\u0331\u033B\u0331\u033C";
7369*c8dee2aaSAndroid Build Coastguard Worker */
7370*c8dee2aaSAndroid Build Coastguard Worker
7371*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7372*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(14);
7373*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
7374*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7375*c8dee2aaSAndroid Build Coastguard Worker
7376*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7377*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7378*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7379*c8dee2aaSAndroid Build Coastguard Worker
7380*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7381*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
7382*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7383*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(SK_ScalarInfinity);
7384*c8dee2aaSAndroid Build Coastguard Worker
7385*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(paragraph->getMinIntrinsicWidth() + 1);
7386*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
7387*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() > 1); // It's not the simple case
7388*c8dee2aaSAndroid Build Coastguard Worker bool hasNonMonotonicPlacement = false;
7389*c8dee2aaSAndroid Build Coastguard Worker for (auto& run : impl->runs()) {
7390*c8dee2aaSAndroid Build Coastguard Worker for (auto& offset : run.offsets()) {
7391*c8dee2aaSAndroid Build Coastguard Worker if (offset.fX < 0) {
7392*c8dee2aaSAndroid Build Coastguard Worker hasNonMonotonicPlacement = true;
7393*c8dee2aaSAndroid Build Coastguard Worker }
7394*c8dee2aaSAndroid Build Coastguard Worker }
7395*c8dee2aaSAndroid Build Coastguard Worker if (hasNonMonotonicPlacement) {
7396*c8dee2aaSAndroid Build Coastguard Worker break;
7397*c8dee2aaSAndroid Build Coastguard Worker }
7398*c8dee2aaSAndroid Build Coastguard Worker }
7399*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, hasNonMonotonicPlacement); // There are non-monotonic placement
7400*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lineNumber() == 1); // But it's still one line
7401*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7402*c8dee2aaSAndroid Build Coastguard Worker }
7403*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_NonMonotonicGlyphsRTL,reporter)7404*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_NonMonotonicGlyphsRTL, reporter) {
7405*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7406*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7407*c8dee2aaSAndroid Build Coastguard Worker NEED_SYSTEM_FONTS(fontCollection)
7408*c8dee2aaSAndroid Build Coastguard Worker
7409*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_NonMonotonicGlyphsRTL.png");
7410*c8dee2aaSAndroid Build Coastguard Worker const char* text = "ٱلْرَّحْمَـانُ";
7411*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
7412*c8dee2aaSAndroid Build Coastguard Worker
7413*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7414*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(14);
7415*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7416*c8dee2aaSAndroid Build Coastguard Worker
7417*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7418*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7419*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7420*c8dee2aaSAndroid Build Coastguard Worker
7421*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7422*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
7423*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7424*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(SK_ScalarInfinity);
7425*c8dee2aaSAndroid Build Coastguard Worker
7426*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(paragraph->getMinIntrinsicWidth() + 1);
7427*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
7428*c8dee2aaSAndroid Build Coastguard Worker bool hasNonMonotonicPlacement = false;
7429*c8dee2aaSAndroid Build Coastguard Worker for (auto& run : impl->runs()) {
7430*c8dee2aaSAndroid Build Coastguard Worker for (auto& offset : run.offsets()) {
7431*c8dee2aaSAndroid Build Coastguard Worker if (offset.fX < 0) {
7432*c8dee2aaSAndroid Build Coastguard Worker hasNonMonotonicPlacement = true;
7433*c8dee2aaSAndroid Build Coastguard Worker }
7434*c8dee2aaSAndroid Build Coastguard Worker }
7435*c8dee2aaSAndroid Build Coastguard Worker if (hasNonMonotonicPlacement) {
7436*c8dee2aaSAndroid Build Coastguard Worker break;
7437*c8dee2aaSAndroid Build Coastguard Worker }
7438*c8dee2aaSAndroid Build Coastguard Worker }
7439*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lineNumber() == 1); // But it's still one line
7440*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7441*c8dee2aaSAndroid Build Coastguard Worker }
7442*c8dee2aaSAndroid Build Coastguard Worker
performGetRectsForRangeConcurrently(skiatest::Reporter * reporter)7443*c8dee2aaSAndroid Build Coastguard Worker void performGetRectsForRangeConcurrently(skiatest::Reporter* reporter) {
7444*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7445*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7446*c8dee2aaSAndroid Build Coastguard Worker
7447*c8dee2aaSAndroid Build Coastguard Worker auto const text = std::u16string(42000, 'x');
7448*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraphStyle;
7449*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
7450*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
7451*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontSize(14);
7452*c8dee2aaSAndroid Build Coastguard Worker textStyle.setColor(SK_ColorBLACK);
7453*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
7454*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::kUpright_Slant));
7455*c8dee2aaSAndroid Build Coastguard Worker
7456*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraphStyle, fontCollection, get_unicode());
7457*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
7458*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
7459*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
7460*c8dee2aaSAndroid Build Coastguard Worker
7461*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7462*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(std::numeric_limits<float>::max());
7463*c8dee2aaSAndroid Build Coastguard Worker
7464*c8dee2aaSAndroid Build Coastguard Worker RectHeightStyle heightStyle = RectHeightStyle::kMax;
7465*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle widthStyle = RectWidthStyle::kMax;
7466*c8dee2aaSAndroid Build Coastguard Worker auto t1 = std::thread([&] {
7467*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(0, 2, heightStyle, widthStyle);
7468*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !result.empty());
7469*c8dee2aaSAndroid Build Coastguard Worker });
7470*c8dee2aaSAndroid Build Coastguard Worker auto t2 = std::thread([&] {
7471*c8dee2aaSAndroid Build Coastguard Worker auto result = paragraph->getRectsForRange(5, 10, heightStyle, widthStyle);
7472*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !result.empty());
7473*c8dee2aaSAndroid Build Coastguard Worker });
7474*c8dee2aaSAndroid Build Coastguard Worker t1.join();
7475*c8dee2aaSAndroid Build Coastguard Worker t2.join();
7476*c8dee2aaSAndroid Build Coastguard Worker }
7477*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeConcurrently,reporter)7478*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeConcurrently, reporter) {
7479*c8dee2aaSAndroid Build Coastguard Worker auto const threads_count = 100;
7480*c8dee2aaSAndroid Build Coastguard Worker std::thread threads[threads_count];
7481*c8dee2aaSAndroid Build Coastguard Worker for (auto& thread : threads) {
7482*c8dee2aaSAndroid Build Coastguard Worker thread = std::thread(performGetRectsForRangeConcurrently, reporter);
7483*c8dee2aaSAndroid Build Coastguard Worker }
7484*c8dee2aaSAndroid Build Coastguard Worker for (auto& thread : threads) {
7485*c8dee2aaSAndroid Build Coastguard Worker thread.join();
7486*c8dee2aaSAndroid Build Coastguard Worker }
7487*c8dee2aaSAndroid Build Coastguard Worker }
7488*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_TabSubstitution,reporter)7489*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_TabSubstitution, reporter) {
7490*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
7491*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7492*c8dee2aaSAndroid Build Coastguard Worker
7493*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_TabSubstitution.png");
7494*c8dee2aaSAndroid Build Coastguard Worker
7495*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7496*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setReplaceTabCharacters(true);
7497*c8dee2aaSAndroid Build Coastguard Worker
7498*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7499*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7500*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
7501*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(100);
7502*c8dee2aaSAndroid Build Coastguard Worker
7503*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder1(paragraph_style, fontCollection, get_unicode());
7504*c8dee2aaSAndroid Build Coastguard Worker builder1.pushStyle(text_style);
7505*c8dee2aaSAndroid Build Coastguard Worker builder1.addText("There is a tab>\t<right here");
7506*c8dee2aaSAndroid Build Coastguard Worker auto paragraph1 = builder1.Build();
7507*c8dee2aaSAndroid Build Coastguard Worker paragraph1->layout(TestCanvasWidth);
7508*c8dee2aaSAndroid Build Coastguard Worker paragraph1->paint(canvas.get(), 0, 0);
7509*c8dee2aaSAndroid Build Coastguard Worker
7510*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setReplaceTabCharacters(false);
7511*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder2(paragraph_style, fontCollection, get_unicode());
7512*c8dee2aaSAndroid Build Coastguard Worker builder2.pushStyle(text_style);
7513*c8dee2aaSAndroid Build Coastguard Worker builder2.addText("There is a tab>\t<right here");
7514*c8dee2aaSAndroid Build Coastguard Worker auto paragraph2 = builder2.Build();
7515*c8dee2aaSAndroid Build Coastguard Worker paragraph2->layout(TestCanvasWidth);
7516*c8dee2aaSAndroid Build Coastguard Worker paragraph2->paint(canvas.get(), 0, 0);
7517*c8dee2aaSAndroid Build Coastguard Worker
7518*c8dee2aaSAndroid Build Coastguard Worker // Second paragraph has an unresolved \t (glyph == 0)
7519*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, ((ParagraphImpl*)paragraph1.get())->runs()[0].glyphs()[15] != 0);
7520*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, ((ParagraphImpl*)paragraph2.get())->runs()[0].glyphs()[15] == 0);
7521*c8dee2aaSAndroid Build Coastguard Worker // Notice, that the cache didn't work for the second paragraph - as it should not
7522*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, 2 == fontCollection->getParagraphCache()->count());
7523*c8dee2aaSAndroid Build Coastguard Worker }
7524*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_lineMetricsWithEllipsis,reporter)7525*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_lineMetricsWithEllipsis, reporter) {
7526*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7527*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7528*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
7529*c8dee2aaSAndroid Build Coastguard Worker fontCollection->enableFontFallback();
7530*c8dee2aaSAndroid Build Coastguard Worker
7531*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7532*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(1);
7533*c8dee2aaSAndroid Build Coastguard Worker std::u16string ellipsis = u"\u2026";
7534*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setEllipsis(ellipsis);
7535*c8dee2aaSAndroid Build Coastguard Worker
7536*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7537*c8dee2aaSAndroid Build Coastguard Worker builder.addText("hello");
7538*c8dee2aaSAndroid Build Coastguard Worker
7539*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7540*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(1.);
7541*c8dee2aaSAndroid Build Coastguard Worker
7542*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> lm;
7543*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(lm);
7544*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm.size() == 1);
7545*c8dee2aaSAndroid Build Coastguard Worker }
7546*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_lineMetricsAfterUpdate,reporter)7547*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_lineMetricsAfterUpdate, reporter) {
7548*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7549*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7550*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
7551*c8dee2aaSAndroid Build Coastguard Worker fontCollection->enableFontFallback();
7552*c8dee2aaSAndroid Build Coastguard Worker
7553*c8dee2aaSAndroid Build Coastguard Worker auto text = std::u16string(u"hello world");
7554*c8dee2aaSAndroid Build Coastguard Worker
7555*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7556*c8dee2aaSAndroid Build Coastguard Worker
7557*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7558*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text);
7559*c8dee2aaSAndroid Build Coastguard Worker
7560*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7561*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(200.);
7562*c8dee2aaSAndroid Build Coastguard Worker
7563*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> lm;
7564*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(lm);
7565*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm.size() == 1, "size: %zu", lm.size());
7566*c8dee2aaSAndroid Build Coastguard Worker
7567*c8dee2aaSAndroid Build Coastguard Worker paragraph->updateFontSize(0, text.size(), 42);
7568*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(200.);
7569*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(lm);
7570*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lm.size() == 2, "size: %zu", lm.size());
7571*c8dee2aaSAndroid Build Coastguard Worker }
7572*c8dee2aaSAndroid Build Coastguard Worker
7573*c8dee2aaSAndroid Build Coastguard Worker // Google logo is shown in one style (the first one)
UNIX_ONLY_TEST(SkParagraph_MultiStyle_Logo,reporter)7574*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_MultiStyle_Logo, reporter) {
7575*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
7576*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7577*c8dee2aaSAndroid Build Coastguard Worker
7578*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_MultiStyle_Logo.png");
7579*c8dee2aaSAndroid Build Coastguard Worker
7580*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawColor(SK_ColorWHITE);
7581*c8dee2aaSAndroid Build Coastguard Worker SkScalar width = TestCanvasWidth;
7582*c8dee2aaSAndroid Build Coastguard Worker SkScalar height = TestCanvasHeight/2;
7583*c8dee2aaSAndroid Build Coastguard Worker
7584*c8dee2aaSAndroid Build Coastguard Worker SkAutoCanvasRestore acr(canvas.get(), true);
7585*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->clipRect(SkRect::MakeWH(width, height));
7586*c8dee2aaSAndroid Build Coastguard Worker
7587*c8dee2aaSAndroid Build Coastguard Worker TextStyle style;
7588*c8dee2aaSAndroid Build Coastguard Worker style.setFontFamilies({SkString("Google Sans")});
7589*c8dee2aaSAndroid Build Coastguard Worker style.setFontSize(30);
7590*c8dee2aaSAndroid Build Coastguard Worker
7591*c8dee2aaSAndroid Build Coastguard Worker TextStyle style0(style);
7592*c8dee2aaSAndroid Build Coastguard Worker style0.setDecoration(TextDecoration::kUnderline);
7593*c8dee2aaSAndroid Build Coastguard Worker style0.setDecorationColor(SK_ColorBLACK);
7594*c8dee2aaSAndroid Build Coastguard Worker
7595*c8dee2aaSAndroid Build Coastguard Worker TextStyle style1(style);
7596*c8dee2aaSAndroid Build Coastguard Worker style1.setDecoration(TextDecoration::kOverline);
7597*c8dee2aaSAndroid Build Coastguard Worker style1.setDecorationColor(SK_ColorBLACK);
7598*c8dee2aaSAndroid Build Coastguard Worker
7599*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paraStyle;
7600*c8dee2aaSAndroid Build Coastguard Worker paraStyle.setTextStyle(style);
7601*c8dee2aaSAndroid Build Coastguard Worker paraStyle.setMaxLines(std::numeric_limits<size_t>::max());
7602*c8dee2aaSAndroid Build Coastguard Worker
7603*c8dee2aaSAndroid Build Coastguard Worker const char* logo1 = "google_";
7604*c8dee2aaSAndroid Build Coastguard Worker const char* logo2 = "logo";
7605*c8dee2aaSAndroid Build Coastguard Worker const char* logo3 = "go";
7606*c8dee2aaSAndroid Build Coastguard Worker const char* logo4 = "ogle_logo";
7607*c8dee2aaSAndroid Build Coastguard Worker const char* logo5 = "google_lo";
7608*c8dee2aaSAndroid Build Coastguard Worker const char* logo6 = "go";
7609*c8dee2aaSAndroid Build Coastguard Worker
7610*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paraStyle, fontCollection, get_unicode());
7611*c8dee2aaSAndroid Build Coastguard Worker style0.setDecorationStyle(TextDecorationStyle::kDouble);
7612*c8dee2aaSAndroid Build Coastguard Worker style0.setForegroundColor(SkPaint(SkColors::kBlack));
7613*c8dee2aaSAndroid Build Coastguard Worker style0.setBackgroundColor(SkPaint(SkColors::kLtGray));
7614*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(style0);
7615*c8dee2aaSAndroid Build Coastguard Worker builder.addText(logo1, strlen(logo1));
7616*c8dee2aaSAndroid Build Coastguard Worker style1.setDecorationStyle(TextDecorationStyle::kWavy);
7617*c8dee2aaSAndroid Build Coastguard Worker style1.setForegroundColor(SkPaint(SkColors::kBlue));
7618*c8dee2aaSAndroid Build Coastguard Worker style1.setBackgroundColor(SkPaint(SkColors::kYellow));
7619*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(style1);
7620*c8dee2aaSAndroid Build Coastguard Worker builder.addText(logo2, strlen(logo2));
7621*c8dee2aaSAndroid Build Coastguard Worker builder.addText(" ", 1);
7622*c8dee2aaSAndroid Build Coastguard Worker
7623*c8dee2aaSAndroid Build Coastguard Worker style0.setDecorationStyle(TextDecorationStyle::kSolid);
7624*c8dee2aaSAndroid Build Coastguard Worker style0.setForegroundColor(SkPaint(SkColors::kBlue));
7625*c8dee2aaSAndroid Build Coastguard Worker style0.setBackgroundColor(SkPaint(SkColors::kWhite));
7626*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(style0);
7627*c8dee2aaSAndroid Build Coastguard Worker builder.addText(logo3, strlen(logo3));
7628*c8dee2aaSAndroid Build Coastguard Worker style1.setDecorationStyle(TextDecorationStyle::kDotted);
7629*c8dee2aaSAndroid Build Coastguard Worker style1.setForegroundColor(SkPaint(SkColors::kBlack));
7630*c8dee2aaSAndroid Build Coastguard Worker style1.setBackgroundColor(SkPaint(SkColors::kMagenta));
7631*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(style1);
7632*c8dee2aaSAndroid Build Coastguard Worker builder.addText(logo4, strlen(logo4));
7633*c8dee2aaSAndroid Build Coastguard Worker builder.addText(" ", 1);
7634*c8dee2aaSAndroid Build Coastguard Worker
7635*c8dee2aaSAndroid Build Coastguard Worker style0.setDecorationStyle(TextDecorationStyle::kDashed);
7636*c8dee2aaSAndroid Build Coastguard Worker style0.setForegroundColor(SkPaint(SkColors::kGreen));
7637*c8dee2aaSAndroid Build Coastguard Worker style0.setBackgroundColor(SkPaint(SkColors::kGray));
7638*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(style0);
7639*c8dee2aaSAndroid Build Coastguard Worker builder.addText(logo5, strlen(logo5));
7640*c8dee2aaSAndroid Build Coastguard Worker style1.setDecorationStyle(TextDecorationStyle::kDouble);
7641*c8dee2aaSAndroid Build Coastguard Worker style1.setForegroundColor(SkPaint(SkColors::kBlue));
7642*c8dee2aaSAndroid Build Coastguard Worker style1.setBackgroundColor(SkPaint(SkColors::kCyan));
7643*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(style1);
7644*c8dee2aaSAndroid Build Coastguard Worker builder.addText(logo6, strlen(logo6));
7645*c8dee2aaSAndroid Build Coastguard Worker
7646*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7647*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(width - 40);
7648*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 20, 20);
7649*c8dee2aaSAndroid Build Coastguard Worker
7650*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
7651*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->lines().size() == 1);
7652*c8dee2aaSAndroid Build Coastguard Worker
7653*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
7654*c8dee2aaSAndroid Build Coastguard Worker SkScalar left = 0.0f;
7655*c8dee2aaSAndroid Build Coastguard Worker impl->lines().data()->scanStyles(StyleType::kDecorations,
7656*c8dee2aaSAndroid Build Coastguard Worker [&index, &left, reporter]
7657*c8dee2aaSAndroid Build Coastguard Worker (TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
7658*c8dee2aaSAndroid Build Coastguard Worker switch (index) {
7659*c8dee2aaSAndroid Build Coastguard Worker case 0: REPORTER_ASSERT(reporter, context.pos == 0 && context.size == 1);
7660*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fLeft, left));
7661*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fRight, 62.6944885f));
7662*c8dee2aaSAndroid Build Coastguard Worker break;
7663*c8dee2aaSAndroid Build Coastguard Worker case 1: REPORTER_ASSERT(reporter, context.pos == 0 && context.size == 2);
7664*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fLeft, left));
7665*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fRight, 105.479904f));
7666*c8dee2aaSAndroid Build Coastguard Worker break;
7667*c8dee2aaSAndroid Build Coastguard Worker case 2: REPORTER_ASSERT(reporter, context.pos == 2 && context.size == 1);
7668*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fLeft, left));
7669*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fRight, 123.3926165f));
7670*c8dee2aaSAndroid Build Coastguard Worker break;
7671*c8dee2aaSAndroid Build Coastguard Worker case 3: REPORTER_ASSERT(reporter, context.pos == 2 && context.size == 2);
7672*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fLeft, left));
7673*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fRight, 210.959808f));
7674*c8dee2aaSAndroid Build Coastguard Worker break;
7675*c8dee2aaSAndroid Build Coastguard Worker case 4: REPORTER_ASSERT(reporter, context.pos == 4 && context.size == 1);
7676*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fLeft, left));
7677*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fRight, 291.567017f));
7678*c8dee2aaSAndroid Build Coastguard Worker break;
7679*c8dee2aaSAndroid Build Coastguard Worker case 5: REPORTER_ASSERT(reporter, context.pos == 4 && context.size == 1); // No space at the end
7680*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fLeft, left));
7681*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(context.clip.fRight, 309.479736f));
7682*c8dee2aaSAndroid Build Coastguard Worker break;
7683*c8dee2aaSAndroid Build Coastguard Worker default: REPORTER_ASSERT(reporter, false); break;
7684*c8dee2aaSAndroid Build Coastguard Worker }
7685*c8dee2aaSAndroid Build Coastguard Worker left = context.clip.fRight;
7686*c8dee2aaSAndroid Build Coastguard Worker ++index;
7687*c8dee2aaSAndroid Build Coastguard Worker });
7688*c8dee2aaSAndroid Build Coastguard Worker }
7689*c8dee2aaSAndroid Build Coastguard Worker
7690*c8dee2aaSAndroid Build Coastguard Worker // Ligature FFI should allow painting and querying by codepoints
UNIX_ONLY_TEST(SkParagraph_MultiStyle_FFI,reporter)7691*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_MultiStyle_FFI, reporter) {
7692*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
7693*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7694*c8dee2aaSAndroid Build Coastguard Worker
7695*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_MultiStyle_FFI.png");
7696*c8dee2aaSAndroid Build Coastguard Worker
7697*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawColor(SK_ColorWHITE);
7698*c8dee2aaSAndroid Build Coastguard Worker
7699*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7700*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7701*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7702*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7703*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
7704*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(60);
7705*c8dee2aaSAndroid Build Coastguard Worker text_style.setBackgroundColor(SkPaint(SkColors::kGray));
7706*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7707*c8dee2aaSAndroid Build Coastguard Worker builder.addText("f");
7708*c8dee2aaSAndroid Build Coastguard Worker text_style.setBackgroundColor(SkPaint(SkColors::kYellow));
7709*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7710*c8dee2aaSAndroid Build Coastguard Worker builder.addText("f");
7711*c8dee2aaSAndroid Build Coastguard Worker text_style.setBackgroundColor(SkPaint(SkColors::kLtGray));
7712*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7713*c8dee2aaSAndroid Build Coastguard Worker builder.addText("i");
7714*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7715*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
7716*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7717*c8dee2aaSAndroid Build Coastguard Worker auto width = paragraph->getLongestLine();
7718*c8dee2aaSAndroid Build Coastguard Worker auto height = paragraph->getHeight();
7719*c8dee2aaSAndroid Build Coastguard Worker
7720*c8dee2aaSAndroid Build Coastguard Worker auto f1Pos = paragraph->getGlyphPositionAtCoordinate(width/6 - 5, height/2);
7721*c8dee2aaSAndroid Build Coastguard Worker auto f2Pos = paragraph->getGlyphPositionAtCoordinate(width/2 - 5, height/2);
7722*c8dee2aaSAndroid Build Coastguard Worker auto iPos = paragraph->getGlyphPositionAtCoordinate(width*5/6 - 5, height/2);
7723*c8dee2aaSAndroid Build Coastguard Worker
7724*c8dee2aaSAndroid Build Coastguard Worker // Positions are aligned with graphemes (no pointing inside ffi grapheme)
7725*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f1Pos.position == 0 && f1Pos.affinity == Affinity::kDownstream);
7726*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f2Pos.position == 1 && f2Pos.affinity == Affinity::kDownstream);
7727*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, iPos.position == 2 && iPos.affinity == Affinity::kDownstream);
7728*c8dee2aaSAndroid Build Coastguard Worker
7729*c8dee2aaSAndroid Build Coastguard Worker // Bounding boxes show the extact position (inside ffi grapheme)
7730*c8dee2aaSAndroid Build Coastguard Worker auto f1 = paragraph->getRectsForRange(0, 1, RectHeightStyle::kTight,
7731*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle::kTight);
7732*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f1.size() == 1);
7733*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f1[0].direction == TextDirection::kLtr);
7734*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(f1[0].rect.fLeft, 0.000000f, EPSILON100));
7735*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(f1[0].rect.fRight, 17.070000f, EPSILON100));
7736*c8dee2aaSAndroid Build Coastguard Worker
7737*c8dee2aaSAndroid Build Coastguard Worker auto f2 = paragraph->getRectsForRange(1, 2, RectHeightStyle::kTight,
7738*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle::kTight);
7739*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f2.size() == 1);
7740*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f2[0].direction == TextDirection::kLtr);
7741*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(f2[0].rect.fLeft, 17.070000f, EPSILON100));
7742*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(f2[0].rect.fRight, 34.139999f, EPSILON100));
7743*c8dee2aaSAndroid Build Coastguard Worker
7744*c8dee2aaSAndroid Build Coastguard Worker auto fi = paragraph->getRectsForRange(2, 3, RectHeightStyle::kTight,
7745*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle::kTight);
7746*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fi.size() == 1);
7747*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fi[0].direction == TextDirection::kLtr);
7748*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(fi[0].rect.fLeft, 34.139999f, EPSILON100));
7749*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(fi[0].rect.fRight, 51.209999f, EPSILON100));
7750*c8dee2aaSAndroid Build Coastguard Worker };
7751*c8dee2aaSAndroid Build Coastguard Worker
7752*c8dee2aaSAndroid Build Coastguard Worker // Multiple code points/single glyph emoji family should be treated as a single glyph
UNIX_ONLY_TEST(SkParagraph_MultiStyle_EmojiFamily,reporter)7753*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_MultiStyle_EmojiFamily, reporter) {
7754*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
7755*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7756*c8dee2aaSAndroid Build Coastguard Worker
7757*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_MultiStyle_EmojiFamily.png");
7758*c8dee2aaSAndroid Build Coastguard Worker
7759*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawColor(SK_ColorWHITE);
7760*c8dee2aaSAndroid Build Coastguard Worker
7761*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7762*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7763*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7764*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7765*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Color Emoji")});
7766*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(40);
7767*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7768*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466");
7769*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7770*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
7771*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
7772*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
7773*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
7774*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(1);
7775*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorLTGRAY);
7776*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawRect(SkRect::MakeXYWH(0, 0, paragraph->getLongestLine(), paragraph->getHeight()), paint);
7777*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7778*c8dee2aaSAndroid Build Coastguard Worker auto width = paragraph->getLongestLine();
7779*c8dee2aaSAndroid Build Coastguard Worker auto height = paragraph->getHeight();
7780*c8dee2aaSAndroid Build Coastguard Worker
7781*c8dee2aaSAndroid Build Coastguard Worker auto pos00 = paragraph->getGlyphPositionAtCoordinate(width/4, height/4);
7782*c8dee2aaSAndroid Build Coastguard Worker auto pos10 = paragraph->getGlyphPositionAtCoordinate(width*3/4, height/2);
7783*c8dee2aaSAndroid Build Coastguard Worker auto pos01 = paragraph->getGlyphPositionAtCoordinate(width/4, height/2);
7784*c8dee2aaSAndroid Build Coastguard Worker auto pos11 = paragraph->getGlyphPositionAtCoordinate(width*3/4, height*3/4);
7785*c8dee2aaSAndroid Build Coastguard Worker
7786*c8dee2aaSAndroid Build Coastguard Worker // Positioning is aligned with the closest grapheme edge (left or right)
7787*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pos00.position == 0 && pos00.affinity == Affinity::kDownstream);
7788*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pos01.position == 0 && pos01.affinity == Affinity::kDownstream);
7789*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pos10.position == 11 && pos10.affinity == Affinity::kUpstream);
7790*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pos11.position == 11 && pos11.affinity == Affinity::kUpstream);
7791*c8dee2aaSAndroid Build Coastguard Worker
7792*c8dee2aaSAndroid Build Coastguard Worker // Bounding boxes around a part of a grapheme are empty
7793*c8dee2aaSAndroid Build Coastguard Worker auto f1 = paragraph->getRectsForRange(0, 2, RectHeightStyle::kTight, RectWidthStyle::kTight);
7794*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f1.size() == 0);
7795*c8dee2aaSAndroid Build Coastguard Worker
7796*c8dee2aaSAndroid Build Coastguard Worker auto f2 = paragraph->getRectsForRange(4, 6, RectHeightStyle::kTight, RectWidthStyle::kTight);
7797*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f2.size() == 0);
7798*c8dee2aaSAndroid Build Coastguard Worker
7799*c8dee2aaSAndroid Build Coastguard Worker auto f3 = paragraph->getRectsForRange(8, 10, RectHeightStyle::kTight, RectWidthStyle::kTight);
7800*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f3.size() == 0);
7801*c8dee2aaSAndroid Build Coastguard Worker
7802*c8dee2aaSAndroid Build Coastguard Worker auto f4 = paragraph->getRectsForRange(8, 10, RectHeightStyle::kTight, RectWidthStyle::kTight);
7803*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f4.size() == 0);
7804*c8dee2aaSAndroid Build Coastguard Worker };
7805*c8dee2aaSAndroid Build Coastguard Worker
7806*c8dee2aaSAndroid Build Coastguard Worker // Arabic Ligature case should be painted into multi styles but queried as a single glyph
UNIX_ONLY_TEST(SkParagraph_MultiStyle_Arabic,reporter)7807*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_MultiStyle_Arabic, reporter) {
7808*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
7809*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7810*c8dee2aaSAndroid Build Coastguard Worker
7811*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_MultiStyle_Arabic.png");
7812*c8dee2aaSAndroid Build Coastguard Worker
7813*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawColor(SK_ColorWHITE);
7814*c8dee2aaSAndroid Build Coastguard Worker
7815*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7816*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Naskh Arabic")});
7817*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(50);
7818*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7819*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7820*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7821*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
7822*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7823*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLUE);
7824*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7825*c8dee2aaSAndroid Build Coastguard Worker builder.addText("ك");
7826*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorRED);
7827*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7828*c8dee2aaSAndroid Build Coastguard Worker builder.addText("ِّ");
7829*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLUE);
7830*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7831*c8dee2aaSAndroid Build Coastguard Worker builder.addText("ـ");
7832*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7833*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
7834*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7835*c8dee2aaSAndroid Build Coastguard Worker
7836*c8dee2aaSAndroid Build Coastguard Worker auto width = paragraph->getLongestLine();
7837*c8dee2aaSAndroid Build Coastguard Worker auto height = paragraph->getHeight();
7838*c8dee2aaSAndroid Build Coastguard Worker
7839*c8dee2aaSAndroid Build Coastguard Worker // Positioning is align with the grapheme
7840*c8dee2aaSAndroid Build Coastguard Worker auto f1Pos = paragraph->getGlyphPositionAtCoordinate(TestCanvasWidth - width*5/6, height/2);
7841*c8dee2aaSAndroid Build Coastguard Worker auto f2Pos = paragraph->getGlyphPositionAtCoordinate(TestCanvasWidth - width/3, height/2);
7842*c8dee2aaSAndroid Build Coastguard Worker auto iPos = paragraph->getGlyphPositionAtCoordinate(TestCanvasWidth - width/6, height/2);
7843*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f1Pos.position == 4 && f1Pos.affinity == Affinity::kUpstream);
7844*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f2Pos.position == 1 && f2Pos.affinity == Affinity::kUpstream);
7845*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, iPos.position == 0 && iPos.affinity == Affinity::kDownstream);
7846*c8dee2aaSAndroid Build Coastguard Worker
7847*c8dee2aaSAndroid Build Coastguard Worker // Bounding boxes around a part of a grapheme are empty
7848*c8dee2aaSAndroid Build Coastguard Worker auto f1 = paragraph->getRectsForRange(0, 1, RectHeightStyle::kTight, RectWidthStyle::kTight);
7849*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f1.size() == 0);
7850*c8dee2aaSAndroid Build Coastguard Worker
7851*c8dee2aaSAndroid Build Coastguard Worker auto f2 = paragraph->getRectsForRange(1, 2, RectHeightStyle::kTight, RectWidthStyle::kTight);
7852*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, f2.size() == 0);
7853*c8dee2aaSAndroid Build Coastguard Worker
7854*c8dee2aaSAndroid Build Coastguard Worker auto fi = paragraph->getRectsForRange(2, 3, RectHeightStyle::kTight, RectWidthStyle::kTight);
7855*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fi.size() == 0);
7856*c8dee2aaSAndroid Build Coastguard Worker };
7857*c8dee2aaSAndroid Build Coastguard Worker
7858*c8dee2aaSAndroid Build Coastguard Worker // Zalgo text should be painted into multi styles but queried as a single glyph
UNIX_ONLY_TEST(SkParagraph_MultiStyle_Zalgo,reporter)7859*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_MultiStyle_Zalgo, reporter) {
7860*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
7861*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7862*c8dee2aaSAndroid Build Coastguard Worker NEED_SYSTEM_FONTS(fontCollection)
7863*c8dee2aaSAndroid Build Coastguard Worker
7864*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_MultiStyle_Zalgo.png");
7865*c8dee2aaSAndroid Build Coastguard Worker
7866*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawColor(SK_ColorWHITE);
7867*c8dee2aaSAndroid Build Coastguard Worker
7868*c8dee2aaSAndroid Build Coastguard Worker //SkString text(">S͛ͭ̋͆̈̔̇͗̍͑̎ͪͮͧͣ̽ͫͣ́ͬ̀͌͑͂͗͒̍̔̄ͧ̏̉̌̊̊̿̀̌̃̄͐̓̓̚̚҉̵̡͜͟͝͠͏̸̵̡̧͜҉̷̡͇̜̘̻̺̘̟̝͙̬̘̩͇̭̼̥̖̤̦͎k͉̩̘͚̜̹̗̗͍̤̥̱͉̳͕͖̤̲̣͚̮̞̬̲͍͔̯̻̮̞̭͈̗̫͓̂ͨ̉ͪ̒͋͛̀̍͊ͧ̿̅͆̓̔̔ͬ̇̑̿ͩ͗ͮ̎͌̿̄ͅP̴̵̡̡̛̪͙̼̣̟̩̭̫̱͙̬͔͉͍̘̠͉̦̝̘̥̟̗͖̫̤͕̙̬̦͍̱̖̮̱͑͐̎̃̒͐͋̚͘͞a̶̶̵̵̵̶̶̡̧̢̢̺͔̣͖̭̺͍̤͚̱̜̰̥͕̬̥̲̞̥̘͇͚̺̰͚̪̺͔̤͍̓̿͆̎͋̓ͦ̈́ͦ̌́̄͗̌̓͌̕͜͜͟͢͝͡ŕ͎̝͕͉̻͎̤̭͚̗̳̖̙̘͚̫͖͓͚͉͔͈̟̰̟̬̗͓̟͚̱̕͡ͅͅͅa̸̶̢̛̛̽ͮͩ̅͒ͫ͗͂̎ͦ̈́̓̚͘͜͢͡҉̷̵̶̢̡̜̮̦̜̥̜̯̙͓͔̼̗̻͜͜ͅḡ̢̛͕̗͖̖̤̦̘͔ͨͨ̊͒ͩͭͤ̍̅̃ͪ̋̏̓̍̋͗̋ͨ̏̽̈́̔̀̋̉ͫ̅̂ͭͫ̏͒͋ͥ̚͜r̶̢̧̧̥̤̼̀̂̒ͪ͌̿͌̅͛ͨͪ͒̍ͥ̉ͤ̌̿̆́ͭ͆̃̒ͤ͛̊ͧ̽͘͝͠a̧̢̧̢͑͑̓͑ͮ̃͂̄͛́̈́͋̂͌̽̄͒̔́̇ͨͧͭ͐ͦ̋ͨ̍ͦ̍̋͆̔ͧ͑͋͌̈̓͛͛̚͢͜͜͏̴̢̧̛̳͍̹͚̰̹̻͔p̨̡͆ͦͣ͊̽̔͂̉ͣ̔ͣ̌̌̉̃̋̂͒ͫ̄̎̐͗̉̌̃̽̽́̀̚͘͜͟҉̱͉h̭̮̘̗͔̜̯͔͈̯̺͔̗̣̭͚̱̰̙̼̹͚̣̻̥̲̮͍̤͜͝<");
7869*c8dee2aaSAndroid Build Coastguard Worker std::u16string text16 = u">S\u035B\u036D\u030B\u0346\u0308\u0314\u0307\u0357\u030D\u0351\u030E\u036A\u036E\u0367\u0363\u033D\u036B\u0363\u0301\u036C\u0300\u034C\u0351\u0342\u0357\u0352\u030D\u0314\u0304\u0367\u030F\u031A\u0309\u030C\u030A\u030A\u033F\u0300\u030C\u0303\u0304\u0350\u0313\u031A\u0313\u0363\u0321\u035C\u035D\u035F\u0360\u0335\u034F\u0321\u0327\u0338\u035C\u0335\u0363\u0337\u0321\u0347\u031C\u0318\u033B\u033A\u0318\u031F\u031D\u0359\u032C\u0318\u0329\u0347\u032D\u033C\u0325\u0316\u0324\u0326\u034Ek\u0302\u0368\u0309\u036A\u0312\u034B\u035B\u0300\u030D\u034A\u0367\u033F\u0305\u0346\u0313\u0314\u0314\u036C\u0307\u0311\u033F\u0369\u0357\u036E\u030E\u034C\u033F\u0304\u0349\u0329\u0318\u035A\u031C\u0339\u0317\u0317\u034D\u0324\u0325\u0331\u0349\u0333\u0355\u0345\u0356\u0324\u0332\u0323\u035A\u032E\u031E\u032C\u0332\u034D\u0354\u032F\u033B\u032E\u031E\u032D\u0348\u0317\u032B\u0353P\u031A\u0351\u0350\u030E\u0303\u0312\u0350\u034B\u0334\u031B\u035E\u0358\u0321\u0335\u0321\u032A\u0359\u033C\u0323\u031F\u0329\u032D\u032B\u0331\u0359\u032C\u0354\u0349\u034D\u0318\u0320\u0349\u0326\u031D\u0318\u0325\u031F\u0317\u0356\u032B\u0324\u0355\u0319\u032C\u0326\u034D\u0331\u0316\u032E\u0331a\u0313\u033F\u0346\u030E\u034B\u0313\u0366\u0344\u0366\u030C\u0301\u0304\u0357\u030C\u0313\u034C\u035C\u0336\u035C\u0321\u0336\u035D\u0315\u0335\u0335\u0335\u035F\u0336\u0336\u0327\u0322\u0361\u0362\u0322\u033A\u0354\u0323\u0356\u032D\u033A\u034D\u0324\u035A\u0331\u031C\u0330\u0325\u0355\u032C\u0325\u0332\u031E\u0325\u0318\u0347\u035A\u033A\u0330\u035A\u032A\u033A\u0354\u0324\u034Dr\u0301\u0361\u0315\u034E\u031D\u0355\u0349\u033B\u034E\u0324\u0345\u0345\u032D\u035A\u0317\u0333\u0316\u0319\u0318\u035A\u0345\u032B\u0356\u0353\u035A\u0349\u0354\u0348\u031F\u0330\u031F\u032C\u0317\u0353\u031F\u035A\u0331a\u033D\u036E\u0369\u0305\u0352\u031A\u036B\u0357\u0342\u030E\u0366\u0344\u0343\u0338\u035C\u0361\u0322\u031B\u0358\u031B\u0362\u0336\u0363\u0337\u035C\u0322\u035C\u0321\u0335\u0336\u0345\u031C\u032E\u0326\u031C\u0325\u031C\u032F\u0319\u0353\u0354\u033C\u0317\u033Bg\u0304\u0368\u0368\u030A\u0352\u0369\u036D\u0364\u030D\u0305\u0303\u036A\u030B\u030F\u0313\u030D\u031A\u030B\u0357\u030B\u0368\u030F\u033D\u0344\u0314\u0300\u030B\u0309\u036B\u0305\u0302\u036D\u036B\u030F\u0352\u034B\u0365\u0322\u031B\u035C\u0355\u0317\u0356\u0316\u0324\u0326\u0318\u0354r\u0300\u0302\u0312\u036A\u034C\u033F\u034C\u0305\u035B\u0368\u036A\u0352\u030D\u0365\u0309\u0364\u030C\u033F\u0306\u0301\u036D\u0346\u0303\u0312\u0364\u035B\u030A\u0367\u033D\u035D\u0360\u0322\u0358\u0327\u0327\u0336\u0325\u0324\u033Ca\u0351\u0351\u0313\u0351\u036E\u0303\u0342\u0304\u035B\u0301\u0344\u034B\u0302\u034C\u033D\u0304\u0352\u0314\u0301\u0307\u0368\u0367\u036D\u0350\u0366\u031A\u030B\u0368\u030D\u0366\u030D\u030B\u0346\u0314\u0367\u0351\u034B\u034C\u0308\u0343\u035B\u035B\u0327\u0322\u0327\u0362\u035C\u035C\u0322\u034F\u0322\u031B\u0334\u0327\u0333\u034D\u0339\u035A\u0330\u0339\u033B\u0354p\u0346\u0366\u031A\u0363\u034A\u033D\u0314\u0342\u0309\u0363\u0314\u0363\u030C\u030C\u0309\u0303\u030B\u0302\u0352\u036B\u0304\u030E\u0310\u0357\u0309\u030C\u0303\u033D\u033D\u0328\u0341\u0358\u0340\u0321\u035C\u035F\u0363\u0331\u0349h\u035C\u035D\u032D\u032E\u0318\u0317\u0354\u031C\u032F\u0354\u0348\u032F\u033A\u0354\u0317\u0323\u032D\u035A\u0331\u0330\u0319\u033C\u0339\u035A\u0323\u033B\u0325\u0332\u032E\u034D\u0324<";
7870*c8dee2aaSAndroid Build Coastguard Worker SkString text = SkUnicode::convertUtf16ToUtf8(text16);
7871*c8dee2aaSAndroid Build Coastguard Worker auto K = text.find("k");
7872*c8dee2aaSAndroid Build Coastguard Worker auto P = text.find("P");
7873*c8dee2aaSAndroid Build Coastguard Worker auto h = text.find("h");
7874*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7875*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7876*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7877*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
7878*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
7879*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorRED);
7880*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7881*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text.data(), K + 3);
7882*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLUE);
7883*c8dee2aaSAndroid Build Coastguard Worker text_style.setBackgroundColor(SkPaint(SkColors::kYellow));
7884*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7885*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text.data() + K + 3, P - K - 3 + 6);
7886*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorGREEN);
7887*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7888*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text.data() + P + 6, h - P - 6);
7889*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7890*c8dee2aaSAndroid Build Coastguard Worker text_style.setBackgroundColor(SkPaint(SkColors::kLtGray));
7891*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7892*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text.data() + h, text.size() - h);
7893*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7894*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
7895*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, paragraph->getHeight() / 2);
7896*c8dee2aaSAndroid Build Coastguard Worker //auto width = paragraph->getLongestLine();
7897*c8dee2aaSAndroid Build Coastguard Worker auto height = paragraph->getHeight();
7898*c8dee2aaSAndroid Build Coastguard Worker
7899*c8dee2aaSAndroid Build Coastguard Worker auto resSK = paragraph->getRectsForRange(0, K, RectHeightStyle::kTight,
7900*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle::kTight);
7901*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, resSK.size() != 0);
7902*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(resSK[0].rect.width(), 10.45f, EPSILON100));
7903*c8dee2aaSAndroid Build Coastguard Worker
7904*c8dee2aaSAndroid Build Coastguard Worker auto resKP = paragraph->getRectsForRange(K, P, RectHeightStyle::kTight,
7905*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle::kTight);
7906*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, resKP.size() != 0);
7907*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(resKP[0].rect.width(), 11.22f));
7908*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(resKP[0].rect.width(), 11.22f, EPSILON100));
7909*c8dee2aaSAndroid Build Coastguard Worker
7910*c8dee2aaSAndroid Build Coastguard Worker auto resPh = paragraph->getRectsForRange(P, h, RectHeightStyle::kTight,
7911*c8dee2aaSAndroid Build Coastguard Worker RectWidthStyle::kTight);
7912*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, resPh.size() != 0);
7913*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkScalarNearlyEqual(resPh[0].rect.width(), 67.26f, EPSILON20));
7914*c8dee2aaSAndroid Build Coastguard Worker
7915*c8dee2aaSAndroid Build Coastguard Worker auto posK = paragraph->getGlyphPositionAtCoordinate(resSK.back().rect.fRight, height/2);
7916*c8dee2aaSAndroid Build Coastguard Worker auto posP = paragraph->getGlyphPositionAtCoordinate(resKP.back().rect.fRight, height/2);
7917*c8dee2aaSAndroid Build Coastguard Worker auto posH = paragraph->getGlyphPositionAtCoordinate(resPh.back().rect.fRight, height/2);
7918*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, posK.position == 148 && posP.position == 264 && posH.position == 572);
7919*c8dee2aaSAndroid Build Coastguard Worker };
7920*c8dee2aaSAndroid Build Coastguard Worker
7921*c8dee2aaSAndroid Build Coastguard Worker // RTL Ellipsis
UNIX_ONLY_TEST(SkParagraph_RtlEllipsis1,reporter)7922*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RtlEllipsis1, reporter) {
7923*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
7924*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7925*c8dee2aaSAndroid Build Coastguard Worker
7926*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RtlEllipsis1.png");
7927*c8dee2aaSAndroid Build Coastguard Worker
7928*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawColor(SK_ColorWHITE);
7929*c8dee2aaSAndroid Build Coastguard Worker
7930*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7931*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Naskh Arabic"), SkString("Roboto")});
7932*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(100);
7933*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7934*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7935*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7936*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
7937*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setEllipsis(u"\u2026");
7938*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kStart);
7939*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(1);
7940*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7941*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7942*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"1 2 3 4 5 6 7 8 9");
7943*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7944*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(474);
7945*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7946*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
7947*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->lineNumber() == 1);
7948*c8dee2aaSAndroid Build Coastguard Worker auto& line = impl->lines()[0];
7949*c8dee2aaSAndroid Build Coastguard Worker bool first = true;
7950*c8dee2aaSAndroid Build Coastguard Worker line.iterateThroughVisualRuns(true,
7951*c8dee2aaSAndroid Build Coastguard Worker [&]
7952*c8dee2aaSAndroid Build Coastguard Worker (const Run* run, SkScalar runOffsetInLine, TextRange textRange, SkScalar* runWidthInLine) {
7953*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, first == (run->isEllipsis()));
7954*c8dee2aaSAndroid Build Coastguard Worker first = false;
7955*c8dee2aaSAndroid Build Coastguard Worker return true;
7956*c8dee2aaSAndroid Build Coastguard Worker });
7957*c8dee2aaSAndroid Build Coastguard Worker };
7958*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_RtlEllipsis2,reporter)7959*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_RtlEllipsis2, reporter) {
7960*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>(true);
7961*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
7962*c8dee2aaSAndroid Build Coastguard Worker
7963*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_RtlEllipsis2.png");
7964*c8dee2aaSAndroid Build Coastguard Worker
7965*c8dee2aaSAndroid Build Coastguard Worker canvas.get()->drawColor(SK_ColorWHITE);
7966*c8dee2aaSAndroid Build Coastguard Worker
7967*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
7968*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Noto Naskh Arabic"), SkString("Roboto")});
7969*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(100);
7970*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
7971*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
7972*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextStyle(text_style);
7973*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextDirection(TextDirection::kRtl);
7974*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setEllipsis(u"\u2026");
7975*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setTextAlign(TextAlign::kStart);
7976*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(2);
7977*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
7978*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
7979*c8dee2aaSAndroid Build Coastguard Worker builder.addText(u"تظاهرات و تجمعات اعتراضی در سراسر کشور ۲۳ مهر");
7980*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
7981*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(474);
7982*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
7983*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
7984*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->lineNumber() == 2);
7985*c8dee2aaSAndroid Build Coastguard Worker auto& line = impl->lines()[1];
7986*c8dee2aaSAndroid Build Coastguard Worker bool first = true;
7987*c8dee2aaSAndroid Build Coastguard Worker line.iterateThroughVisualRuns(true,
7988*c8dee2aaSAndroid Build Coastguard Worker [&]
7989*c8dee2aaSAndroid Build Coastguard Worker (const Run* run, SkScalar runOffsetInLine, TextRange textRange, SkScalar* runWidthInLine) {
7990*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, first == (run->isEllipsis()));
7991*c8dee2aaSAndroid Build Coastguard Worker first = false;
7992*c8dee2aaSAndroid Build Coastguard Worker return true;
7993*c8dee2aaSAndroid Build Coastguard Worker });
7994*c8dee2aaSAndroid Build Coastguard Worker };
7995*c8dee2aaSAndroid Build Coastguard Worker
has_empty_typeface(SkFont f)7996*c8dee2aaSAndroid Build Coastguard Worker static bool has_empty_typeface(SkFont f) {
7997*c8dee2aaSAndroid Build Coastguard Worker SkTypeface* face = f.getTypeface();
7998*c8dee2aaSAndroid Build Coastguard Worker if (!face) {
7999*c8dee2aaSAndroid Build Coastguard Worker return true; // Should be impossible, but just in case...
8000*c8dee2aaSAndroid Build Coastguard Worker }
8001*c8dee2aaSAndroid Build Coastguard Worker return face->countGlyphs() == 0 && face->getBounds().isEmpty();
8002*c8dee2aaSAndroid Build Coastguard Worker }
8003*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_TextEditingFunctionality,reporter)8004*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_TextEditingFunctionality, reporter) {
8005*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
8006*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
8007*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_TextEditingFunctionality.png");
8008*c8dee2aaSAndroid Build Coastguard Worker const char* text =
8009*c8dee2aaSAndroid Build Coastguard Worker "This is a very long sentence to test if the text will properly wrap "
8010*c8dee2aaSAndroid Build Coastguard Worker "around and go to the next line. Sometimes, short sentence. Longer "
8011*c8dee2aaSAndroid Build Coastguard Worker "sentences are okay too because they are nessecary. Very short. "
8012*c8dee2aaSAndroid Build Coastguard Worker "This is a very long sentence to test if the text will properly wrap "
8013*c8dee2aaSAndroid Build Coastguard Worker "around and go to the next line. Sometimes, short sentence. Longer "
8014*c8dee2aaSAndroid Build Coastguard Worker "sentences are okay too because they are nessecary. Very short. ";
8015*c8dee2aaSAndroid Build Coastguard Worker
8016*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
8017*c8dee2aaSAndroid Build Coastguard Worker
8018*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
8019*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setEllipsis(u"\u2026");
8020*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(3);
8021*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
8022*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
8023*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
8024*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
8025*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
8026*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
8027*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
8028*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
8029*c8dee2aaSAndroid Build Coastguard Worker
8030*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
8031*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
8032*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 0, 0);
8033*c8dee2aaSAndroid Build Coastguard Worker
8034*c8dee2aaSAndroid Build Coastguard Worker auto lineNumber = paragraph->getLineNumberAt(0);
8035*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineNumber == 0);
8036*c8dee2aaSAndroid Build Coastguard Worker lineNumber = paragraph->getLineNumberAt(len / 2);
8037*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineNumber == 1);
8038*c8dee2aaSAndroid Build Coastguard Worker lineNumber = paragraph->getLineNumberAt(len - 1);
8039*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineNumber == -1);
8040*c8dee2aaSAndroid Build Coastguard Worker lineNumber = paragraph->getLineNumberAt(len);
8041*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineNumber == -1);
8042*c8dee2aaSAndroid Build Coastguard Worker lineNumber = paragraph->getLineNumberAt(len + 10);
8043*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, lineNumber == -1);
8044*c8dee2aaSAndroid Build Coastguard Worker
8045*c8dee2aaSAndroid Build Coastguard Worker LineMetrics lineMetrics;
8046*c8dee2aaSAndroid Build Coastguard Worker auto foundMetrics = paragraph->getLineMetricsAt(0, &lineMetrics);
8047*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, foundMetrics && lineMetrics.fLineNumber == 0);
8048*c8dee2aaSAndroid Build Coastguard Worker foundMetrics = paragraph->getLineMetricsAt(1, &lineMetrics);
8049*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, foundMetrics && lineMetrics.fLineNumber == 1);
8050*c8dee2aaSAndroid Build Coastguard Worker foundMetrics = paragraph->getLineMetricsAt(3, &lineMetrics);
8051*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !foundMetrics);
8052*c8dee2aaSAndroid Build Coastguard Worker foundMetrics = paragraph->getLineMetricsAt(10, &lineMetrics);
8053*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !foundMetrics);
8054*c8dee2aaSAndroid Build Coastguard Worker
8055*c8dee2aaSAndroid Build Coastguard Worker std::vector<LineMetrics> metrics;
8056*c8dee2aaSAndroid Build Coastguard Worker paragraph->getLineMetrics(metrics);
8057*c8dee2aaSAndroid Build Coastguard Worker auto actualText = paragraph->getActualTextRange(0, false);
8058*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, actualText.end == metrics[0].fEndExcludingWhitespaces);
8059*c8dee2aaSAndroid Build Coastguard Worker actualText = paragraph->getActualTextRange(1, false);
8060*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, actualText.end == metrics[1].fEndExcludingWhitespaces);
8061*c8dee2aaSAndroid Build Coastguard Worker actualText = paragraph->getActualTextRange(2, false);
8062*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, actualText.end == metrics[2].fEndExcludingWhitespaces);
8063*c8dee2aaSAndroid Build Coastguard Worker
8064*c8dee2aaSAndroid Build Coastguard Worker Paragraph::GlyphClusterInfo glyphInfo;
8065*c8dee2aaSAndroid Build Coastguard Worker auto foundCluster = paragraph->getGlyphClusterAt(0, &glyphInfo);
8066*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, foundCluster && glyphInfo.fClusterTextRange.start == 0);
8067*c8dee2aaSAndroid Build Coastguard Worker foundCluster = paragraph->getGlyphClusterAt(len / 2, &glyphInfo);
8068*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, foundCluster && glyphInfo.fClusterTextRange.start == len / 2);
8069*c8dee2aaSAndroid Build Coastguard Worker foundCluster = paragraph->getGlyphClusterAt(len, &glyphInfo);
8070*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !foundCluster);
8071*c8dee2aaSAndroid Build Coastguard Worker
8072*c8dee2aaSAndroid Build Coastguard Worker auto foundClosest = paragraph->getClosestGlyphClusterAt(0, 10, &glyphInfo);
8073*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, foundClosest && glyphInfo.fClusterTextRange.start == 0 &&
8074*c8dee2aaSAndroid Build Coastguard Worker glyphInfo.fClusterTextRange.end == 1);
8075*c8dee2aaSAndroid Build Coastguard Worker foundClosest = paragraph->getClosestGlyphClusterAt(TestCanvasWidth / 2, 20, &glyphInfo);
8076*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, foundClosest && glyphInfo.fClusterTextRange.start == 61 &&
8077*c8dee2aaSAndroid Build Coastguard Worker glyphInfo.fClusterTextRange.end == 62);
8078*c8dee2aaSAndroid Build Coastguard Worker foundClosest = paragraph->getClosestGlyphClusterAt(TestCanvasWidth + 10, 30, &glyphInfo);
8079*c8dee2aaSAndroid Build Coastguard Worker
8080*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, foundClosest && glyphInfo.fClusterTextRange.start == 228 &&
8081*c8dee2aaSAndroid Build Coastguard Worker glyphInfo.fClusterTextRange.end == 229);
8082*c8dee2aaSAndroid Build Coastguard Worker
8083*c8dee2aaSAndroid Build Coastguard Worker auto font = paragraph->getFontAt(10);
8084*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !has_empty_typeface(font));
8085*c8dee2aaSAndroid Build Coastguard Worker SkString fontFamily;
8086*c8dee2aaSAndroid Build Coastguard Worker font.getTypeface()->getFamilyName(&fontFamily);
8087*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fontFamily.equals("Roboto"));
8088*c8dee2aaSAndroid Build Coastguard Worker
8089*c8dee2aaSAndroid Build Coastguard Worker auto fonts = paragraph->getFonts();
8090*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fonts.size() == 1);
8091*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fonts[0].fTextRange.start == 0 && fonts[0].fTextRange.end == len);
8092*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !has_empty_typeface(fonts[0].fFont));
8093*c8dee2aaSAndroid Build Coastguard Worker font.getTypeface()->getFamilyName(&fontFamily);
8094*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fontFamily.equals("Roboto"));
8095*c8dee2aaSAndroid Build Coastguard Worker }
8096*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_getLineNumberAt_Ellipsis,reporter)8097*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_getLineNumberAt_Ellipsis, reporter) {
8098*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
8099*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
8100*c8dee2aaSAndroid Build Coastguard Worker fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr());
8101*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_Ellipsis.png");
8102*c8dee2aaSAndroid Build Coastguard Worker
8103*c8dee2aaSAndroid Build Coastguard Worker // The second line will be ellipsized. The 10th glyph ("0") will be replaced
8104*c8dee2aaSAndroid Build Coastguard Worker // by U+2026.
8105*c8dee2aaSAndroid Build Coastguard Worker const char* text = "This\n" // [0, 5)
8106*c8dee2aaSAndroid Build Coastguard Worker "1234567890ABCD"; // [5, len)
8107*c8dee2aaSAndroid Build Coastguard Worker
8108*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
8109*c8dee2aaSAndroid Build Coastguard Worker
8110*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
8111*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setEllipsis(u"\u2026");
8112*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.setMaxLines(2);
8113*c8dee2aaSAndroid Build Coastguard Worker
8114*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
8115*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Ahem")});
8116*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
8117*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(10);
8118*c8dee2aaSAndroid Build Coastguard Worker
8119*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
8120*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
8121*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
8122*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
8123*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
8124*c8dee2aaSAndroid Build Coastguard Worker
8125*c8dee2aaSAndroid Build Coastguard Worker // Roughly 10 characters wide.
8126*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(100);
8127*c8dee2aaSAndroid Build Coastguard Worker
8128*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getLineNumberAt(0) == 0);
8129*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getLineNumberAt(4) == 0);
8130*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getLineNumberAt(5) == 1);
8131*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getLineNumberAt(len) == -1);
8132*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getLineNumberAt(len - 1) == -1);
8133*c8dee2aaSAndroid Build Coastguard Worker // "0" should be ellipsized away so the call return -1 instead of 1.
8134*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getLineNumberAt(14) == -1);
8135*c8dee2aaSAndroid Build Coastguard Worker }
8136*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_API_USES_UTF16,reporter)8137*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_API_USES_UTF16, reporter) {
8138*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
8139*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
8140*c8dee2aaSAndroid Build Coastguard Worker // Each of these characters consists of 3 UTF-8 code points, or 1 UTF-16
8141*c8dee2aaSAndroid Build Coastguard Worker // code point.
8142*c8dee2aaSAndroid Build Coastguard Worker const char* text = "一丁丂七";
8143*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
8144*c8dee2aaSAndroid Build Coastguard Worker
8145*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
8146*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
8147*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
8148*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
8149*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
8150*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
8151*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
8152*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
8153*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
8154*c8dee2aaSAndroid Build Coastguard Worker
8155*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
8156*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
8157*c8dee2aaSAndroid Build Coastguard Worker
8158*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !has_empty_typeface(paragraph->getFontAtUTF16Offset(0)));
8159*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, has_empty_typeface(paragraph->getFontAtUTF16Offset(4)));
8160*c8dee2aaSAndroid Build Coastguard Worker
8161*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphInfoAtUTF16Offset(0, nullptr));
8162*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !paragraph->getGlyphInfoAtUTF16Offset(4, nullptr));
8163*c8dee2aaSAndroid Build Coastguard Worker // Verify the output also uses UTF-16
8164*c8dee2aaSAndroid Build Coastguard Worker Paragraph::GlyphInfo glyphInfo;
8165*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphInfoAtUTF16Offset(3, &glyphInfo));
8166*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.start == 3);
8167*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.end == 4);
8168*c8dee2aaSAndroid Build Coastguard Worker
8169*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getLineNumberAtUTF16Offset(0) == 0);
8170*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getLineNumberAtUTF16Offset(4) == -1);
8171*c8dee2aaSAndroid Build Coastguard Worker
8172*c8dee2aaSAndroid Build Coastguard Worker // The last logical character ("七") is considered hit.
8173*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getClosestUTF16GlyphInfoAt(999.0f, 999.0f, &glyphInfo));
8174*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.start == 3);
8175*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.end == 4);
8176*c8dee2aaSAndroid Build Coastguard Worker
8177*c8dee2aaSAndroid Build Coastguard Worker // The first logical character ("一") is considered hit.
8178*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getClosestUTF16GlyphInfoAt(-999.0f, 0.0f, &glyphInfo));
8179*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.start == 0);
8180*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.end == 1);
8181*c8dee2aaSAndroid Build Coastguard Worker }
8182*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_Empty_Paragraph_Metrics,reporter)8183*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_Empty_Paragraph_Metrics, reporter) {
8184*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
8185*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
8186*c8dee2aaSAndroid Build Coastguard Worker const char* text = "";
8187*c8dee2aaSAndroid Build Coastguard Worker
8188*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
8189*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
8190*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
8191*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
8192*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
8193*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
8194*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
8195*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, 0);
8196*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
8197*c8dee2aaSAndroid Build Coastguard Worker
8198*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
8199*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
8200*c8dee2aaSAndroid Build Coastguard Worker
8201*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, has_empty_typeface(paragraph->getFontAt(0)));
8202*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !paragraph->getGlyphClusterAt(0, nullptr));
8203*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getLineNumberAt(0) == -1);
8204*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !paragraph->getClosestGlyphClusterAt(10.0, 5.0, nullptr));
8205*c8dee2aaSAndroid Build Coastguard Worker }
8206*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GlyphCluster_Ligature,reporter)8207*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GlyphCluster_Ligature, reporter) {
8208*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
8209*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
8210*c8dee2aaSAndroid Build Coastguard Worker const char* text = "fi";
8211*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
8212*c8dee2aaSAndroid Build Coastguard Worker
8213*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
8214*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
8215*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
8216*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
8217*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(20);
8218*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
8219*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
8220*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
8221*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
8222*c8dee2aaSAndroid Build Coastguard Worker
8223*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
8224*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
8225*c8dee2aaSAndroid Build Coastguard Worker
8226*c8dee2aaSAndroid Build Coastguard Worker Paragraph::GlyphClusterInfo glyphInfo;
8227*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphClusterAt(0, &glyphInfo));
8228*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fClusterTextRange.start == 0);
8229*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fClusterTextRange.end == len);
8230*c8dee2aaSAndroid Build Coastguard Worker }
8231*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_GlyphInfo_LigatureDiacritics,reporter)8232*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_GlyphInfo_LigatureDiacritics, reporter) {
8233*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
8234*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
8235*c8dee2aaSAndroid Build Coastguard Worker // Ligature + diacritics
8236*c8dee2aaSAndroid Build Coastguard Worker // text = lam + hamza + alef + hamza
8237*c8dee2aaSAndroid Build Coastguard Worker // lam and alef form a laam-alif ligature and the 2 hamza are diacritical
8238*c8dee2aaSAndroid Build Coastguard Worker // marks the combines into the ligated base glyphs.
8239*c8dee2aaSAndroid Build Coastguard Worker const char* text = "لٔأ";
8240*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
8241*c8dee2aaSAndroid Build Coastguard Worker
8242*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
8243*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
8244*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
8245*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Katibeh")});
8246*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontSize(100);
8247*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
8248*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
8249*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
8250*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
8251*c8dee2aaSAndroid Build Coastguard Worker
8252*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
8253*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
8254*c8dee2aaSAndroid Build Coastguard Worker TestCanvas canvas("SkParagraph_laam_alif_diacritics.png");
8255*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(canvas.get(), 50, 50);
8256*c8dee2aaSAndroid Build Coastguard Worker
8257*c8dee2aaSAndroid Build Coastguard Worker Paragraph::GlyphInfo glyphInfo;
8258*c8dee2aaSAndroid Build Coastguard Worker
8259*c8dee2aaSAndroid Build Coastguard Worker const auto boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, RectWidthStyle::kTight);
8260*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, boxes.size() == 1);
8261*c8dee2aaSAndroid Build Coastguard Worker const SkRect fullRect = boxes[0].rect;
8262*c8dee2aaSAndroid Build Coastguard Worker
8263*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphInfoAtUTF16Offset(0, &glyphInfo));
8264*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.start == 0);
8265*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.end == 2);
8266*c8dee2aaSAndroid Build Coastguard Worker const SkRect rect0 = glyphInfo.fGraphemeLayoutBounds;
8267*c8dee2aaSAndroid Build Coastguard Worker
8268*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphInfoAtUTF16Offset(1, &glyphInfo));
8269*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.start == 0);
8270*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.end == 2);
8271*c8dee2aaSAndroid Build Coastguard Worker const SkRect rect1 = glyphInfo.fGraphemeLayoutBounds;
8272*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, rect0 == rect1);
8273*c8dee2aaSAndroid Build Coastguard Worker
8274*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphInfoAtUTF16Offset(2, &glyphInfo));
8275*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.start == 2);
8276*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.end == 4);
8277*c8dee2aaSAndroid Build Coastguard Worker const SkRect rect2 = glyphInfo.fGraphemeLayoutBounds;
8278*c8dee2aaSAndroid Build Coastguard Worker // The latter half of the text forms a different grapheme.
8279*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, rect2 != rect1);
8280*c8dee2aaSAndroid Build Coastguard Worker
8281*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, paragraph->getGlyphInfoAtUTF16Offset(3, &glyphInfo));
8282*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.start == 2);
8283*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphInfo.fGraphemeClusterTextRange.end == 4);
8284*c8dee2aaSAndroid Build Coastguard Worker const SkRect rect3 = glyphInfo.fGraphemeLayoutBounds;
8285*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, rect2 == rect3);
8286*c8dee2aaSAndroid Build Coastguard Worker
8287*c8dee2aaSAndroid Build Coastguard Worker // RTL text.
8288*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fullRect.left() == rect2.left());
8289*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fullRect.right() == rect0.right());
8290*c8dee2aaSAndroid Build Coastguard Worker
8291*c8dee2aaSAndroid Build Coastguard Worker // Currently it seems the 2 grapheme rects do not overlap each other.
8292*c8dee2aaSAndroid Build Coastguard Worker // REPORTER_ASSERT(reporter, rect2.right() < rect0.left());
8293*c8dee2aaSAndroid Build Coastguard Worker }
8294*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_SingleDummyPlaceholder,reporter)8295*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_SingleDummyPlaceholder, reporter) {
8296*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
8297*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
8298*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Single dummy placeholder";
8299*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
8300*c8dee2aaSAndroid Build Coastguard Worker
8301*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
8302*c8dee2aaSAndroid Build Coastguard Worker paragraph_style.turnHintingOff();
8303*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
8304*c8dee2aaSAndroid Build Coastguard Worker
8305*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
8306*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("Roboto")});
8307*c8dee2aaSAndroid Build Coastguard Worker text_style.setColor(SK_ColorBLACK);
8308*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
8309*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
8310*c8dee2aaSAndroid Build Coastguard Worker
8311*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
8312*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(TestCanvasWidth);
8313*c8dee2aaSAndroid Build Coastguard Worker
8314*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
8315*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->placeholders().size() == 1);
8316*c8dee2aaSAndroid Build Coastguard Worker
8317*c8dee2aaSAndroid Build Coastguard Worker size_t index = 0;
8318*c8dee2aaSAndroid Build Coastguard Worker for (auto& line : impl->lines()) {
8319*c8dee2aaSAndroid Build Coastguard Worker line.scanStyles(StyleType::kDecorations,
8320*c8dee2aaSAndroid Build Coastguard Worker [&index, reporter]
8321*c8dee2aaSAndroid Build Coastguard Worker (TextRange textRange, const TextStyle& style, const TextLine::ClipContext& context) {
8322*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, index == 0);
8323*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, style.getColor() == SK_ColorBLACK);
8324*c8dee2aaSAndroid Build Coastguard Worker ++index;
8325*c8dee2aaSAndroid Build Coastguard Worker });
8326*c8dee2aaSAndroid Build Coastguard Worker }
8327*c8dee2aaSAndroid Build Coastguard Worker }
8328*c8dee2aaSAndroid Build Coastguard Worker
UNIX_ONLY_TEST(SkParagraph_EndWithLineSeparator,reporter)8329*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_EndWithLineSeparator, reporter) {
8330*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
8331*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
8332*c8dee2aaSAndroid Build Coastguard Worker
8333*c8dee2aaSAndroid Build Coastguard Worker const char* text = "A text ending with line separator.\u2028";
8334*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
8335*c8dee2aaSAndroid Build Coastguard Worker
8336*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
8337*c8dee2aaSAndroid Build Coastguard Worker
8338*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
8339*c8dee2aaSAndroid Build Coastguard Worker TextStyle textStyle;
8340*c8dee2aaSAndroid Build Coastguard Worker textStyle.setFontFamilies({SkString("Roboto")});
8341*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(textStyle);
8342*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
8343*c8dee2aaSAndroid Build Coastguard Worker
8344*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
8345*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(SK_ScalarMax);
8346*c8dee2aaSAndroid Build Coastguard Worker
8347*c8dee2aaSAndroid Build Coastguard Worker int visitedCount = 0;
8348*c8dee2aaSAndroid Build Coastguard Worker paragraph->visit([&visitedCount, reporter](int lineNumber, const Paragraph::VisitorInfo* info) {
8349*c8dee2aaSAndroid Build Coastguard Worker visitedCount++;
8350*c8dee2aaSAndroid Build Coastguard Worker if (lineNumber == 1) {
8351*c8dee2aaSAndroid Build Coastguard Worker // Visitor for second line created from line separator should only be called for 'end of line'.
8352*c8dee2aaSAndroid Build Coastguard Worker // 'end of line' is denoted by 'info' being nullptr.
8353*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, info == nullptr);
8354*c8dee2aaSAndroid Build Coastguard Worker }
8355*c8dee2aaSAndroid Build Coastguard Worker });
8356*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, visitedCount == 3, "visitedCount: %d", visitedCount);
8357*c8dee2aaSAndroid Build Coastguard Worker }
8358*c8dee2aaSAndroid Build Coastguard Worker
SkParagraph_EmojiFontResolution(sk_sp<SkUnicode> icu,skiatest::Reporter * reporter)8359*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]] static void SkParagraph_EmojiFontResolution(sk_sp<SkUnicode> icu, skiatest::Reporter* reporter) {
8360*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
8361*c8dee2aaSAndroid Build Coastguard Worker SKIP_IF_FONTS_NOT_FOUND(reporter, fontCollection)
8362*c8dee2aaSAndroid Build Coastguard Worker
8363*c8dee2aaSAndroid Build Coastguard Worker const char* text = "♻️";
8364*c8dee2aaSAndroid Build Coastguard Worker const char* text1 = "♻️";
8365*c8dee2aaSAndroid Build Coastguard Worker const size_t len = strlen(text);
8366*c8dee2aaSAndroid Build Coastguard Worker const size_t len1 = strlen(text1);
8367*c8dee2aaSAndroid Build Coastguard Worker
8368*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style;
8369*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
8370*c8dee2aaSAndroid Build Coastguard Worker TextStyle text_style;
8371*c8dee2aaSAndroid Build Coastguard Worker text_style.setFontFamilies({SkString("")});
8372*c8dee2aaSAndroid Build Coastguard Worker builder.pushStyle(text_style);
8373*c8dee2aaSAndroid Build Coastguard Worker builder.addText(text, len);
8374*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
8375*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(SK_ScalarMax);
8376*c8dee2aaSAndroid Build Coastguard Worker
8377*c8dee2aaSAndroid Build Coastguard Worker auto impl = static_cast<ParagraphImpl*>(paragraph.get());
8378*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl->runs().size() == 1, "size: %zu", impl->runs().size());
8379*c8dee2aaSAndroid Build Coastguard Worker
8380*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder1(paragraph_style, fontCollection, get_unicode());
8381*c8dee2aaSAndroid Build Coastguard Worker builder1.pushStyle(text_style);
8382*c8dee2aaSAndroid Build Coastguard Worker builder1.addText(text1, len1);
8383*c8dee2aaSAndroid Build Coastguard Worker auto paragraph1 = builder1.Build();
8384*c8dee2aaSAndroid Build Coastguard Worker paragraph1->layout(SK_ScalarMax);
8385*c8dee2aaSAndroid Build Coastguard Worker
8386*c8dee2aaSAndroid Build Coastguard Worker auto impl1 = static_cast<ParagraphImpl*>(paragraph1.get());
8387*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, impl1->runs().size() == 1, "size: %zu", impl1->runs().size());
8388*c8dee2aaSAndroid Build Coastguard Worker if (impl1->runs().size() == 1) {
8389*c8dee2aaSAndroid Build Coastguard Worker SkString ff;
8390*c8dee2aaSAndroid Build Coastguard Worker impl->run(0).font().getTypeface()->getFamilyName(&ff);
8391*c8dee2aaSAndroid Build Coastguard Worker SkString ff1;
8392*c8dee2aaSAndroid Build Coastguard Worker impl1->run(0).font().getTypeface()->getFamilyName(&ff1);
8393*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, ff.equals(ff1));
8394*c8dee2aaSAndroid Build Coastguard Worker }
8395*c8dee2aaSAndroid Build Coastguard Worker }
8396*c8dee2aaSAndroid Build Coastguard Worker
8397*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
UNIX_ONLY_TEST(SkParagraph_ICU_EmojiFontResolution,reporter)8398*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ICU_EmojiFontResolution, reporter) {
8399*c8dee2aaSAndroid Build Coastguard Worker SkParagraph_EmojiFontResolution(SkUnicodes::ICU::Make(), reporter);
8400*c8dee2aaSAndroid Build Coastguard Worker }
8401*c8dee2aaSAndroid Build Coastguard Worker #endif
8402*c8dee2aaSAndroid Build Coastguard Worker
8403*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
UNIX_ONLY_TEST(SkParagraph_ICU4X_EmojiFontResolution,reporter)8404*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ICU4X_EmojiFontResolution, reporter) {
8405*c8dee2aaSAndroid Build Coastguard Worker SkParagraph_EmojiFontResolution(SkUnicodes::ICU4X::Make(), reporter);
8406*c8dee2aaSAndroid Build Coastguard Worker }
8407*c8dee2aaSAndroid Build Coastguard Worker #endif
8408*c8dee2aaSAndroid Build Coastguard Worker
SkUnicode_Emoji(sk_sp<SkUnicode> icu,skiatest::Reporter * reporter)8409*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]] static void SkUnicode_Emoji(sk_sp<SkUnicode> icu, skiatest::Reporter* reporter) {
8410*c8dee2aaSAndroid Build Coastguard Worker auto test = [&](const char* text, SkUnichar expected) {
8411*c8dee2aaSAndroid Build Coastguard Worker SkString str(text);
8412*c8dee2aaSAndroid Build Coastguard Worker if ((false)) {
8413*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("'%s'\n", text);
8414*c8dee2aaSAndroid Build Coastguard Worker const char* begin = str.data();
8415*c8dee2aaSAndroid Build Coastguard Worker const char* end = str.data() + str.size();
8416*c8dee2aaSAndroid Build Coastguard Worker while (begin != end) {
8417*c8dee2aaSAndroid Build Coastguard Worker auto unicode = SkUTF::NextUTF8WithReplacement(&begin, end);
8418*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" %d: %s %s\n", unicode,
8419*c8dee2aaSAndroid Build Coastguard Worker icu->isEmoji(unicode) ? "isEmoji" : "",
8420*c8dee2aaSAndroid Build Coastguard Worker icu->isEmojiComponent(unicode) ? "isEmojiComponent" : ""
8421*c8dee2aaSAndroid Build Coastguard Worker );
8422*c8dee2aaSAndroid Build Coastguard Worker }
8423*c8dee2aaSAndroid Build Coastguard Worker
8424*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Graphemes:");
8425*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<SkUnicode::CodeUnitFlags, true> codeUnitProperties;
8426*c8dee2aaSAndroid Build Coastguard Worker icu->computeCodeUnitFlags(str.data(), str.size(), false, &codeUnitProperties);
8427*c8dee2aaSAndroid Build Coastguard Worker int index = 0;
8428*c8dee2aaSAndroid Build Coastguard Worker for (auto& cp : codeUnitProperties) {
8429*c8dee2aaSAndroid Build Coastguard Worker if (SkUnicode::hasGraphemeStartFlag(cp)) {
8430*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" %d", index);
8431*c8dee2aaSAndroid Build Coastguard Worker }
8432*c8dee2aaSAndroid Build Coastguard Worker ++index;
8433*c8dee2aaSAndroid Build Coastguard Worker }
8434*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
8435*c8dee2aaSAndroid Build Coastguard Worker }
8436*c8dee2aaSAndroid Build Coastguard Worker
8437*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const char> textSpan(str.data(), str.size());
8438*c8dee2aaSAndroid Build Coastguard Worker const char* begin = str.data();
8439*c8dee2aaSAndroid Build Coastguard Worker const char* end = begin + str.size();
8440*c8dee2aaSAndroid Build Coastguard Worker auto emojiStart = OneLineShaper::getEmojiSequenceStart(icu.get(), &begin, end);
8441*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, expected == emojiStart);
8442*c8dee2aaSAndroid Build Coastguard Worker };
8443*c8dee2aaSAndroid Build Coastguard Worker
8444*c8dee2aaSAndroid Build Coastguard Worker test("", -1);
8445*c8dee2aaSAndroid Build Coastguard Worker test("0", -1);
8446*c8dee2aaSAndroid Build Coastguard Worker test("2nd", -1);
8447*c8dee2aaSAndroid Build Coastguard Worker test("99", -1);
8448*c8dee2aaSAndroid Build Coastguard Worker test("0️⃣", 48);
8449*c8dee2aaSAndroid Build Coastguard Worker test("0️⃣12", 48);
8450*c8dee2aaSAndroid Build Coastguard Worker test("#", -1);
8451*c8dee2aaSAndroid Build Coastguard Worker test("#️⃣", 35);
8452*c8dee2aaSAndroid Build Coastguard Worker test("#️⃣#", 35);
8453*c8dee2aaSAndroid Build Coastguard Worker test("#️⃣#️⃣", 35);
8454*c8dee2aaSAndroid Build Coastguard Worker test("*", -1);
8455*c8dee2aaSAndroid Build Coastguard Worker test("*️⃣", 42);
8456*c8dee2aaSAndroid Build Coastguard Worker test("*️⃣abc", 42);
8457*c8dee2aaSAndroid Build Coastguard Worker test("*️⃣", 42);
8458*c8dee2aaSAndroid Build Coastguard Worker test("", 128522);
8459*c8dee2aaSAndroid Build Coastguard Worker test("abc", 128522);
8460*c8dee2aaSAndroid Build Coastguard Worker test("*️⃣",128522);
8461*c8dee2aaSAndroid Build Coastguard Worker test("", 128104);
8462*c8dee2aaSAndroid Build Coastguard Worker
8463*c8dee2aaSAndroid Build Coastguard Worker // These 2 have emoji components as the first codepoint
8464*c8dee2aaSAndroid Build Coastguard Worker test("", 127479); // Flag sequence
8465*c8dee2aaSAndroid Build Coastguard Worker test("0️⃣", 48); // Keycap sequence
8466*c8dee2aaSAndroid Build Coastguard Worker
8467*c8dee2aaSAndroid Build Coastguard Worker // These have a simple emoji as a first codepoint
8468*c8dee2aaSAndroid Build Coastguard Worker test("", 127988); // Tag sequence
8469*c8dee2aaSAndroid Build Coastguard Worker test("", 128075); // Modifier sequence
8470*c8dee2aaSAndroid Build Coastguard Worker test("", 128104); // ZWJ sequence
8471*c8dee2aaSAndroid Build Coastguard Worker }
8472*c8dee2aaSAndroid Build Coastguard Worker
8473*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
UNIX_ONLY_TEST(SkParagraph_ICU_EmojiRuns,reporter)8474*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ICU_EmojiRuns, reporter) {
8475*c8dee2aaSAndroid Build Coastguard Worker SkUnicode_Emoji(SkUnicodes::ICU::Make(), reporter);
8476*c8dee2aaSAndroid Build Coastguard Worker }
8477*c8dee2aaSAndroid Build Coastguard Worker #endif
8478*c8dee2aaSAndroid Build Coastguard Worker
8479*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
UNIX_ONLY_TEST(SkParagraph_ICU4X_EmojiRuns,reporter)8480*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkParagraph_ICU4X_EmojiRuns, reporter) {
8481*c8dee2aaSAndroid Build Coastguard Worker SkUnicode_Emoji(SkUnicodes::ICU4X::Make(), reporter);
8482*c8dee2aaSAndroid Build Coastguard Worker }
8483*c8dee2aaSAndroid Build Coastguard Worker #endif
8484