Attach an ellipsis to the end of a grapheme

Flutter bugs:
https://github.com/flutter/flutter/issues/18761
https://github.com/flutter/flutter/issues/114949

Change-Id: Ic37554a13589bf169283df18050a2e32faf4794b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/668478
Commit-Queue: Julia Lavrova <jlavrova@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
(cherry picked from commit 0d31aa1f49cb8cfd790c44d92a9a023839524865)
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/681477
Reviewed-by: Eric Boren <borenet@google.com>
diff --git a/modules/skparagraph/slides/ParagraphSlide.cpp b/modules/skparagraph/slides/ParagraphSlide.cpp
index cbaf7f5..66494f6 100644
--- a/modules/skparagraph/slides/ParagraphSlide.cpp
+++ b/modules/skparagraph/slides/ParagraphSlide.cpp
@@ -4011,9 +4011,9 @@
     }
 };
 
-class ParagraphSlideLast : public ParagraphSlide_Base {
+class ParagraphSlideMixedTextDirection : public ParagraphSlide_Base {
 public:
-    ParagraphSlideLast() { fName = "ParagraphSlideLast"; }
+    ParagraphSlideMixedTextDirection() { fName = "ParagraphSlideMixedTextDirection"; }
     void draw(SkCanvas* canvas) override {
         canvas->drawColor(SK_ColorWHITE);
         auto fontCollection = getFontCollection();
@@ -4045,6 +4045,40 @@
         draw(u"تظاهرات و(defalt RTL) تجمعات اعتراضی در سراسر کشور ۲۳ مهر", 2, TextDirection::kRtl);
     }
 };
+
+
+class ParagraphSlideLast : public ParagraphSlide_Base {
+public:
+    ParagraphSlideLast() { fName = "ParagraphSlideLast"; }
+    void draw(SkCanvas* canvas) override {
+        canvas->drawColor(SK_ColorWHITE);
+        auto fontCollection = getFontCollection();
+        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
+        fontCollection->enableFontFallback();
+        TextStyle text_style;
+        text_style.setFontFamilies({SkString("Noto Naskh Arabic")});
+        text_style.setFontSize(100);
+        text_style.setColor(SK_ColorBLACK);
+        ParagraphStyle paragraph_style;
+        paragraph_style.setTextStyle(text_style);
+        paragraph_style.setTextAlign(TextAlign::kStart);
+        paragraph_style.setEllipsis(u"\u2026");
+        auto draw = [&](std::u16string text) {
+            paragraph_style.setMaxLines(1);
+            ParagraphBuilderImpl builder(paragraph_style, fontCollection);
+            builder.pushStyle(text_style);
+            builder.addText(text);
+            auto paragraph = builder.Build();
+            paragraph->layout(this->size().width());
+            paragraph->paint(canvas, 0, 0);
+            canvas->translate(0, paragraph->getHeight() + 10);
+        };
+
+        draw(u"你abcdefsdasdsasas");
+        draw(u"한111111111111111111");
+        draw(u"abcdefsdasds1112222");
+    }
+};
 }  // namespace
 
 //////////////////////////////////////////////////////////////////////////////
@@ -4118,5 +4152,6 @@
 DEF_SLIDE(return new ParagraphSlide_MultiStyle_Arabic1();)
 DEF_SLIDE(return new ParagraphSlide_MultiStyle_Zalgo();)
 DEF_SLIDE(return new ParagraphSlide_MultiStyle_Arabic2();)
+DEF_SLIDE(return new ParagraphSlideMixedTextDirection();)
 DEF_SLIDE(return new ParagraphSlideLast();)
 
diff --git a/modules/skparagraph/src/TextWrapper.cpp b/modules/skparagraph/src/TextWrapper.cpp
index 9e4fcb9..99f7515 100644
--- a/modules/skparagraph/src/TextWrapper.cpp
+++ b/modules/skparagraph/src/TextWrapper.cpp
@@ -174,7 +174,11 @@
     // If nothing fits we show the clipping.
     if (!fWords.empty()) {
         fEndLine.extend(fWords);
-        if (!fTooLongWord || hasEllipsis) {
+#ifdef SK_IGNORE_SKPARAGRAPH_ELLIPSIS_FIX
+        if (!fTooLongWord || hasEllipsis) { // Ellipsis added to a word
+#else
+        if (!fTooLongWord && !hasEllipsis) { // Ellipsis added to a grapheme
+#endif
             return;
         }
     }