Revert "ICU: SkShaper (bidi iterator only)"

This reverts commit 64e3d040e911687a9e65514696c421a50953a6fe.

Reason for revert: Breaking google3

Original change's description:
> ICU: SkShaper (bidi iterator only)
> 
> Change-Id: I845cc0a962790ce37600f943473f21f619ee029b
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/308508
> Reviewed-by: Ben Wagner <bungeman@google.com>
> Commit-Queue: Julia Lavrova <jlavrova@google.com>

TBR=djsollen@google.com,bungeman@google.com,reed@google.com,jlavrova@google.com

Change-Id: Ib081d97f61e57f74bb9414b3973cca640f3b3929
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309442
Reviewed-by: Julia Lavrova <jlavrova@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
diff --git a/modules/skparagraph/src/ParagraphImpl.cpp b/modules/skparagraph/src/ParagraphImpl.cpp
index b0c0470..7849f9a 100644
--- a/modules/skparagraph/src/ParagraphImpl.cpp
+++ b/modules/skparagraph/src/ParagraphImpl.cpp
@@ -83,7 +83,7 @@
         , fOldWidth(0)
         , fOldHeight(0)
         , fOrigin(SkRect::MakeEmpty()) {
-    fICU = ::SkUnicode::Make();
+    fICU = ::skia::SkUnicode::Make();
 }
 
 ParagraphImpl::ParagraphImpl(const std::u16string& utf16text,
diff --git a/modules/skshaper/include/SkShaper.h b/modules/skshaper/include/SkShaper.h
index a8f724f..c0864af 100644
--- a/modules/skshaper/include/SkShaper.h
+++ b/modules/skshaper/include/SkShaper.h
@@ -39,7 +39,6 @@
 
 class SkFont;
 class SkFontMgr;
-class SkUnicode;
 
 /**
    Shapes text using HarfBuzz and places the shaped text into a
@@ -134,9 +133,9 @@
 
     static std::unique_ptr<BiDiRunIterator>
     MakeBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel);
-    #ifdef SK_UNICODE_AVAILABLE
+    #ifdef SK_SHAPER_HARFBUZZ_AVAILABLE
     static std::unique_ptr<BiDiRunIterator>
-    MakeSkUnicodeBidiRunIterator(SkUnicode* unicode, const char* utf8, size_t utf8Bytes, uint8_t bidiLevel);
+    MakeIcuBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel);
     #endif
     class TrivialBiDiRunIterator : public TrivialRunIterator<BiDiRunIterator> {
     public:
diff --git a/modules/skshaper/src/SkShaper.cpp b/modules/skshaper/src/SkShaper.cpp
index 185d349..bd2df51 100644
--- a/modules/skshaper/src/SkShaper.cpp
+++ b/modules/skshaper/src/SkShaper.cpp
@@ -38,13 +38,9 @@
 
 std::unique_ptr<SkShaper::BiDiRunIterator>
 SkShaper::MakeBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel) {
-#ifdef SK_UNICODE_AVAILABLE
-    auto unicode = SkUnicode::Make();
+#ifdef SK_SHAPER_HARFBUZZ_AVAILABLE
     std::unique_ptr<SkShaper::BiDiRunIterator> bidi =
-        SkShaper::MakeSkUnicodeBidiRunIterator(unicode.get(),
-                                               utf8,
-                                               utf8Bytes,
-                                               bidiLevel);
+        SkShaper::MakeIcuBiDiRunIterator(utf8, utf8Bytes, bidiLevel);
     if (bidi) {
         return bidi;
     }
diff --git a/modules/skshaper/src/SkShaper_harfbuzz.cpp b/modules/skshaper/src/SkShaper_harfbuzz.cpp
index fd36b9c..905747f 100644
--- a/modules/skshaper/src/SkShaper_harfbuzz.cpp
+++ b/modules/skshaper/src/SkShaper_harfbuzz.cpp
@@ -26,7 +26,6 @@
 #include "include/private/SkTemplates.h"
 #include "include/private/SkTo.h"
 #include "modules/skshaper/include/SkShaper.h"
-#include "modules/skshaper/src/SkUnicode.h"
 #include "src/core/SkLRUCache.h"
 #include "src/core/SkSpan.h"
 #include "src/core/SkTDPQueue.h"
@@ -35,6 +34,7 @@
 #include <hb.h>
 #include <hb-icu.h>
 #include <hb-ot.h>
+#include <unicode/ubidi.h>
 #include <unicode/ubrk.h>
 #include <unicode/umachine.h>
 #include <unicode/urename.h>
@@ -71,11 +71,10 @@
 using HBFace   = resource<hb_face_t     , decltype(hb_face_destroy)  , hb_face_destroy  >;
 using HBFont   = resource<hb_font_t     , decltype(hb_font_destroy)  , hb_font_destroy  >;
 using HBBuffer = resource<hb_buffer_t   , decltype(hb_buffer_destroy), hb_buffer_destroy>;
+using ICUBiDi  = resource<UBiDi         , decltype(ubidi_close)      , ubidi_close      >;
 using ICUBrk   = resource<UBreakIterator, decltype(ubrk_close)       , ubrk_close       >;
 using ICUUText = resource<UText         , decltype(utext_close)      , utext_close      >;
 
-using SkUnicodeBidi = std::unique_ptr<SkBidiIterator>;
-
 hb_position_t skhb_position(SkScalar value) {
     // Treat HarfBuzz hb_position_t as 16.16 fixed-point.
     constexpr int kHbPosition1 = 1 << 16;
@@ -344,26 +343,25 @@
     return val < 0 ? 0xFFFD : val;
 }
 
-class SkUnicodeBidiRunIterator final : public SkShaper::BiDiRunIterator {
+class IcuBiDiRunIterator final : public SkShaper::BiDiRunIterator {
 public:
-    SkUnicodeBidiRunIterator(const char* utf8, const char* end, SkUnicodeBidi bidi)
+    IcuBiDiRunIterator(const char* utf8, const char* end, ICUBiDi bidi)
         : fBidi(std::move(bidi))
         , fEndOfCurrentRun(utf8)
         , fBegin(utf8)
         , fEnd(end)
         , fUTF16LogicalPosition(0)
-        , fLevel(SkBidiIterator::kLTR)
+        , fLevel(UBIDI_DEFAULT_LTR)
     {}
-
     void consume() override {
-        SkASSERT(fUTF16LogicalPosition < fBidi->getLength());
-        int32_t endPosition = fBidi->getLength();
-        fLevel = fBidi->getLevelAt(fUTF16LogicalPosition);
+        SkASSERT(fUTF16LogicalPosition < ubidi_getLength(fBidi.get()));
+        int32_t endPosition = ubidi_getLength(fBidi.get());
+        fLevel = ubidi_getLevelAt(fBidi.get(), fUTF16LogicalPosition);
         SkUnichar u = utf8_next(&fEndOfCurrentRun, fEnd);
         fUTF16LogicalPosition += SkUTF::ToUTF16(u);
-        SkBidiIterator::Level level;
+        UBiDiLevel level;
         while (fUTF16LogicalPosition < endPosition) {
-            level = fBidi->getLevelAt(fUTF16LogicalPosition);
+            level = ubidi_getLevelAt(fBidi.get(), fUTF16LogicalPosition);
             if (level != fLevel) {
                 break;
             }
@@ -376,18 +374,19 @@
         return fEndOfCurrentRun - fBegin;
     }
     bool atEnd() const override {
-        return fUTF16LogicalPosition == fBidi->getLength();
+        return fUTF16LogicalPosition == ubidi_getLength(fBidi.get());
     }
-    SkBidiIterator::Level currentLevel() const override {
+
+    UBiDiLevel currentLevel() const override {
         return fLevel;
     }
 private:
-    SkUnicodeBidi fBidi;
+    ICUBiDi fBidi;
     char const * fEndOfCurrentRun;
     char const * const fBegin;
     char const * const fEnd;
     int32_t fUTF16LogicalPosition;
-    SkBidiIterator::Level fLevel;
+    UBiDiLevel fLevel;
 };
 
 class HbIcuScriptRunIterator final : public SkShaper::ScriptRunIterator {
@@ -510,7 +509,7 @@
     bool fUnsafeToBreak;
 };
 struct ShapedRun {
-    ShapedRun(SkShaper::RunHandler::Range utf8Range, const SkFont& font, SkBidiIterator::Level level,
+    ShapedRun(SkShaper::RunHandler::Range utf8Range, const SkFont& font, UBiDiLevel level,
               std::unique_ptr<ShapedGlyph[]> glyphs, size_t numGlyphs, SkVector advance = {0, 0})
         : fUtf8Range(utf8Range), fFont(font), fLevel(level)
         , fGlyphs(std::move(glyphs)), fNumGlyphs(numGlyphs), fAdvance(advance)
@@ -518,7 +517,7 @@
 
     SkShaper::RunHandler::Range fUtf8Range;
     SkFont fFont;
-    SkBidiIterator::Level fLevel;
+    UBiDiLevel fLevel;
     std::unique_ptr<ShapedGlyph[]> fGlyphs;
     size_t fNumGlyphs;
     SkVector fAdvance;
@@ -528,7 +527,7 @@
     SkVector fAdvance = { 0, 0 };
 };
 
-constexpr bool is_LTR(SkBidiIterator::Level level) {
+constexpr bool is_LTR(UBiDiLevel level) {
     return (level & 1) == 0;
 }
 
@@ -566,12 +565,12 @@
     handler->beginLine();
 
     int numRuns = line.runs.size();
-    SkAutoSTMalloc<4, SkBidiIterator::Level> runLevels(numRuns);
+    SkAutoSTMalloc<4, UBiDiLevel> runLevels(numRuns);
     for (int i = 0; i < numRuns; ++i) {
         runLevels[i] = line.runs[i].fLevel;
     }
     SkAutoSTMalloc<4, int32_t> logicalFromVisual(numRuns);
-    SkBidiIterator::ReorderVisual(runLevels, numRuns, logicalFromVisual);
+    ubidi_reorderVisual(runLevels, numRuns, logicalFromVisual);
 
     for (int i = 0; i < numRuns; ++i) {
         int logicalIndex = logicalFromVisual[i];
@@ -668,7 +667,6 @@
                     const FontRunIterator&,
                     const Feature*, size_t featuresSize) const;
 private:
-    std::unique_ptr<SkUnicode> fUnicode = SkUnicode::Make();
     const sk_sp<SkFontMgr> fFontMgr;
     HBBuffer               fBuffer;
     hb_language_t          fUndefinedLanguage;
@@ -806,12 +804,9 @@
                            SkScalar width,
                            RunHandler* handler) const
 {
-    SkBidiIterator::Level defaultLevel = leftToRight ? SkBidiIterator::kLTR : SkBidiIterator::kRTL;
-    std::unique_ptr<BiDiRunIterator> bidi(MakeSkUnicodeBidiRunIterator(fUnicode.get(),
-                                                                       utf8,
-                                                                       utf8Bytes,
-                                                                       defaultLevel));
+    UBiDiLevel defaultLevel = leftToRight ? UBIDI_DEFAULT_LTR : UBIDI_DEFAULT_RTL;
 
+    std::unique_ptr<BiDiRunIterator> bidi(MakeIcuBiDiRunIterator(utf8, utf8Bytes, defaultLevel));
     if (!bidi) {
         return;
     }
@@ -1187,12 +1182,12 @@
         }
 
         int numRuns = current.fRunIndex - previousBreak.fRunIndex + 1;
-        SkAutoSTMalloc<4, SkBidiIterator::Level> runLevels(numRuns);
+        SkAutoSTMalloc<4, UBiDiLevel> runLevels(numRuns);
         for (int i = 0; i < numRuns; ++i) {
             runLevels[i] = runs[previousBreak.fRunIndex + i].fLevel;
         }
         SkAutoSTMalloc<4, int32_t> logicalFromVisual(numRuns);
-        SkBidiIterator::ReorderVisual(runLevels, numRuns, logicalFromVisual);
+        ubidi_reorderVisual(runLevels, numRuns, logicalFromVisual);
 
         // step through the runs in reverse visual order and the glyphs in reverse logical order
         // until a visible glyph is found and force them to the end of the visual line.
@@ -1442,7 +1437,7 @@
 }  // namespace
 
 std::unique_ptr<SkShaper::BiDiRunIterator>
-SkShaper::MakeSkUnicodeBidiRunIterator(SkUnicode* unicode, const char* utf8, size_t utf8Bytes, uint8_t bidiLevel) {
+SkShaper::MakeIcuBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel) {
     // ubidi only accepts utf16 (though internally it basically works on utf32 chars).
     // We want an ubidi_setPara(UBiDi*, UText*, UBiDiLevel, UBiDiLevel*, UErrorCode*);
     if (!SkTFitsIn<int32_t>(utf8Bytes)) {
@@ -1450,23 +1445,35 @@
         return nullptr;
     }
 
-    int32_t utf16Units = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, utf8Bytes);
-    if (utf16Units < 0) {
-        SkDEBUGF("Invalid utf8 input\n");
+    UErrorCode status = U_ZERO_ERROR;
+
+    // Getting the length like this seems to always set U_BUFFER_OVERFLOW_ERROR
+    int32_t utf16Units;
+    u_strFromUTF8(nullptr, 0, &utf16Units, utf8, utf8Bytes, &status);
+    status = U_ZERO_ERROR;
+    std::unique_ptr<UChar[]> utf16(new UChar[utf16Units]);
+    u_strFromUTF8(utf16.get(), utf16Units, nullptr, utf8, utf8Bytes, &status);
+    if (U_FAILURE(status)) {
+        SkDEBUGF("Invalid utf8 input: %s", u_errorName(status));
         return nullptr;
     }
 
-    std::unique_ptr<uint16_t[]> utf16(new uint16_t[utf16Units]);
-    (void)SkUTF::UTF8ToUTF16(utf16.get(), utf16Units, utf8, utf8Bytes);
+    ICUBiDi bidi(ubidi_openSized(utf16Units, 0, &status));
+    if (U_FAILURE(status)) {
+        SkDEBUGF("Bidi error: %s", u_errorName(status));
+        return nullptr;
+    }
+    SkASSERT(bidi);
 
-    auto bidiDir = (bidiLevel % 2 == 0) ? SkBidiIterator::kLTR : SkBidiIterator::kRTL;
-    SkUnicodeBidi bidi = unicode->makeBidiIterator(utf16.get(), utf16Units, bidiDir);
-    if (!bidi) {
-        SkDEBUGF("Bidi error\n");
+    // The required lifetime of utf16 isn't well documented.
+    // It appears it isn't used after ubidi_setPara except through ubidi_getText.
+    ubidi_setPara(bidi.get(), utf16.get(), utf16Units, bidiLevel, nullptr, &status);
+    if (U_FAILURE(status)) {
+        SkDEBUGF("Bidi error: %s", u_errorName(status));
         return nullptr;
     }
 
-    return std::make_unique<SkUnicodeBidiRunIterator>(utf8, utf8 + utf8Bytes, std::move(bidi));
+    return std::make_unique<IcuBiDiRunIterator>(utf8, utf8 + utf8Bytes, std::move(bidi));
 }
 
 std::unique_ptr<SkShaper::ScriptRunIterator>
diff --git a/modules/skshaper/src/SkUnicode.h b/modules/skshaper/src/SkUnicode.h
index 0b5b363..2219ce3 100644
--- a/modules/skshaper/src/SkUnicode.h
+++ b/modules/skshaper/src/SkUnicode.h
@@ -31,6 +31,8 @@
     #endif
 #endif
 
+namespace skia {
+
 enum class UtfFormat {
     kUTF8,
     kUTF16
@@ -71,40 +73,12 @@
     Position end;
 };
 
-class SKUNICODE_API SkBidiIterator {
-public:
-    typedef int32_t Position;
-    typedef uint8_t Level;
-    struct Region {
-        Region(Position start, Position end, Level level)
-            : start(start), end(end), level(level) { }
-        Position start;
-        Position end;
-        Level level;
-    };
-    enum Direction {
-        kLTR,
-        kRTL,
-    };
-    virtual ~SkBidiIterator() {}
-    virtual Position getLength() = 0;
-    virtual Level getLevelAt(Position) = 0;
-    static void ReorderVisual(const Level runLevels[], int levelsCount, int32_t logicalFromVisual[]);
-};
-
 class SKUNICODE_API SkUnicode {
     public:
         typedef uint32_t ScriptID;
         typedef uint32_t CombiningClass;
         typedef uint32_t GeneralCategory;
         virtual ~SkUnicode() = default;
-
-        // Iterators (used in SkShaper)
-        virtual std::unique_ptr<SkBidiIterator> makeBidiIterator
-            (const uint16_t text[], int count, SkBidiIterator::Direction) = 0;
-        virtual std::unique_ptr<SkBidiIterator> makeBidiIterator
-            (const char text[], int count, SkBidiIterator::Direction) = 0;
-
         // High level methods (that we actually use somewhere=SkParagraph)
         virtual bool getBidiRegions
                (const char utf8[], int utf8Units, Direction dir, std::vector<BidiRegion>* results) = 0;
@@ -122,4 +96,6 @@
         static std::unique_ptr<SkUnicode> Make();
 };
 
+}  // namespace skia
+
 #endif // SkUnicode_DEFINED
diff --git a/modules/skshaper/src/SkUnicode_icu.cpp b/modules/skshaper/src/SkUnicode_icu.cpp
index 7f218b9..4e426c2 100644
--- a/modules/skshaper/src/SkUnicode_icu.cpp
+++ b/modules/skshaper/src/SkUnicode_icu.cpp
@@ -15,7 +15,7 @@
 #include <vector>
 #include <functional>
 
-using SkUnicodeBidi = std::unique_ptr<UBiDi, SkFunctionWrapper<decltype(ubidi_close), ubidi_close>>;
+using ICUBiDi = std::unique_ptr<UBiDi, SkFunctionWrapper<decltype(ubidi_close), ubidi_close>>;
 using ICUUText = std::unique_ptr<UText, SkFunctionWrapper<decltype(utext_close), utext_close>>;
 using ICUBreakIterator = std::unique_ptr<UBreakIterator, SkFunctionWrapper<decltype(ubrk_close), ubrk_close>>;
 
@@ -25,92 +25,7 @@
     return val < 0 ? 0xFFFD : val;
 }
 
-class SkBidiIterator_icu : public SkBidiIterator {
-    SkUnicodeBidi fBidi;
-public:
-    explicit SkBidiIterator_icu(SkUnicodeBidi bidi) : fBidi(std::move(bidi)) {}
-    Position getLength() override { return ubidi_getLength(fBidi.get()); }
-    Level getLevelAt(Position pos) override { return ubidi_getLevelAt(fBidi.get(), pos); }
-
-    static std::unique_ptr<SkBidiIterator> makeBidiIterator(const uint16_t utf16[], int utf16Units, Direction dir) {
-        UErrorCode status = U_ZERO_ERROR;
-        SkUnicodeBidi bidi(ubidi_openSized(utf16Units, 0, &status));
-        if (U_FAILURE(status)) {
-            SkDEBUGF("Bidi error: %s", u_errorName(status));
-            return nullptr;
-        }
-        SkASSERT(bidi);
-        uint8_t bidiLevel = (dir == SkBidiIterator::kLTR) ? UBIDI_LTR : UBIDI_RTL;
-        // The required lifetime of utf16 isn't well documented.
-        // It appears it isn't used after ubidi_setPara except through ubidi_getText.
-        ubidi_setPara(bidi.get(), (const UChar*)utf16, utf16Units, bidiLevel, nullptr, &status);
-        if (U_FAILURE(status)) {
-            SkDEBUGF("Bidi error: %s", u_errorName(status));
-            return nullptr;
-        }
-        return std::unique_ptr<SkBidiIterator>(new SkBidiIterator_icu(std::move(bidi)));
-    }
-
-    // ICU bidi iterator works with utf16 but clients (Flutter for instance) may work with utf8
-    // This method allows the clients not to think about all these details
-    static std::unique_ptr<SkBidiIterator> makeBidiIterator(const char utf8[], int utf8Units, Direction dir) {
-        // Convert utf8 into utf16 since ubidi only accepts utf16
-        if (!SkTFitsIn<int32_t>(utf8Units)) {
-            SkDEBUGF("Bidi error: text too long");
-            return nullptr;
-        }
-
-        // Getting the length like this seems to always set U_BUFFER_OVERFLOW_ERROR
-        int utf16Units = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, utf8Units);
-        if (utf16Units < 0) {
-            SkDEBUGF("Bidi error: Invalid utf8 input");
-            return nullptr;
-        }
-        std::unique_ptr<uint16_t[]> utf16(new uint16_t[utf16Units]);
-        SkDEBUGCODE(int dstLen =) SkUTF::UTF8ToUTF16(utf16.get(), utf16Units, utf8, utf8Units);
-        SkASSERT(dstLen == utf16Units);
-
-        return makeBidiIterator(utf16.get(), utf16Units, dir);
-    }
-
-    // This method returns the final results only: a list of bidi regions
-    // (this is all SkParagraph really needs; SkShaper however uses the iterator itself)
-    static std::vector<Region> getBidiRegions(const char utf8[], int utf8Units, Direction dir) {
-
-        auto bidiIterator = makeBidiIterator(utf8, utf8Units, dir);
-        std::vector<Region> bidiRegions;
-        const char* start8 = utf8;
-        const char* end8 = utf8 + utf8Units;
-        SkBidiIterator::Level currentLevel = 0;
-
-        Position pos8 = 0;
-        Position pos16 = 0;
-        Position end16 = bidiIterator->getLength();
-        while (pos16 < end16) {
-            auto level = bidiIterator->getLevelAt(pos16);
-            if (pos16 == 0) {
-                currentLevel = level;
-            } else if (level != currentLevel) {
-                auto end = start8 - utf8;
-                bidiRegions.emplace_back(pos8, end, currentLevel);
-                currentLevel = level;
-                pos8 = end;
-            }
-            SkUnichar u = utf8_next(&start8, end8);
-            pos16 += SkUTF::ToUTF16(u);
-        }
-        auto end = start8 - utf8;
-        if (end != pos8) {
-            bidiRegions.emplace_back(pos8, end, currentLevel);
-        }
-        return bidiRegions;
-    }
-};
-
-void SkBidiIterator::ReorderVisual(const Level runLevels[], int levelsCount,
-                                   int32_t logicalFromVisual[]) {
-    ubidi_reorderVisual(runLevels, levelsCount, logicalFromVisual);
-}
+namespace skia {
 
 class SkUnicode_icu : public SkUnicode {
 
@@ -148,7 +63,7 @@
 
         // Create bidi iterator
         UErrorCode status = U_ZERO_ERROR;
-        SkUnicodeBidi bidi(ubidi_openSized(utf16Units, 0, &status));
+        ICUBiDi bidi(ubidi_openSized(utf16Units, 0, &status));
         if (U_FAILURE(status)) {
             SkDEBUGF("Bidi error: %s", u_errorName(status));
             return false;
@@ -278,14 +193,6 @@
 
 public:
     ~SkUnicode_icu() override { }
-    std::unique_ptr<SkBidiIterator> makeBidiIterator(const uint16_t text[], int count,
-                                                     SkBidiIterator::Direction dir) override {
-        return SkBidiIterator_icu::makeBidiIterator(text, count, dir);
-    }
-    std::unique_ptr<SkBidiIterator> makeBidiIterator(const char text[], int count,
-                                                     SkBidiIterator::Direction dir) override {
-        return SkBidiIterator_icu::makeBidiIterator(text, count, dir);
-    }
 
     bool getBidiRegions(const char utf8[], int utf8Units, Direction dir, std::vector<BidiRegion>* results) override {
         return extractBidi(utf8, utf8Units, dir, results);
@@ -331,3 +238,6 @@
 };
 
 std::unique_ptr<SkUnicode> SkUnicode::Make() { return std::make_unique<SkUnicode_icu>(); }
+
+}  // namespace skia
+