58#if defined(SK_UNICODE_ICU_IMPLEMENTATION)
62#if defined(SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION)
66#if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
75 "subdirectory of //resources for fonts to use for these tests");
76static DEFINE_bool(run_paragraph_tests_needing_system_fonts,
true,
77 "Some tests are finicky and need certain system fonts. "
78 "Set this to false to skip those.");
80#define VeryLongCanvasWidth 1000000
81#define TestCanvasWidth 1000
82#define TestCanvasHeight 600
95 return std::strncmp(
b,
base +
a.start,
a.width()) == 0;
98std::u16string
mirror(
const std::string&
text) {
101 for (
auto i =
text.size(); i > 0; --i) {
108std::u16string straight(
const std::string&
text) {
111 for (
auto ch :
text) {
118 static const std::vector<sk_sp<SkTypeface>>& getTypefaces() {
119 static std::vector<sk_sp<SkTypeface>> typefaces = []() -> std::vector<
sk_sp<SkTypeface>> {
120 if (FLAGS_paragraph_fonts.size() == 0) {
126 const char* fontDir = fontResources.
c_str();
129 while (iter.
next(&path)) {
131 SkDebugf(
"Found font file: %s\n", path.c_str());
134 fullPath.
printf(
"%s/%s", fontDir, path.c_str());
140 return strcmp(a.c_str(), b.c_str()) < 0;
146 std::vector<sk_sp<SkTypeface>> typefaces;
147 bool fontsFound =
false;
148 for (
auto&& path : paths) {
150 SkDebugf(
"Reading font: %s\n", path.c_str());
153 SkASSERTF(stream,
"%s not readable", path.c_str());
160 typeface->getFamilyName(&familyName);
161 SkDebugf(
"Creating: %s size: %zu\n",
163 typeface->openExistingStream(
nullptr)->getLength());
165 if (path.endsWith(
"Roboto-Italic.ttf")) {
168 typefaces.emplace_back(std::move(typeface));
170 SkDEBUGF(
"%s was not turned into a Typeface. Did you set --nativeFonts?\n",
175 "Did you set --nativeFonts?");
176 SkASSERTF_RELEASE(fontsFound,
"--paragraph_fonts set but Roboto-Italic.ttf not found");
182 ResourceFontCollection(
bool testOnly =
false)
185 , fFontProvider(sk_make_sp<TypefaceFontProvider>()) {
186 const std::vector<sk_sp<SkTypeface>>& typefaces = getTypefaces();
187 fFontsFound = !typefaces.empty();
188 for (
auto&& typeface : typefaces) {
189 fFontProvider->registerTypeface(typeface);
193 this->setTestFontManager(std::move(fFontProvider));
195 this->setAssetFontManager(std::move(fFontProvider));
197 this->disableFontFallback();
200 size_t resolvedFonts()
const {
return fResolvedFonts; }
203 bool fontsFound()
const {
return fFontsFound; }
207 size_t fResolvedFonts;
213 TestCanvas(
const char* testName) :
name(testName) {
236 paint.setAntiAlias(
true);
237 paint.setStrokeWidth(1);
241 canvas->drawRect(r.rect,
paint);
249 paint.setAntiAlias(
true);
250 paint.setStrokeWidth(1);
253 canvas->drawLine(rect.fLeft, rect.fTop, rect.fLeft, rect.fBottom,
paint);
255 canvas->drawLine(rect.fLeft, rect.fTop, rect.fRight, rect.fTop,
paint);
262 drawLine(
color, r.rect);
275 return sk_ref_sp<SkUnicode>(factory->getUnicode());
282#define SKIP_IF_FONTS_NOT_FOUND(r, fontCollection) \
283 if (!fontCollection->fontsFound()) { \
284 if (FLAGS_paragraph_fonts.size() != 0) { \
285 ERRORF(r, "SkParagraphTests Fonts not found!\n"); \
290#define NEED_SYSTEM_FONTS(fontCollection) \
291 if (!FLAGS_run_paragraph_tests_needing_system_fonts) { \
294 fontCollection->setDefaultFontManager(ToolUtils::TestFontMgr()); \
295 fontCollection->enableFontFallback();
300 const char*
text =
"Hello World Text Dialog";
301 const size_t len = strlen(
text);
310 builder.pushStyle(text_style);
311 builder.addText(
text, len);
314 auto paragraph = builder.Build();
324 for (
auto& line : impl->lines()) {
325 line.scanStyles(StyleType::kDecorations,
338 const char*
text =
"AAAAAAAAAA";
339 const size_t len = strlen(
text);
348 auto testFontSize = {1.5f, 10.0f/3, 10.0f/6, 10.0f};
349 for (
auto fontSize : testFontSize) {
352 builder.pushStyle(text_style);
353 builder.addText(
text, len);
356 auto paragraph = builder.Build();
360 paragraph->layout(paragraph->getMaxIntrinsicWidth());
365 auto& line = impl->
lines()[0];
374 TestCanvas canvas(
"SkParagraph_InlinePlaceholderParagraph.png");
377 const char*
text =
"012 34";
378 const size_t len = strlen(
text);
393 builder.pushStyle(text_style);
394 builder.addText(
text, len);
396 PlaceholderStyle placeholder1(50, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 0);
397 builder.addPlaceholder(placeholder1);
398 builder.addText(
text, len);
399 builder.addPlaceholder(placeholder1);
401 PlaceholderStyle placeholder2(5, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 50);
402 builder.addPlaceholder(placeholder2);
403 builder.addPlaceholder(placeholder1);
404 builder.addPlaceholder(placeholder2);
405 builder.addText(
text, len);
406 builder.addPlaceholder(placeholder2);
407 builder.addText(
text, len);
408 builder.addText(
text, len);
409 builder.addPlaceholder(placeholder2);
410 builder.addPlaceholder(placeholder2);
411 builder.addPlaceholder(placeholder2);
412 builder.addPlaceholder(placeholder2);
413 builder.addPlaceholder(placeholder2);
414 builder.addPlaceholder(placeholder1);
415 builder.addText(
text, len);
416 builder.addText(
text, len);
417 builder.addText(
text, len);
418 builder.addText(
text, len);
419 builder.addText(
text, len);
420 builder.addPlaceholder(placeholder2);
421 builder.addPlaceholder(placeholder1);
422 builder.addText(
text, len);
423 builder.addText(
text, len);
427 auto paragraph = builder.Build();
429 paragraph->paint(canvas.get(), 0, 0);
434 auto boxes = paragraph->getRectsForRange(0, 3, rect_height_style, rect_width_style);
438 boxes = paragraph->getRectsForRange(0, 3, rect_height_style, rect_width_style);
442 boxes = paragraph->getRectsForPlaceholders();
445 boxes = paragraph->getRectsForRange(4, 17, rect_height_style, rect_width_style);
473 TestCanvas canvas(
"SkParagraph_InlinePlaceholderBaselineParagraph.png");
476 const char*
text =
"012 34";
477 const size_t len = strlen(
text);
492 builder.pushStyle(text_style);
493 builder.addText(
text, len);
495 PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 38.347f);
496 builder.addPlaceholder(placeholder);
497 builder.addText(
text, len);
501 auto paragraph = builder.Build();
503 paragraph->paint(canvas.get(), 0, 0);
505 auto boxes = paragraph->getRectsForPlaceholders();
517 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
529 TestCanvas canvas(
"SkParagraph_InlinePlaceholderAboveBaselineParagraph.png");
532 const char*
text =
"012 34";
533 const size_t len = strlen(
text);
548 builder.pushStyle(text_style);
549 builder.addText(
text, len);
551 PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kAboveBaseline, TextBaseline::kAlphabetic, 903129.129308f);
552 builder.addPlaceholder(placeholder);
553 builder.addText(
text, len);
557 auto paragraph = builder.Build();
559 paragraph->paint(canvas.get(), 0, 0);
561 auto boxes = paragraph->getRectsForPlaceholders();
573 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
585 TestCanvas canvas(
"SkParagraph_InlinePlaceholderBelowBaselineParagraph.png");
588 const char*
text =
"012 34";
589 const size_t len = strlen(
text);
604 builder.pushStyle(text_style);
605 builder.addText(
text, len);
607 PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kBelowBaseline, TextBaseline::kAlphabetic, 903129.129308f);
608 builder.addPlaceholder(placeholder);
609 builder.addText(
text, len);
613 auto paragraph = builder.Build();
615 paragraph->paint(canvas.get(), 0, 0);
617 auto boxes = paragraph->getRectsForPlaceholders();
629 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
641 TestCanvas canvas(
"SkParagraph_InlinePlaceholderBottomParagraph.png");
644 const char*
text =
"012 34";
645 const size_t len = strlen(
text);
660 builder.pushStyle(text_style);
661 builder.addText(
text, len);
663 PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kBottom, TextBaseline::kAlphabetic, 0);
664 builder.addPlaceholder(placeholder);
665 builder.addText(
text, len);
669 auto paragraph = builder.Build();
671 paragraph->paint(canvas.get(), 0, 0);
676 auto boxes = paragraph->getRectsForPlaceholders();
684 boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
695 TestCanvas canvas(
"SkParagraph_InlinePlaceholderTopParagraph.png");
698 const char*
text =
"012 34";
699 const size_t len = strlen(
text);
714 builder.pushStyle(text_style);
715 builder.addText(
text, len);
717 PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kTop, TextBaseline::kAlphabetic, 0);
718 builder.addPlaceholder(placeholder);
719 builder.addText(
text, len);
723 auto paragraph = builder.Build();
725 paragraph->paint(canvas.get(), 0, 0);
730 auto boxes = paragraph->getRectsForPlaceholders();
738 boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
749 TestCanvas canvas(
"SkParagraph_InlinePlaceholderMiddleParagraph.png");
752 const char*
text =
"012 34";
753 const size_t len = strlen(
text);
768 builder.pushStyle(text_style);
769 builder.addText(
text, len);
771 PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kMiddle, TextBaseline::kAlphabetic, 0);
772 builder.addPlaceholder(placeholder);
773 builder.addText(
text, len);
777 auto paragraph = builder.Build();
779 paragraph->paint(canvas.get(), 0, 0);
784 auto boxes = paragraph->getRectsForPlaceholders();
792 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
803 TestCanvas canvas(
"SkParagraph_InlinePlaceholderIdeographicBaselineParagraph.png");
806 const char*
text =
"給能上目秘使";
807 const size_t len = strlen(
text);
822 builder.pushStyle(text_style);
823 builder.addText(
text, len);
824 PlaceholderStyle placeholder(55, 50, PlaceholderAlignment::kBaseline, TextBaseline::kIdeographic, 38.347f);
825 builder.addPlaceholder(placeholder);
826 builder.addText(
text, len);
830 auto paragraph = builder.Build();
832 paragraph->paint(canvas.get(), 0, 0);
837 auto boxes = paragraph->getRectsForPlaceholders();
845 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
856 TestCanvas canvas(
"SkParagraph_InlinePlaceholderBreakParagraph.png");
859 const char*
text =
"012 34";
860 const size_t len = strlen(
text);
875 builder.pushStyle(text_style);
876 builder.addText(
text, len);
878 PlaceholderStyle placeholder1(50, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 50);
879 PlaceholderStyle placeholder2(25, 25, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 12.5f);
881 builder.addPlaceholder(placeholder1);
882 builder.addPlaceholder(placeholder1);
883 builder.addPlaceholder(placeholder1);
884 builder.addPlaceholder(placeholder2);
885 builder.addPlaceholder(placeholder1);
886 builder.addText(
text, len);
888 builder.addPlaceholder(placeholder1);
889 builder.addPlaceholder(placeholder1);
890 builder.addPlaceholder(placeholder1);
891 builder.addPlaceholder(placeholder1);
892 builder.addPlaceholder(placeholder2);
893 builder.addPlaceholder(placeholder1);
894 builder.addPlaceholder(placeholder1);
895 builder.addPlaceholder(placeholder1);
896 builder.addPlaceholder(placeholder1);
897 builder.addPlaceholder(placeholder1);
898 builder.addPlaceholder(placeholder1);
899 builder.addPlaceholder(placeholder2);
900 builder.addPlaceholder(placeholder1);
901 builder.addPlaceholder(placeholder1);
902 builder.addPlaceholder(placeholder1);
903 builder.addPlaceholder(placeholder1);
904 builder.addPlaceholder(placeholder1);
905 builder.addPlaceholder(placeholder1);
906 builder.addPlaceholder(placeholder1);
907 builder.addPlaceholder(placeholder2);
909 builder.addPlaceholder(placeholder1);
910 builder.addText(
text, len);
911 builder.addPlaceholder(placeholder1);
912 builder.addPlaceholder(placeholder2);
914 builder.addText(
text, len);
915 builder.addText(
text, len);
916 builder.addText(
text, len);
917 builder.addText(
text, len);
919 builder.addPlaceholder(placeholder2);
920 builder.addPlaceholder(placeholder1);
922 builder.addText(
text, len);
924 builder.addPlaceholder(placeholder2);
926 builder.addText(
text, len);
927 builder.addText(
text, len);
928 builder.addText(
text, len);
929 builder.addText(
text, len);
930 builder.addText(
text, len);
931 builder.addText(
text, len);
932 builder.addText(
text, len);
933 builder.addText(
text, len);
934 builder.addText(
text, len);
935 builder.addText(
text, len);
936 builder.addText(
text, len);
937 builder.addText(
text, len);
938 builder.addText(
text, len);
939 builder.addText(
text, len);
940 builder.addText(
text, len);
941 builder.addText(
text, len);
942 builder.addText(
text, len);
943 builder.addText(
text, len);
944 builder.addText(
text, len);
948 auto paragraph = builder.Build();
950 paragraph->paint(canvas.get(), 0, 0);
955 auto boxes = paragraph->getRectsForRange(0, 3, rect_height_style, rect_width_style);
959 boxes = paragraph->getRectsForRange(175, 176, rect_height_style, rect_width_style);
967 boxes = paragraph->getRectsForPlaceholders();
970 boxes = paragraph->getRectsForRange(4, 45, rect_height_style, rect_width_style);
991 TestCanvas canvas(
"SkParagraph_InlinePlaceholderGetRectsParagraph.png");
994 const char*
text =
"012 34";
995 const size_t len = strlen(
text);
1010 builder.pushStyle(text_style);
1011 builder.addText(
text, len);
1013 PlaceholderStyle placeholder1(50, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 50);
1014 PlaceholderStyle placeholder2(5, 20, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 10);
1016 builder.addPlaceholder(placeholder1);
1017 builder.addPlaceholder(placeholder1);
1018 builder.addPlaceholder(placeholder1);
1019 builder.addPlaceholder(placeholder1);
1020 builder.addPlaceholder(placeholder1);
1021 builder.addPlaceholder(placeholder1);
1022 builder.addPlaceholder(placeholder1);
1023 builder.addPlaceholder(placeholder1);
1024 builder.addPlaceholder(placeholder2);
1025 builder.addPlaceholder(placeholder1);
1026 builder.addPlaceholder(placeholder1);
1027 builder.addPlaceholder(placeholder1);
1028 builder.addPlaceholder(placeholder1);
1029 builder.addPlaceholder(placeholder1);
1030 builder.addPlaceholder(placeholder2);
1031 builder.addPlaceholder(placeholder1);
1032 builder.addPlaceholder(placeholder1);
1033 builder.addPlaceholder(placeholder1);
1034 builder.addPlaceholder(placeholder1);
1035 builder.addPlaceholder(placeholder1);
1036 builder.addPlaceholder(placeholder1);
1037 builder.addPlaceholder(placeholder1);
1038 builder.addPlaceholder(placeholder1);
1040 builder.addText(
text, len);
1042 builder.addPlaceholder(placeholder1);
1043 builder.addPlaceholder(placeholder2);
1044 builder.addPlaceholder(placeholder2);
1045 builder.addPlaceholder(placeholder1);
1046 builder.addPlaceholder(placeholder2);
1047 builder.addPlaceholder(placeholder2);
1049 builder.addText(
text, len);
1050 builder.addText(
text, len);
1051 builder.addText(
text, len);
1052 builder.addText(
text, len);
1053 builder.addText(
text, len);
1054 builder.addText(
text, len);
1055 builder.addText(
text, len);
1056 builder.addText(
text, len);
1057 builder.addText(
text, len);
1058 builder.addText(
text, len);
1059 builder.addText(
text, len);
1061 builder.addPlaceholder(placeholder2);
1062 builder.addPlaceholder(placeholder1);
1063 builder.addPlaceholder(placeholder2);
1064 builder.addPlaceholder(placeholder1);
1065 builder.addPlaceholder(placeholder2);
1067 builder.addText(
text, len);
1071 auto paragraph = builder.Build();
1073 paragraph->paint(canvas.get(), 0, 0);
1078 auto boxes = paragraph->getRectsForPlaceholders();
1097 boxes = paragraph->getRectsForRange(30, 50, rect_height_style, rect_width_style);
1120 const char*
text =
"I am RED";
1121 const size_t len = strlen(
text);
1130 builder.pushStyle(text_style);
1131 builder.addText(
text, len);
1134 auto paragraph = builder.Build();
1144 for (
auto& line : impl->lines()) {
1145 line.scanStyles(StyleType::kDecorations,
1158 TestCanvas canvas(
"SkParagraph_RainbowParagraph.png");
1160 const char* text1 =
"Red Roboto";
1161 const char* text2 =
"big Greeen Default";
1162 const char* text3 =
"Defcolor Homemade Apple";
1163 const char* text4 =
"Small Blue Roboto";
1164 const char* text41 =
"Small Blue ";
1166 "Continue Last Style With lots of words to check if it overlaps "
1168 const char* text42 =
1170 "Continue Last Style With lots of words to check if it overlaps "
1183 builder.pushStyle(text_style1);
1184 builder.addText(text1, strlen(text1));
1194 TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
1197 builder.pushStyle(text_style2);
1198 builder.addText(text2, strlen(text2));
1203 builder.pushStyle(text_style3);
1204 builder.addText(text3, strlen(text3));
1211 TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
1213 builder.pushStyle(text_style4);
1214 builder.addText(text4, strlen(text4));
1216 builder.addText(text5, strlen(text5));
1219 auto paragraph = builder.Build();
1220 paragraph->layout(1000);
1221 paragraph->paint(canvas.get(), 0, 0);
1230 auto rects = paragraph->getRectsForRange(0, impl->text().size(), RectHeightStyle::kMax, RectWidthStyle::kTight);
1234 impl->lines()[0].scanStyles(
1235 StyleType::kAllAttributes,
1261 impl->lines()[1].scanStyles(
1262 StyleType::kAllAttributes,
1282 TestCanvas canvas(
"SkParagraph_DefaultStyleParagraph.png");
1283 const char*
text =
"No TextStyle! Uh Oh!";
1284 const size_t len = strlen(
text);
1293 builder.addText(
text, len);
1295 auto paragraph = builder.Build();
1297 paragraph->paint(canvas.get(), 10.0, 15.0);
1308 impl->lines()[0].scanStyles(
1309 StyleType::kAllAttributes,
1322 TestCanvas canvas(
"SkParagraph_BoldParagraph.png");
1323 const char*
text =
"This is Red max bold text!";
1324 const size_t len = strlen(
text);
1337 builder.pushStyle(text_style);
1338 builder.addText(
text, len);
1341 auto paragraph = builder.Build();
1343 paragraph->paint(canvas.get(), 10.0, 60.0);
1354 impl->lines()[0].scanStyles(
1355 StyleType::kAllAttributes,
1368 TestCanvas canvas(
"SkParagraph_HeightOverrideParagraph.png");
1369 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1370 const size_t len = strlen(
text);
1383 builder.pushStyle(text_style);
1384 builder.addText(
text, len);
1387 auto paragraph = builder.Build();
1388 paragraph->layout(550);
1395 paragraph->paint(canvas.get(), 0, 0);
1399 paint.setAntiAlias(
true);
1400 paint.setStrokeWidth(1);
1403 RectHeightStyle rect_height_style = RectHeightStyle::kIncludeLineSpacingMiddle;
1406 std::vector<TextBox> boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
1410 boxes = paragraph->getRectsForRange(0, 40, rect_height_style, rect_width_style);
1424 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1425 const size_t len = strlen(
text);
1427 TestCanvas canvas(
"SkParagraph_BasicHalfLeading.png");
1442 builder.pushStyle(text_style);
1443 builder.addText(
text);
1445 auto paragraph = builder.Build();
1446 paragraph->layout(550);
1452 paragraph->paint(canvas.get(), 0, 0);
1455 std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1456 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1462 const auto line_spacing1 = boxes[1].rect.top() - boxes[0].rect.bottom();
1463 const auto line_spacing2 = boxes[2].rect.top() - boxes[1].rect.bottom();
1482 const char*
text =
"Cookies need love";
1483 const size_t len = strlen(
text);
1485 TestCanvas canvas(
"SkParagraph_ZeroHeightHalfLeading.png");
1502 builder.pushStyle(text_style);
1503 builder.addText(
text);
1507 builder.pushStyle(text_style);
1508 builder.addText(
text);
1510 auto paragraph = builder.Build();
1511 paragraph->layout(550);
1512 paragraph->paint(canvas.get(), 0, 0);
1521 std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1522 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1529 const auto metricsAscent = -18.5546875f;
1530 const auto metricsDescent = 4.8828125f;
1540 const auto run1_ascent = (metricsAscent + metricsDescent) / 2;
1541 const auto run1_descent = (metricsAscent + metricsDescent) / 2;
1542 const auto run2_ascent = 0.0f;
1543 const auto run2_descent = 0.0f;
1544 const auto line_top = std::min(run1_ascent, run2_ascent);
1545 const auto line_bottom = std::max(run1_descent, run2_descent);
1548 const auto glyphs_top = metricsAscent - line_top;
1549 const auto glyphs_bottom = metricsDescent - line_top;
1553 const auto actual_glyphs_top = boxes[0].rect.top() - lineBoxes[0].rect.top();
1554 const auto actual_glyphs_bottom = boxes[0].rect.bottom() - lineBoxes[0].rect.top();
1572 const char*
text =
"A";
1573 const size_t len = strlen(
text);
1575 TestCanvas canvas(
"SkParagraph_StrutHalfLeading.png");
1601 builder.pushStyle(text_style);
1602 builder.addText(
text);
1604 auto paragraph = builder.Build();
1605 paragraph->layout(550);
1610 paragraph->paint(canvas.get(), 0, 0);
1613 std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1614 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1624 std::vector<LineMetrics> lineMetrics;
1625 paragraph->getLineMetrics(lineMetrics);
1637 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1638 const size_t len = strlen(
text);
1640 TestCanvas canvas(
"SkParagraph_StrutHalfLeading.png");
1666 builder.pushStyle(text_style);
1667 builder.addText(
text);
1669 auto paragraph = builder.Build();
1670 paragraph->layout(550);
1675 paragraph->paint(canvas.get(), 0, 0);
1678 std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1679 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1685 const auto line_spacing1 = boxes[1].rect.top() - boxes[0].rect.bottom();
1686 const auto line_spacing2 = boxes[2].rect.top() - boxes[1].rect.bottom();
1704 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1705 const size_t len = strlen(
text);
1707 TestCanvas canvas(
"SkParagraph_TrimHalfLeading.png");
1723 builder.pushStyle(text_style);
1724 builder.addText(
text);
1726 auto paragraph = builder.Build();
1727 paragraph->layout(550);
1728 paragraph->paint(canvas.get(), 0, 0);
1732 std::vector<TextBox> boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, rect_width_style);
1733 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kMax, rect_width_style);
1739 const auto line_spacing1 = boxes[1].rect.top() - boxes[0].rect.bottom();
1740 const auto line_spacing2 = boxes[2].rect.top() - boxes[1].rect.bottom();
1750 const auto halfLeading = lineBoxes[0].rect.bottom() - boxes[0].rect.bottom();
1752 const auto epsilon = EPSILON10;
1766 TestCanvas canvas(
"SkParagraph_LeftAlignParagraph.png");
1768 "This is a very long sentence to test if the text will properly wrap "
1769 "around and go to the next line. Sometimes, short sentence. Longer "
1770 "sentences are okay too because they are nessecary. Very short. "
1771 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1772 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1773 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1774 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1775 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1776 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1777 "mollit anim id est laborum. "
1778 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1779 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1780 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1781 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1782 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1783 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1784 "mollit anim id est laborum.";
1785 const size_t len = strlen(
text);
1802 builder.pushStyle(text_style);
1803 builder.addText(
text, len);
1806 auto paragraph = builder.Build();
1808 paragraph->paint(canvas.get(), 0, 0);
1818 double expected_y = 0;
1819 double epsilon = 0.01f;
1832 expected_y += 30 * 10;
1837 paragraph_style.
getTextAlign() == impl->paragraphStyle().getTextAlign());
1850 TestCanvas canvas(
"SkParagraph_RightAlignParagraph.png");
1852 "This is a very long sentence to test if the text will properly wrap "
1853 "around and go to the next line. Sometimes, short sentence. Longer "
1854 "sentences are okay too because they are nessecary. Very short. "
1855 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1856 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1857 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1858 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1859 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1860 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1861 "mollit anim id est laborum. "
1862 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1863 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1864 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1865 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1866 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1867 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1868 "mollit anim id est laborum.";
1869 const size_t len = strlen(
text);
1886 builder.pushStyle(text_style);
1887 builder.addText(
text, len);
1890 auto paragraph = builder.Build();
1893 paragraph->paint(canvas.get(), 0, 0);
1902 double expected_y = 0;
1903 double epsilon = 0.01f;
1916 expected_y += 30 * 10;
1931 paragraph_style.
getTextAlign() == impl->paragraphStyle().getTextAlign());
1937 TestCanvas canvas(
"SkParagraph_CenterAlignParagraph.png");
1939 "This is a very long sentence to test if the text will properly wrap "
1940 "around and go to the next line. Sometimes, short sentence. Longer "
1941 "sentences are okay too because they are nessecary. Very short. "
1942 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1943 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1944 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1945 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1946 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1947 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1948 "mollit anim id est laborum. "
1949 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1950 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1951 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1952 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1953 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1954 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1955 "mollit anim id est laborum.";
1956 const size_t len = strlen(
text);
1973 builder.pushStyle(text_style);
1974 builder.addText(
text, len);
1977 auto paragraph = builder.Build();
1979 paragraph->paint(canvas.get(), 0, 0);
1989 double expected_y = 0;
1990 double epsilon = 0.01f;
2003 expected_y += 30 * 10;
2018 paragraph_style.
getTextAlign() == impl->paragraphStyle().getTextAlign());
2024 TestCanvas canvas(
"SkParagraph_JustifyAlignParagraph.png");
2026 "This is a very long sentence to test if the text will properly wrap "
2027 "around and go to the next line. Sometimes, short sentence. Longer "
2028 "sentences are okay too because they are nessecary. Very short. "
2029 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
2030 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
2031 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
2032 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
2033 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
2034 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
2035 "mollit anim id est laborum. "
2036 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
2037 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
2038 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
2039 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
2040 "velit esse cillum dolore eu fugiat.";
2041 const size_t len = strlen(
text);
2058 builder.pushStyle(text_style);
2059 builder.addText(
text, len);
2062 auto paragraph = builder.Build();
2064 paragraph->paint(canvas.get(), 0, 0);
2068 auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2078 double expected_y = 0;
2091 expected_y += 30 * 9;
2096 return line.offset().fX;
2105 paragraph_style.
getTextAlign() == impl->paragraphStyle().getTextAlign());
2112 TestCanvas canvas(
"SkParagraph_JustifyRTL.png");
2114 "אאא בּבּבּבּ אאאא בּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ "
2115 "אאאאא בּבּבּבּבּ אאאבּבּבּבּבּבּאאאאא בּבּבּבּבּבּאאאאאבּבּבּבּבּבּ אאאאא בּבּבּבּבּ "
2116 "אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ "
2117 "אאאאאבּבּבּבּבּבּאאאאאבּבּבּבּבּבּאאאאאבּבּבּבּבּבּ "
2118 "אאאאא בּבּבּבּבּבּ";
2119 const size_t len = strlen(
text);
2132 builder.pushStyle(text_style);
2133 builder.addText(
text, len);
2136 auto paragraph = builder.Build();
2138 paragraph->paint(canvas.get(), 0, 0);
2145 for (
auto& line : impl->lines()) {
2146 if (&line == &impl->lines().back() || &line == &impl->lines()[impl->lines().size() - 2]) {
2156 for (
auto&
run : impl->runs()) {
2163 auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2167 boxes = paragraph->getRectsForRange(226, 278, rect_height_style, rect_width_style);
2176 boxes = paragraph->getRectsForRange(292, 296, rect_height_style, rect_width_style);
2189 TestCanvas canvas(
"SkParagraph_JustifyRTLNewLine.png");
2191 "אאא בּבּבּבּ אאאא\nבּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ "
2192 "אאאאא בּבּבּבּבּ אאאבּבּבּבּבּבּאאאאא בּבּבּבּבּבּאאאאאבּבּבּבּבּבּ אאאאא בּבּבּבּבּ "
2193 "אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ";
2194 const size_t len = strlen(
text);
2207 builder.pushStyle(text_style);
2208 builder.addText(
text, len);
2211 auto paragraph = builder.Build();
2213 paragraph->paint(canvas.get(), 0, 0);
2219 paint.setAntiAlias(
true);
2220 paint.setStrokeWidth(1);
2226 auto boxes = paragraph->getRectsForRange(0, 30, rect_height_style, rect_width_style);
2227 for (
size_t i = 0; i < boxes.size(); ++i) {
2228 canvas.get()->drawRect(boxes[i].rect,
paint);
2237 boxes = paragraph->getRectsForRange(240, 250, rect_height_style, rect_width_style);
2238 for (
size_t i = 0; i < boxes.size(); ++i) {
2239 canvas.get()->drawRect(boxes[i].rect,
paint);
2249 for (
auto& line : impl->lines()) {
2250 ptrdiff_t num = &line - impl->lines().data();
2251 if (num == 0 || num == 5) {
2264 TestCanvas canvas(
"SkParagraph_LeadingSpaceRTL.png");
2266 const char*
text =
" leading space";
2267 const size_t len = strlen(
text);
2280 builder.pushStyle(text_style);
2281 builder.addText(
text, len);
2284 auto paragraph = builder.Build();
2286 paragraph->paint(canvas.get(), 0, 0);
2290 paint.setAntiAlias(
true);
2291 paint.setStrokeWidth(1);
2297 auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2298 for (
size_t i = 0; i < boxes.size(); ++i) {
2299 canvas.get()->drawRect(boxes[i].rect,
paint);
2307 TestCanvas canvas(
"SkParagraph_DecorationsParagraph.png");
2308 const char* text1 =
"This text should be";
2309 const char* text2 =
" decorated even when";
2310 const char* text3 =
" wrapped around to";
2311 const char* text4 =
" the next line.";
2312 const char* text5 =
" Otherwise, bad things happen.";
2330 TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
2334 builder.pushStyle(text_style);
2335 builder.addText(text1, strlen(text1));
2340 builder.pushStyle(text_style);
2341 builder.addText(text2, strlen(text2));
2345 builder.pushStyle(text_style);
2346 builder.addText(text3, strlen(text3));
2351 builder.pushStyle(text_style);
2352 builder.addText(text4, strlen(text4));
2357 builder.pushStyle(text_style);
2358 builder.addText(text5, strlen(text5));
2361 auto paragraph = builder.Build();
2363 paragraph->paint(canvas.get(), 0, 0);
2368 for (
auto& line : impl->lines()) {
2370 StyleType::kDecorations,
2373 TextDecoration::kOverline |
2374 TextDecoration::kLineThrough);
2379 TextDecorationStyle::kSolid);
2386 TextDecorationStyle::kDouble);
2393 TextDecorationStyle::kDotted);
2401 TextDecorationStyle::kDashed);
2408 TextDecorationStyle::kWavy);
2428 TestCanvas canvas(
"SkParagraph_ItalicsParagraph.png");
2429 const char* text1 =
"No italic ";
2430 const char* text2 =
"Yes Italic ";
2431 const char* text3 =
"No Italic again.";
2441 builder.pushStyle(text_style);
2442 builder.addText(text1, strlen(text1));
2446 builder.pushStyle(text_style);
2447 builder.addText(text2, strlen(text2));
2449 builder.addText(text3, strlen(text3));
2451 auto paragraph = builder.Build();
2453 paragraph->paint(canvas.get(), 0, 0);
2460 auto& line = impl->lines()[0];
2463 StyleType::kForeground,
2492 TestCanvas canvas(
"SkParagraph_ChineseParagraph.png");
2494 " 左線読設重説切後碁給能上目秘使約。満毎冠行来昼本可必図将発確年。今属場育"
2495 "図情闘陰野高備込制詩西校客。審対江置講今固残必託地集済決維駆年策。立得庭"
2496 "際輝求佐抗蒼提夜合逃表。注統天言件自謙雅載報紙喪。作画稿愛器灯女書利変探"
2497 "訃第金線朝開化建。子戦年帝励害表月幕株漠新期刊人秘。図的海力生禁挙保天戦"
2499 const size_t len = strlen(
text);
2507 auto decoration = (
TextDecoration)(TextDecoration::kUnderline | TextDecoration::kOverline |
2508 TextDecoration::kLineThrough);
2519 builder.pushStyle(text_style);
2520 builder.addText(
text, len);
2523 auto paragraph = builder.Build();
2525 paragraph->paint(canvas.get(), 0, 0);
2541 TestCanvas canvas(
"SkParagraph_ArabicParagraph.png");
2543 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
2544 "بمباركة التقليدية قام عن. تصفح";
2545 const size_t len = strlen(
text);
2553 auto decoration = (
TextDecoration)(TextDecoration::kUnderline | TextDecoration::kOverline |
2554 TextDecoration::kLineThrough);
2564 builder.pushStyle(text_style);
2565 builder.addText(
text, len);
2568 auto paragraph = builder.Build();
2570 paragraph->paint(canvas.get(), 0, 0);
2587 TestCanvas canvas(
"SkParagraph_ArabicRectsParagraph.png");
2588 const char*
text =
"بمباركة التقليدية قام عن. تصفح يد ";
2589 const size_t len = strlen(
text);
2605 builder.pushStyle(text_style);
2606 builder.addText(
text, len);
2609 auto paragraph = builder.Build();
2615 paragraph->paint(canvas.get(), 0, 0);
2619 std::vector<TextBox> boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2638 TestCanvas canvas(
"SkParagraph_ArabicRectsLTRLeftAlignParagraph.png");
2639 const char*
text =
"Helloبمباركة التقليدية قام عن. تصفح يد ";
2640 const size_t len = strlen(
text);
2656 builder.pushStyle(text_style);
2657 builder.addText(
text, len);
2660 auto paragraph = builder.Build();
2666 paragraph->paint(canvas.get(), 0, 0);
2671 std::vector<TextBox> boxes = paragraph->getRectsForRange(36, 40, rect_height_style, rect_width_style);
2686 TestCanvas canvas(
"SkParagraph_ArabicRectsLTRRightAlignParagraph.png");
2687 const char*
text =
"Helloبمباركة التقليدية قام عن. تصفح يد ";
2688 const size_t len = strlen(
text);
2704 builder.pushStyle(text_style);
2705 builder.addText(
text, len);
2708 auto paragraph = builder.Build();
2714 paragraph->paint(canvas.get(), 0, 0);
2718 std::vector<TextBox> boxes =
2719 paragraph->getRectsForRange(36, 40, rect_height_style, rect_width_style);
2732 TestCanvas canvas(
"SkParagraph_GetGlyphPositionAtCoordinateParagraph.png");
2734 "12345 67890 12345 67890 12345 67890 12345 67890 12345 67890 12345 "
2736 const size_t len = strlen(
text);
2753 builder.pushStyle(textStyle);
2754 builder.addText(
text, len);
2757 auto paragraph = builder.Build();
2758 paragraph->layout(550);
2759 paragraph->paint(canvas.get(), 0, 0);
2767 paragraph->getGlyphPositionAtCoordinate(-10000, -10000).position == 0);
2773 paragraph->getGlyphPositionAtCoordinate(300, 2).position == 11);
2782 paragraph->getGlyphPositionAtCoordinate(20, -80).position == 1);
2796 TestCanvas canvas(
"SkParagraph_GetRectsForRangeParagraph.png");
2798 "12345, \"67890\" 12345 67890 12345 67890 12345 67890 12345 67890 12345 "
2800 const size_t len = strlen(
text);
2814 builder.pushStyle(textStyle);
2815 builder.addText(
text, len);
2818 auto paragraph = builder.Build();
2819 paragraph->layout(550);
2820 paragraph->paint(canvas.get(), 0, 0);
2827 paint.setAntiAlias(
true);
2828 paint.setStrokeWidth(1);
2831 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
2835 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
2844 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
2853 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
2862 auto result = paragraph->getRectsForRange(30, 100, heightStyle, widthStyle);
2875 auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
2884 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
2892 TestCanvas canvas(
"SkParagraph_GetRectsForRangeTight.png");
2894 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
2895 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
2896 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
2897 const size_t len = strlen(
text);
2917 builder.pushStyle(textStyle);
2918 builder.addText(
text, len);
2921 auto paragraph = builder.Build();
2922 paragraph->layout(550);
2923 paragraph->paint(canvas.get(), 0, 0);
2928 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
2932 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
2941 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
2950 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
2964 TestCanvas canvas(
"SkParagraph_GetRectsForRangeIncludeLineSpacingMiddle.png");
2966 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
2967 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
2968 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
2969 const size_t len = strlen(
text);
2985 builder.pushStyle(textStyle);
2986 builder.addText(
text, len);
2989 auto paragraph = builder.Build();
2990 paragraph->layout(550);
2991 paragraph->paint(canvas.get(), 0, 0);
2993 RectHeightStyle heightStyle = RectHeightStyle::kIncludeLineSpacingMiddle;
2996 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3001 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3010 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3019 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3028 auto result = paragraph->getRectsForRange(30, 150, heightStyle, widthStyle);
3063 auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
3077 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3086 TestCanvas canvas(
"SkParagraph_GetRectsForRangeIncludeLineSpacingTop.png");
3088 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3089 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3090 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
3091 const size_t len = strlen(
text);
3107 builder.pushStyle(textStyle);
3108 builder.addText(
text, len);
3111 auto paragraph = builder.Build();
3112 paragraph->layout(550);
3113 paragraph->paint(canvas.get(), 0, 0);
3115 RectHeightStyle heightStyle = RectHeightStyle::kIncludeLineSpacingTop;
3118 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3123 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3132 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3141 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3150 auto result = paragraph->getRectsForRange(30, 150, heightStyle, widthStyle);
3185 auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
3199 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3208 TestCanvas canvas(
"SkParagraph_GetRectsForRangeIncludeLineSpacingBottom.png");
3210 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3211 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3212 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
3213 const size_t len = strlen(
text);
3229 builder.pushStyle(textStyle);
3230 builder.addText(
text, len);
3233 auto paragraph = builder.Build();
3234 paragraph->layout(550);
3235 paragraph->paint(canvas.get(), 0, 0);
3237 RectHeightStyle heightStyle = RectHeightStyle::kIncludeLineSpacingBottom;
3240 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3245 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3254 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3263 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3272 auto result = paragraph->getRectsForRange(30, 150, heightStyle, widthStyle);
3307 auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
3321 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3331 TestCanvas canvas(
"SkParagraph_GetRectsForRangeIncludeCombiningCharacter.png");
3332 const char*
text =
"ดีสวัสดีชาวโลกที่น่ารัก";
3333 const size_t len = strlen(
text);
3349 builder.pushStyle(textStyle);
3350 builder.addText(
text, len);
3353 auto paragraph = builder.Build();
3355 paragraph->paint(canvas.get(), 0, 0);
3363 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3367 auto first = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3368 auto second = paragraph->getRectsForRange(1, 2, heightStyle, widthStyle);
3369 auto last = paragraph->getRectsForRange(0, 2, heightStyle, widthStyle);
3374 auto first = paragraph->getRectsForRange(3, 4, heightStyle, widthStyle);
3375 auto second = paragraph->getRectsForRange(4, 5, heightStyle, widthStyle);
3376 auto last = paragraph->getRectsForRange(3, 5, heightStyle, widthStyle);
3381 auto first = paragraph->getRectsForRange(14, 15, heightStyle, widthStyle);
3382 auto second = paragraph->getRectsForRange(15, 16, heightStyle, widthStyle);
3383 auto third = paragraph->getRectsForRange(16, 17, heightStyle, widthStyle);
3384 auto last = paragraph->getRectsForRange(14, 17, heightStyle, widthStyle);
3394 TestCanvas canvas(
"SkParagraph_GetRectsForRangeCenterParagraph.png");
3399 const char*
text =
"01234 ";
3400 const size_t len = strlen(
text);
3416 builder.pushStyle(textStyle);
3417 builder.addText(
text, len);
3420 auto paragraph = builder.Build();
3421 paragraph->layout(550);
3422 paragraph->paint(canvas.get(), 0, 0);
3428 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3433 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3443 auto result = paragraph->getRectsForRange(2, 4, heightStyle, widthStyle);
3453 auto result = paragraph->getRectsForRange(4, 5, heightStyle, widthStyle);
3463 auto result = paragraph->getRectsForRange(4, 6, heightStyle, widthStyle);
3473 auto result = paragraph->getRectsForRange(5, 6, heightStyle, widthStyle);
3483 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3492 TestCanvas canvas(
"SkParagraph_GetRectsForRangeCenterParagraphNewlineCentered.png");
3493 const char*
text =
"01234\n";
3494 const size_t len = strlen(
text);
3510 builder.pushStyle(textStyle);
3511 builder.addText(
text, len);
3514 auto paragraph = builder.Build();
3515 paragraph->layout(550);
3517 paragraph->paint(canvas.get(), 0, 0);
3525 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3530 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3540 auto result = paragraph->getRectsForRange(6, 7, heightStyle, widthStyle);
3554 TestCanvas canvas(
"SkParagraph_GetRectsForRangeCenterMultiLineParagraph.png");
3555 const char*
text =
"01234 \n0123 ";
3556 const size_t len = strlen(
text);
3572 builder.pushStyle(textStyle);
3573 builder.addText(
text, len);
3576 auto paragraph = builder.Build();
3577 paragraph->layout(550);
3579 paragraph->paint(canvas.get(), 0, 0);
3589 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3593 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3602 auto result = paragraph->getRectsForRange(2, 4, heightStyle, widthStyle);
3611 auto result = paragraph->getRectsForRange(4, 6, heightStyle, widthStyle);
3620 auto result = paragraph->getRectsForRange(5, 6, heightStyle, widthStyle);
3629 auto result = paragraph->getRectsForRange(10, 12, heightStyle, widthStyle);
3638 auto result = paragraph->getRectsForRange(14, 18, heightStyle, widthStyle);
3647 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3656 TestCanvas canvas(
"SkParagraph_GetRectsForRangeStrut.png");
3657 const char*
text =
"Chinese 字典";
3658 const size_t len = strlen(
text);
3674 builder.pushStyle(textStyle);
3675 builder.addText(
text, len);
3678 auto paragraph = builder.Build();
3679 paragraph->layout(550);
3680 paragraph->paint(canvas.get(), 0, 0);
3683 auto result = paragraph->getRectsForRange(0, 10, RectHeightStyle::kTight, RectWidthStyle::kMax);
3689 auto result = paragraph->getRectsForRange(0, 10, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3702 const char*
text =
"A";
3703 const size_t len = strlen(
text);
3722 builder.pushStyle(textStyle);
3723 builder.addText(
text, len);
3726 auto paragraph = builder.Build();
3727 paragraph->layout(550);
3729 auto result = paragraph->getRectsForRange(0, 1, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3740 const char*
text =
"A";
3741 const size_t len = strlen(
text);
3761 builder.pushStyle(textStyle);
3762 builder.addText(
text, len);
3765 auto paragraph = builder.Build();
3766 paragraph->layout(550);
3769 auto result = paragraph->getRectsForRange(0, 1, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3780 TestCanvas canvas(
"SkParagraph_GetRectsForRangeStrutFallback.png");
3781 const char*
text =
"Chinese 字典";
3782 const size_t len = strlen(
text);
3796 builder.pushStyle(textStyle);
3797 builder.addText(
text, len);
3800 auto paragraph = builder.Build();
3801 paragraph->layout(550);
3802 paragraph->paint(canvas.get(), 0, 0);
3805 auto result1 = paragraph->getRectsForRange(0, 10, RectHeightStyle::kTight, RectWidthStyle::kMax);
3809 auto result2 = paragraph->getRectsForRange(0, 10, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3820 TestCanvas canvas(
"SkParagraph_GetWordBoundaryParagraph.png");
3821 const char*
text =
"12345 67890 12345 67890 12345 67890 12345 "
3822 "67890 12345 67890 12345 67890 12345";
3823 const size_t len = strlen(
text);
3838 builder.pushStyle(textStyle);
3839 builder.addText(
text, len);
3842 auto paragraph = builder.Build();
3843 paragraph->layout(550);
3844 paragraph->paint(canvas.get(), 0, 0);
3851 auto boxes = paragraph->getRectsForRange(5, 6, RectHeightStyle::kMax, RectWidthStyle::kTight);
3855 boxes = paragraph->getRectsForRange(6, 7, RectHeightStyle::kMax, RectWidthStyle::kTight);
3859 boxes = paragraph->getRectsForRange(7, 8, RectHeightStyle::kMax, RectWidthStyle::kTight);
3871 boxes = paragraph->getRectsForRange(12, 13, RectHeightStyle::kMax, RectWidthStyle::kTight);
3873 boxes = paragraph->getRectsForRange(13, 14, RectHeightStyle::kMax, RectWidthStyle::kTight);
3875 boxes = paragraph->getRectsForRange(18, 19, RectHeightStyle::kMax, RectWidthStyle::kTight);
3877 boxes = paragraph->getRectsForRange(19, 20, RectHeightStyle::kMax, RectWidthStyle::kTight);
3879 boxes = paragraph->getRectsForRange(24, 25, RectHeightStyle::kMax, RectWidthStyle::kTight);
3881 boxes = paragraph->getRectsForRange(25, 26, RectHeightStyle::kMax, RectWidthStyle::kTight);
3883 boxes = paragraph->getRectsForRange(30, 31, RectHeightStyle::kMax, RectWidthStyle::kTight);
3885 boxes = paragraph->getRectsForRange(31, 32, RectHeightStyle::kMax, RectWidthStyle::kTight);
3896 TestCanvas canvas(
"SkParagraph_SpacingParagraph.png");
3909 builder.pushStyle(text_style);
3910 builder.addText(
"H", 1);
3915 builder.pushStyle(text_style);
3916 builder.addText(
"H", 1);
3921 builder.pushStyle(text_style);
3922 builder.addText(
"H", 1);
3927 builder.pushStyle(text_style);
3928 builder.addText(
"|", 1);
3931 const char* hSpace =
"H ";
3932 const size_t len = strlen(hSpace);
3936 builder.pushStyle(text_style);
3937 builder.addText(hSpace, len);
3942 builder.pushStyle(text_style);
3943 builder.addText(hSpace, len);
3949 builder.pushStyle(text_style);
3950 builder.addText(hSpace, len);
3953 auto paragraph = builder.Build();
3954 paragraph->layout(550);
3955 paragraph->paint(canvas.get(), 0, 0);
3960 impl->lines().begin()->scanStyles(StyleType::kLetterSpacing,
3967 impl->lines().begin()->scanStyles(StyleType::kWordSpacing,
3979 TestCanvas canvas(
"SkParagraph_LongWordParagraph.png");
3982 "veryverylongwordtoseewherethiswillwraporifitwillatallandifitdoesthenthat"
3983 "wouldbeagoodthingbecausethebreakingisworking.";
3984 const size_t len = strlen(
text);
3998 builder.pushStyle(text_style);
3999 builder.addText(
text, len);
4002 auto paragraph = builder.Build();
4004 paragraph->paint(canvas.get(), 0, 0);
4022 TestCanvas canvas(
"SkParagraph_KernScaleParagraph.png");
4024 const char* text1 =
"AVAVAWAH A0 V0 VA To The Lo";
4025 const char* text2 =
" Dialog Text List lots of words to see "
4026 "if kerning works on a bigger set of characters AVAVAW";
4035 builder.pushStyle(text_style);
4036 builder.addText(text1, strlen(text1));
4037 builder.pushStyle(text_style);
4038 builder.addText(
"A", 1);
4039 builder.pushStyle(text_style);
4040 builder.addText(
"V", 1);
4042 builder.pushStyle(text_style);
4043 builder.addText(text2, strlen(text2));
4046 auto paragraph = builder.Build();
4049 paragraph->paint(canvas.get(), 0, 0);
4050 canvas.get()->scale(1, 1);
4068 TestCanvas canvas(
"SkParagraph_NewlineParagraph.png");
4070 "line1\nline2 test1 test2 test3 test4 test5 test6 test7\nline3\n\nline4 "
4071 "test1 test2 test3 test4";
4072 const size_t len = strlen(
text);
4084 builder.pushStyle(text_style);
4085 builder.addText(
text, len);
4088 auto paragraph = builder.Build();
4090 paragraph->paint(canvas.get(), 0, 0);
4109 TestCanvas canvas(
"SkParagraph_EmojiParagraph.png");
4111 "😀😃😄😁😆😅😂🤣☺😇🙂😍😡😟😢😻👽💩👍👎🙏👌👋👄👁👦👼👨🚀👨🚒🙋♂️👳👨👨👧👧\
4112 💼👡👠☂🐶🐰🐻🐼🐷🐒🐵🐔🐧🐦🐋🐟🐡🕸🐌🐴🐊🐄🐪🐘🌸🌏🔥🌟🌚🌝💦💧\
4113 ❄🍕🍔🍟🥝🍱🕶🎩🏈⚽🚴♀️🎻🎼🎹🚨🚎🚐⚓🛳🚀🚁🏪🏢🖱⏰📱💾💉📉🛏🔑🔓\
4114 📁🗓📊❤💯🚫🔻♠♣🕓❗🏳🏁🏳️🌈🇮🇹🇱🇷🇺🇸🇬🇧🇨🇳🇧🇴";
4115 const size_t len = strlen(
text);
4126 builder.pushStyle(text_style);
4127 builder.addText(
text, len);
4130 auto paragraph = builder.Build();
4132 paragraph->paint(canvas.get(), 0, 0);
4139 for (
auto& line : impl->lines()) {
4140 if (&line != impl->lines().end() - 1) {
4153 TestCanvas canvas(
"SkParagraph_EmojiMultiLineRectsParagraph.png");
4155 "👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧i🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸"
4156 "👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸"
4157 "👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸"
4158 "👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸"
4159 "❄🍕🍔🍟🥝🍱🕶🎩🏈⚽🚴♀️🎻🎼🎹🚨🚎🚐⚓🛳🚀🚁🏪🏢🖱⏰📱💾💉📉🛏🔑🔓"
4160 "📁🗓📊❤💯🚫🔻♠♣🕓❗🏳🏁🏳️🌈🇮🇹🇱🇷🇺🇸🇬🇧🇨🇳🇧🇴";
4161 const size_t len = strlen(
text);
4171 builder.pushStyle(text_style);
4172 builder.addText(
text, len);
4175 auto paragraph = builder.Build();
4177 paragraph->paint(canvas.get(), 0, 0);
4182 auto result = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4185 result = paragraph->getRectsForRange(0, 119, rect_height_style, rect_width_style);
4189 result = paragraph->getRectsForRange(122, 132, rect_height_style, rect_width_style);
4194 auto pos = paragraph->getGlyphPositionAtCoordinate(610, 100).position;
4195 result = paragraph->getRectsForRange(0,
pos, rect_height_style, rect_width_style);
4199 pos = paragraph->getGlyphPositionAtCoordinate(580, 100).position;
4200 result = paragraph->getRectsForRange(0,
pos, rect_height_style, rect_width_style);
4204 pos = paragraph->getGlyphPositionAtCoordinate(560, 100).position;
4205 result = paragraph->getRectsForRange(0,
pos, rect_height_style, rect_width_style);
4214 TestCanvas canvas(
"SkParagraph_RepeatLayoutParagraph.png");
4216 "Sentence to layout at diff widths to get diff line counts. short words "
4217 "short words short words short words short words short words short words "
4218 "short words short words short words short words short words short words "
4220 const size_t len = strlen(
text);
4230 builder.pushStyle(text_style);
4231 builder.addText(
text, len);
4234 auto paragraph = builder.Build();
4235 paragraph->layout(300);
4243 paragraph->layout(600);
4244 paragraph->paint(canvas.get(), 0, 0);
4254 TestCanvas canvas(
"SkParagraph_Ellipsize.png");
4256 "This is a very long sentence to test if the text will properly wrap "
4257 "around and go to the next line. Sometimes, short sentence. Longer "
4258 "sentences are okay too because they are nessecary. Very short. ";
4259 const size_t len = strlen(
text);
4263 std::u16string ellipsis = u
"\u2026";
4272 builder.pushStyle(text_style);
4273 builder.addText(
text, len);
4276 auto paragraph = builder.Build();
4278 paragraph->paint(canvas.get(), 0, 0);
4285 auto& line = impl->lines()[0];
4294 TestCanvas canvas(
"SkParagraph_UnderlineShiftParagraph.png");
4295 const char* text1 =
"fluttser ";
4296 const char* text2 =
"mdje";
4297 const char* text3 =
"fluttser mdje";
4308 builder.pushStyle(text_style);
4309 builder.addText(text1, strlen(text1));
4312 builder.pushStyle(text_style);
4313 builder.addText(text2, strlen(text2));
4316 auto paragraph = builder.Build();
4318 paragraph->paint(canvas.get(), 0, 0);
4325 builder1.
addText(text3, strlen(text3));
4328 auto paragraph1 = builder1.
Build();
4330 paragraph1->paint(canvas.get(), 0, 25);
4337 auto rect = paragraph->getRectsForRange(0, 12, RectHeightStyle::kMax, RectWidthStyle::kTight)
4340 auto rect1 = paragraph1->getRectsForRange(0, 12, RectHeightStyle::kMax, RectWidthStyle::kTight)
4346 for (
size_t i = 0; i < 12; ++i) {
4348 auto r1 = paragraph->getRectsForRange(i, i + 1, RectHeightStyle::kMax, RectWidthStyle::kTight);
4349 auto r2 = paragraph1->getRectsForRange(i, i + 1, RectHeightStyle::kMax, RectWidthStyle::kTight);
4352 if (!r1.empty() && !r2.empty()) {
4363 TestCanvas canvas(
"SkParagraph_SimpleShadow.png");
4364 const char*
text =
"Hello World Text Dialog";
4365 const size_t len = strlen(
text);
4375 builder.pushStyle(text_style);
4376 builder.addText(
text, len);
4378 auto paragraph = builder.Build();
4380 paragraph->paint(canvas.get(), 10.0, 15.0);
4387 for (
auto& line : impl->lines()) {
4388 line.scanStyles(StyleType::kShadow,
4401 TestCanvas canvas(
"SkParagraph_ComplexShadow.png");
4402 const char*
text =
"Text Chunk ";
4403 const size_t len = strlen(
text);
4413 builder.pushStyle(text_style);
4414 builder.addText(
text, len);
4418 builder.pushStyle(text_style);
4419 builder.addText(
text, len);
4422 builder.addText(
text, len);
4425 builder.pushStyle(text_style);
4426 builder.addText(
text, len);
4429 builder.addText(
text, len);
4431 auto paragraph = builder.Build();
4433 paragraph->paint(canvas.get(), 10.0, 15.0);
4438 for (
auto& line : impl->lines()) {
4439 line.scanStyles(StyleType::kShadow,
4471 TestCanvas canvas(
"SkParagraph_BaselineParagraph.png");
4473 "左線読設Byg後碁給能上目秘使約。満毎冠行来昼本可必図将発確年。今属場育"
4474 "図情闘陰野高備込制詩西校客。審対江置講今固残必託地集済決維駆年策。立得";
4475 const size_t len = strlen(
text);
4491 builder.pushStyle(text_style);
4492 builder.addText(
text, len);
4495 auto paragraph = builder.Build();
4497 paragraph->paint(canvas.get(), 0, 0);
4500 paragraph->getMaxWidth(),
4501 paragraph->getIdeographicBaseline());
4503 paragraph->getMaxWidth(),
4504 paragraph->getAlphabeticBaseline());
4518 TestCanvas canvas(
"SkParagraph_FontFallbackParagraph.png");
4520 const char* text1 =
"Roboto 字典 ";
4521 const char* text2 =
"Homemade Apple 字典";
4522 const char* text3 =
"Chinese 字典";
4533 SkString(
"Next one should be a real font..."),
4535 SkString(
"another fake one in between"),
4539 builder.pushStyle(text_style);
4540 builder.addText(text1, strlen(text1));
4547 SkString(
"Next one should be a real font..."),
4549 SkString(
"another fake one in between"),
4553 builder.pushStyle(text_style);
4554 builder.addText(text2, strlen(text2));
4561 SkString(
"Next one should be a real font..."),
4563 SkString(
"another fake one in between"),
4567 builder.pushStyle(text_style);
4568 builder.addText(text3, strlen(text3));
4572 auto paragraph = builder.Build();
4575 paragraph->paint(canvas.get(), 10.0, 15.0);
4577 size_t spaceRun = 1;
4589 auto robotoAdvance = impl->runs()[0].advance().fX +
4590 impl->runs()[1].advance().fX;
4591 robotoAdvance += impl->runs()[2].advance().fX;
4600 REPORTER_ASSERT(
reporter, impl->runs()[3 + spaceRun].correctAscent() != impl->runs()[5 + spaceRun].correctAscent());
4601 REPORTER_ASSERT(
reporter, impl->runs()[3 + spaceRun].correctDescent() != impl->runs()[5 + spaceRun].correctDescent());
4608 TestCanvas canvas(
"SkParagraph_StrutParagraph1.png");
4610 const char*
text =
"01234満毎冠p来É本可\nabcd\n満毎É行p昼本可";
4611 const size_t len = strlen(
text);
4635 builder.pushStyle(text_style);
4636 builder.addText(
text, len);
4639 auto paragraph = builder.Build();
4640 paragraph->layout(550);
4641 paragraph->paint(canvas.get(), 0, 0);
4650 auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4654 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
4663 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
4672 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
4681 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
4690 auto boxes = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
4699 auto boxes = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
4713 TestCanvas canvas(
"SkParagraph_StrutParagraph2.png");
4715 const char*
text =
"01234ABCDEFGH\nabcd\nABCDEFGH";
4716 const size_t len = strlen(
text);
4741 builder.pushStyle(text_style);
4742 builder.addText(
text, len);
4745 auto paragraph = builder.Build();
4746 paragraph->layout(550);
4747 paragraph->paint(canvas.get(), 0, 0);
4757 auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4761 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
4770 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
4779 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
4788 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
4797 auto boxes = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
4806 auto boxes = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
4820 TestCanvas canvas(
"SkParagraph_StrutParagraph3.png");
4823 const char*
text =
"01234満毎p行来昼本可\nabcd\n満毎冠行来昼本可";
4824 const size_t len = strlen(
text);
4848 builder.pushStyle(text_style);
4849 builder.addText(
text, len);
4852 auto paragraph = builder.Build();
4853 paragraph->layout(550);
4854 paragraph->paint(canvas.get(), 0, 0);
4865 auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4869 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
4878 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
4887 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
4896 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
4905 auto boxes = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
4914 auto boxes = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
4928 TestCanvas canvas(
"SkParagraph_StrutForceParagraph.png");
4929 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
4930 const size_t len = strlen(
text);
4955 builder.pushStyle(text_style);
4956 builder.addText(
text, len);
4959 auto paragraph = builder.Build();
4960 paragraph->layout(550);
4961 paragraph->paint(canvas.get(), 0, 0);
4971 auto boxes1 = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4974 auto boxes2 = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
4982 auto boxes3 = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
4990 auto boxes4 = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
4998 auto boxes5 = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
5006 auto boxes6 = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
5014 auto boxes7 = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
5027 TestCanvas canvas(
"SkParagraph_StrutDefaultParagraph.png");
5029 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
5030 const size_t len = strlen(
text);
5052 builder.pushStyle(text_style);
5053 builder.addText(
text, len);
5056 auto paragraph = builder.Build();
5057 paragraph->layout(550);
5058 paragraph->paint(canvas.get(), 0, 0);
5064 auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
5068 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
5077 auto boxes = paragraph->getRectsForRange(0, 2, rect_height_strut_style, rect_width_style);
5091 TestCanvas canvas(
"SkParagraph_FontFeaturesParagraph.png");
5093 const char*
text =
"12ab\n";
5105 builder.pushStyle(text_style);
5106 builder.addText(
text);
5111 builder.pushStyle(text_style);
5112 builder.addText(
text);
5117 auto paragraph = builder.Build();
5120 paragraph->paint(canvas.get(), 10.0, 15.0);
5125 auto& tnum_line = impl->lines()[0];
5126 auto& pnum_line = impl->lines()[1];
5142 const char*
text =
"English English 字典 字典 😀😃😄 😀😃😄";
5143 const size_t len = strlen(
text);
5153 builder.pushStyle(text_style);
5154 builder.addText(
text, len);
5157 auto paragraph = builder.Build();
5163 for (
size_t i = 0; i < impl->runs().size() - 1; ++i) {
5164 auto first = impl->
runs()[i].textRange();
5165 auto next = impl->runs()[i + 1].textRange();
5174 const char*
text =
"👨👩👧👦";
5175 const size_t len = strlen(
text);
5183 builder.pushStyle(text_style);
5184 builder.addText(
text, len);
5187 auto paragraph = builder.Build();
5192 auto&
run = impl->runs().front();
5199 std::string toCheckUtf8{utf1to1.data(), utf1to1.size()};
5200 SkASSERT(std::strcmp(text, utf1to1.data()) == 0);
5201 SkASSERT(glyph1to1.size() == 1);
5202 SkASSERT(*glyph1to1.begin() == 1611);
5213 const char*
text =
"p〠q";
5214 const size_t len = strlen(
text);
5224 builder.pushStyle(text_style);
5225 builder.addText(
text, len);
5228 auto paragraph = builder.Build();
5235 for (
auto&
run : impl->runs()) {
5237 impl->text().begin() +
run.textRange().start, 0,
run.textRange().width(),
5238 run.glyphs(),
run.clusterIndexes(),
5242 std::string toCheckUtf8{utf1to1.data(), utf1to1.size()};
5243 SkASSERT(std::strcmp(text, utf1to1.data()) == 0);
5244 SkASSERT(glyph1to1.size() == 3);
5266 auto test = [&](
const char*
text,
int count,
bool expectedToBeFound) {
5268 builder.pushStyle(text_style);
5269 builder.addText(
text, strlen(
text));
5271 auto paragraph = builder.Build();
5275 auto found = cache.findParagraph(impl);
5277 auto added = cache.updateParagraph(impl);
5281 test(
"text1", 0,
false);
5282 test(
"text1", 1,
true);
5283 test(
"text2", 1,
false);
5284 test(
"text2", 2,
true);
5285 test(
"text3", 2,
false);
5300 const char*
text =
"text";
5301 const size_t len = strlen(
text);
5303 auto test = [&](
int count,
bool expectedToBeFound) {
5305 builder.pushStyle(text_style);
5306 builder.addText(
text, len);
5308 auto paragraph = builder.Build();
5312 auto found = cache.findParagraph(impl);
5314 auto added = cache.updateParagraph(impl);
5341 auto test = [&](
const char* text1,
5346 bool expectedToBeFound) {
5349 builder.pushStyle(text_style);
5350 builder.addText(text1, strlen(text1));
5353 builder.pushStyle(text_style);
5354 builder.addText(text2, strlen(text2));
5356 auto paragraph = builder.Build();
5360 auto found = cache.findParagraph(impl);
5362 auto added = cache.updateParagraph(impl);
5366 test(
"text",
"",
"Roboto",
"Homemade Apple", 0,
false);
5367 test(
"t",
"ext",
"Roboto",
"Homemade Apple", 1,
false);
5368 test(
"te",
"xt",
"Roboto",
"Homemade Apple", 2,
false);
5369 test(
"tex",
"t",
"Roboto",
"Homemade Apple", 3,
false);
5370 test(
"text",
"",
"Roboto",
"Homemade Apple", 4,
true);
5386 const char*
text =
"text";
5387 const size_t len = strlen(
text);
5389 auto test = [&](
int count,
bool expectedToBeFound) {
5391 builder.pushStyle(text_style);
5392 builder.addText(
text, len);
5394 auto paragraph = builder.Build();
5398 auto found = cache.findParagraph(impl);
5400 auto added = cache.updateParagraph(impl);
5417 fontCollection->enableFontFallback();
5419 TestCanvas canvas(
"SkParagraph_ParagraphWithLineBreak.png");
5427 builder.addText(
"abc\n\ndef");
5430 auto paragraph = builder.Build();
5432 paragraph->paint(canvas.get(), 0, 0);
5435 auto pos = paragraph->getGlyphPositionAtCoordinate(0, 21);
5437 auto rect = paragraph->getRectsForRange(4, 5, RectHeightStyle::kTight, RectWidthStyle::kTight);
5447 const SkString text(
"null terminator ->\u0000<- on purpose did you see it?");
5455 builder.addText(
text.c_str(),
text.size());
5457 auto paragraph = builder.Build();
5473 PlaceholderStyle placeholder(0, 0, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 0);
5474 builder.addPlaceholder(placeholder);
5476 auto paragraph = builder.Build();
5478 auto result = paragraph->getRectsForPlaceholders();
5486 fontCollection->enableFontFallback();
5487 TestCanvas canvas(
"SkParagraph_Fallbacks.png");
5489 const char* multiScript =
"A1!aÀàĀāƁƀḂⱠꜲꬰəͲἀἏЀЖԠꙐꙮՁخࡔࠇܦআਉઐଘஇఘಧൺඣᭆᯔᮯ᳇ꠈᜅᩌꪈ༇ꥄꡙꫤ᧰៘꧁꧂ᜰᨏᯤᢆᣭᗗꗃⵞ𐒎߷ጩꬤ𖠺‡₩℻Ⅷ↹⋇⏳ⓖ╋▒◛⚧⑆שׁ🅕㊼龜ポ䷤🂡\n";
5490 const size_t len = strlen(multiScript);
5492 const char* androidFonts[] = {
5494 "sans-serif-condensed",
5500 "sans-serif-smallcaps",
5503 for (
auto& font : androidFonts) {
5514 builder.pushStyle(text_style);
5515 builder.addText(multiScript, len);
5519 auto paragraph = builder.Build();
5521 paragraph->paint(canvas.get(), 0, 0);
5522 canvas.get()->translate(0, paragraph->getHeight() + 10);
5530 fontCollection->enableFontFallback();
5531 TestCanvas canvas(
"SkParagraph_Bidi1.png");
5533 std::u16string abc = u
"\u202Dabc";
5534 std::u16string
DEF = u
"\u202EDEF";
5535 std::u16string ghi = u
"\u202Dghi";
5536 std::u16string JKL = u
"\u202EJKL";
5537 std::u16string mno = u
"\u202Dmno";
5539 std::u16string abcDEFghiJKLmno = u
"\u202Dabc\u202EDEF\u202Dghi\u202EJKL\u202Dmno";
5550 builder.pushStyle(text_style);
5551 builder.addText(abc);
5555 builder.pushStyle(text_style);
5556 builder.addText(
DEF);
5560 builder.pushStyle(text_style);
5561 builder.addText(ghi);
5565 builder.pushStyle(text_style);
5566 builder.addText(JKL);
5570 builder.pushStyle(text_style);
5571 builder.addText(mno);
5573 auto paragraph = builder.Build();
5574 paragraph->layout(400);
5575 paragraph->paint(canvas.get(), 0, 0);
5582 fontCollection->enableFontFallback();
5583 TestCanvas canvas(
"SkParagraph_Bidi2.png");
5585 std::u16string abcD = u
"\u202Dabc\u202ED";
5586 std::u16string EFgh = u
"EF\u202Dgh";
5587 std::u16string iJKLmno = u
"i\u202EJKL\u202Dmno";
5589 std::u16string abcDEFghiJKLmno = u
"\u202Dabc\u202EDEF\u202Dghi\u202EJKL\u202Dmno";
5598 builder.pushStyle(text_style);
5599 builder.addText(abcD);
5600 builder.pushStyle(text_style);
5601 builder.addText(EFgh);
5602 builder.pushStyle(text_style);
5603 builder.addText(iJKLmno);
5604 auto paragraph = builder.Build();
5605 paragraph->layout(360);
5606 paragraph->paint(canvas.get(), 0, 0);
5608 canvas.get()->translate(0, 400);
5611 builder.pushStyle(text_style);
5612 builder.addText(abcDEFghiJKLmno);
5613 auto paragraph = builder.Build();
5614 paragraph->layout(360);
5615 paragraph->paint(canvas.get(), 0, 0);
5634 builder.addText(
"\n");
5635 auto paragraph = builder.Build();
5636 paragraph->layout(1000);
5641 TestCanvas canvas(
"SkParagraph_FontResolutions.png");
5644 sk_make_sp<TestFontCollection>(
GetResourcePath(
"fonts").c_str(),
false);
5647 if (!fontCollection->addFontFromFile(
"abc/abc.ttf",
"abc")) {
5651 if (!fontCollection->addFontFromFile(
"abc/abc+grave.ttf",
"abc+grave")) {
5655 if (!fontCollection->addFontFromFile(
"abc/abc+agrave.ttf",
"abc+agrave")) {
5669 builder.pushStyle(text_style);
5670 builder.addText(u
"a\u0300");
5672 builder.pushStyle(text_style);
5673 builder.addText(u
"à");
5678 builder.pushStyle(text_style);
5679 builder.addText(u
"a\u0300");
5681 builder.pushStyle(text_style);
5682 builder.addText(u
"à");
5684 auto paragraph = builder.Build();
5697 paragraph->paint(canvas.get(), 100, 100);
5701 TestCanvas canvas(
"SkParagraph_FontStyle.png");
5728 builder.addText(
"Default text\n");
5729 builder.pushStyle(boldItalic);
5730 builder.addText(
"Bold and Italic\n");
5732 builder.addText(
"back to normal");
5733 auto paragraph = builder.Build();
5734 paragraph->layout(250);
5735 paragraph->paint(canvas.get(), 0, 0);
5739 TestCanvas canvas(
"SkParagraph_Shaping.png");
5742 sk_make_sp<TestFontCollection>(
GetResourcePath(
"fonts").c_str(),
true);
5757 builder.pushStyle(text_style);
5758 builder.addText(
"Eat0 apple0 pies0 | Eat1 apple1 pies1 | Eat2 apple2 pies2");
5759 auto paragraph = builder.Build();
5760 paragraph->layout(380);
5761 paragraph->paint(canvas.get(), 0, 0);
5768 TestCanvas canvas(
"SkParagraph_Ellipsis.png");
5770 const char*
text =
"This\n"
5771 "is a wrapping test. It should wrap at manual newlines, and if softWrap is true, also at spaces.";
5777 auto relayout = [&](
size_t lines,
bool ellipsis,
5789 builder.addText(
text);
5790 auto paragraph = builder.Build();
5791 paragraph->layout(50);
5792 paragraph->paint(canvas.get(), 0, 0);
5793 canvas.get()->translate(50, paragraph->getHeight() + 10);
5794 auto result = paragraph->getRectsForRange(0, strlen(
text), RectHeightStyle::kTight, RectWidthStyle::kTight);
5800 canvas.get()->drawRect(
result.front().rect, background);
5812 relayout(1,
false, 50, 10, 950, 950,
SK_ColorRED);
5814 relayout(std::numeric_limits<size_t>::max(),
false, 50, 200, 90, 950,
SK_ColorGREEN);
5818 relayout(std::numeric_limits<size_t>::max(),
true, 50, 20, 950, 950,
SK_ColorCYAN);
5820 relayout(1,
false, 50, 10, 950, 950,
SK_ColorRED);
5822 relayout(std::numeric_limits<size_t>::max(),
false, 50, 200, 90, 950,
SK_ColorGREEN);
5831 for (
size_t i = 0; i < 10; i++)
5834 paint.setAntiAlias(
true);
5846 builder.addText(
text.c_str());
5848 auto paragraph = builder.Build();
5849 paragraph->layout(100);
5860 TestCanvas canvas(
"SkParagraph_FormattingInfinity.png");
5862 const char*
text =
"Some text\nAnother line";
5865 paint.setAntiAlias(
true);
5878 builder.addText(
text);
5879 auto paragraph = builder.Build();
5881 paragraph->paint(canvas.get(), 0, 0);
5882 canvas.get()->translate(0, 100);
5885 draw(
"left", TextAlign::kLeft, TextDirection::kLtr);
5886 draw(
"right", TextAlign::kRight, TextDirection::kLtr);
5887 draw(
"center", TextAlign::kCenter, TextDirection::kLtr);
5888 draw(
"justify LTR", TextAlign::kJustify, TextDirection::kLtr);
5889 draw(
"justify RTL", TextAlign::kJustify, TextDirection::kRtl);
5915 TestCanvas canvas(
"SkParagraph_LineMetrics.png");
5917 const char*
text =
"One line of text\n";
5918 const size_t len = strlen(
text);
5929 builder.pushStyle(text_style);
5930 builder.addText(
text, len);
5934 builder.pushStyle(text_style);
5935 builder.addText(
text, len);
5939 builder.pushStyle(text_style);
5940 builder.addText(
text, len);
5944 builder.pushStyle(text_style);
5945 builder.addText(
text, len - 1);
5948 auto paragraph = builder.Build();
5951 std::vector<LineMetrics> metrics;
5952 paragraph->getLineMetrics(metrics);
5955 SkASSERT(metrics.size() == impl->lines().size());
5956 for (
size_t i = 0; i < metrics.size(); ++i) {
5958 SkDEBUGCODE(
auto baseline = metrics[i].fBaseline;)
5960 SkDEBUGCODE(
auto bottom = line.offset().fY + line.height();)
5961 SkASSERT( baseline > top && baseline <= bottom);
5964 paragraph->paint(canvas.get(), 0, 0);
5965 auto rects = paragraph->getRectsForRange(0, len * 4, RectHeightStyle::kMax, RectWidthStyle::kTight);
5973 for (
auto& rect : rects) {
5974 canvas.get()->drawRect(rect.rect, red);
5982 for (
auto& metric : metrics) {
5984 auto x1 = metric.fWidth;
5985 auto y = metric.fBaseline;
5986 canvas.get()->drawLine(x0,
y, x1,
y, green);
5991 TestCanvas canvas(
"SkParagraph_PlaceholderHeightInf.png");
6002 placeholder_style.
fWidth = 16.0f;
6004 placeholder_style.
fAlignment = PlaceholderAlignment::kBottom;
6005 placeholder_style.
fBaseline = TextBaseline::kAlphabetic;
6011 builder.pushStyle(text_style);
6012 builder.addText(
"Limited by budget");
6013 builder.addPlaceholder(placeholder_style);
6014 auto paragraph = builder.Build();
6016 paragraph->paint(canvas.get(), 0, 0);
6028 TestCanvas canvas(
"SkParagraph_LineMetricsTextAlign.png");
6036 auto layout = [&](
TextAlign text_align) -> std::pair<SkScalar, SkScalar> {
6039 builder.pushStyle(text_style);
6040 builder.addText(
"Some text that takes more than 200 px");
6041 auto paragraph = builder.Build();
6042 paragraph->layout(200);
6043 paragraph->paint(canvas.get(), 0, 0);
6044 canvas.get()->translate(0, paragraph->getHeight());
6045 std::vector<LineMetrics> metrics;
6046 paragraph->getLineMetrics(metrics);
6048 return { metrics[0].fLeft, metrics[0].fWidth };
6053 std::tie(
left[0],
width[0]) = layout(TextAlign::kLeft);
6054 std::tie(
left[1],
width[1]) = layout(TextAlign::kCenter);
6055 std::tie(
left[2],
width[2]) = layout(TextAlign::kRight);
6056 std::tie(
left[3],
width[3]) = layout(TextAlign::kJustify);
6071 TestCanvas canvas(
"SkParagraph_FontResolutionInRTL.png");
6072 const char*
text =
" אאא בּבּבּבּ אאאא בּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ ";
6073 const size_t len = strlen(
text);
6086 builder.pushStyle(text_style);
6087 builder.addText(
text, len);
6090 auto paragraph = builder.Build();
6092 paragraph->paint(canvas.get(), 0, 0);
6101 TestCanvas canvas(
"SkParagraph_FontResolutionInLTR.png");
6102 auto text = u
"abc \u01A2 \u01A2 def";
6113 builder.pushStyle(text_style);
6114 builder.addText(
text);
6117 auto paragraph = builder.Build();
6119 paragraph->paint(canvas.get(), 0, 0);
6143 builder.pushStyle(text_style);
6144 builder.addText(
text.c_str());
6146 auto paragraph = builder.Build();
6147 paragraph->layout(300000.0f);
6161 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6162 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6163 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6164 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6165 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6166 "عل بمباركة التقليدية قام عن. تصفح";
6178 auto test = [&](
const char*
test,
const char*
text,
bool editing) {
6181 builder.pushStyle(text_style);
6182 builder.addText(
text);
6185 auto cache = fontCollection->getParagraphCache();
6186 auto countBefore = cache->count();
6187 auto paragraph = builder.Build();
6189 auto countAfter = cache->count();
6191 if (
test ==
nullptr) {
6199 test(
"Long arabic text", str.
c_str(),
false);
6202 test(
"+2 character at the end", str.
c_str(),
true);
6205 test(
"-2 characters from the end", str.
c_str(),
true);
6208 test(
"+2 character at the start", str.
c_str(),
true);
6210 test(
"-2 characters from the start",
text,
true);
6213 test(
"different strings",
"0123456789 0123456789 0123456789 0123456789 0123456789",
false);
6220 TestCanvas canvas(
"SkParagraph_HeightCalculations.png");
6233 builder.pushStyle(text_style);
6234 builder.addText(
text);
6236 auto paragraph = builder.Build();
6237 paragraph->layout(500);
6238 paragraph->paint(canvas.get(), 0, 0);
6239 canvas.get()->translate(0, paragraph->getHeight());
6243 draw(TextHeightBehavior::kAll,
"Hello\nLine 2\nLine 3", 210);
6244 draw(TextHeightBehavior::kDisableAll,
"Hello\nLine 2\nLine 3", 157);
6245 draw(TextHeightBehavior::kDisableFirstAscent,
"Hello", 28);
6253 TestCanvas canvas(
"SkParagraph_RTL_With_Styles.png");
6264 const char* arabic =
"قففغغغغقففغغغغقففغغغ";
6277 builder.pushStyle(text_style);
6278 builder.addText(
" ");
6280 builder.pushStyle(text_style);
6281 builder.addText(arabic);
6283 auto paragraph = builder.Build();
6284 paragraph->layout(300);
6285 paragraph->paint(canvas.get(), 0, 0);
6293 TestCanvas canvas(
"SkParagraph_PositionInsideEmoji.png");
6295 std::u16string
text = u
"\U0001f469\u200D\U0001f469\u200D\U0001f467\u200D\U0001f467\U0001f469\U0001f469\U0001f467\U0001f467";
6302 builder.pushStyle(text_style);
6303 builder.addText(
text);
6305 auto paragraph = builder.Build();
6307 paragraph->paint(canvas.get(), 0, 0);
6319 auto family = paragraph->getRectsForRange(0, 11, RectHeightStyle::kTight, RectWidthStyle::kTight);
6320 auto face01 = paragraph->getRectsForRange(11, 13, RectHeightStyle::kTight, RectWidthStyle::kTight);
6321 auto face02 = paragraph->getRectsForRange(13, 15, RectHeightStyle::kTight, RectWidthStyle::kTight);
6322 auto face03 = paragraph->getRectsForRange(15, 17, RectHeightStyle::kTight, RectWidthStyle::kTight);
6323 auto face04 = paragraph->getRectsForRange(17, 19, RectHeightStyle::kTight, RectWidthStyle::kTight);
6325 int32_t words[] = { 11, 13, 15, 17, 19, 21};
6327 for (
auto i : words) {
6328 auto rects = paragraph->getRectsForRange(j, i, RectHeightStyle::kTight, RectWidthStyle::kTight);
6329 if (rects.empty()) {
6332 auto X = rects[0].rect.centerX();
6333 auto Y = rects[0].rect.centerY();
6334 auto res1 = paragraph->getGlyphPositionAtCoordinate(
X - 5,
Y);
6336 auto res2 = paragraph->getGlyphPositionAtCoordinate(
X + 5,
Y);
6347 TestCanvas canvas(
"SkParagraph_SingleLineHeight1.png");
6360 builder.pushStyle(text_style);
6361 builder.addText(
text);
6362 auto paragraph = builder.Build();
6363 paragraph->layout(80);
6364 paragraph->paint(canvas.get(), 0, 0);
6368 paint(
"Loooooooooooooooooooooooooooooooooooong text");
6376 TestCanvas canvas(
"SkParagraph_SingleLineHeight2.png");
6388 builder.pushStyle(text_style);
6389 builder.addText(
text);
6390 auto paragraph = builder.Build();
6391 paragraph->layout(80);
6392 paragraph->paint(canvas.get(), 0, 0);
6396 paint(
"Loooooooooooooooooooooooooooooooooooong text");
6405 TestCanvas canvas(
"SkParagraph_PlaceholderWidth.png");
6407 const char*
text =
"1 23 456 7890";
6414 PlaceholderStyle placeholder(300, 50, PlaceholderAlignment::kBaseline, TextBaseline::kAlphabetic, 0);
6416 auto draw = [&](
bool withPlaceholder) {
6418 builder.pushStyle(text_style);
6419 builder.addText(
text);
6420 if (withPlaceholder) {
6424 builder.pushStyle(text_style);
6425 builder.addPlaceholder(placeholder);
6427 builder.addText(
text);
6429 auto paragraph = builder.Build();
6430 paragraph->layout(950);
6431 paragraph->paint(canvas.get(), 0, 0);
6432 canvas.get()->translate(0, paragraph->getHeight());
6433 return paragraph->getMinIntrinsicWidth();
6436 auto len1 =
draw(
true);
6437 auto len2 =
draw(
false);
6449 TestCanvas canvas(
"SkParagraph_GlyphPositionsInEmptyLines.png");
6456 builder.pushStyle(text_style);
6457 builder.addText(
"A\n\n");
6459 auto paragraph = builder.Build();
6460 paragraph->layout(300);
6461 paragraph->paint(canvas.get(), 0, 0);
6463 auto res1 = paragraph->
6464 getGlyphPositionAtCoordinate(paragraph->getMinIntrinsicWidth(),1);
6467 auto res2 = paragraph->
6468 getGlyphPositionAtCoordinate(0,paragraph->getHeight() * 0.5);
6471 auto res3 = paragraph->
6472 getGlyphPositionAtCoordinate(0,paragraph->getHeight() - 1);
6481 TestCanvas canvas(
"SkParagraph_RTLGlyphPositions.png");
6489 builder.pushStyle(text_style);
6490 builder.addText(
"אאאא");
6492 auto paragraph = builder.Build();
6493 paragraph->layout(500);
6494 paragraph->paint(canvas.get(), 0, 0);
6496 std::vector<std::pair<SkScalar, PositionWithAffinity>> checks = {
6509 for (
auto check : checks) {
6510 auto pos = paragraph->getGlyphPositionAtCoordinate(
check.first, 0);
6521 TestCanvas canvas(
"SkParagraph_RTLGlyphPositionsInEmptyLines.png");
6530 builder.pushStyle(text_style);
6532 builder.addText(
"בבבב\n\nאאאא");
6534 auto paragraph = builder.Build();
6535 paragraph->layout(500);
6536 paragraph->paint(canvas.get(), 0, 0);
6538 auto height = paragraph->getHeight();
6539 auto res1 = paragraph->getGlyphPositionAtCoordinate(0, 0);
6541 auto res2 = paragraph->getGlyphPositionAtCoordinate(0,
height / 2);
6543 auto res3 = paragraph->getGlyphPositionAtCoordinate(0,
height);
6552 TestCanvas canvas(
"SkParagraph_LTRGlyphPositionsForTrailingSpaces.png");
6560 auto test = [&](
const char*
text) {
6561 auto str = straight(
text);
6563 builder.pushStyle(text_style);
6564 builder.addText(str);
6567 auto paragraph = builder.Build();
6568 paragraph->layout(100);
6569 canvas.get()->translate(0, 20);
6570 canvas.get()->drawRect(
SkRect::MakeXYWH(0, 0, paragraph->getMaxIntrinsicWidth(), paragraph->getHeight()), gray);
6571 paragraph->paint(canvas.get(), 0, 0);
6572 canvas.get()->translate(0, paragraph->getHeight());
6574 for (
size_t i = 0; i < str.size(); ++i) {
6575 auto res = paragraph->getGlyphPositionAtCoordinate(i * 10, 2);
6593 TestCanvas canvas(
"SkParagraph_RTLGlyphPositionsForTrailingSpaces.png");
6602 canvas.get()->translate(200, 0);
6604 auto test = [&](
const char*
text,
int whitespaces) {
6607 builder.pushStyle(text_style);
6608 builder.addText(str);
6611 auto paragraph = builder.Build();
6612 paragraph->layout(100);
6613 canvas.get()->translate(0, 20);
6614 auto res = paragraph->getRectsForRange(0, str.size(), RectHeightStyle::kTight, RectWidthStyle::kTight);
6616 for (
auto& r : res) {
6623 canvas.get()->drawRect(r.rect, gray);
6626 canvas.get()->drawRect(
SkRect::MakeXYWH(0, 0, 1, paragraph->getHeight()), gray);
6627 paragraph->paint(canvas.get(), 0, 0);
6628 canvas.get()->translate(0, paragraph->getHeight());
6630 for (
int i = 0; i <
SkToInt(str.size()); ++i) {
6633 auto pointX = (whitespaces + i) * 10.0f + 1.0f;
6634 auto pos = paragraph->getGlyphPositionAtCoordinate(pointX, 2);
6642 test(
" hello", -10);
6650 TestCanvas canvas(
"SkParagraph_LTRLineMetricsDoesNotIncludeNewLine.png");
6659 builder.pushStyle(text_style);
6660 builder.addText(
"one two\n\nthree four\nwith spaces \n \n______________________");
6662 auto paragraph = builder.Build();
6663 paragraph->layout(190);
6664 paragraph->paint(canvas.get(), 0, 0);
6666 std::vector<std::tuple<size_t, size_t, size_t, size_t>> expected = {
6675 std::vector<LineMetrics> metrics;
6676 paragraph->getLineMetrics(metrics);
6677 for (
auto& metric : metrics) {
6679 auto result = expected[metric.fLineNumber];
6692 TestCanvas canvas(
"SkParagraph_RTLLineMetricsDoesNotIncludeNewLine.png");
6693 canvas.get()->translate(100, 100);
6703 builder.pushStyle(text_style);
6704 builder.addText(
mirror(
"______________________\none two\n\nthree four\nwith spaces \n "));
6706 auto paragraph = builder.Build();
6707 paragraph->layout(190);
6708 paragraph->paint(canvas.get(), 0, 0);
6716 canvas.get()->drawRect(
SkRect::MakeXYWH(0, 0, paragraph->getMaxWidth(), paragraph->getHeight()), gray);
6730 auto boxes = paragraph->getRectsForRange(0, 100, RectHeightStyle::kTight, RectWidthStyle::kTight);
6732 for (
auto& box : boxes) {
6733 canvas.get()->drawRect(box.rect, even ? red : blue);
6740 std::vector<std::tuple<int, int, int, int>> expected = {
6750 std::vector<LineMetrics> metrics;
6751 paragraph->getLineMetrics(metrics);
6752 for (
auto& metric : metrics) {
6754 auto result = expected[metric.fLineNumber];
6766 TestCanvas canvas(
"SkParagraph_PlaceholderPosition.png");
6767 canvas.get()->translate(100, 100);
6776 builder.pushStyle(text_style);
6777 builder.addText(
"abcd");
6780 placeholder_style.
fHeight = 10;
6781 placeholder_style.
fWidth = 10;
6782 placeholder_style.
fBaseline = TextBaseline::kAlphabetic;
6783 placeholder_style.
fAlignment = PlaceholderAlignment::kBottom;
6784 builder.addPlaceholder(placeholder_style);
6786 auto paragraph = builder.Build();
6787 paragraph->layout(500);
6788 paragraph->paint(canvas.get(), 0, 0);
6790 auto result = paragraph->getGlyphPositionAtCoordinate(41.0f, 0.0f);
6798 TestCanvas canvas(
"SkParagraph_LineEnd.png");
6799 canvas.get()->translate(100, 100);
6808 builder.pushStyle(text_style);
6809 builder.addText(
"Hello ");
6810 builder.addText(
"hello ");
6811 builder.addText(
"hello\n");
6812 builder.addText(
"hello \n");
6813 builder.addText(
"world");
6815 auto paragraph = builder.Build();
6816 paragraph->layout(60.0f);
6817 paragraph->paint(canvas.get(), 0, 0);
6819 std::vector<LineMetrics> lm;
6820 paragraph->getLineMetrics(lm);
6826 REPORTER_ASSERT(
reporter, lm[0].fEndExcludingWhitespaces == 05 && lm[0].fEndIndex == 06 && lm[0].fEndIncludingNewline == 06);
6827 REPORTER_ASSERT(
reporter, lm[1].fEndExcludingWhitespaces == 11 && lm[1].fEndIndex == 14 && lm[1].fEndIncludingNewline == 14);
6828 REPORTER_ASSERT(
reporter, lm[2].fEndExcludingWhitespaces == 19 && lm[2].fEndIndex == 19 && lm[2].fEndIncludingNewline == 20);
6829 REPORTER_ASSERT(
reporter, lm[3].fEndExcludingWhitespaces == 25 && lm[3].fEndIndex == 28 && lm[3].fEndIncludingNewline == 29);
6836 TestCanvas canvas(
"SkParagraph_Utf16Indexes.png");
6837 canvas.get()->translate(100, 100);
6846 builder.pushStyle(text_style);
6847 builder.addText(
"áéíóú\nxxxx");
6848 auto paragraph = builder.Build();
6849 paragraph->layout(60.0f);
6850 paragraph->paint(canvas.get(), 0, 0);
6851 std::vector<LineMetrics> lm;
6852 paragraph->getLineMetrics(lm);
6856 REPORTER_ASSERT(
reporter, lm[0].fEndExcludingWhitespaces == 05 && lm[0].fEndIndex == 05 && lm[0].fEndIncludingNewline == 06);
6857 REPORTER_ASSERT(
reporter, lm[1].fEndExcludingWhitespaces == 10 && lm[1].fEndIndex == 10 && lm[1].fEndIncludingNewline == 10);
6864 TestCanvas canvas(
"SkParagraph_RTLFollowedByLTR.png");
6865 canvas.get()->translate(100, 100);
6876 builder.pushStyle(text_style);
6877 builder.addText(u
"\u05D0\u05D0\u05D0ABC");
6878 auto paragraph = builder.Build();
6879 paragraph->layout(100);
6880 paragraph->paint(canvas.get(), 0, 0);
6882 auto boxes = paragraph->getRectsForRange(
6883 0, paragraph->getMaxWidth(), RectHeightStyle::kTight, RectWidthStyle::kTight);
6887 boxes[0].direction == TextDirection::kRtl && boxes[1].direction == TextDirection::kLtr);
6893 std::vector<std::pair<SkScalar, PositionWithAffinity>> checks = {
6910 for (
auto check : checks) {
6911 auto pos = paragraph->getGlyphPositionAtCoordinate(
check.first, 0);
6921 TestCanvas canvas(
"SkParagraph_StrutTopLine.png");
6944 builder.pushStyle(text_style);
6945 builder.addText(u
"Atwater Peel Sherbrooke Bonaventure\nhi\nwasssup!");
6947 auto paragraph = builder.Build();
6948 paragraph->layout(797);
6949 paragraph->paint(canvas.get(), 0, 0);
6950 auto boxes = paragraph->getRectsForRange(0, 60, RectHeightStyle::kIncludeLineSpacingTop, RectWidthStyle::kMax);
6969 TestCanvas canvas(
"SkParagraph_DifferentFontsTopLine.png");
6984 builder.pushStyle(text_style);
6985 builder.addText(u
"Atwater Peel ");
6987 builder.pushStyle(text_style);
6988 builder.addText(u
"Sherbrooke Bonaventure ");
6990 builder.pushStyle(text_style);
6991 builder.addText(u
"hi wassup!");
6993 auto paragraph = builder.Build();
6994 paragraph->layout(797);
6995 paragraph->paint(canvas.get(), 0, 0);
6996 auto boxes = paragraph->getRectsForRange(0, 60, RectHeightStyle::kIncludeLineSpacingTop, RectWidthStyle::kMax);
7014 const char*
text =
"Hello World Text Dialog";
7015 const size_t len = strlen(
text);
7021 for (
int iteration = 0; iteration < 2; iteration += 1) {
7028 builder.pushStyle(text_style);
7029 builder.addText(
text, len);
7032 auto paragraph = builder.Build();
7042 for (
auto& line : impl->lines()) {
7043 line.scanStyles(StyleType::kDecorations,
7057 TestCanvas canvas(
"SkParagraph_EllipsisGetRectForRange.png");
7059 "This is a very long sentence to test if the text will properly wrap "
7060 "around and go to the next line. Sometimes, short sentence. Longer "
7061 "sentences are okay too because they are nessecary. Very short. ";
7062 const size_t len = strlen(
text);
7066 std::u16string ellipsis = u
"\u2026";
7075 builder.pushStyle(text_style);
7076 builder.addText(
text, len);
7079 auto paragraph = builder.Build();
7081 paragraph->paint(canvas.get(), 0, 0);
7088 auto boxes1 = impl->getRectsForRange(0, 2, RectHeightStyle::kTight, RectWidthStyle::kTight);
7091 auto boxes2 = impl->getRectsForRange(0, 3, RectHeightStyle::kTight, RectWidthStyle::kTight);
7102 const char*
text =
"";
7103 const size_t len = strlen(
text);
7123 builder.pushStyle(text_style);
7124 builder.addText(
text, len);
7125 auto paragraph = builder.Build();
7127 return paragraph->getHeight();
7130 auto height1 = layout(TextHeightBehavior::kDisableAll);
7131 auto height2 = layout(TextHeightBehavior::kAll);
7143 TestCanvas canvas(
"SkParagraph_NonMonotonicGlyphsLTR.png");
7144 std::u16string
text =
7145 u
"\u0068\u0301\u0350\u0312\u0357\u030C\u0369\u0305\u036C\u0304\u0310\u033F\u0366\u0350 ";
7166 builder.pushStyle(text_style);
7167 builder.addText(
text);
7168 auto paragraph = builder.Build();
7171 paragraph->layout(paragraph->getMinIntrinsicWidth() + 1);
7174 bool hasNonMonotonicPlacement =
false;
7175 for (
auto&
run : impl->runs()) {
7178 hasNonMonotonicPlacement =
true;
7181 if (hasNonMonotonicPlacement) {
7187 paragraph->paint(canvas.get(), 0, 0);
7195 TestCanvas canvas(
"SkParagraph_NonMonotonicGlyphsRTL.png");
7196 const char*
text =
"ٱلْرَّحْمَـانُ";
7197 const size_t len = strlen(
text);
7207 builder.pushStyle(text_style);
7208 builder.addText(
text, len);
7209 auto paragraph = builder.Build();
7212 paragraph->layout(paragraph->getMinIntrinsicWidth() + 1);
7214 bool hasNonMonotonicPlacement =
false;
7215 for (
auto&
run : impl->runs()) {
7218 hasNonMonotonicPlacement =
true;
7221 if (hasNonMonotonicPlacement) {
7226 paragraph->paint(canvas.get(), 0, 0);
7233 auto const text = std::u16string(42000,
'x');
7243 builder.pushStyle(textStyle);
7244 builder.addText(
text);
7247 auto paragraph = builder.Build();
7248 paragraph->layout(std::numeric_limits<float>::max());
7252 auto t1 = std::thread([&] {
7253 auto result = paragraph->getRectsForRange(0, 2, heightStyle, widthStyle);
7256 auto t2 = std::thread([&] {
7257 auto result = paragraph->getRectsForRange(5, 10, heightStyle, widthStyle);
7265 auto const threads_count = 100;
7266 std::thread threads[threads_count];
7267 for (
auto& thread : threads) {
7270 for (
auto& thread : threads) {
7279 TestCanvas canvas(
"SkParagraph_TabSubstitution.png");
7291 builder1.
addText(
"There is a tab>\t<right here");
7292 auto paragraph1 = builder1.
Build();
7294 paragraph1->paint(canvas.get(), 0, 0);
7299 builder2.
addText(
"There is a tab>\t<right here");
7300 auto paragraph2 = builder2.
Build();
7302 paragraph2->paint(canvas.get(), 0, 0);
7315 fontCollection->enableFontFallback();
7319 std::u16string ellipsis = u
"\u2026";
7323 builder.addText(
"hello");
7325 auto paragraph = builder.Build();
7326 paragraph->layout(1.);
7328 std::vector<LineMetrics> lm;
7329 paragraph->getLineMetrics(lm);
7337 fontCollection->enableFontFallback();
7339 auto text = std::u16string(u
"hello world");
7344 builder.addText(
text);
7346 auto paragraph = builder.Build();
7347 paragraph->layout(200.);
7349 std::vector<LineMetrics> lm;
7350 paragraph->getLineMetrics(lm);
7353 paragraph->updateFontSize(0,
text.size(), 42);
7354 paragraph->layout(200.);
7355 paragraph->getLineMetrics(lm);
7364 TestCanvas canvas(
"SkParagraph_MultiStyle_Logo.png");
7387 paraStyle.
setMaxLines(std::numeric_limits<size_t>::max());
7389 const char* logo1 =
"google_";
7390 const char* logo2 =
"logo";
7391 const char* logo3 =
"go";
7392 const char* logo4 =
"ogle_logo";
7393 const char* logo5 =
"google_lo";
7394 const char* logo6 =
"go";
7400 builder.pushStyle(style0);
7401 builder.addText(logo1, strlen(logo1));
7405 builder.pushStyle(style1);
7406 builder.addText(logo2, strlen(logo2));
7407 builder.addText(
" ", 1);
7412 builder.pushStyle(style0);
7413 builder.addText(logo3, strlen(logo3));
7417 builder.pushStyle(style1);
7418 builder.addText(logo4, strlen(logo4));
7419 builder.addText(
" ", 1);
7424 builder.pushStyle(style0);
7425 builder.addText(logo5, strlen(logo5));
7429 builder.pushStyle(style1);
7430 builder.addText(logo6, strlen(logo6));
7432 auto paragraph = builder.Build();
7433 paragraph->layout(
width - 40);
7434 paragraph->paint(canvas.get(), 20, 20);
7441 impl->lines().data()->scanStyles(StyleType::kDecorations,
7481 TestCanvas canvas(
"SkParagraph_MultiStyle_FFI.png");
7492 builder.pushStyle(text_style);
7493 builder.addText(
"f");
7495 builder.pushStyle(text_style);
7496 builder.addText(
"f");
7498 builder.pushStyle(text_style);
7499 builder.addText(
"i");
7500 auto paragraph = builder.Build();
7502 paragraph->paint(canvas.get(), 0, 0);
7503 auto width = paragraph->getLongestLine();
7504 auto height = paragraph->getHeight();
7506 auto f1Pos = paragraph->getGlyphPositionAtCoordinate(
width/6 - 5,
height/2);
7507 auto f2Pos = paragraph->getGlyphPositionAtCoordinate(
width/2 - 5,
height/2);
7508 auto iPos = paragraph->getGlyphPositionAtCoordinate(
width*5/6 - 5,
height/2);
7516 auto f1 = paragraph->getRectsForRange(0, 1, RectHeightStyle::kTight,
7517 RectWidthStyle::kTight);
7523 auto f2 = paragraph->getRectsForRange(1, 2, RectHeightStyle::kTight,
7524 RectWidthStyle::kTight);
7530 auto fi = paragraph->getRectsForRange(2, 3, RectHeightStyle::kTight,
7531 RectWidthStyle::kTight);
7543 TestCanvas canvas(
"SkParagraph_MultiStyle_EmojiFamily.png");
7553 builder.pushStyle(text_style);
7554 builder.addText(u
"\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466");
7555 auto paragraph = builder.Build();
7559 paint.setAntiAlias(
true);
7560 paint.setStrokeWidth(1);
7562 canvas.get()->drawRect(
SkRect::MakeXYWH(0, 0, paragraph->getLongestLine(), paragraph->getHeight()),
paint);
7563 paragraph->paint(canvas.get(), 0, 0);
7564 auto width = paragraph->getLongestLine();
7565 auto height = paragraph->getHeight();
7567 auto pos00 = paragraph->getGlyphPositionAtCoordinate(
width/4,
height/4);
7568 auto pos10 = paragraph->getGlyphPositionAtCoordinate(
width*3/4,
height/2);
7569 auto pos01 = paragraph->getGlyphPositionAtCoordinate(
width/4,
height/2);
7570 auto pos11 = paragraph->getGlyphPositionAtCoordinate(
width*3/4,
height*3/4);
7579 auto f1 = paragraph->getRectsForRange(0, 2, RectHeightStyle::kTight, RectWidthStyle::kTight);
7582 auto f2 = paragraph->getRectsForRange(4, 6, RectHeightStyle::kTight, RectWidthStyle::kTight);
7585 auto f3 = paragraph->getRectsForRange(8, 10, RectHeightStyle::kTight, RectWidthStyle::kTight);
7588 auto f4 = paragraph->getRectsForRange(8, 10, RectHeightStyle::kTight, RectWidthStyle::kTight);
7597 TestCanvas canvas(
"SkParagraph_MultiStyle_Arabic.png");
7610 builder.pushStyle(text_style);
7611 builder.addText(
"ك");
7613 builder.pushStyle(text_style);
7614 builder.addText(
"ِّ");
7616 builder.pushStyle(text_style);
7617 builder.addText(
"ـ");
7618 auto paragraph = builder.Build();
7620 paragraph->paint(canvas.get(), 0, 0);
7622 auto width = paragraph->getLongestLine();
7623 auto height = paragraph->getHeight();
7634 auto f1 = paragraph->getRectsForRange(0, 1, RectHeightStyle::kTight, RectWidthStyle::kTight);
7637 auto f2 = paragraph->getRectsForRange(1, 2, RectHeightStyle::kTight, RectWidthStyle::kTight);
7640 auto fi = paragraph->getRectsForRange(2, 3, RectHeightStyle::kTight, RectWidthStyle::kTight);
7650 TestCanvas canvas(
"SkParagraph_MultiStyle_Zalgo.png");
7655 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<";
7657 auto K =
text.find(
"k");
7658 auto P =
text.find(
"P");
7659 auto h =
text.find(
"h");
7666 builder.pushStyle(text_style);
7667 builder.addText(
text.data(),
K + 3);
7670 builder.pushStyle(text_style);
7671 builder.addText(
text.data() +
K + 3, P -
K - 3 + 6);
7673 builder.pushStyle(text_style);
7674 builder.addText(
text.data() + P + 6,
h - P - 6);
7677 builder.pushStyle(text_style);
7678 builder.addText(
text.data() +
h,
text.size() -
h);
7679 auto paragraph = builder.Build();
7681 paragraph->paint(canvas.get(), 0, paragraph->getHeight() / 2);
7683 auto height = paragraph->getHeight();
7685 auto resSK = paragraph->getRectsForRange(0,
K, RectHeightStyle::kTight,
7686 RectWidthStyle::kTight);
7690 auto resKP = paragraph->getRectsForRange(
K, P, RectHeightStyle::kTight,
7691 RectWidthStyle::kTight);
7696 auto resPh = paragraph->getRectsForRange(P,
h, RectHeightStyle::kTight,
7697 RectWidthStyle::kTight);
7701 auto posK = paragraph->getGlyphPositionAtCoordinate(resSK.back().rect.fRight,
height/2);
7702 auto posP = paragraph->getGlyphPositionAtCoordinate(resKP.back().rect.fRight,
height/2);
7703 auto posH = paragraph->getGlyphPositionAtCoordinate(resPh.back().rect.fRight,
height/2);
7712 TestCanvas canvas(
"SkParagraph_RtlEllipsis1.png");
7727 builder.pushStyle(text_style);
7728 builder.addText(u
"1 2 3 4 5 6 7 8 9");
7729 auto paragraph = builder.Build();
7730 paragraph->layout(474);
7731 paragraph->paint(canvas.get(), 0, 0);
7734 auto& line = impl->lines()[0];
7736 line.iterateThroughVisualRuns(
true,
7749 TestCanvas canvas(
"SkParagraph_RtlEllipsis2.png");
7764 builder.pushStyle(text_style);
7765 builder.addText(u
"تظاهرات و تجمعات اعتراضی در سراسر کشور ۲۳ مهر");
7766 auto paragraph = builder.Build();
7767 paragraph->layout(474);
7768 paragraph->paint(canvas.get(), 0, 0);
7771 auto& line = impl->lines()[1];
7773 line.iterateThroughVisualRuns(
true,
7793 TestCanvas canvas(
"SkParagraph_TextEditingFunctionality.png");
7795 "This is a very long sentence to test if the text will properly wrap "
7796 "around and go to the next line. Sometimes, short sentence. Longer "
7797 "sentences are okay too because they are nessecary. Very short. "
7798 "This is a very long sentence to test if the text will properly wrap "
7799 "around and go to the next line. Sometimes, short sentence. Longer "
7800 "sentences are okay too because they are nessecary. Very short. ";
7802 const size_t len = strlen(
text);
7812 builder.pushStyle(text_style);
7813 builder.addText(
text, len);
7816 auto paragraph = builder.Build();
7818 paragraph->paint(canvas.get(), 0, 0);
7820 auto lineNumber = paragraph->getLineNumberAt(0);
7822 lineNumber = paragraph->getLineNumberAt(len / 2);
7824 lineNumber = paragraph->getLineNumberAt(len - 1);
7826 lineNumber = paragraph->getLineNumberAt(len);
7828 lineNumber = paragraph->getLineNumberAt(len + 10);
7832 auto foundMetrics = paragraph->getLineMetricsAt(0, &lineMetrics);
7834 foundMetrics = paragraph->getLineMetricsAt(1, &lineMetrics);
7836 foundMetrics = paragraph->getLineMetricsAt(3, &lineMetrics);
7838 foundMetrics = paragraph->getLineMetricsAt(10, &lineMetrics);
7841 std::vector<LineMetrics> metrics;
7842 paragraph->getLineMetrics(metrics);
7843 auto actualText = paragraph->getActualTextRange(0,
false);
7845 actualText = paragraph->getActualTextRange(1,
false);
7847 actualText = paragraph->getActualTextRange(2,
false);
7851 auto foundCluster = paragraph->getGlyphClusterAt(0, &glyphInfo);
7853 foundCluster = paragraph->getGlyphClusterAt(len / 2, &glyphInfo);
7855 foundCluster = paragraph->getGlyphClusterAt(len, &glyphInfo);
7858 auto foundClosest = paragraph->getClosestGlyphClusterAt(0, 10, &glyphInfo);
7861 foundClosest = paragraph->getClosestGlyphClusterAt(
TestCanvasWidth / 2, 20, &glyphInfo);
7864 foundClosest = paragraph->getClosestGlyphClusterAt(
TestCanvasWidth + 10, 30, &glyphInfo);
7869 auto font = paragraph->getFontAt(10);
7872 font.getTypeface()->getFamilyName(&fontFamily);
7875 auto fonts = paragraph->getFonts();
7879 font.getTypeface()->getFamilyName(&fontFamily);
7887 TestCanvas canvas(
"SkParagraph_Ellipsis.png");
7891 const char*
text =
"This\n"
7894 const size_t len = strlen(
text);
7906 builder.pushStyle(text_style);
7907 builder.addText(
text, len);
7909 auto paragraph = builder.Build();
7912 paragraph->layout(100);
7928 const char*
text =
"一丁丂七";
7929 const size_t len = strlen(
text);
7937 builder.pushStyle(text_style);
7938 builder.addText(
text, len);
7941 auto paragraph = builder.Build();
7972 const char*
text =
"";
7980 builder.pushStyle(text_style);
7981 builder.addText(
text, 0);
7984 auto paragraph = builder.Build();
7996 const char*
text =
"fi";
7997 const size_t len = strlen(
text);
8005 builder.pushStyle(text_style);
8006 builder.addText(
text, len);
8009 auto paragraph = builder.Build();
8025 const char*
text =
"لٔأ";
8026 const size_t len = strlen(
text);
8034 builder.pushStyle(text_style);
8035 builder.addText(
text, len);
8038 auto paragraph = builder.Build();
8040 TestCanvas canvas(
"SkParagraph_laam_alif_diacritics.png");
8041 paragraph->paint(canvas.get(), 50, 50);
8045 const auto boxes = paragraph->getRectsForRange(0, len, RectHeightStyle::kTight, RectWidthStyle::kTight);
8047 const SkRect fullRect = boxes[0].rect;
8084 const char*
text =
"Single dummy placeholder";
8085 const size_t len = strlen(
text);
8094 builder.pushStyle(text_style);
8095 builder.addText(
text, len);
8097 auto paragraph = builder.Build();
8104 for (
auto& line : impl->lines()) {
8105 line.scanStyles(StyleType::kDecorations,
8119 const char*
text =
"A text ending with line separator.\u2028";
8120 const size_t len = strlen(
text);
8127 builder.pushStyle(textStyle);
8128 builder.addText(
text, len);
8130 auto paragraph = builder.Build();
8133 int visitedCount = 0;
8136 if (lineNumber == 1) {
8149 const char*
text =
"♻️🏴";
8150 const char* text1 =
"♻️";
8151 const size_t len = strlen(
text);
8152 const size_t len1 = strlen(text1);
8158 builder.pushStyle(text_style);
8159 builder.addText(
text, len);
8160 auto paragraph = builder.Build();
8168 builder1.
addText(text1, len1);
8169 auto paragraph1 = builder1.
Build();
8174 if (impl1->runs().size() == 1) {
8176 impl->run(0).font().getTypeface()->getFamilyName(&ff);
8178 impl1->run(0).font().getTypeface()->getFamilyName(&ff1);
8183#if defined(SK_UNICODE_ICU_IMPLEMENTATION)
8189#if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
8205 icu->isEmoji(unicode) ?
"isEmoji" :
"",
8206 icu->isEmojiComponent(unicode) ?
"isEmojiComponent" :
""
8212 icu->computeCodeUnitFlags(str.
data(), str.
size(),
false, &codeUnitProperties);
8214 for (
auto& cp : codeUnitProperties) {
8245 test(
"😊abc", 128522);
8246 test(
"😊*️⃣",128522);
8247 test(
"👨👩👦👦", 128104);
8254 test(
"🏴", 127988);
8256 test(
"👨👩👧👦", 128104);
8259#if defined(SK_UNICODE_ICU_IMPLEMENTATION)
8265#if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
#define DEFINE_bool(name, defaultValue, helpString)
#define DEFINE_string(name, defaultValue, helpString)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static bool equal(const SkBitmap &a, const SkBitmap &b)
static float next(float f)
#define check(reporter, ref, unref, make, kill)
SkString GetResourcePath(const char *resource)
#define SkASSERTF_RELEASE(cond, fmt,...)
#define SkASSERTF(cond, fmt,...)
static unsigned mirror(SkFixed fx, int max)
constexpr SkColor SK_ColorYELLOW
constexpr SkColor SK_ColorLTGRAY
constexpr SkColor SK_ColorMAGENTA
constexpr SkColor SK_ColorCYAN
constexpr SkColor SK_ColorGRAY
constexpr SkColor SK_ColorBLUE
constexpr SkColor SK_ColorRED
constexpr SkColor SK_ColorBLACK
constexpr SkColor SK_ColorGREEN
constexpr SkColor SK_ColorWHITE
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static bool SkIsFinite(T x, Pack... values)
static bool has_empty_typeface(SkFont f)
#define VeryLongCanvasWidth
#define NEED_SYSTEM_FONTS(fontCollection)
static void SkUnicode_Emoji(sk_sp< SkUnicode > icu, skiatest::Reporter *reporter)
void performGetRectsForRangeConcurrently(skiatest::Reporter *reporter)
static void SkParagraph_EmojiFontResolution(sk_sp< SkUnicode > icu, skiatest::Reporter *reporter)
#define SKIP_IF_FONTS_NOT_FOUND(r, fontCollection)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
#define SK_ScalarInfinity
#define SK_ScalarNegativeInfinity
void SkTQSort(T *begin, T *end, const C &lessThan)
constexpr int SkToInt(S x)
constexpr uint32_t SkToU32(S x)
#define DEF_TEST_DISABLED(name, reporter)
#define REPORTER_ASSERT(r, cond,...)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
static constexpr SkFontStyle Italic()
SK_SPI bool next(SkString *name, bool getDir=false)
static SkString Join(const char *rootPath, const char *relativePath)
void setStyle(Style style)
void setColor(SkColor color)
void setAntiAlias(bool aa)
@ kStroke_Style
set to stroke geometry
void setStrokeWidth(SkScalar width)
static void VisualizeClusters(const char utf8[], size_t utf8Begin, size_t utf8End, SkSpan< const SkGlyphID > glyphIDs, SkSpan< const uint32_t > clusters, const VisualizeClustersCallback &processMToN)
static std::unique_ptr< SkStreamAsset > MakeFromFile(const char path[])
void printf(const char format[],...) SK_PRINTF_LIKE(2
const char * data() const
bool equals(const SkString &) const
void append(const char text[])
void insert(size_t offset, const char text[])
const char * c_str() const
static bool hasGraphemeStartFlag(SkUnicode::CodeUnitFlags flags)
static SkString convertUtf16ToUtf8(const char16_t *utf16, int utf16Units)
static SkUnichar getEmojiSequenceStart(SkUnicode *unicode, const char **begin, const char *end)
void addText(const std::u16string &text) override
void pushStyle(const TextStyle &style) override
std::unique_ptr< Paragraph > Build() override
SkSpan< TextLine > lines()
void setDecorationStyle(TextDecorationStyle style)
void addShadow(TextShadow shadow)
SkColor getDecorationColor() const
void setFontFamilies(std::vector< SkString > families)
size_t getShadowNumber() const
void setHeight(SkScalar height)
void setLetterSpacing(SkScalar letterSpacing)
void setWordSpacing(SkScalar wordSpacing)
TextDecorationStyle getDecorationStyle() const
SkScalar getDecorationThicknessMultiplier() const
SkFontStyle getFontStyle() const
void setColor(SkColor color)
void setHeightOverride(bool heightOverride)
bool equals(const TextStyle &other) const
void setFontStyle(SkFontStyle fontStyle)
void setBackgroundColor(SkPaint paint)
void setLocale(const SkString &locale)
TextDecoration getDecorationType() const
void setHalfLeading(bool halfLeading)
void setFontSize(SkScalar size)
void setForegroundColor(SkPaint paint)
void addFontFeature(const SkString &fontFeature, int value)
void setDecorationColor(SkColor color)
void setDecoration(TextDecoration decoration)
void setDecorationThicknessMultiplier(SkScalar m)
T & emplace_back(Args &&... args)
static const char * begin(const StringSlice &s)
constexpr SkColor4f kLtGray
constexpr SkColor4f kMagenta
constexpr SkColor4f kGreen
constexpr SkColor4f kWhite
constexpr SkColor4f kCyan
constexpr SkColor4f kBlack
constexpr SkColor4f kGray
constexpr SkColor4f kBlue
constexpr SkColor4f kYellow
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
sk_sp< Factory > BestAvailable()
SK_SPI SkUnichar NextUTF8WithReplacement(const char **ptr, const char *end)
SKUNICODE_API sk_sp< SkUnicode > Make()
SKUNICODE_API sk_sp< SkUnicode > Make()
static bool nearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
static sk_sp< SkUnicode > get_unicode()
static constexpr SkPoint Make(float x, float y)
constexpr float left() const
SkScalar fLeft
smaller x-axis bounds
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
SkScalar fRight
larger x-axis bounds
constexpr float right() const
static constexpr SkRect MakeWH(float w, float h)
std::u16string getEllipsisUtf16() const
TextAlign getTextAlign() const
void setReplaceTabCharacters(bool value)
void setEllipsis(const std::u16string &ellipsis)
void setTextDirection(TextDirection direction)
void setTextStyle(const TextStyle &textStyle)
void setMaxLines(size_t maxLines)
const TextStyle & getTextStyle() const
void setHeight(SkScalar height)
void setStrutStyle(StrutStyle strutStyle)
void setTextHeightBehavior(TextHeightBehavior v)
void setTextAlign(TextAlign align)
void setApplyRoundingHack(bool value)
size_t getMaxLines() const
TextRange fClusterTextRange
TextRange fGraphemeClusterTextRange
SkRect fGraphemeLayoutBounds
PlaceholderAlignment fAlignment
void setHalfLeading(bool halfLeading)
void setFontFamilies(std::vector< SkString > families)
void setHeight(SkScalar height)
void setStrutEnabled(bool v)
void setForceStrutHeight(bool v)
void setHeightOverride(bool v)
void setLeading(SkScalar Leading)
void setFontSize(SkScalar size)