diff --git a/modules/skparagraph/samples/SampleParagraph.cpp b/modules/skparagraph/samples/SampleParagraph.cpp index 67d2fb647c..f3163c9993 100644 --- a/modules/skparagraph/samples/SampleParagraph.cpp +++ b/modules/skparagraph/samples/SampleParagraph.cpp @@ -3416,6 +3416,57 @@ private: using INHERITED = Sample; }; +void print_line_metrics(std::vector metrics) { + for (size_t i = 0; i < metrics.size(); ++i) { + auto& line = metrics[i]; + printf("Line[%zd] startIndex=%zd, endIndex=%zd, endExcludingWhitespaces=%zd, _endIncludingNewline=%zd, hardBreak=%d, baseline=%.2f, ascent=%.2f, descent=%.2f, unscaledAscent=%.2f, height=%.2f, width=%.2f, left=%.2f, lineNumber=%zd\n", + i, + line.fStartIndex, line.fEndIndex, + line.fEndExcludingWhitespaces, line.fEndIncludingNewline, + line.fHardBreak, + line.fBaseline, line.fAscent, line.fDescent, line.fUnscaledAscent, + line.fHeight, line.fWidth, line.fLeft, + line.fLineNumber); + } +} + +class ParagraphView58 : public ParagraphView_Base { +protected: + SkString name() override { return SkString("Paragraph58"); } + + void onDrawContent(SkCanvas* canvas) override { + canvas->drawColor(SK_ColorWHITE); + + auto fontCollection = getFontCollection(); + fontCollection->setDefaultFontManager(SkFontMgr::RefDefault()); + fontCollection->enableFontFallback(); + + ParagraphStyle paragraph_style; + + ParagraphBuilderImpl builder(paragraph_style, fontCollection); + TextStyle text_style; + text_style.setFontFamilies({SkString("Roboto")}); + text_style.setFontSize(32); + text_style.setHeight(5.0); + text_style.setHeightOverride(true); + text_style.setColor(SK_ColorBLACK); + builder.pushStyle(text_style); + builder.addText("Line1\nLine2\nLine3\nLine4\n"); + + auto paragraph = builder.Build(); + paragraph->layout(width()); + paragraph->paint(canvas, 0, 0); + + std::vector metrics; + paragraph->getLineMetrics(metrics); + + print_line_metrics(metrics); + } + +private: + using INHERITED = Sample; +}; + } // namespace ////////////////////////////////////////////////////////////////////////////// @@ -3474,3 +3525,4 @@ DEF_SAMPLE(return new ParagraphView54();) DEF_SAMPLE(return new ParagraphView55();) DEF_SAMPLE(return new ParagraphView56();) DEF_SAMPLE(return new ParagraphView57();) +DEF_SAMPLE(return new ParagraphView58();) diff --git a/modules/skparagraph/src/OneLineShaper.cpp b/modules/skparagraph/src/OneLineShaper.cpp index d1707b8dac..be6ae9e5bc 100644 --- a/modules/skparagraph/src/OneLineShaper.cpp +++ b/modules/skparagraph/src/OneLineShaper.cpp @@ -299,6 +299,7 @@ void OneLineShaper::addUnresolvedWithRun(GlyphRange glyphRange) { #ifndef SK_PARAGRAPH_GRAPHEME_EDGES void OneLineShaper::sortOutGlyphs(std::function&& sortOutUnresolvedBLock) { + auto text = fCurrentRun->fOwner->text(); size_t unresolvedGlyphs = 0; GlyphRange block = EMPTY_RANGE; @@ -314,8 +315,13 @@ void OneLineShaper::sortOutGlyphs(std::function&& sortOutUnres GraphemeIndex gi = fParagraph->findPreviousGraphemeBoundary(ci); if ((fCurrentRun->leftToRight() ? gi > graphemeStart : gi < graphemeStart) || graphemeStart == EMPTY_INDEX) { + // This is the Flutter change + // Do not count control codepoints as unresolved + const char* cluster = text.begin() + ci; + SkUnichar codepoint = nextUtf8Unit(&cluster, text.end()); + bool isControl8 = fParagraph->getUnicode()->isControl(codepoint); // We only count glyph resolved if all the glyphs in its grapheme are resolved - graphemeResolved = glyph != 0; + graphemeResolved = glyph != 0 || isControl8; graphemeStart = gi; } else if (glyph == 0) { // Found unresolved glyph - the entire grapheme is unresolved now