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();
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) {
161 SkDebugf(
"Creating: %s size: %zu\n",
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;
236 paint.setAntiAlias(
true);
237 paint.setStrokeWidth(1);
241 canvas->drawRect(r.rect,
paint);
249 paint.setAntiAlias(
true);
250 paint.setStrokeWidth(1);
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);
314 auto paragraph =
builder.Build();
324 for (
auto&
line : impl->lines()) {
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) {
356 auto paragraph =
builder.Build();
360 paragraph->layout(paragraph->getMaxIntrinsicWidth());
374 TestCanvas canvas(
"SkParagraph_InlinePlaceholderParagraph.png");
377 const char*
text =
"012 34";
378 const size_t len = strlen(
text);
397 builder.addPlaceholder(placeholder1);
399 builder.addPlaceholder(placeholder1);
402 builder.addPlaceholder(placeholder2);
403 builder.addPlaceholder(placeholder1);
404 builder.addPlaceholder(placeholder2);
406 builder.addPlaceholder(placeholder2);
409 builder.addPlaceholder(placeholder2);
410 builder.addPlaceholder(placeholder2);
411 builder.addPlaceholder(placeholder2);
412 builder.addPlaceholder(placeholder2);
413 builder.addPlaceholder(placeholder2);
414 builder.addPlaceholder(placeholder1);
420 builder.addPlaceholder(placeholder2);
421 builder.addPlaceholder(placeholder1);
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);
449 if (boxes.size() >= 7) {
474 TestCanvas canvas(
"SkParagraph_InlinePlaceholderBaselineParagraph.png");
477 const char*
text =
"012 34";
478 const size_t len = strlen(
text);
497 builder.addPlaceholder(placeholder);
502 auto paragraph =
builder.Build();
504 paragraph->paint(canvas.get(), 0, 0);
506 auto boxes = paragraph->getRectsForPlaceholders();
510 if (boxes.size() >= 1) {
520 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
524 if (boxes.size() >= 1) {
534 TestCanvas canvas(
"SkParagraph_InlinePlaceholderAboveBaselineParagraph.png");
537 const char*
text =
"012 34";
538 const size_t len = strlen(
text);
557 builder.addPlaceholder(placeholder);
562 auto paragraph =
builder.Build();
564 paragraph->paint(canvas.get(), 0, 0);
566 auto boxes = paragraph->getRectsForPlaceholders();
570 if (boxes.size() >= 1) {
580 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
584 if (boxes.size() >= 1) {
594 TestCanvas canvas(
"SkParagraph_InlinePlaceholderBelowBaselineParagraph.png");
597 const char*
text =
"012 34";
598 const size_t len = strlen(
text);
617 builder.addPlaceholder(placeholder);
622 auto paragraph =
builder.Build();
624 paragraph->paint(canvas.get(), 0, 0);
626 auto boxes = paragraph->getRectsForPlaceholders();
630 if (boxes.size() >= 1) {
640 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
644 if (boxes.size() >= 1) {
654 TestCanvas canvas(
"SkParagraph_InlinePlaceholderBottomParagraph.png");
657 const char*
text =
"012 34";
658 const size_t len = strlen(
text);
677 builder.addPlaceholder(placeholder);
682 auto paragraph =
builder.Build();
684 paragraph->paint(canvas.get(), 0, 0);
689 auto boxes = paragraph->getRectsForPlaceholders();
692 if (boxes.size() >= 1) {
699 boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
702 if (boxes.size() >= 1) {
712 TestCanvas canvas(
"SkParagraph_InlinePlaceholderTopParagraph.png");
715 const char*
text =
"012 34";
716 const size_t len = strlen(
text);
735 builder.addPlaceholder(placeholder);
740 auto paragraph =
builder.Build();
742 paragraph->paint(canvas.get(), 0, 0);
747 auto boxes = paragraph->getRectsForPlaceholders();
750 if (boxes.size() >= 1) {
757 boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
760 if (boxes.size() >= 1) {
770 TestCanvas canvas(
"SkParagraph_InlinePlaceholderMiddleParagraph.png");
773 const char*
text =
"012 34";
774 const size_t len = strlen(
text);
793 builder.addPlaceholder(placeholder);
798 auto paragraph =
builder.Build();
800 paragraph->paint(canvas.get(), 0, 0);
805 auto boxes = paragraph->getRectsForPlaceholders();
808 if (boxes.size() >= 1) {
815 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
818 if (boxes.size() >= 1) {
828 TestCanvas canvas(
"SkParagraph_InlinePlaceholderIdeographicBaselineParagraph.png");
831 const char*
text =
"給能上目秘使";
832 const size_t len = strlen(
text);
850 builder.addPlaceholder(placeholder);
855 auto paragraph =
builder.Build();
857 paragraph->paint(canvas.get(), 0, 0);
862 auto boxes = paragraph->getRectsForPlaceholders();
865 if (boxes.size() >= 1) {
872 boxes = paragraph->getRectsForRange(5, 6, rect_height_style, rect_width_style);
875 if (boxes.size() >= 1) {
885 TestCanvas canvas(
"SkParagraph_InlinePlaceholderBreakParagraph.png");
888 const char*
text =
"012 34";
889 const size_t len = strlen(
text);
910 builder.addPlaceholder(placeholder1);
911 builder.addPlaceholder(placeholder1);
912 builder.addPlaceholder(placeholder1);
913 builder.addPlaceholder(placeholder2);
914 builder.addPlaceholder(placeholder1);
917 builder.addPlaceholder(placeholder1);
918 builder.addPlaceholder(placeholder1);
919 builder.addPlaceholder(placeholder1);
920 builder.addPlaceholder(placeholder1);
921 builder.addPlaceholder(placeholder2);
922 builder.addPlaceholder(placeholder1);
923 builder.addPlaceholder(placeholder1);
924 builder.addPlaceholder(placeholder1);
925 builder.addPlaceholder(placeholder1);
926 builder.addPlaceholder(placeholder1);
927 builder.addPlaceholder(placeholder1);
928 builder.addPlaceholder(placeholder2);
929 builder.addPlaceholder(placeholder1);
930 builder.addPlaceholder(placeholder1);
931 builder.addPlaceholder(placeholder1);
932 builder.addPlaceholder(placeholder1);
933 builder.addPlaceholder(placeholder1);
934 builder.addPlaceholder(placeholder1);
935 builder.addPlaceholder(placeholder1);
936 builder.addPlaceholder(placeholder2);
938 builder.addPlaceholder(placeholder1);
940 builder.addPlaceholder(placeholder1);
941 builder.addPlaceholder(placeholder2);
948 builder.addPlaceholder(placeholder2);
949 builder.addPlaceholder(placeholder1);
953 builder.addPlaceholder(placeholder2);
977 auto paragraph =
builder.Build();
979 paragraph->paint(canvas.get(), 0, 0);
984 auto boxes = paragraph->getRectsForRange(0, 3, rect_height_style, rect_width_style);
988 boxes = paragraph->getRectsForRange(175, 176, rect_height_style, rect_width_style);
991 if (boxes.size() >= 1) {
998 boxes = paragraph->getRectsForPlaceholders();
1001 boxes = paragraph->getRectsForRange(4, 45, rect_height_style, rect_width_style);
1004 if (boxes.size() >= 30) {
1024 TestCanvas canvas(
"SkParagraph_InlinePlaceholderGetRectsParagraph.png");
1027 const char*
text =
"012 34";
1028 const size_t len = strlen(
text);
1043 builder.pushStyle(text_style);
1049 builder.addPlaceholder(placeholder1);
1050 builder.addPlaceholder(placeholder1);
1051 builder.addPlaceholder(placeholder1);
1052 builder.addPlaceholder(placeholder1);
1053 builder.addPlaceholder(placeholder1);
1054 builder.addPlaceholder(placeholder1);
1055 builder.addPlaceholder(placeholder1);
1056 builder.addPlaceholder(placeholder1);
1057 builder.addPlaceholder(placeholder2);
1058 builder.addPlaceholder(placeholder1);
1059 builder.addPlaceholder(placeholder1);
1060 builder.addPlaceholder(placeholder1);
1061 builder.addPlaceholder(placeholder1);
1062 builder.addPlaceholder(placeholder1);
1063 builder.addPlaceholder(placeholder2);
1064 builder.addPlaceholder(placeholder1);
1065 builder.addPlaceholder(placeholder1);
1066 builder.addPlaceholder(placeholder1);
1067 builder.addPlaceholder(placeholder1);
1068 builder.addPlaceholder(placeholder1);
1069 builder.addPlaceholder(placeholder1);
1070 builder.addPlaceholder(placeholder1);
1071 builder.addPlaceholder(placeholder1);
1075 builder.addPlaceholder(placeholder1);
1076 builder.addPlaceholder(placeholder2);
1077 builder.addPlaceholder(placeholder2);
1078 builder.addPlaceholder(placeholder1);
1079 builder.addPlaceholder(placeholder2);
1080 builder.addPlaceholder(placeholder2);
1094 builder.addPlaceholder(placeholder2);
1095 builder.addPlaceholder(placeholder1);
1096 builder.addPlaceholder(placeholder2);
1097 builder.addPlaceholder(placeholder1);
1098 builder.addPlaceholder(placeholder2);
1104 auto paragraph =
builder.Build();
1106 paragraph->paint(canvas.get(), 0, 0);
1111 auto boxes = paragraph->getRectsForPlaceholders();
1115 if (boxes.size() >= 34) {
1132 boxes = paragraph->getRectsForRange(30, 50, rect_height_style, rect_width_style);
1136 if (boxes.size() >= 8) {
1157 const char*
text =
"I am RED";
1158 const size_t len = strlen(
text);
1167 builder.pushStyle(text_style);
1171 auto paragraph =
builder.Build();
1181 for (
auto&
line : impl->lines()) {
1195 TestCanvas canvas(
"SkParagraph_RainbowParagraph.png");
1197 const char* text1 =
"Red Roboto";
1198 const char* text2 =
"big Greeen Default";
1199 const char* text3 =
"Defcolor Homemade Apple";
1200 const char* text4 =
"Small Blue Roboto";
1201 const char* text41 =
"Small Blue ";
1203 "Continue Last Style With lots of words to check if it overlaps "
1205 const char* text42 =
1207 "Continue Last Style With lots of words to check if it overlaps "
1220 builder.pushStyle(text_style1);
1221 builder.addText(text1, strlen(text1));
1234 builder.pushStyle(text_style2);
1235 builder.addText(text2, strlen(text2));
1240 builder.pushStyle(text_style3);
1241 builder.addText(text3, strlen(text3));
1250 builder.pushStyle(text_style4);
1251 builder.addText(text4, strlen(text4));
1253 builder.addText(text5, strlen(text5));
1256 auto paragraph =
builder.Build();
1257 paragraph->layout(1000);
1258 paragraph->paint(canvas.get(), 0, 0);
1267 auto rects = paragraph->getRectsForRange(0, impl->text().size(), RectHeightStyle::kMax, RectWidthStyle::kTight);
1271 impl->lines()[0].scanStyles(
1298 impl->lines()[1].scanStyles(
1319 TestCanvas canvas(
"SkParagraph_DefaultStyleParagraph.png");
1320 const char*
text =
"No TextStyle! Uh Oh!";
1321 const size_t len = strlen(
text);
1332 auto paragraph =
builder.Build();
1334 paragraph->paint(canvas.get(), 10.0, 15.0);
1345 impl->lines()[0].scanStyles(
1359 TestCanvas canvas(
"SkParagraph_BoldParagraph.png");
1360 const char*
text =
"This is Red max bold text!";
1361 const size_t len = strlen(
text);
1374 builder.pushStyle(text_style);
1378 auto paragraph =
builder.Build();
1380 paragraph->paint(canvas.get(), 10.0, 60.0);
1391 impl->lines()[0].scanStyles(
1405 TestCanvas canvas(
"SkParagraph_HeightOverrideParagraph.png");
1406 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1407 const size_t len = strlen(
text);
1420 builder.pushStyle(text_style);
1424 auto paragraph =
builder.Build();
1425 paragraph->layout(550);
1432 paragraph->paint(canvas.get(), 0, 0);
1436 paint.setAntiAlias(
true);
1437 paint.setStrokeWidth(1);
1440 RectHeightStyle rect_height_style = RectHeightStyle::kIncludeLineSpacingMiddle;
1443 std::vector<TextBox> boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
1447 boxes = paragraph->getRectsForRange(0, 40, rect_height_style, rect_width_style);
1450 if (boxes.size() >= 3) {
1462 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1463 const size_t len = strlen(
text);
1465 TestCanvas canvas(
"SkParagraph_BasicHalfLeading.png");
1480 builder.pushStyle(text_style);
1483 auto paragraph =
builder.Build();
1484 paragraph->layout(550);
1490 paragraph->paint(canvas.get(), 0, 0);
1493 std::vector<TextBox> boxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kTight, rect_width_style);
1494 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kMax, rect_width_style);
1499 if (boxes.size() >= 3) {
1500 const auto line_spacing1 = boxes[1].rect.top() - boxes[0].rect.bottom();
1501 const auto line_spacing2 = boxes[2].rect.top() - boxes[1].rect.bottom();
1521 const char*
text =
"Cookies need love";
1522 const size_t len = strlen(
text);
1524 TestCanvas canvas(
"SkParagraph_ZeroHeightHalfLeading.png");
1541 builder.pushStyle(text_style);
1546 builder.pushStyle(text_style);
1549 auto paragraph =
builder.Build();
1550 paragraph->layout(550);
1551 paragraph->paint(canvas.get(), 0, 0);
1560 std::vector<TextBox> boxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kTight, rect_width_style);
1561 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kMax, rect_width_style);
1568 const auto metricsAscent = -18.5546875f;
1569 const auto metricsDescent = 4.8828125f;
1579 const auto run1_ascent = (metricsAscent + metricsDescent) / 2;
1580 const auto run1_descent = (metricsAscent + metricsDescent) / 2;
1581 const auto run2_ascent = 0.0f;
1582 const auto run2_descent = 0.0f;
1583 const auto line_top =
std::min(run1_ascent, run2_ascent);
1584 const auto line_bottom =
std::max(run1_descent, run2_descent);
1587 const auto glyphs_top = metricsAscent - line_top;
1588 const auto glyphs_bottom = metricsDescent - line_top;
1592 const auto actual_glyphs_top = boxes[0].rect.top() - lineBoxes[0].rect.top();
1593 const auto actual_glyphs_bottom = boxes[0].rect.bottom() - lineBoxes[0].rect.top();
1611 const char*
text =
"A";
1612 const size_t len = strlen(
text);
1614 TestCanvas canvas(
"SkParagraph_StrutHalfLeading.png");
1640 builder.pushStyle(text_style);
1643 auto paragraph =
builder.Build();
1644 paragraph->layout(550);
1649 paragraph->paint(canvas.get(), 0, 0);
1652 std::vector<TextBox> boxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kTight, rect_width_style);
1653 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kMax, rect_width_style);
1657 if (lineBoxes.size() >= 1 && boxes.size() >= 1) {
1663 std::vector<LineMetrics> lineMetrics;
1664 paragraph->getLineMetrics(lineMetrics);
1677 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1678 const size_t len = strlen(
text);
1680 TestCanvas canvas(
"SkParagraph_StrutHalfLeading.png");
1706 builder.pushStyle(text_style);
1709 auto paragraph =
builder.Build();
1710 paragraph->layout(550);
1715 paragraph->paint(canvas.get(), 0, 0);
1718 std::vector<TextBox> boxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kTight, rect_width_style);
1719 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kMax, rect_width_style);
1724 if (boxes.size() >= 3) {
1725 const auto line_spacing1 = boxes[1].rect.top() - boxes[0].rect.bottom();
1726 const auto line_spacing2 = boxes[2].rect.top() - boxes[1].rect.bottom();
1745 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
1746 const size_t len = strlen(
text);
1748 TestCanvas canvas(
"SkParagraph_TrimHalfLeading.png");
1764 builder.pushStyle(text_style);
1767 auto paragraph =
builder.Build();
1768 paragraph->layout(550);
1769 paragraph->paint(canvas.get(), 0, 0);
1773 std::vector<TextBox> boxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kTight, rect_width_style);
1774 std::vector<TextBox> lineBoxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kMax, rect_width_style);
1779 if (boxes.size() >= 3) {
1780 const auto line_spacing1 = boxes[1].rect.top() - boxes[0].rect.bottom();
1781 const auto line_spacing2 = boxes[2].rect.top() - boxes[1].rect.bottom();
1791 const auto halfLeading = lineBoxes[0].rect.bottom() - boxes[0].rect.bottom();
1793 const auto epsilon = EPSILON10;
1808 TestCanvas canvas(
"SkParagraph_LeftAlignParagraph.png");
1810 "This is a very long sentence to test if the text will properly wrap "
1811 "around and go to the next line. Sometimes, short sentence. Longer "
1812 "sentences are okay too because they are nessecary. Very short. "
1813 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1814 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1815 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1816 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1817 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1818 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1819 "mollit anim id est laborum. "
1820 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1821 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1822 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1823 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1824 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1825 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1826 "mollit anim id est laborum.";
1827 const size_t len = strlen(
text);
1844 builder.pushStyle(text_style);
1848 auto paragraph =
builder.Build();
1850 paragraph->paint(canvas.get(), 0, 0);
1860 double expected_y = 0;
1861 double epsilon = 0.01f;
1874 expected_y += 30 * 10;
1879 paragraph_style.
getTextAlign() == impl->paragraphStyle().getTextAlign());
1892 TestCanvas canvas(
"SkParagraph_RightAlignParagraph.png");
1894 "This is a very long sentence to test if the text will properly wrap "
1895 "around and go to the next line. Sometimes, short sentence. Longer "
1896 "sentences are okay too because they are nessecary. Very short. "
1897 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1898 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1899 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1900 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1901 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1902 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1903 "mollit anim id est laborum. "
1904 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1905 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1906 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1907 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1908 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1909 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1910 "mollit anim id est laborum.";
1911 const size_t len = strlen(
text);
1928 builder.pushStyle(text_style);
1932 auto paragraph =
builder.Build();
1935 paragraph->paint(canvas.get(), 0, 0);
1944 double expected_y = 0;
1945 double epsilon = 0.01f;
1958 expected_y += 30 * 10;
1973 paragraph_style.
getTextAlign() == impl->paragraphStyle().getTextAlign());
1979 TestCanvas canvas(
"SkParagraph_CenterAlignParagraph.png");
1981 "This is a very long sentence to test if the text will properly wrap "
1982 "around and go to the next line. Sometimes, short sentence. Longer "
1983 "sentences are okay too because they are nessecary. Very short. "
1984 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1985 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1986 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1987 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1988 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1989 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1990 "mollit anim id est laborum. "
1991 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
1992 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
1993 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
1994 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
1995 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
1996 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
1997 "mollit anim id est laborum.";
1998 const size_t len = strlen(
text);
2015 builder.pushStyle(text_style);
2019 auto paragraph =
builder.Build();
2021 paragraph->paint(canvas.get(), 0, 0);
2031 double expected_y = 0;
2032 double epsilon = 0.01f;
2045 expected_y += 30 * 10;
2060 paragraph_style.
getTextAlign() == impl->paragraphStyle().getTextAlign());
2066 TestCanvas canvas(
"SkParagraph_JustifyAlignParagraph.png");
2068 "This is a very long sentence to test if the text will properly wrap "
2069 "around and go to the next line. Sometimes, short sentence. Longer "
2070 "sentences are okay too because they are nessecary. Very short. "
2071 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
2072 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
2073 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
2074 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
2075 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
2076 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
2077 "mollit anim id est laborum. "
2078 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
2079 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
2080 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
2081 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
2082 "velit esse cillum dolore eu fugiat.";
2083 const size_t len = strlen(
text);
2100 builder.pushStyle(text_style);
2104 auto paragraph =
builder.Build();
2106 paragraph->paint(canvas.get(), 0, 0);
2110 auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2120 double expected_y = 0;
2133 expected_y += 30 * 9;
2138 return line.offset().fX;
2147 paragraph_style.
getTextAlign() == impl->paragraphStyle().getTextAlign());
2154 TestCanvas canvas(
"SkParagraph_JustifyRTL.png");
2156 "אאא בּבּבּבּ אאאא בּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ "
2157 "אאאאא בּבּבּבּבּ אאאבּבּבּבּבּבּאאאאא בּבּבּבּבּבּאאאאאבּבּבּבּבּבּ אאאאא בּבּבּבּבּ "
2158 "אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ "
2159 "אאאאאבּבּבּבּבּבּאאאאאבּבּבּבּבּבּאאאאאבּבּבּבּבּבּ "
2160 "אאאאא בּבּבּבּבּבּ";
2161 const size_t len = strlen(
text);
2174 builder.pushStyle(text_style);
2178 auto paragraph =
builder.Build();
2180 paragraph->paint(canvas.get(), 0, 0);
2187 for (
auto&
line : impl->lines()) {
2188 if (&
line == &impl->lines().back() || &
line == &impl->lines()[impl->lines().size() - 2]) {
2198 for (
auto&
run : impl->runs()) {
2205 auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2209 boxes = paragraph->getRectsForRange(226, 278, rect_height_style, rect_width_style);
2218 boxes = paragraph->getRectsForRange(292, 296, rect_height_style, rect_width_style);
2231 TestCanvas canvas(
"SkParagraph_JustifyRTLNewLine.png");
2233 "אאא בּבּבּבּ אאאא\nבּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ "
2234 "אאאאא בּבּבּבּבּ אאאבּבּבּבּבּבּאאאאא בּבּבּבּבּבּאאאאאבּבּבּבּבּבּ אאאאא בּבּבּבּבּ "
2235 "אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ";
2236 const size_t len = strlen(
text);
2249 builder.pushStyle(text_style);
2253 auto paragraph =
builder.Build();
2255 paragraph->paint(canvas.get(), 0, 0);
2261 paint.setAntiAlias(
true);
2262 paint.setStrokeWidth(1);
2268 auto boxes = paragraph->getRectsForRange(0, 30, rect_height_style, rect_width_style);
2269 for (
size_t i = 0;
i < boxes.size(); ++
i) {
2270 canvas.get()->drawRect(boxes[
i].
rect,
paint);
2273 if (boxes.size() >= 2) {
2281 boxes = paragraph->getRectsForRange(240, 250, rect_height_style, rect_width_style);
2282 for (
size_t i = 0;
i < boxes.size(); ++
i) {
2283 canvas.get()->drawRect(boxes[
i].
rect,
paint);
2286 if (boxes.size() >= 1) {
2295 for (
auto&
line : impl->lines()) {
2296 ptrdiff_t num = &
line - impl->lines().data();
2297 if (num == 0 || num == 5) {
2310 TestCanvas canvas(
"SkParagraph_LeadingSpaceRTL.png");
2312 const char*
text =
" leading space";
2313 const size_t len = strlen(
text);
2326 builder.pushStyle(text_style);
2330 auto paragraph =
builder.Build();
2332 paragraph->paint(canvas.get(), 0, 0);
2336 paint.setAntiAlias(
true);
2337 paint.setStrokeWidth(1);
2343 auto boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2344 for (
size_t i = 0;
i < boxes.size(); ++
i) {
2345 canvas.get()->drawRect(boxes[
i].
rect,
paint);
2353 TestCanvas canvas(
"SkParagraph_DecorationsParagraph.png");
2354 const char* text1 =
"This text should be";
2355 const char* text2 =
" decorated even when";
2356 const char* text3 =
" wrapped around to";
2357 const char* text4 =
" the next line.";
2358 const char* text5 =
" Otherwise, bad things happen.";
2380 builder.pushStyle(text_style);
2381 builder.addText(text1, strlen(text1));
2386 builder.pushStyle(text_style);
2387 builder.addText(text2, strlen(text2));
2391 builder.pushStyle(text_style);
2392 builder.addText(text3, strlen(text3));
2397 builder.pushStyle(text_style);
2398 builder.addText(text4, strlen(text4));
2403 builder.pushStyle(text_style);
2404 builder.addText(text5, strlen(text5));
2407 auto paragraph =
builder.Build();
2409 paragraph->paint(canvas.get(), 0, 0);
2414 for (
auto&
line : impl->lines()) {
2474 TestCanvas canvas(
"SkParagraph_ItalicsParagraph.png");
2475 const char* text1 =
"No italic ";
2476 const char* text2 =
"Yes Italic ";
2477 const char* text3 =
"No Italic again.";
2487 builder.pushStyle(text_style);
2488 builder.addText(text1, strlen(text1));
2492 builder.pushStyle(text_style);
2493 builder.addText(text2, strlen(text2));
2495 builder.addText(text3, strlen(text3));
2497 auto paragraph =
builder.Build();
2499 paragraph->paint(canvas.get(), 0, 0);
2506 auto&
line = impl->lines()[0];
2538 TestCanvas canvas(
"SkParagraph_ChineseParagraph.png");
2540 " 左線読設重説切後碁給能上目秘使約。満毎冠行来昼本可必図将発確年。今属場育"
2541 "図情闘陰野高備込制詩西校客。審対江置講今固残必託地集済決維駆年策。立得庭"
2542 "際輝求佐抗蒼提夜合逃表。注統天言件自謙雅載報紙喪。作画稿愛器灯女書利変探"
2543 "訃第金線朝開化建。子戦年帝励害表月幕株漠新期刊人秘。図的海力生禁挙保天戦"
2545 const size_t len = strlen(
text);
2565 builder.pushStyle(text_style);
2569 auto paragraph =
builder.Build();
2571 paragraph->paint(canvas.get(), 0, 0);
2580 if (impl->styles().size() >= 1) {
2589 TestCanvas canvas(
"SkParagraph_ArabicParagraph.png");
2591 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
2592 "بمباركة التقليدية قام عن. تصفح";
2593 const size_t len = strlen(
text);
2612 builder.pushStyle(text_style);
2616 auto paragraph =
builder.Build();
2618 paragraph->paint(canvas.get(), 0, 0);
2627 if (impl->styles().size() >= 1) {
2637 TestCanvas canvas(
"SkParagraph_ArabicRectsParagraph.png");
2638 const char*
text =
"بمباركة التقليدية قام عن. تصفح يد ";
2639 const size_t len = strlen(
text);
2655 builder.pushStyle(text_style);
2659 auto paragraph =
builder.Build();
2665 paragraph->paint(canvas.get(), 0, 0);
2669 std::vector<TextBox> boxes = paragraph->getRectsForRange(0, 100, rect_height_style, rect_width_style);
2673 if (boxes.size() >= 1) {
2689 TestCanvas canvas(
"SkParagraph_ArabicRectsLTRLeftAlignParagraph.png");
2690 const char*
text =
"Helloبمباركة التقليدية قام عن. تصفح يد ";
2691 const size_t len = strlen(
text);
2707 builder.pushStyle(text_style);
2711 auto paragraph =
builder.Build();
2717 paragraph->paint(canvas.get(), 0, 0);
2722 std::vector<TextBox> boxes = paragraph->getRectsForRange(36, 40, rect_height_style, rect_width_style);
2726 if (boxes.size() >= 2) {
2739 TestCanvas canvas(
"SkParagraph_ArabicRectsLTRRightAlignParagraph.png");
2740 const char*
text =
"Helloبمباركة التقليدية قام عن. تصفح يد ";
2741 const size_t len = strlen(
text);
2757 builder.pushStyle(text_style);
2761 auto paragraph =
builder.Build();
2767 paragraph->paint(canvas.get(), 0, 0);
2771 std::vector<TextBox> boxes =
2772 paragraph->getRectsForRange(36, 40, rect_height_style, rect_width_style);
2776 if (boxes.size() >= 2) {
2787 TestCanvas canvas(
"SkParagraph_GetGlyphPositionAtCoordinateParagraph.png");
2789 "12345 67890 12345 67890 12345 67890 12345 67890 12345 67890 12345 "
2791 const size_t len = strlen(
text);
2812 auto paragraph =
builder.Build();
2813 paragraph->layout(550);
2814 paragraph->paint(canvas.get(), 0, 0);
2822 paragraph->getGlyphPositionAtCoordinate(-10000, -10000).position == 0);
2828 paragraph->getGlyphPositionAtCoordinate(300, 2).position == 11);
2837 paragraph->getGlyphPositionAtCoordinate(20, -80).position == 1);
2851 TestCanvas canvas(
"SkParagraph_GetRectsForRangeParagraph.png");
2853 "12345, \"67890\" 12345 67890 12345 67890 12345 67890 12345 67890 12345 "
2855 const size_t len = strlen(
text);
2873 auto paragraph =
builder.Build();
2874 paragraph->layout(550);
2875 paragraph->paint(canvas.get(), 0, 0);
2882 paint.setAntiAlias(
true);
2883 paint.setStrokeWidth(1);
2886 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
2890 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
2893 if (
result.size() >= 1) {
2901 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
2904 if (
result.size() >= 1) {
2912 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
2915 if (
result.size() >= 1) {
2923 auto result = paragraph->getRectsForRange(30, 100, heightStyle, widthStyle);
2926 if (
result.size() >= 4) {
2938 auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
2941 if (
result.size() >= 1) {
2949 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
2957 TestCanvas canvas(
"SkParagraph_GetRectsForRangeTight.png");
2959 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
2960 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
2961 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
2962 const size_t len = strlen(
text);
2986 auto paragraph =
builder.Build();
2987 paragraph->layout(550);
2988 paragraph->paint(canvas.get(), 0, 0);
2993 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
2997 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3000 if (
result.size() >= 1) {
3008 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3011 if (
result.size() >= 1) {
3019 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3022 if (
result.size() >= 2) {
3035 TestCanvas canvas(
"SkParagraph_GetRectsForRangeIncludeLineSpacingMiddle.png");
3037 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3038 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3039 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
3040 const size_t len = strlen(
text);
3060 auto paragraph =
builder.Build();
3061 paragraph->layout(550);
3062 paragraph->paint(canvas.get(), 0, 0);
3064 RectHeightStyle heightStyle = RectHeightStyle::kIncludeLineSpacingMiddle;
3067 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3072 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3075 if (
result.size() >= 1) {
3083 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3086 if (
result.size() >= 1) {
3094 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3097 if (
result.size() >= 1) {
3105 auto result = paragraph->getRectsForRange(30, 150, heightStyle, widthStyle);
3108 if (
result.size() >= 8) {
3141 auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
3144 if (
result.size() >= 2) {
3157 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3166 TestCanvas canvas(
"SkParagraph_GetRectsForRangeIncludeLineSpacingTop.png");
3168 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3169 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3170 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
3171 const size_t len = strlen(
text);
3191 auto paragraph =
builder.Build();
3192 paragraph->layout(550);
3193 paragraph->paint(canvas.get(), 0, 0);
3195 RectHeightStyle heightStyle = RectHeightStyle::kIncludeLineSpacingTop;
3198 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3203 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3206 if (
result.size() >= 1) {
3214 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3217 if (
result.size() >= 1) {
3225 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3228 if (
result.size() >= 1) {
3236 auto result = paragraph->getRectsForRange(30, 150, heightStyle, widthStyle);
3239 if (
result.size() >= 8) {
3272 auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
3275 if (
result.size() >= 2) {
3288 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3297 TestCanvas canvas(
"SkParagraph_GetRectsForRangeIncludeLineSpacingBottom.png");
3299 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3300 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
3301 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
3302 const size_t len = strlen(
text);
3322 auto paragraph =
builder.Build();
3323 paragraph->layout(550);
3324 paragraph->paint(canvas.get(), 0, 0);
3326 RectHeightStyle heightStyle = RectHeightStyle::kIncludeLineSpacingBottom;
3329 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3334 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3337 if (
result.size() >= 1) {
3345 auto result = paragraph->getRectsForRange(2, 8, heightStyle, widthStyle);
3348 if (
result.size() >= 1) {
3356 auto result = paragraph->getRectsForRange(8, 21, heightStyle, widthStyle);
3359 if (
result.size() >= 1) {
3367 auto result = paragraph->getRectsForRange(30, 150, heightStyle, widthStyle);
3370 if (
result.size() >= 8) {
3403 auto result = paragraph->getRectsForRange(19, 22, heightStyle, widthStyle);
3406 if (
result.size() >= 2) {
3419 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3429 TestCanvas canvas(
"SkParagraph_GetRectsForRangeIncludeCombiningCharacter.png");
3430 const char*
text =
"ดีสวัสดีชาวโลกที่น่ารัก";
3431 const size_t len = strlen(
text);
3451 auto paragraph =
builder.Build();
3453 paragraph->paint(canvas.get(), 0, 0);
3461 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3465 auto first = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3466 auto second = paragraph->getRectsForRange(1, 2, heightStyle, widthStyle);
3467 auto last = paragraph->getRectsForRange(0, 2, heightStyle, widthStyle);
3472 auto first = paragraph->getRectsForRange(3, 4, heightStyle, widthStyle);
3473 auto second = paragraph->getRectsForRange(4, 5, heightStyle, widthStyle);
3474 auto last = paragraph->getRectsForRange(3, 5, heightStyle, widthStyle);
3479 auto first = paragraph->getRectsForRange(14, 15, heightStyle, widthStyle);
3480 auto second = paragraph->getRectsForRange(15, 16, heightStyle, widthStyle);
3481 auto third = paragraph->getRectsForRange(16, 17, heightStyle, widthStyle);
3482 auto last = paragraph->getRectsForRange(14, 17, heightStyle, widthStyle);
3492 TestCanvas canvas(
"SkParagraph_GetRectsForRangeCenterParagraph.png");
3497 const char*
text =
"01234 ";
3498 const size_t len = strlen(
text);
3518 auto paragraph =
builder.Build();
3519 paragraph->layout(550);
3520 paragraph->paint(canvas.get(), 0, 0);
3526 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3531 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3534 if (
result.size() >= 1) {
3543 auto result = paragraph->getRectsForRange(2, 4, heightStyle, widthStyle);
3546 if (
result.size() >= 1) {
3555 auto result = paragraph->getRectsForRange(4, 5, heightStyle, widthStyle);
3558 if (
result.size() >= 1) {
3567 auto result = paragraph->getRectsForRange(4, 6, heightStyle, widthStyle);
3570 if (
result.size() >= 1) {
3579 auto result = paragraph->getRectsForRange(5, 6, heightStyle, widthStyle);
3582 if (
result.size() >= 1) {
3591 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3600 TestCanvas canvas(
"SkParagraph_GetRectsForRangeCenterParagraphNewlineCentered.png");
3601 const char*
text =
"01234\n";
3602 const size_t len = strlen(
text);
3622 auto paragraph =
builder.Build();
3623 paragraph->layout(550);
3625 paragraph->paint(canvas.get(), 0, 0);
3633 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3638 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3641 if (
result.size() >= 1) {
3650 auto result = paragraph->getRectsForRange(6, 7, heightStyle, widthStyle);
3653 if (
result.size() >= 1) {
3666 TestCanvas canvas(
"SkParagraph_GetRectsForRangeCenterMultiLineParagraph.png");
3667 const char*
text =
"01234 \n0123 ";
3668 const size_t len = strlen(
text);
3688 auto paragraph =
builder.Build();
3689 paragraph->layout(550);
3691 paragraph->paint(canvas.get(), 0, 0);
3701 auto result = paragraph->getRectsForRange(0, 0, heightStyle, widthStyle);
3705 auto result = paragraph->getRectsForRange(0, 1, heightStyle, widthStyle);
3708 if (
result.size() >= 1) {
3716 auto result = paragraph->getRectsForRange(2, 4, heightStyle, widthStyle);
3719 if (
result.size() >= 1) {
3727 auto result = paragraph->getRectsForRange(4, 6, heightStyle, widthStyle);
3730 if (
result.size() >= 1) {
3738 auto result = paragraph->getRectsForRange(5, 6, heightStyle, widthStyle);
3741 if (
result.size() >= 1) {
3749 auto result = paragraph->getRectsForRange(10, 12, heightStyle, widthStyle);
3752 if (
result.size() >= 1) {
3760 auto result = paragraph->getRectsForRange(14, 18, heightStyle, widthStyle);
3763 if (
result.size() >= 1) {
3771 auto result = paragraph->getRectsForRange(21, 21, heightStyle, widthStyle);
3780 TestCanvas canvas(
"SkParagraph_GetRectsForRangeStrut.png");
3781 const char*
text =
"Chinese 字典";
3782 const size_t len = strlen(
text);
3802 auto paragraph =
builder.Build();
3803 paragraph->layout(550);
3804 paragraph->paint(canvas.get(), 0, 0);
3807 auto result = paragraph->getRectsForRange(0, 10, RectHeightStyle::kTight, RectWidthStyle::kMax);
3813 auto result = paragraph->getRectsForRange(0, 10, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3816 if (
result.size() >= 1) {
3828 const char*
text =
"A";
3829 const size_t len = strlen(
text);
3852 auto paragraph =
builder.Build();
3853 paragraph->layout(550);
3855 auto result = paragraph->getRectsForRange(0, 1, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3857 if (
result.size() >= 1) {
3868 const char*
text =
"A";
3869 const size_t len = strlen(
text);
3893 auto paragraph =
builder.Build();
3894 paragraph->layout(550);
3897 auto result = paragraph->getRectsForRange(0, 1, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3899 if (
result.size() >= 1) {
3910 TestCanvas canvas(
"SkParagraph_GetRectsForRangeStrutFallback.png");
3911 const char*
text =
"Chinese 字典";
3912 const size_t len = strlen(
text);
3930 auto paragraph =
builder.Build();
3931 paragraph->layout(550);
3932 paragraph->paint(canvas.get(), 0, 0);
3934 auto result1 = paragraph->getRectsForRange(0, 10, RectHeightStyle::kTight, RectWidthStyle::kMax);
3938 auto result2 = paragraph->getRectsForRange(0, 10, RectHeightStyle::kStrut, RectWidthStyle::kMax);
3942 if (result1.size() >= 1 && result2.size() >= 1) {
3951 TestCanvas canvas(
"SkParagraph_GetWordBoundaryParagraph.png");
3952 const char*
text =
"12345 67890 12345 67890 12345 67890 12345 "
3953 "67890 12345 67890 12345 67890 12345";
3954 const size_t len = strlen(
text);
3973 auto paragraph =
builder.Build();
3974 paragraph->layout(550);
3975 paragraph->paint(canvas.get(), 0, 0);
3982 auto boxes = paragraph->getRectsForRange(5, 6, RectHeightStyle::kMax, RectWidthStyle::kTight);
3986 boxes = paragraph->getRectsForRange(6, 7, RectHeightStyle::kMax, RectWidthStyle::kTight);
3990 boxes = paragraph->getRectsForRange(7, 8, RectHeightStyle::kMax, RectWidthStyle::kTight);
4002 boxes = paragraph->getRectsForRange(12, 13, RectHeightStyle::kMax, RectWidthStyle::kTight);
4004 boxes = paragraph->getRectsForRange(13, 14, RectHeightStyle::kMax, RectWidthStyle::kTight);
4006 boxes = paragraph->getRectsForRange(18, 19, RectHeightStyle::kMax, RectWidthStyle::kTight);
4008 boxes = paragraph->getRectsForRange(19, 20, RectHeightStyle::kMax, RectWidthStyle::kTight);
4010 boxes = paragraph->getRectsForRange(24, 25, RectHeightStyle::kMax, RectWidthStyle::kTight);
4012 boxes = paragraph->getRectsForRange(25, 26, RectHeightStyle::kMax, RectWidthStyle::kTight);
4014 boxes = paragraph->getRectsForRange(30, 31, RectHeightStyle::kMax, RectWidthStyle::kTight);
4016 boxes = paragraph->getRectsForRange(31, 32, RectHeightStyle::kMax, RectWidthStyle::kTight);
4027 TestCanvas canvas(
"SkParagraph_SpacingParagraph.png");
4040 builder.pushStyle(text_style);
4046 builder.pushStyle(text_style);
4052 builder.pushStyle(text_style);
4058 builder.pushStyle(text_style);
4062 const char* hSpace =
"H ";
4063 const size_t len = strlen(hSpace);
4067 builder.pushStyle(text_style);
4073 builder.pushStyle(text_style);
4080 builder.pushStyle(text_style);
4084 auto paragraph =
builder.Build();
4085 paragraph->layout(550);
4086 paragraph->paint(canvas.get(), 0, 0);
4110 TestCanvas canvas(
"SkParagraph_LongWordParagraph.png");
4113 "veryverylongwordtoseewherethiswillwraporifitwillatallandifitdoesthenthat"
4114 "wouldbeagoodthingbecausethebreakingisworking.";
4115 const size_t len = strlen(
text);
4129 builder.pushStyle(text_style);
4133 auto paragraph =
builder.Build();
4135 paragraph->paint(canvas.get(), 0, 0);
4141 if (impl->styles().size() >= 1) {
4145 if (impl->lines().size() >= 4) {
4156 TestCanvas canvas(
"SkParagraph_KernScaleParagraph.png");
4158 const char* text1 =
"AVAVAWAH A0 V0 VA To The Lo";
4159 const char* text2 =
" Dialog Text List lots of words to see "
4160 "if kerning works on a bigger set of characters AVAVAW";
4169 builder.pushStyle(text_style);
4170 builder.addText(text1, strlen(text1));
4171 builder.pushStyle(text_style);
4173 builder.pushStyle(text_style);
4176 builder.pushStyle(text_style);
4177 builder.addText(text2, strlen(text2));
4180 auto paragraph =
builder.Build();
4183 paragraph->paint(canvas.get(), 0, 0);
4184 canvas.get()->scale(1, 1);
4190 if (impl->lines().size() >= 3) {
4204 TestCanvas canvas(
"SkParagraph_NewlineParagraph.png");
4206 "line1\nline2 test1 test2 test3 test4 test5 test6 test7\nline3\n\nline4 "
4207 "test1 test2 test3 test4";
4208 const size_t len = strlen(
text);
4220 builder.pushStyle(text_style);
4224 auto paragraph =
builder.Build();
4226 paragraph->paint(canvas.get(), 0, 0);
4232 if (impl->lines().size() >= 7) {
4247 TestCanvas canvas(
"SkParagraph_EmojiParagraph.png");
4249 "😀😃😄😁😆😅😂🤣☺😇🙂😍😡😟😢😻👽💩👍👎🙏👌👋👄👁👦👼👨🚀👨🚒🙋♂️👳👨👨👧👧\
4250 💼👡👠☂🐶🐰🐻🐼🐷🐒🐵🐔🐧🐦🐋🐟🐡🕸🐌🐴🐊🐄🐪🐘🌸🌏🔥🌟🌚🌝💦💧\
4251 ❄🍕🍔🍟🥝🍱🕶🎩🏈⚽🚴♀️🎻🎼🎹🚨🚎🚐⚓🛳🚀🚁🏪🏢🖱⏰📱💾💉📉🛏🔑🔓\
4252 📁🗓📊❤💯🚫🔻♠♣🕓❗🏳🏁🏳️🌈🇮🇹🇱🇷🇺🇸🇬🇧🇨🇳🇧🇴";
4253 const size_t len = strlen(
text);
4264 builder.pushStyle(text_style);
4268 auto paragraph =
builder.Build();
4270 paragraph->paint(canvas.get(), 0, 0);
4277 for (
auto&
line : impl->lines()) {
4278 if (&
line != impl->lines().end() - 1) {
4282 line.width() == 998.25f ||
4283 (998.1 <
line.width() &&
line.width() < 998.2),
4284 "width: %f",
line.width());
4296 TestCanvas canvas(
"SkParagraph_EmojiMultiLineRectsParagraph.png");
4298 "👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧i🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸"
4299 "👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸"
4300 "👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸"
4301 "👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸👩👩👦👩👩👧👧🇺🇸"
4302 "❄🍕🍔🍟🥝🍱🕶🎩🏈⚽🚴♀️🎻🎼🎹🚨🚎🚐⚓🛳🚀🚁🏪🏢🖱⏰📱💾💉📉🛏🔑🔓"
4303 "📁🗓📊❤💯🚫🔻♠♣🕓❗🏳🏁🏳️🌈🇮🇹🇱🇷🇺🇸🇬🇧🇨🇳🇧🇴";
4304 const size_t len = strlen(
text);
4314 builder.pushStyle(text_style);
4318 auto paragraph =
builder.Build();
4320 paragraph->paint(canvas.get(), 0, 0);
4325 auto result = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4328 result = paragraph->getRectsForRange(0, 119, rect_height_style, rect_width_style);
4332 result = paragraph->getRectsForRange(122, 132, rect_height_style, rect_width_style);
4337 auto pos = paragraph->getGlyphPositionAtCoordinate(610, 100).position;
4338 result = paragraph->getRectsForRange(0,
pos, rect_height_style, rect_width_style);
4342 pos = paragraph->getGlyphPositionAtCoordinate(580, 100).position;
4343 result = paragraph->getRectsForRange(0,
pos, rect_height_style, rect_width_style);
4347 pos = paragraph->getGlyphPositionAtCoordinate(560, 100).position;
4348 result = paragraph->getRectsForRange(0,
pos, rect_height_style, rect_width_style);
4357 TestCanvas canvas(
"SkParagraph_RepeatLayoutParagraph.png");
4359 "Sentence to layout at diff widths to get diff line counts. short words "
4360 "short words short words short words short words short words short words "
4361 "short words short words short words short words short words short words "
4363 const size_t len = strlen(
text);
4373 builder.pushStyle(text_style);
4377 auto paragraph =
builder.Build();
4378 paragraph->layout(300);
4386 paragraph->layout(600);
4387 paragraph->paint(canvas.get(), 0, 0);
4397 TestCanvas canvas(
"SkParagraph_Ellipsize.png");
4399 "This is a very long sentence to test if the text will properly wrap "
4400 "around and go to the next line. Sometimes, short sentence. Longer "
4401 "sentences are okay too because they are nessecary. Very short. ";
4402 const size_t len = strlen(
text);
4406 std::u16string ellipsis = u
"\u2026";
4415 builder.pushStyle(text_style);
4419 auto paragraph =
builder.Build();
4421 paragraph->paint(canvas.get(), 0, 0);
4427 if (impl->lines().size() >= 1) {
4428 auto&
line = impl->lines()[0];
4438 TestCanvas canvas(
"SkParagraph_UnderlineShiftParagraph.png");
4439 const char* text1 =
"fluttser ";
4440 const char* text2 =
"mdje";
4441 const char* text3 =
"fluttser mdje";
4452 builder.pushStyle(text_style);
4453 builder.addText(text1, strlen(text1));
4456 builder.pushStyle(text_style);
4457 builder.addText(text2, strlen(text2));
4460 auto paragraph =
builder.Build();
4462 paragraph->paint(canvas.get(), 0, 0);
4469 builder1.
addText(text3, strlen(text3));
4472 auto paragraph1 = builder1.
Build();
4474 paragraph1->paint(canvas.get(), 0, 25);
4481 auto rect = paragraph->getRectsForRange(0, 12, RectHeightStyle::kMax, RectWidthStyle::kTight)
4484 auto rect1 = paragraph1->getRectsForRange(0, 12, RectHeightStyle::kMax, RectWidthStyle::kTight)
4490 for (
size_t i = 0;
i < 12; ++
i) {
4492 auto r1 = paragraph->getRectsForRange(
i,
i + 1, RectHeightStyle::kMax, RectWidthStyle::kTight);
4493 auto r2 = paragraph1->getRectsForRange(
i,
i + 1, RectHeightStyle::kMax, RectWidthStyle::kTight);
4496 if (!r1.empty() && !r2.empty()) {
4507 TestCanvas canvas(
"SkParagraph_SimpleShadow.png");
4508 const char*
text =
"Hello World Text Dialog";
4509 const size_t len = strlen(
text);
4519 builder.pushStyle(text_style);
4522 auto paragraph =
builder.Build();
4524 paragraph->paint(canvas.get(), 10.0, 15.0);
4531 for (
auto&
line : impl->lines()) {
4545 TestCanvas canvas(
"SkParagraph_ComplexShadow.png");
4546 const char*
text =
"Text Chunk ";
4547 const size_t len = strlen(
text);
4557 builder.pushStyle(text_style);
4562 builder.pushStyle(text_style);
4569 builder.pushStyle(text_style);
4575 auto paragraph =
builder.Build();
4577 paragraph->paint(canvas.get(), 10.0, 15.0);
4582 for (
auto&
line : impl->lines()) {
4615 TestCanvas canvas(
"SkParagraph_BaselineParagraph.png");
4617 "左線読設Byg後碁給能上目秘使約。満毎冠行来昼本可必図将発確年。今属場育"
4618 "図情闘陰野高備込制詩西校客。審対江置講今固残必託地集済決維駆年策。立得";
4619 const size_t len = strlen(
text);
4635 builder.pushStyle(text_style);
4639 auto paragraph =
builder.Build();
4641 paragraph->paint(canvas.get(), 0, 0);
4644 paragraph->getMaxWidth(),
4645 paragraph->getIdeographicBaseline());
4647 paragraph->getMaxWidth(),
4648 paragraph->getAlphabeticBaseline());
4662 TestCanvas canvas(
"SkParagraph_FontFallbackParagraph.png");
4664 const char* text1 =
"Roboto 字典 ";
4665 const char* text2 =
"Homemade Apple 字典";
4666 const char* text3 =
"Chinese 字典";
4677 SkString(
"Next one should be a real font..."),
4679 SkString(
"another fake one in between"),
4683 builder.pushStyle(text_style);
4684 builder.addText(text1, strlen(text1));
4691 SkString(
"Next one should be a real font..."),
4693 SkString(
"another fake one in between"),
4697 builder.pushStyle(text_style);
4698 builder.addText(text2, strlen(text2));
4705 SkString(
"Next one should be a real font..."),
4707 SkString(
"another fake one in between"),
4711 builder.pushStyle(text_style);
4712 builder.addText(text3, strlen(text3));
4716 auto paragraph =
builder.Build();
4719 paragraph->paint(canvas.get(), 10.0, 15.0);
4721 size_t spaceRun = 1;
4727 if (impl->runs().size() == 6 + spaceRun) {
4733 auto robotoAdvance = impl->runs()[0].advance().fX +
4734 impl->runs()[1].advance().fX;
4735 robotoAdvance += impl->runs()[2].advance().fX;
4744 REPORTER_ASSERT(
reporter, impl->runs()[3 + spaceRun].correctAscent() != impl->runs()[5 + spaceRun].correctAscent());
4745 REPORTER_ASSERT(
reporter, impl->runs()[3 + spaceRun].correctDescent() != impl->runs()[5 + spaceRun].correctDescent());
4753 TestCanvas canvas(
"SkParagraph_StrutParagraph1.png");
4755 const char*
text =
"01234満毎冠p来É本可\nabcd\n満毎É行p昼本可";
4756 const size_t len = strlen(
text);
4780 builder.pushStyle(text_style);
4784 auto paragraph =
builder.Build();
4785 paragraph->layout(550);
4786 paragraph->paint(canvas.get(), 0, 0);
4795 auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4799 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
4802 if (boxes.size() >= 1) {
4810 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
4813 if (boxes.size() >= 1) {
4821 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
4824 if (boxes.size() >= 1) {
4832 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
4835 if (boxes.size() >= 1) {
4843 auto boxes = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
4846 if (boxes.size() >= 1) {
4854 auto boxes = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
4857 if (boxes.size() >= 1) {
4870 TestCanvas canvas(
"SkParagraph_StrutParagraph2.png");
4872 const char*
text =
"01234ABCDEFGH\nabcd\nABCDEFGH";
4873 const size_t len = strlen(
text);
4898 builder.pushStyle(text_style);
4902 auto paragraph =
builder.Build();
4903 paragraph->layout(550);
4904 paragraph->paint(canvas.get(), 0, 0);
4914 auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
4918 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
4921 if (boxes.size() >= 1) {
4929 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
4932 if (boxes.size() >= 1) {
4940 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
4943 if (boxes.size() >= 1) {
4951 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
4954 if (boxes.size() >= 1) {
4962 auto boxes = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
4965 if (boxes.size() >= 1) {
4973 auto boxes = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
4976 if (boxes.size() >= 1) {
4989 TestCanvas canvas(
"SkParagraph_StrutParagraph3.png");
4992 const char*
text =
"01234満毎p行来昼本可\nabcd\n満毎冠行来昼本可";
4993 const size_t len = strlen(
text);
5017 builder.pushStyle(text_style);
5021 auto paragraph =
builder.Build();
5022 paragraph->layout(550);
5023 paragraph->paint(canvas.get(), 0, 0);
5034 auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
5038 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
5041 if (boxes.size() >= 1) {
5049 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
5052 if (boxes.size() >= 1) {
5060 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
5063 if (boxes.size() >= 1) {
5071 auto boxes = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
5074 if (boxes.size() >= 1) {
5082 auto boxes = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
5085 if (boxes.size() >= 1) {
5093 auto boxes = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
5096 if (boxes.size() >= 1) {
5109 TestCanvas canvas(
"SkParagraph_StrutForceParagraph.png");
5110 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
5111 const size_t len = strlen(
text);
5136 builder.pushStyle(text_style);
5140 auto paragraph =
builder.Build();
5141 paragraph->layout(550);
5142 paragraph->paint(canvas.get(), 0, 0);
5152 auto boxes1 = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
5155 auto boxes2 = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
5158 if (boxes2.size() >= 1) {
5165 auto boxes3 = paragraph->getRectsForRange(0, 1, rect_height_max_style, rect_width_style);
5168 if (boxes3.size() >= 1) {
5175 auto boxes4 = paragraph->getRectsForRange(6, 10, rect_height_style, rect_width_style);
5178 if (boxes4.size() >= 1) {
5185 auto boxes5 = paragraph->getRectsForRange(6, 10, rect_height_max_style, rect_width_style);
5188 if (boxes5.size() >= 1) {
5195 auto boxes6 = paragraph->getRectsForRange(14, 16, rect_height_max_style, rect_width_style);
5198 if (boxes6.size() >= 1) {
5205 auto boxes7 = paragraph->getRectsForRange(20, 25, rect_height_max_style, rect_width_style);
5208 if (boxes7.size() >= 1) {
5220 TestCanvas canvas(
"SkParagraph_StrutDefaultParagraph.png");
5222 const char*
text =
"01234満毎冠行来昼本可\nabcd\n満毎冠行来昼本可";
5223 const size_t len = strlen(
text);
5245 builder.pushStyle(text_style);
5249 auto paragraph =
builder.Build();
5250 paragraph->layout(550);
5251 paragraph->paint(canvas.get(), 0, 0);
5257 auto boxes = paragraph->getRectsForRange(0, 0, rect_height_style, rect_width_style);
5261 auto boxes = paragraph->getRectsForRange(0, 1, rect_height_style, rect_width_style);
5264 if (boxes.size() >= 1) {
5272 auto boxes = paragraph->getRectsForRange(0, 2, rect_height_strut_style, rect_width_style);
5275 if (boxes.size() >= 1) {
5288 TestCanvas canvas(
"SkParagraph_FontFeaturesParagraph.png");
5290 const char*
text =
"12ab\n";
5302 builder.pushStyle(text_style);
5308 builder.pushStyle(text_style);
5314 auto paragraph =
builder.Build();
5317 paragraph->paint(canvas.get(), 10.0, 15.0);
5321 if (paragraph->lineNumber() >= 3) {
5322 auto& tnum_line = impl->lines()[0];
5323 auto& pnum_line = impl->lines()[1];
5340 const char*
text =
"English English 字典 字典 😀😃😄 😀😃😄";
5341 const size_t len = strlen(
text);
5351 builder.pushStyle(text_style);
5355 auto paragraph =
builder.Build();
5361 for (
size_t i = 0;
i < impl->runs().size() - 1; ++
i) {
5362 auto first = impl->
runs()[
i].textRange();
5363 auto next = impl->runs()[
i + 1].textRange();
5372 const char*
text =
"👨👩👧👦";
5373 const size_t len = strlen(
text);
5381 builder.pushStyle(text_style);
5385 auto paragraph =
builder.Build();
5390 auto&
run = impl->runs().front();
5397 std::string toCheckUtf8{utf1to1.data(), utf1to1.size()};
5398 SkASSERT(std::strcmp(text, utf1to1.data()) == 0);
5399 SkASSERT(glyph1to1.size() == 1);
5400 SkASSERT(*glyph1to1.begin() == 1611);
5411 const char*
text =
"p〠q";
5412 const size_t len = strlen(
text);
5422 builder.pushStyle(text_style);
5426 auto paragraph =
builder.Build();
5433 for (
auto&
run : impl->runs()) {
5435 impl->text().begin() +
run.textRange().start, 0,
run.textRange().width(),
5436 run.glyphs(),
run.clusterIndexes(),
5440 std::string toCheckUtf8{utf1to1.data(), utf1to1.size()};
5441 SkASSERT(std::strcmp(text, utf1to1.data()) == 0);
5442 SkASSERT(glyph1to1.size() == 3);
5464 auto test = [&](
const char*
text,
int count,
bool expectedToBeFound) {
5466 builder.pushStyle(text_style);
5469 auto paragraph =
builder.Build();
5473 auto found =
cache.findParagraph(impl);
5475 auto added =
cache.updateParagraph(impl);
5479 test(
"text1", 0,
false);
5480 test(
"text1", 1,
true);
5481 test(
"text2", 1,
false);
5482 test(
"text2", 2,
true);
5483 test(
"text3", 2,
false);
5498 const char*
text =
"text";
5499 const size_t len = strlen(
text);
5501 auto test = [&](
int count,
bool expectedToBeFound) {
5503 builder.pushStyle(text_style);
5506 auto paragraph =
builder.Build();
5510 auto found =
cache.findParagraph(impl);
5512 auto added =
cache.updateParagraph(impl);
5539 auto test = [&](
const char* text1,
5544 bool expectedToBeFound) {
5547 builder.pushStyle(text_style);
5548 builder.addText(text1, strlen(text1));
5551 builder.pushStyle(text_style);
5552 builder.addText(text2, strlen(text2));
5554 auto paragraph =
builder.Build();
5558 auto found =
cache.findParagraph(impl);
5560 auto added =
cache.updateParagraph(impl);
5564 test(
"text",
"",
"Roboto",
"Homemade Apple", 0,
false);
5565 test(
"t",
"ext",
"Roboto",
"Homemade Apple", 1,
false);
5566 test(
"te",
"xt",
"Roboto",
"Homemade Apple", 2,
false);
5567 test(
"tex",
"t",
"Roboto",
"Homemade Apple", 3,
false);
5568 test(
"text",
"",
"Roboto",
"Homemade Apple", 4,
true);
5584 const char*
text =
"text";
5585 const size_t len = strlen(
text);
5587 auto test = [&](
int count,
bool expectedToBeFound) {
5589 builder.pushStyle(text_style);
5592 auto paragraph =
builder.Build();
5596 auto found =
cache.findParagraph(impl);
5598 auto added =
cache.updateParagraph(impl);
5615 fontCollection->enableFontFallback();
5617 TestCanvas canvas(
"SkParagraph_ParagraphWithLineBreak.png");
5625 builder.addText(
"abc\n\ndef");
5628 auto paragraph =
builder.Build();
5630 paragraph->paint(canvas.get(), 0, 0);
5633 auto pos = paragraph->getGlyphPositionAtCoordinate(0, 21);
5635 auto rect = paragraph->getRectsForRange(4, 5, RectHeightStyle::kTight, RectWidthStyle::kTight);
5645 const SkString text(
"null terminator ->\u0000<- on purpose did you see it?");
5655 auto paragraph =
builder.Build();
5672 builder.addPlaceholder(placeholder);
5674 auto paragraph =
builder.Build();
5676 auto result = paragraph->getRectsForPlaceholders();
5684 fontCollection->enableFontFallback();
5685 TestCanvas canvas(
"SkParagraph_Fallbacks.png");
5687 const char* multiScript =
"A1!aÀàĀāƁƀḂⱠꜲꬰəͲἀἏЀЖԠꙐꙮՁخࡔࠇܦআਉઐଘஇఘಧൺඣᭆᯔᮯ᳇ꠈᜅᩌꪈ༇ꥄꡙꫤ᧰៘꧁꧂ᜰᨏᯤᢆᣭᗗꗃⵞ𐒎߷ጩꬤ𖠺‡₩℻Ⅷ↹⋇⏳ⓖ╋▒◛⚧⑆שׁ🅕㊼龜ポ䷤🂡\n";
5688 const size_t len = strlen(multiScript);
5690 const char* androidFonts[] = {
5692 "sans-serif-condensed",
5698 "sans-serif-smallcaps",
5701 for (
auto&
font : androidFonts) {
5712 builder.pushStyle(text_style);
5717 auto paragraph =
builder.Build();
5719 paragraph->paint(canvas.get(), 0, 0);
5720 canvas.get()->translate(0, paragraph->getHeight() + 10);
5728 fontCollection->enableFontFallback();
5729 TestCanvas canvas(
"SkParagraph_Bidi1.png");
5731 std::u16string abc = u
"\u202Dabc";
5732 std::u16string
DEF = u
"\u202EDEF";
5733 std::u16string ghi = u
"\u202Dghi";
5734 std::u16string JKL = u
"\u202EJKL";
5735 std::u16string mno = u
"\u202Dmno";
5737 std::u16string abcDEFghiJKLmno = u
"\u202Dabc\u202EDEF\u202Dghi\u202EJKL\u202Dmno";
5748 builder.pushStyle(text_style);
5753 builder.pushStyle(text_style);
5758 builder.pushStyle(text_style);
5763 builder.pushStyle(text_style);
5768 builder.pushStyle(text_style);
5771 auto paragraph =
builder.Build();
5772 paragraph->layout(400);
5773 paragraph->paint(canvas.get(), 0, 0);
5780 fontCollection->enableFontFallback();
5781 TestCanvas canvas(
"SkParagraph_Bidi2.png");
5783 std::u16string abcD = u
"\u202Dabc\u202ED";
5784 std::u16string EFgh = u
"EF\u202Dgh";
5785 std::u16string iJKLmno = u
"i\u202EJKL\u202Dmno";
5787 std::u16string abcDEFghiJKLmno = u
"\u202Dabc\u202EDEF\u202Dghi\u202EJKL\u202Dmno";
5796 builder.pushStyle(text_style);
5798 builder.pushStyle(text_style);
5800 builder.pushStyle(text_style);
5802 auto paragraph =
builder.Build();
5803 paragraph->layout(360);
5804 paragraph->paint(canvas.get(), 0, 0);
5806 canvas.get()->translate(0, 400);
5809 builder.pushStyle(text_style);
5810 builder.addText(abcDEFghiJKLmno);
5811 auto paragraph =
builder.Build();
5812 paragraph->layout(360);
5813 paragraph->paint(canvas.get(), 0, 0);
5833 auto paragraph =
builder.Build();
5834 paragraph->layout(1000);
5839 TestCanvas canvas(
"SkParagraph_FontResolutions.png");
5842 sk_make_sp<TestFontCollection>(
GetResourcePath(
"fonts").c_str(),
false);
5845 if (!fontCollection->addFontFromFile(
"abc/abc.ttf",
"abc")) {
5849 if (!fontCollection->addFontFromFile(
"abc/abc+grave.ttf",
"abc+grave")) {
5853 if (!fontCollection->addFontFromFile(
"abc/abc+agrave.ttf",
"abc+agrave")) {
5867 builder.pushStyle(text_style);
5870 builder.pushStyle(text_style);
5876 builder.pushStyle(text_style);
5879 builder.pushStyle(text_style);
5882 auto paragraph =
builder.Build();
5887 if (impl->runs().size() >= 2) {
5889 if (impl->runs().front().size() >= 4) {
5895 if (impl->runs().back().size() >= 2) {
5900 paragraph->paint(canvas.get(), 100, 100);
5904 TestCanvas canvas(
"SkParagraph_FontStyle.png");
5914 SkFontStyle::Weight::kLight_Weight,
5915 SkFontStyle::Width::kNormal_Width,
5916 SkFontStyle::Slant::kUpright_Slant
5925 SkFontStyle::Weight::kBold_Weight,
5926 SkFontStyle::Width::kNormal_Width,
5927 SkFontStyle::Slant::kItalic_Slant
5931 builder.addText(
"Default text\n");
5932 builder.pushStyle(boldItalic);
5933 builder.addText(
"Bold and Italic\n");
5935 builder.addText(
"back to normal");
5936 auto paragraph =
builder.Build();
5937 paragraph->layout(250);
5938 paragraph->paint(canvas.get(), 0, 0);
5942 TestCanvas canvas(
"SkParagraph_Shaping.png");
5945 sk_make_sp<TestFontCollection>(
GetResourcePath(
"fonts").c_str(),
true);
5953 SkFontStyle::Weight::kNormal_Weight,
5954 SkFontStyle::Width::kNormal_Width,
5955 SkFontStyle::Slant::kUpright_Slant
5960 builder.pushStyle(text_style);
5961 builder.addText(
"Eat0 apple0 pies0 | Eat1 apple1 pies1 | Eat2 apple2 pies2");
5962 auto paragraph =
builder.Build();
5963 paragraph->layout(380);
5964 paragraph->paint(canvas.get(), 0, 0);
5971 TestCanvas canvas(
"SkParagraph_Ellipsis.png");
5973 const char*
text =
"This\n"
5974 "is a wrapping test. It should wrap at manual newlines, and if softWrap is true, also at spaces.";
5980 auto relayout = [&](
size_t lines,
bool ellipsis,
5993 auto paragraph =
builder.Build();
5994 paragraph->layout(50);
5995 paragraph->paint(canvas.get(), 0, 0);
5996 canvas.get()->translate(50, paragraph->getHeight() + 10);
5997 auto result = paragraph->getRectsForRange(0, strlen(
text), RectHeightStyle::kTight, RectWidthStyle::kTight);
6003 canvas.get()->drawRect(
result.front().rect, background);
6015 relayout(1,
false, 50, 10, 950, 950,
SK_ColorRED);
6023 relayout(1,
false, 50, 10, 950, 950,
SK_ColorRED);
6034 for (
size_t i = 0;
i < 10;
i++)
6037 paint.setAntiAlias(
true);
6051 auto paragraph =
builder.Build();
6052 paragraph->layout(100);
6063 TestCanvas canvas(
"SkParagraph_FormattingInfinity.png");
6065 const char*
text =
"Some text\nAnother line";
6068 paint.setAntiAlias(
true);
6082 auto paragraph =
builder.Build();
6084 paragraph->paint(canvas.get(), 0, 0);
6085 canvas.get()->translate(0, 100);
6088 draw(
"left", TextAlign::kLeft, TextDirection::kLtr);
6089 draw(
"right", TextAlign::kRight, TextDirection::kLtr);
6090 draw(
"center", TextAlign::kCenter, TextDirection::kLtr);
6091 draw(
"justify LTR", TextAlign::kJustify, TextDirection::kLtr);
6092 draw(
"justify RTL", TextAlign::kJustify, TextDirection::kRtl);
6118 TestCanvas canvas(
"SkParagraph_LineMetrics.png");
6120 const char*
text =
"One line of text\n";
6121 const size_t len = strlen(
text);
6132 builder.pushStyle(text_style);
6137 builder.pushStyle(text_style);
6142 builder.pushStyle(text_style);
6147 builder.pushStyle(text_style);
6151 auto paragraph =
builder.Build();
6154 std::vector<LineMetrics> metrics;
6155 paragraph->getLineMetrics(metrics);
6158 SkASSERT(metrics.size() == impl->lines().size());
6159 for (
size_t i = 0;
i < metrics.size(); ++
i) {
6164 SkASSERT( baseline > top && baseline <= bottom);
6167 paragraph->paint(canvas.get(), 0, 0);
6168 auto rects = paragraph->getRectsForRange(0,
len * 4, RectHeightStyle::kMax, RectWidthStyle::kTight);
6176 for (
auto&
rect : rects) {
6177 canvas.get()->drawRect(
rect.rect, red);
6185 for (
auto& metric : metrics) {
6187 auto x1 = metric.fWidth;
6188 auto y = metric.fBaseline;
6189 canvas.get()->drawLine(x0,
y, x1,
y, green);
6194 TestCanvas canvas(
"SkParagraph_PlaceholderHeightInf.png");
6205 placeholder_style.
fWidth = 16.0f;
6214 builder.pushStyle(text_style);
6215 builder.addText(
"Limited by budget");
6216 builder.addPlaceholder(placeholder_style);
6217 auto paragraph =
builder.Build();
6219 paragraph->paint(canvas.get(), 0, 0);
6231 TestCanvas canvas(
"SkParagraph_LineMetricsTextAlign.png");
6239 auto layout = [&](
TextAlign text_align) -> std::pair<SkScalar, SkScalar> {
6242 builder.pushStyle(text_style);
6243 builder.addText(
"Some text that takes more than 200 px");
6244 auto paragraph =
builder.Build();
6245 paragraph->layout(200);
6246 paragraph->paint(canvas.get(), 0, 0);
6247 canvas.get()->translate(0, paragraph->getHeight());
6248 std::vector<LineMetrics> metrics;
6249 paragraph->getLineMetrics(metrics);
6251 return { metrics[0].fLeft, metrics[0].fWidth };
6256 std::tie(
left[0],
width[0]) = layout(TextAlign::kLeft);
6257 std::tie(
left[1],
width[1]) = layout(TextAlign::kCenter);
6258 std::tie(
left[2],
width[2]) = layout(TextAlign::kRight);
6259 std::tie(
left[3],
width[3]) = layout(TextAlign::kJustify);
6274 TestCanvas canvas(
"SkParagraph_FontResolutionInRTL.png");
6275 const char*
text =
" אאא בּבּבּבּ אאאא בּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ ";
6276 const size_t len = strlen(
text);
6289 builder.pushStyle(text_style);
6293 auto paragraph =
builder.Build();
6295 paragraph->paint(canvas.get(), 0, 0);
6304 TestCanvas canvas(
"SkParagraph_FontResolutionInLTR.png");
6305 auto text = u
"abc \u01A2 \u01A2 def";
6316 builder.pushStyle(text_style);
6320 auto paragraph =
builder.Build();
6322 paragraph->paint(canvas.get(), 0, 0);
6326 if (impl->runs().size() >= 5) {
6348 builder.pushStyle(text_style);
6351 auto paragraph =
builder.Build();
6352 paragraph->layout(300000.0f);
6366 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6367 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6368 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6369 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6370 "من أسر وإعلان الخاصّة وهولندا،, عل قائمة الضغوط بالمطالبة تلك. الصفحة "
6371 "عل بمباركة التقليدية قام عن. تصفح";
6382 auto test = [&](
const char*
test,
const char*
text,
bool editing) {
6385 builder.pushStyle(text_style);
6389 auto cache = fontCollection->getParagraphCache();
6390 auto countBefore =
cache->count();
6391 auto paragraph =
builder.Build();
6393 auto countAfter =
cache->count();
6395 if (
test ==
nullptr) {
6403 test(
"Long arabic text", str.
c_str(),
false);
6406 test(
"+2 character at the end", str.
c_str(),
true);
6409 test(
"-2 characters from the end", str.
c_str(),
true);
6412 test(
"+2 character at the start", str.
c_str(),
true);
6414 test(
"-2 characters from the start",
text,
true);
6417 test(
"different strings",
"0123456789 0123456789 0123456789 0123456789 0123456789",
false);
6424 TestCanvas canvas(
"SkParagraph_HeightCalculations.png");
6437 builder.pushStyle(text_style);
6440 auto paragraph =
builder.Build();
6441 paragraph->layout(500);
6442 paragraph->paint(canvas.get(), 0, 0);
6443 canvas.get()->translate(0, paragraph->getHeight());
6447 draw(TextHeightBehavior::kAll,
"Hello\nLine 2\nLine 3", 210);
6457 TestCanvas canvas(
"SkParagraph_RTL_With_Styles.png");
6468 const char* arabic =
"قففغغغغقففغغغغقففغغغ";
6481 builder.pushStyle(text_style);
6484 builder.pushStyle(text_style);
6487 auto paragraph =
builder.Build();
6488 paragraph->layout(300);
6489 paragraph->paint(canvas.get(), 0, 0);
6497 TestCanvas canvas(
"SkParagraph_PositionInsideEmoji.png");
6499 std::u16string
text = u
"\U0001f469\u200D\U0001f469\u200D\U0001f467\u200D\U0001f467\U0001f469\U0001f469\U0001f467\U0001f467";
6506 builder.pushStyle(text_style);
6509 auto paragraph =
builder.Build();
6511 paragraph->paint(canvas.get(), 0, 0);
6523 auto family = paragraph->getRectsForRange(0, 11, RectHeightStyle::kTight, RectWidthStyle::kTight);
6524 auto face01 = paragraph->getRectsForRange(11, 13, RectHeightStyle::kTight, RectWidthStyle::kTight);
6525 auto face02 = paragraph->getRectsForRange(13, 15, RectHeightStyle::kTight, RectWidthStyle::kTight);
6526 auto face03 = paragraph->getRectsForRange(15, 17, RectHeightStyle::kTight, RectWidthStyle::kTight);
6527 auto face04 = paragraph->getRectsForRange(17, 19, RectHeightStyle::kTight, RectWidthStyle::kTight);
6529 int32_t words[] = { 11, 13, 15, 17, 19, 21};
6531 for (
auto i : words) {
6532 auto rects = paragraph->getRectsForRange(j,
i, RectHeightStyle::kTight, RectWidthStyle::kTight);
6533 if (rects.empty()) {
6536 auto X = rects[0].rect.centerX();
6537 auto Y = rects[0].rect.centerY();
6538 auto res1 = paragraph->getGlyphPositionAtCoordinate(
X - 5,
Y);
6540 auto res2 = paragraph->getGlyphPositionAtCoordinate(
X + 5,
Y);
6551 TestCanvas canvas(
"SkParagraph_SingleLineHeight1.png");
6564 builder.pushStyle(text_style);
6566 auto paragraph =
builder.Build();
6567 paragraph->layout(80);
6568 paragraph->paint(canvas.get(), 0, 0);
6572 paint(
"Loooooooooooooooooooooooooooooooooooong text");
6580 TestCanvas canvas(
"SkParagraph_SingleLineHeight2.png");
6592 builder.pushStyle(text_style);
6594 auto paragraph =
builder.Build();
6595 paragraph->layout(80);
6596 paragraph->paint(canvas.get(), 0, 0);
6600 paint(
"Loooooooooooooooooooooooooooooooooooong text");
6609 TestCanvas canvas(
"SkParagraph_PlaceholderWidth.png");
6611 const char*
text =
"1 23 456 7890";
6620 auto draw = [&](
bool withPlaceholder) {
6622 builder.pushStyle(text_style);
6624 if (withPlaceholder) {
6628 builder.pushStyle(text_style);
6629 builder.addPlaceholder(placeholder);
6633 auto paragraph =
builder.Build();
6634 paragraph->layout(950);
6635 paragraph->paint(canvas.get(), 0, 0);
6636 canvas.get()->translate(0, paragraph->getHeight());
6637 return paragraph->getMinIntrinsicWidth();
6640 auto len1 =
draw(
true);
6641 auto len2 =
draw(
false);
6653 TestCanvas canvas(
"SkParagraph_GlyphPositionsInEmptyLines.png");
6660 builder.pushStyle(text_style);
6663 auto paragraph =
builder.Build();
6664 paragraph->layout(300);
6665 paragraph->paint(canvas.get(), 0, 0);
6667 auto res1 = paragraph->
6668 getGlyphPositionAtCoordinate(paragraph->getMinIntrinsicWidth(),1);
6671 auto res2 = paragraph->
6672 getGlyphPositionAtCoordinate(0,paragraph->getHeight() * 0.5);
6675 auto res3 = paragraph->
6676 getGlyphPositionAtCoordinate(0,paragraph->getHeight() - 1);
6685 TestCanvas canvas(
"SkParagraph_RTLGlyphPositions.png");
6693 builder.pushStyle(text_style);
6696 auto paragraph =
builder.Build();
6697 paragraph->layout(500);
6698 paragraph->paint(canvas.get(), 0, 0);
6700 std::vector<std::pair<SkScalar, PositionWithAffinity>> checks = {
6713 for (
auto check : checks) {
6714 auto pos = paragraph->getGlyphPositionAtCoordinate(
check.first, 0);
6725 TestCanvas canvas(
"SkParagraph_RTLGlyphPositionsInEmptyLines.png");
6734 builder.pushStyle(text_style);
6736 builder.addText(
"בבבב\n\nאאאא");
6738 auto paragraph =
builder.Build();
6739 paragraph->layout(500);
6740 paragraph->paint(canvas.get(), 0, 0);
6742 auto height = paragraph->getHeight();
6743 auto res1 = paragraph->getGlyphPositionAtCoordinate(0, 0);
6745 auto res2 = paragraph->getGlyphPositionAtCoordinate(0,
height / 2);
6747 auto res3 = paragraph->getGlyphPositionAtCoordinate(0,
height);
6756 TestCanvas canvas(
"SkParagraph_LTRGlyphPositionsForTrailingSpaces.png");
6764 auto test = [&](
const char*
text) {
6765 auto str = straight(
text);
6767 builder.pushStyle(text_style);
6771 auto paragraph =
builder.Build();
6772 paragraph->layout(100);
6773 canvas.get()->translate(0, 20);
6774 canvas.get()->drawRect(
SkRect::MakeXYWH(0, 0, paragraph->getMaxIntrinsicWidth(), paragraph->getHeight()), gray);
6775 paragraph->paint(canvas.get(), 0, 0);
6776 canvas.get()->translate(0, paragraph->getHeight());
6778 for (
size_t i = 0;
i < str.size(); ++
i) {
6779 auto res = paragraph->getGlyphPositionAtCoordinate(
i * 10, 2);
6797 TestCanvas canvas(
"SkParagraph_RTLGlyphPositionsForTrailingSpaces.png");
6806 canvas.get()->translate(200, 0);
6808 auto test = [&](
const char*
text,
int whitespaces) {
6811 builder.pushStyle(text_style);
6815 auto paragraph =
builder.Build();
6816 paragraph->layout(100);
6817 canvas.get()->translate(0, 20);
6818 auto res = paragraph->getRectsForRange(0, str.size(), RectHeightStyle::kTight, RectWidthStyle::kTight);
6820 for (
auto& r : res) {
6827 canvas.get()->drawRect(r.rect, gray);
6830 canvas.get()->drawRect(
SkRect::MakeXYWH(0, 0, 1, paragraph->getHeight()), gray);
6831 paragraph->paint(canvas.get(), 0, 0);
6832 canvas.get()->translate(0, paragraph->getHeight());
6834 for (
int i = 0;
i <
SkToInt(str.size()); ++
i) {
6837 auto pointX = (whitespaces +
i) * 10.0f + 1.0f;
6838 auto pos = paragraph->getGlyphPositionAtCoordinate(pointX, 2);
6846 test(
" hello", -10);
6854 TestCanvas canvas(
"SkParagraph_LTRLineMetricsDoesNotIncludeNewLine.png");
6863 builder.pushStyle(text_style);
6864 builder.addText(
"one two\n\nthree four\nwith spaces \n \n______________________");
6866 auto paragraph =
builder.Build();
6867 paragraph->layout(190);
6868 paragraph->paint(canvas.get(), 0, 0);
6870 std::vector<std::tuple<size_t, size_t, size_t, size_t>> expected = {
6879 std::vector<LineMetrics> metrics;
6880 paragraph->getLineMetrics(metrics);
6881 for (
auto& metric : metrics) {
6883 auto result = expected[metric.fLineNumber];
6896 TestCanvas canvas(
"SkParagraph_RTLLineMetricsDoesNotIncludeNewLine.png");
6897 canvas.get()->translate(100, 100);
6907 builder.pushStyle(text_style);
6908 builder.addText(
mirror(
"______________________\none two\n\nthree four\nwith spaces \n "));
6910 auto paragraph =
builder.Build();
6911 paragraph->layout(190);
6912 paragraph->paint(canvas.get(), 0, 0);
6920 canvas.get()->drawRect(
SkRect::MakeXYWH(0, 0, paragraph->getMaxWidth(), paragraph->getHeight()), gray);
6934 auto boxes = paragraph->getRectsForRange(0, 100, RectHeightStyle::kTight, RectWidthStyle::kTight);
6936 for (
auto& box : boxes) {
6937 canvas.get()->drawRect(box.rect, even ? red : blue);
6944 std::vector<std::tuple<int, int, int, int>> expected = {
6954 std::vector<LineMetrics> metrics;
6955 paragraph->getLineMetrics(metrics);
6956 for (
auto& metric : metrics) {
6958 auto result = expected[metric.fLineNumber];
6970 TestCanvas canvas(
"SkParagraph_PlaceholderPosition.png");
6971 canvas.get()->translate(100, 100);
6980 builder.pushStyle(text_style);
6984 placeholder_style.
fHeight = 10;
6985 placeholder_style.
fWidth = 10;
6988 builder.addPlaceholder(placeholder_style);
6990 auto paragraph =
builder.Build();
6991 paragraph->layout(500);
6992 paragraph->paint(canvas.get(), 0, 0);
6994 auto result = paragraph->getGlyphPositionAtCoordinate(41.0f, 0.0f);
7002 TestCanvas canvas(
"SkParagraph_LineEnd.png");
7003 canvas.get()->translate(100, 100);
7012 builder.pushStyle(text_style);
7019 auto paragraph =
builder.Build();
7020 paragraph->layout(60.0f);
7021 paragraph->paint(canvas.get(), 0, 0);
7023 std::vector<LineMetrics> lm;
7024 paragraph->getLineMetrics(lm);
7031 if (lm.size() >= 4) {
7032 REPORTER_ASSERT(
reporter, lm[0].fEndExcludingWhitespaces == 05 && lm[0].fEndIndex == 06 && lm[0].fEndIncludingNewline == 06);
7033 REPORTER_ASSERT(
reporter, lm[1].fEndExcludingWhitespaces == 11 && lm[1].fEndIndex == 14 && lm[1].fEndIncludingNewline == 14);
7034 REPORTER_ASSERT(
reporter, lm[2].fEndExcludingWhitespaces == 19 && lm[2].fEndIndex == 19 && lm[2].fEndIncludingNewline == 20);
7035 REPORTER_ASSERT(
reporter, lm[3].fEndExcludingWhitespaces == 25 && lm[3].fEndIndex == 28 && lm[3].fEndIncludingNewline == 29);
7043 TestCanvas canvas(
"SkParagraph_Utf16Indexes.png");
7044 canvas.get()->translate(100, 100);
7053 builder.pushStyle(text_style);
7054 builder.addText(
"áéíóú\nxxxx");
7055 auto paragraph =
builder.Build();
7056 paragraph->layout(60.0f);
7057 paragraph->paint(canvas.get(), 0, 0);
7058 std::vector<LineMetrics> lm;
7059 paragraph->getLineMetrics(lm);
7064 if (lm.size() >= 2) {
7065 REPORTER_ASSERT(
reporter, lm[0].fEndExcludingWhitespaces == 05 && lm[0].fEndIndex == 05 && lm[0].fEndIncludingNewline == 06);
7066 REPORTER_ASSERT(
reporter, lm[1].fEndExcludingWhitespaces == 10 && lm[1].fEndIndex == 10 && lm[1].fEndIncludingNewline == 10);
7074 TestCanvas canvas(
"SkParagraph_RTLFollowedByLTR.png");
7075 canvas.get()->translate(100, 100);
7086 builder.pushStyle(text_style);
7087 builder.addText(u
"\u05D0\u05D0\u05D0ABC");
7088 auto paragraph =
builder.Build();
7089 paragraph->layout(100);
7090 paragraph->paint(canvas.get(), 0, 0);
7092 auto boxes = paragraph->getRectsForRange(
7093 0, paragraph->getMaxWidth(), RectHeightStyle::kTight, RectWidthStyle::kTight);
7097 boxes[0].direction == TextDirection::kRtl && boxes[1].direction == TextDirection::kLtr);
7103 std::vector<std::pair<SkScalar, PositionWithAffinity>> checks = {
7120 for (
auto check : checks) {
7121 auto pos = paragraph->getGlyphPositionAtCoordinate(
check.first, 0);
7131 TestCanvas canvas(
"SkParagraph_StrutTopLine.png");
7154 builder.pushStyle(text_style);
7155 builder.addText(u
"Atwater Peel Sherbrooke Bonaventure\nhi\nwasssup!");
7157 auto paragraph =
builder.Build();
7158 paragraph->layout(797);
7159 paragraph->paint(canvas.get(), 0, 0);
7160 auto boxes = paragraph->getRectsForRange(0, 60, RectHeightStyle::kIncludeLineSpacingTop, RectWidthStyle::kMax);
7162 if (boxes.size() >= 4) {
7181 TestCanvas canvas(
"SkParagraph_DifferentFontsTopLine.png");
7196 builder.pushStyle(text_style);
7197 builder.addText(u
"Atwater Peel ");
7199 builder.pushStyle(text_style);
7200 builder.addText(u
"Sherbrooke Bonaventure ");
7202 builder.pushStyle(text_style);
7203 builder.addText(u
"hi wassup!");
7205 auto paragraph =
builder.Build();
7206 paragraph->layout(797);
7207 paragraph->paint(canvas.get(), 0, 0);
7208 auto boxes = paragraph->getRectsForRange(0, 60, RectHeightStyle::kIncludeLineSpacingTop, RectWidthStyle::kMax);
7210 if (boxes.size() >= 4) {
7228 const char*
text =
"Hello World Text Dialog";
7229 const size_t len = strlen(
text);
7235 for (
int iteration = 0; iteration < 2; iteration += 1) {
7242 builder.pushStyle(text_style);
7246 auto paragraph =
builder.Build();
7256 for (
auto&
line : impl->lines()) {
7271 TestCanvas canvas(
"SkParagraph_EllipsisGetRectForRange.png");
7273 "This is a very long sentence to test if the text will properly wrap "
7274 "around and go to the next line. Sometimes, short sentence. Longer "
7275 "sentences are okay too because they are nessecary. Very short. ";
7276 const size_t len = strlen(
text);
7280 std::u16string ellipsis = u
"\u2026";
7289 builder.pushStyle(text_style);
7293 auto paragraph =
builder.Build();
7295 paragraph->paint(canvas.get(), 0, 0);
7302 auto boxes1 = impl->getRectsForRange(0, 2, RectHeightStyle::kTight, RectWidthStyle::kTight);
7305 auto boxes2 = impl->getRectsForRange(0, 3, RectHeightStyle::kTight, RectWidthStyle::kTight);
7316 const char*
text =
"";
7317 const size_t len = strlen(
text);
7337 builder.pushStyle(text_style);
7339 auto paragraph =
builder.Build();
7341 return paragraph->getHeight();
7345 auto height2 = layout(TextHeightBehavior::kAll);
7357 TestCanvas canvas(
"SkParagraph_NonMonotonicGlyphsLTR.png");
7358 std::u16string
text =
7359 u
"\u0068\u0301\u0350\u0312\u0357\u030C\u0369\u0305\u036C\u0304\u0310\u033F\u0366\u0350 ";
7380 builder.pushStyle(text_style);
7382 auto paragraph =
builder.Build();
7385 paragraph->layout(paragraph->getMinIntrinsicWidth() + 1);
7388 bool hasNonMonotonicPlacement =
false;
7389 for (
auto&
run : impl->runs()) {
7392 hasNonMonotonicPlacement =
true;
7395 if (hasNonMonotonicPlacement) {
7401 paragraph->paint(canvas.get(), 0, 0);
7409 TestCanvas canvas(
"SkParagraph_NonMonotonicGlyphsRTL.png");
7410 const char*
text =
"ٱلْرَّحْمَـانُ";
7411 const size_t len = strlen(
text);
7421 builder.pushStyle(text_style);
7423 auto paragraph =
builder.Build();
7426 paragraph->layout(paragraph->getMinIntrinsicWidth() + 1);
7428 bool hasNonMonotonicPlacement =
false;
7429 for (
auto&
run : impl->runs()) {
7432 hasNonMonotonicPlacement =
true;
7435 if (hasNonMonotonicPlacement) {
7440 paragraph->paint(canvas.get(), 0, 0);
7447 auto const text = std::u16string(42000,
'x');
7461 auto paragraph =
builder.Build();
7466 auto t1 = std::thread([&] {
7467 auto result = paragraph->getRectsForRange(0, 2, heightStyle, widthStyle);
7470 auto t2 = std::thread([&] {
7471 auto result = paragraph->getRectsForRange(5, 10, heightStyle, widthStyle);
7479 auto const threads_count = 100;
7480 std::thread threads[threads_count];
7481 for (
auto& thread : threads) {
7484 for (
auto& thread : threads) {
7493 TestCanvas canvas(
"SkParagraph_TabSubstitution.png");
7505 builder1.
addText(
"There is a tab>\t<right here");
7506 auto paragraph1 = builder1.
Build();
7508 paragraph1->paint(canvas.get(), 0, 0);
7513 builder2.
addText(
"There is a tab>\t<right here");
7514 auto paragraph2 = builder2.
Build();
7516 paragraph2->paint(canvas.get(), 0, 0);
7529 fontCollection->enableFontFallback();
7533 std::u16string ellipsis = u
"\u2026";
7539 auto paragraph =
builder.Build();
7540 paragraph->layout(1.);
7542 std::vector<LineMetrics> lm;
7543 paragraph->getLineMetrics(lm);
7551 fontCollection->enableFontFallback();
7553 auto text = std::u16string(u
"hello world");
7560 auto paragraph =
builder.Build();
7561 paragraph->layout(200.);
7563 std::vector<LineMetrics> lm;
7564 paragraph->getLineMetrics(lm);
7567 paragraph->updateFontSize(0,
text.size(), 42);
7568 paragraph->layout(200.);
7569 paragraph->getLineMetrics(lm);
7578 TestCanvas canvas(
"SkParagraph_MultiStyle_Logo.png");
7603 const char* logo1 =
"google_";
7604 const char* logo2 =
"logo";
7605 const char* logo3 =
"go";
7606 const char* logo4 =
"ogle_logo";
7607 const char* logo5 =
"google_lo";
7608 const char* logo6 =
"go";
7615 builder.addText(logo1, strlen(logo1));
7620 builder.addText(logo2, strlen(logo2));
7627 builder.addText(logo3, strlen(logo3));
7632 builder.addText(logo4, strlen(logo4));
7639 builder.addText(logo5, strlen(logo5));
7644 builder.addText(logo6, strlen(logo6));
7646 auto paragraph =
builder.Build();
7647 paragraph->layout(
width - 40);
7648 paragraph->paint(canvas.get(), 20, 20);
7695 TestCanvas canvas(
"SkParagraph_MultiStyle_FFI.png");
7706 builder.pushStyle(text_style);
7709 builder.pushStyle(text_style);
7712 builder.pushStyle(text_style);
7714 auto paragraph =
builder.Build();
7716 paragraph->paint(canvas.get(), 0, 0);
7717 auto width = paragraph->getLongestLine();
7718 auto height = paragraph->getHeight();
7720 auto f1Pos = paragraph->getGlyphPositionAtCoordinate(
width/6 - 5,
height/2);
7721 auto f2Pos = paragraph->getGlyphPositionAtCoordinate(
width/2 - 5,
height/2);
7722 auto iPos = paragraph->getGlyphPositionAtCoordinate(
width*5/6 - 5,
height/2);
7730 auto f1 = paragraph->getRectsForRange(0, 1, RectHeightStyle::kTight,
7731 RectWidthStyle::kTight);
7737 auto f2 = paragraph->getRectsForRange(1, 2, RectHeightStyle::kTight,
7738 RectWidthStyle::kTight);
7744 auto fi = paragraph->getRectsForRange(2, 3, RectHeightStyle::kTight,
7745 RectWidthStyle::kTight);
7757 TestCanvas canvas(
"SkParagraph_MultiStyle_EmojiFamily.png");
7767 builder.pushStyle(text_style);
7768 builder.addText(u
"\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466");
7769 auto paragraph =
builder.Build();
7773 paint.setAntiAlias(
true);
7774 paint.setStrokeWidth(1);
7776 canvas.get()->drawRect(
SkRect::MakeXYWH(0, 0, paragraph->getLongestLine(), paragraph->getHeight()),
paint);
7777 paragraph->paint(canvas.get(), 0, 0);
7778 auto width = paragraph->getLongestLine();
7779 auto height = paragraph->getHeight();
7781 auto pos00 = paragraph->getGlyphPositionAtCoordinate(
width/4,
height/4);
7782 auto pos10 = paragraph->getGlyphPositionAtCoordinate(
width*3/4,
height/2);
7783 auto pos01 = paragraph->getGlyphPositionAtCoordinate(
width/4,
height/2);
7784 auto pos11 = paragraph->getGlyphPositionAtCoordinate(
width*3/4,
height*3/4);
7793 auto f1 = paragraph->getRectsForRange(0, 2, RectHeightStyle::kTight, RectWidthStyle::kTight);
7796 auto f2 = paragraph->getRectsForRange(4, 6, RectHeightStyle::kTight, RectWidthStyle::kTight);
7799 auto f3 = paragraph->getRectsForRange(8, 10, RectHeightStyle::kTight, RectWidthStyle::kTight);
7802 auto f4 = paragraph->getRectsForRange(8, 10, RectHeightStyle::kTight, RectWidthStyle::kTight);
7811 TestCanvas canvas(
"SkParagraph_MultiStyle_Arabic.png");
7824 builder.pushStyle(text_style);
7827 builder.pushStyle(text_style);
7830 builder.pushStyle(text_style);
7832 auto paragraph =
builder.Build();
7834 paragraph->paint(canvas.get(), 0, 0);
7836 auto width = paragraph->getLongestLine();
7837 auto height = paragraph->getHeight();
7848 auto f1 = paragraph->getRectsForRange(0, 1, RectHeightStyle::kTight, RectWidthStyle::kTight);
7851 auto f2 = paragraph->getRectsForRange(1, 2, RectHeightStyle::kTight, RectWidthStyle::kTight);
7854 auto fi = paragraph->getRectsForRange(2, 3, RectHeightStyle::kTight, RectWidthStyle::kTight);
7864 TestCanvas canvas(
"SkParagraph_MultiStyle_Zalgo.png");
7869 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<";
7871 auto K =
text.find(
"k");
7872 auto P =
text.find(
"P");
7873 auto h =
text.find(
"h");
7880 builder.pushStyle(text_style);
7884 builder.pushStyle(text_style);
7887 builder.pushStyle(text_style);
7891 builder.pushStyle(text_style);
7893 auto paragraph =
builder.Build();
7895 paragraph->paint(canvas.get(), 0, paragraph->getHeight() / 2);
7897 auto height = paragraph->getHeight();
7899 auto resSK = paragraph->getRectsForRange(0,
K, RectHeightStyle::kTight,
7900 RectWidthStyle::kTight);
7904 auto resKP = paragraph->getRectsForRange(
K,
P, RectHeightStyle::kTight,
7905 RectWidthStyle::kTight);
7910 auto resPh = paragraph->getRectsForRange(
P,
h, RectHeightStyle::kTight,
7911 RectWidthStyle::kTight);
7915 auto posK = paragraph->getGlyphPositionAtCoordinate(resSK.back().rect.fRight,
height/2);
7916 auto posP = paragraph->getGlyphPositionAtCoordinate(resKP.back().rect.fRight,
height/2);
7917 auto posH = paragraph->getGlyphPositionAtCoordinate(resPh.back().rect.fRight,
height/2);
7926 TestCanvas canvas(
"SkParagraph_RtlEllipsis1.png");
7941 builder.pushStyle(text_style);
7942 builder.addText(u
"1 2 3 4 5 6 7 8 9");
7943 auto paragraph =
builder.Build();
7944 paragraph->layout(474);
7945 paragraph->paint(canvas.get(), 0, 0);
7948 auto&
line = impl->lines()[0];
7950 line.iterateThroughVisualRuns(
true,
7963 TestCanvas canvas(
"SkParagraph_RtlEllipsis2.png");
7978 builder.pushStyle(text_style);
7979 builder.addText(u
"تظاهرات و تجمعات اعتراضی در سراسر کشور ۲۳ مهر");
7980 auto paragraph =
builder.Build();
7981 paragraph->layout(474);
7982 paragraph->paint(canvas.get(), 0, 0);
7985 auto&
line = impl->lines()[1];
7987 line.iterateThroughVisualRuns(
true,
8007 TestCanvas canvas(
"SkParagraph_TextEditingFunctionality.png");
8009 "This is a very long sentence to test if the text will properly wrap "
8010 "around and go to the next line. Sometimes, short sentence. Longer "
8011 "sentences are okay too because they are nessecary. Very short. "
8012 "This is a very long sentence to test if the text will properly wrap "
8013 "around and go to the next line. Sometimes, short sentence. Longer "
8014 "sentences are okay too because they are nessecary. Very short. ";
8016 const size_t len = strlen(
text);
8026 builder.pushStyle(text_style);
8030 auto paragraph =
builder.Build();
8032 paragraph->paint(canvas.get(), 0, 0);
8034 auto lineNumber = paragraph->getLineNumberAt(0);
8036 lineNumber = paragraph->getLineNumberAt(
len / 2);
8038 lineNumber = paragraph->getLineNumberAt(
len - 1);
8040 lineNumber = paragraph->getLineNumberAt(
len);
8042 lineNumber = paragraph->getLineNumberAt(
len + 10);
8046 auto foundMetrics = paragraph->getLineMetricsAt(0, &lineMetrics);
8048 foundMetrics = paragraph->getLineMetricsAt(1, &lineMetrics);
8050 foundMetrics = paragraph->getLineMetricsAt(3, &lineMetrics);
8052 foundMetrics = paragraph->getLineMetricsAt(10, &lineMetrics);
8055 std::vector<LineMetrics> metrics;
8056 paragraph->getLineMetrics(metrics);
8057 auto actualText = paragraph->getActualTextRange(0,
false);
8059 actualText = paragraph->getActualTextRange(1,
false);
8061 actualText = paragraph->getActualTextRange(2,
false);
8065 auto foundCluster = paragraph->getGlyphClusterAt(0, &glyphInfo);
8067 foundCluster = paragraph->getGlyphClusterAt(
len / 2, &glyphInfo);
8069 foundCluster = paragraph->getGlyphClusterAt(
len, &glyphInfo);
8072 auto foundClosest = paragraph->getClosestGlyphClusterAt(0, 10, &glyphInfo);
8075 foundClosest = paragraph->getClosestGlyphClusterAt(
TestCanvasWidth / 2, 20, &glyphInfo);
8078 foundClosest = paragraph->getClosestGlyphClusterAt(
TestCanvasWidth + 10, 30, &glyphInfo);
8083 auto font = paragraph->getFontAt(10);
8086 font.getTypeface()->getFamilyName(&fontFamily);
8089 auto fonts = paragraph->getFonts();
8093 font.getTypeface()->getFamilyName(&fontFamily);
8101 TestCanvas canvas(
"SkParagraph_Ellipsis.png");
8105 const char*
text =
"This\n"
8108 const size_t len = strlen(
text);
8120 builder.pushStyle(text_style);
8123 auto paragraph =
builder.Build();
8126 paragraph->layout(100);
8142 const char*
text =
"一丁丂七";
8143 const size_t len = strlen(
text);
8151 builder.pushStyle(text_style);
8155 auto paragraph =
builder.Build();
8186 const char*
text =
"";
8194 builder.pushStyle(text_style);
8198 auto paragraph =
builder.Build();
8210 const char*
text =
"fi";
8211 const size_t len = strlen(
text);
8219 builder.pushStyle(text_style);
8223 auto paragraph =
builder.Build();
8239 const char*
text =
"لٔأ";
8240 const size_t len = strlen(
text);
8248 builder.pushStyle(text_style);
8252 auto paragraph =
builder.Build();
8254 TestCanvas canvas(
"SkParagraph_laam_alif_diacritics.png");
8255 paragraph->paint(canvas.get(), 50, 50);
8259 const auto boxes = paragraph->getRectsForRange(0,
len, RectHeightStyle::kTight, RectWidthStyle::kTight);
8261 const SkRect fullRect = boxes[0].rect;
8298 const char*
text =
"Single dummy placeholder";
8299 const size_t len = strlen(
text);
8308 builder.pushStyle(text_style);
8311 auto paragraph =
builder.Build();
8318 for (
auto&
line : impl->lines()) {
8333 const char*
text =
"A text ending with line separator.\u2028";
8334 const size_t len = strlen(
text);
8344 auto paragraph =
builder.Build();
8347 int visitedCount = 0;
8350 if (lineNumber == 1) {
8363 const char*
text =
"♻️🏴";
8364 const char* text1 =
"♻️";
8365 const size_t len = strlen(
text);
8366 const size_t len1 = strlen(text1);
8372 builder.pushStyle(text_style);
8374 auto paragraph =
builder.Build();
8382 builder1.
addText(text1, len1);
8383 auto paragraph1 = builder1.
Build();
8388 if (impl1->runs().size() == 1) {
8390 impl->run(0).font().getTypeface()->getFamilyName(&ff);
8392 impl1->run(0).font().getTypeface()->getFamilyName(&ff1);
8397#if defined(SK_UNICODE_ICU_IMPLEMENTATION)
8403#if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
8428 for (
auto& cp : codeUnitProperties) {
8440 auto emojiStart = OneLineShaper::getEmojiSequenceStart(icu.
get(), &
begin,
end);
8459 test(
"😊abc", 128522);
8460 test(
"😊*️⃣",128522);
8461 test(
"👨👩👦👦", 128104);
8468 test(
"🏴", 127988);
8470 test(
"👨👩👧👦", 128104);
8473#if defined(SK_UNICODE_ICU_IMPLEMENTATION)
8479#if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
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 DEFINE_bool(run_paragraph_tests_needing_system_fonts, true, "Some tests are finicky and need certain system fonts. " "Set this to false to skip those.")
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)
DEF_TEST_DISABLED(SkParagraph_GetRectsForRangeIncludeCombiningCharacter, 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 DEFINE_string(paragraph_fonts, "", "subdirectory of //resources for fonts to use for these tests")
UNIX_ONLY_TEST(SkParagraph_SimpleParagraph, reporter)
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
sk_sp< SkUnicode > get_unicode()
void SkTQSort(T *begin, T *end, const C &lessThan)
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
constexpr int SkToInt(S x)
constexpr uint32_t SkToU32(S x)
#define REPORTER_ASSERT(r, cond,...)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
sk_sp< SkTypeface > makeFromStream(std::unique_ptr< SkStreamAsset >, int ttcIndex=0) const
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
std::unique_ptr< SkStreamAsset > openExistingStream(int *ttcIndex) const
void getFamilyName(SkString *name) const
virtual bool isEmojiComponent(SkUnichar utf8)=0
static bool hasGraphemeStartFlag(SkUnicode::CodeUnitFlags flags)
static SkString convertUtf16ToUtf8(const char16_t *utf16, int utf16Units)
virtual bool isEmoji(SkUnichar utf8)=0
virtual bool computeCodeUnitFlags(char utf8[], int utf8Units, bool replaceTabs, skia_private::TArray< SkUnicode::CodeUnitFlags, true > *results)=0
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)
static float max(float r, float g, float b)
static float min(float r, float g, float b)
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< SkBlender > blender SkRect rect
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()
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library name
it will be possible to load the file into Perfetto s trace viewer disable asset fonts
font
Font Metadata and Metrics.
const myers::Point & get< 1 >(const myers::Segment &s)
const myers::Point & get< 0 >(const myers::Segment &s)
const myers::Point & get(const myers::Segment &)
static bool nearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
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)