1cb93a386Sopenharmony_ci /* 2cb93a386Sopenharmony_ci* Copyright 2022 Google Inc. 3cb93a386Sopenharmony_ci* 4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci* found in the LICENSE file. 6cb93a386Sopenharmony_ci*/ 7cb93a386Sopenharmony_ci#include "include/core/SkSpan.h" 8cb93a386Sopenharmony_ci#include "include/core/SkString.h" 9cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 10cb93a386Sopenharmony_ci#include "include/private/SkBitmaskEnum.h" 11cb93a386Sopenharmony_ci#include "include/private/SkTArray.h" 12cb93a386Sopenharmony_ci#include "include/private/SkTo.h" 13cb93a386Sopenharmony_ci#include "modules/skunicode/include/SkUnicode.h" 14cb93a386Sopenharmony_ci#include "modules/skunicode/src/SkUnicode_client.h" 15cb93a386Sopenharmony_ci#include "modules/skunicode/src/SkUnicode_icu_bidi.h" 16cb93a386Sopenharmony_ci#include "src/utils/SkUTF.h" 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci#include <algorithm> 19cb93a386Sopenharmony_ci#include <cstdint> 20cb93a386Sopenharmony_ci#include <memory> 21cb93a386Sopenharmony_ci#include <string> 22cb93a386Sopenharmony_ci#include <utility> 23cb93a386Sopenharmony_ci#include <vector> 24cb93a386Sopenharmony_ci#include <array> 25cb93a386Sopenharmony_ci#include <unicode/ubidi.h> 26cb93a386Sopenharmony_ci#include <unicode/ubrk.h> 27cb93a386Sopenharmony_ci#include <unicode/uchar.h> 28cb93a386Sopenharmony_ci#include <unicode/uloc.h> 29cb93a386Sopenharmony_ci#include <unicode/uscript.h> 30cb93a386Sopenharmony_ci#include <unicode/ustring.h> 31cb93a386Sopenharmony_ci#include <unicode/utext.h> 32cb93a386Sopenharmony_ci#include <unicode/utypes.h> 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci#ifndef SK_UNICODE_ICU_IMPLEMENTATION 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ciconst char* SkUnicode_IcuBidi::errorName(UErrorCode status) { 38cb93a386Sopenharmony_ci return u_errorName_skia(status); 39cb93a386Sopenharmony_ci} 40cb93a386Sopenharmony_civoid SkUnicode_IcuBidi::bidi_close(UBiDi* bidi) { 41cb93a386Sopenharmony_ci ubidi_close_skia(bidi); 42cb93a386Sopenharmony_ci} 43cb93a386Sopenharmony_ciUBiDiDirection SkUnicode_IcuBidi::bidi_getDirection(const UBiDi* bidi) { 44cb93a386Sopenharmony_ci return ubidi_getDirection_skia(bidi); 45cb93a386Sopenharmony_ci} 46cb93a386Sopenharmony_ciSkBidiIterator::Position SkUnicode_IcuBidi::bidi_getLength(const UBiDi* bidi) { 47cb93a386Sopenharmony_ci return ubidi_getLength_skia(bidi); 48cb93a386Sopenharmony_ci} 49cb93a386Sopenharmony_ciSkBidiIterator::Level SkUnicode_IcuBidi::bidi_getLevelAt(const UBiDi* bidi, int pos) { 50cb93a386Sopenharmony_ci return ubidi_getLevelAt_skia(bidi, pos); 51cb93a386Sopenharmony_ci} 52cb93a386Sopenharmony_ciUBiDi* SkUnicode_IcuBidi::bidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode* pErrorCode) { 53cb93a386Sopenharmony_ci return ubidi_openSized_skia(maxLength, maxRunCount, pErrorCode); 54cb93a386Sopenharmony_ci} 55cb93a386Sopenharmony_civoid SkUnicode_IcuBidi::bidi_setPara(UBiDi* bidi, 56cb93a386Sopenharmony_ci const UChar* text, 57cb93a386Sopenharmony_ci int32_t length, 58cb93a386Sopenharmony_ci UBiDiLevel paraLevel, 59cb93a386Sopenharmony_ci UBiDiLevel* embeddingLevels, 60cb93a386Sopenharmony_ci UErrorCode* status) { 61cb93a386Sopenharmony_ci return ubidi_setPara_skia(bidi, text, length, paraLevel, embeddingLevels, status); 62cb93a386Sopenharmony_ci} 63cb93a386Sopenharmony_civoid SkUnicode_IcuBidi::bidi_reorderVisual(const SkUnicode::BidiLevel runLevels[], 64cb93a386Sopenharmony_ci int levelsCount, 65cb93a386Sopenharmony_ci int32_t logicalFromVisual[]) { 66cb93a386Sopenharmony_ci ubidi_reorderVisual_skia(runLevels, levelsCount, logicalFromVisual); 67cb93a386Sopenharmony_ci} 68cb93a386Sopenharmony_ci#endif 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ciclass SkUnicode_client : public SkUnicode { 71cb93a386Sopenharmony_cipublic: 72cb93a386Sopenharmony_ci struct Data { 73cb93a386Sopenharmony_ci SkSpan<const char> fText8; 74cb93a386Sopenharmony_ci SkSpan<const char16_t> fText16; 75cb93a386Sopenharmony_ci std::vector<Position> fWords; 76cb93a386Sopenharmony_ci std::vector<SkUnicode::Position> fGraphemeBreaks; 77cb93a386Sopenharmony_ci std::vector<SkUnicode::LineBreakBefore> fLineBreaks; 78cb93a386Sopenharmony_ci Data(SkSpan<char> text, 79cb93a386Sopenharmony_ci std::vector<SkUnicode::Position> words, 80cb93a386Sopenharmony_ci std::vector<SkUnicode::Position> graphemeBreaks, 81cb93a386Sopenharmony_ci std::vector<SkUnicode::LineBreakBefore> lineBreaks) 82cb93a386Sopenharmony_ci : fText8(text) 83cb93a386Sopenharmony_ci , fText16(SkSpan<const char16_t>(nullptr, 0)) 84cb93a386Sopenharmony_ci , fWords(std::move(words)) 85cb93a386Sopenharmony_ci , fGraphemeBreaks(std::move(graphemeBreaks)) 86cb93a386Sopenharmony_ci , fLineBreaks(std::move(lineBreaks)) { 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci void reset() { 90cb93a386Sopenharmony_ci fText8 = SkSpan<const char>(nullptr, 0); 91cb93a386Sopenharmony_ci fText16 = SkSpan<const char16_t>(nullptr, 0); 92cb93a386Sopenharmony_ci fGraphemeBreaks.clear(); 93cb93a386Sopenharmony_ci fLineBreaks.clear(); 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci }; 96cb93a386Sopenharmony_ci SkUnicode_client() = delete; 97cb93a386Sopenharmony_ci SkUnicode_client(SkSpan<char> text, 98cb93a386Sopenharmony_ci std::vector<SkUnicode::Position> words, 99cb93a386Sopenharmony_ci std::vector<SkUnicode::Position> graphemeBreaks, 100cb93a386Sopenharmony_ci std::vector<SkUnicode::LineBreakBefore> lineBreaks) 101cb93a386Sopenharmony_ci : fData(std::make_shared<Data>(text, 102cb93a386Sopenharmony_ci std::move(words), 103cb93a386Sopenharmony_ci std::move(graphemeBreaks), 104cb93a386Sopenharmony_ci std::move(lineBreaks))) { } 105cb93a386Sopenharmony_ci SkUnicode_client(const SkUnicode_client* origin) 106cb93a386Sopenharmony_ci : fData(origin->fData) {} 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci std::unique_ptr<SkUnicode> copy() override { 110cb93a386Sopenharmony_ci return std::make_unique<SkUnicode_client>(this); 111cb93a386Sopenharmony_ci } 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_ci ~SkUnicode_client() override = default; 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_ci void reset() { fData->reset(); } 116cb93a386Sopenharmony_ci // For SkShaper 117cb93a386Sopenharmony_ci std::unique_ptr<SkBidiIterator> makeBidiIterator(const uint16_t text[], int count, 118cb93a386Sopenharmony_ci SkBidiIterator::Direction dir) override; 119cb93a386Sopenharmony_ci std::unique_ptr<SkBidiIterator> makeBidiIterator(const char text[], 120cb93a386Sopenharmony_ci int count, 121cb93a386Sopenharmony_ci SkBidiIterator::Direction dir) override; 122cb93a386Sopenharmony_ci std::unique_ptr<SkBreakIterator> makeBreakIterator(const char locale[], 123cb93a386Sopenharmony_ci BreakType breakType) override; 124cb93a386Sopenharmony_ci std::unique_ptr<SkBreakIterator> makeBreakIterator(BreakType breakType) override; 125cb93a386Sopenharmony_ci // For SkParagraph 126cb93a386Sopenharmony_ci bool getBidiRegions(const char utf8[], 127cb93a386Sopenharmony_ci int utf8Units, 128cb93a386Sopenharmony_ci TextDirection dir, 129cb93a386Sopenharmony_ci std::vector<BidiRegion>* results) override { 130cb93a386Sopenharmony_ci return SkUnicode::extractBidi(utf8, utf8Units, dir, results); 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci // TODO: Take if from the Client or hard code here? 134cb93a386Sopenharmony_ci static bool isControl(SkUnichar utf8) { 135cb93a386Sopenharmony_ci return (utf8 < ' ') || (utf8 >= 0x7f && utf8 <= 0x9f) || 136cb93a386Sopenharmony_ci (utf8 >= 0x200D && utf8 <= 0x200F) || 137cb93a386Sopenharmony_ci (utf8 >= 0x202A && utf8 <= 0x202E); 138cb93a386Sopenharmony_ci } 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci static bool isWhitespace(SkUnichar unichar) { 141cb93a386Sopenharmony_ci static constexpr std::array<SkUnichar, 21> whitespaces { 142cb93a386Sopenharmony_ci 0x0009, // character tabulation 143cb93a386Sopenharmony_ci 0x000A, // line feed 144cb93a386Sopenharmony_ci 0x000B, // line tabulation 145cb93a386Sopenharmony_ci 0x000C, // form feed 146cb93a386Sopenharmony_ci 0x000D, // carriage return 147cb93a386Sopenharmony_ci 0x0020, // space 148cb93a386Sopenharmony_ci //0x0085, // next line 149cb93a386Sopenharmony_ci //0x00A0, // no-break space 150cb93a386Sopenharmony_ci 0x1680, // ogham space mark 151cb93a386Sopenharmony_ci 0x2000, // en quad 152cb93a386Sopenharmony_ci 0x2001, // em quad 153cb93a386Sopenharmony_ci 0x2002, // en space 154cb93a386Sopenharmony_ci 0x2003, // em space 155cb93a386Sopenharmony_ci 0x2004, // three-per-em space 156cb93a386Sopenharmony_ci 0x2005, // four-per-em space 157cb93a386Sopenharmony_ci 0x2006, // six-per-em space 158cb93a386Sopenharmony_ci //0x2007, // figure space 159cb93a386Sopenharmony_ci 0x2008, // punctuation space 160cb93a386Sopenharmony_ci 0x2009, // thin space 161cb93a386Sopenharmony_ci 0x200A, // hair space 162cb93a386Sopenharmony_ci 0x2028, // line separator 163cb93a386Sopenharmony_ci 0x2029, // paragraph separator 164cb93a386Sopenharmony_ci //0x202F, // narrow no-break space 165cb93a386Sopenharmony_ci 0x205F, // medium mathematical space 166cb93a386Sopenharmony_ci 0x3000};// ideographic space 167cb93a386Sopenharmony_ci return std::find(whitespaces.begin(), whitespaces.end(), unichar) != whitespaces.end(); 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci static bool isSpace(SkUnichar unichar) { 171cb93a386Sopenharmony_ci static constexpr std::array<SkUnichar, 25> spaces { 172cb93a386Sopenharmony_ci 0x0009, // character tabulation 173cb93a386Sopenharmony_ci 0x000A, // line feed 174cb93a386Sopenharmony_ci 0x000B, // line tabulation 175cb93a386Sopenharmony_ci 0x000C, // form feed 176cb93a386Sopenharmony_ci 0x000D, // carriage return 177cb93a386Sopenharmony_ci 0x0020, // space 178cb93a386Sopenharmony_ci 0x0085, // next line 179cb93a386Sopenharmony_ci 0x00A0, // no-break space 180cb93a386Sopenharmony_ci 0x1680, // ogham space mark 181cb93a386Sopenharmony_ci 0x2000, // en quad 182cb93a386Sopenharmony_ci 0x2001, // em quad 183cb93a386Sopenharmony_ci 0x2002, // en space 184cb93a386Sopenharmony_ci 0x2003, // em space 185cb93a386Sopenharmony_ci 0x2004, // three-per-em space 186cb93a386Sopenharmony_ci 0x2005, // four-per-em space 187cb93a386Sopenharmony_ci 0x2006, // six-per-em space 188cb93a386Sopenharmony_ci 0x2007, // figure space 189cb93a386Sopenharmony_ci 0x2008, // punctuation space 190cb93a386Sopenharmony_ci 0x2009, // thin space 191cb93a386Sopenharmony_ci 0x200A, // hair space 192cb93a386Sopenharmony_ci 0x2028, // line separator 193cb93a386Sopenharmony_ci 0x2029, // paragraph separator 194cb93a386Sopenharmony_ci 0x202F, // narrow no-break space 195cb93a386Sopenharmony_ci 0x205F, // medium mathematical space 196cb93a386Sopenharmony_ci 0x3000}; // ideographic space 197cb93a386Sopenharmony_ci return std::find(spaces.begin(), spaces.end(), unichar) != spaces.end(); 198cb93a386Sopenharmony_ci } 199cb93a386Sopenharmony_ci 200cb93a386Sopenharmony_ci static bool isTabulation(SkUnichar utf8) { 201cb93a386Sopenharmony_ci return utf8 == '\t'; 202cb93a386Sopenharmony_ci } 203cb93a386Sopenharmony_ci 204cb93a386Sopenharmony_ci static bool isHardBreak(SkUnichar utf8) { 205cb93a386Sopenharmony_ci return utf8 == '\n'; 206cb93a386Sopenharmony_ci } 207cb93a386Sopenharmony_ci 208cb93a386Sopenharmony_ci static bool isIdeographic(SkUnichar unichar) { 209cb93a386Sopenharmony_ci static constexpr std::array<std::pair<SkUnichar, SkUnichar>, 8> ranges {{ 210cb93a386Sopenharmony_ci {4352, 4607}, // Hangul Jamo 211cb93a386Sopenharmony_ci {11904, 42191}, // CJK_Radicals 212cb93a386Sopenharmony_ci {43072, 43135}, // Phags_Pa 213cb93a386Sopenharmony_ci {44032, 55215}, // Hangul_Syllables 214cb93a386Sopenharmony_ci {63744, 64255}, // CJK_Compatibility_Ideographs 215cb93a386Sopenharmony_ci {65072, 65103}, // CJK_Compatibility_Forms 216cb93a386Sopenharmony_ci {65381, 65500}, // Katakana_Hangul_Halfwidth 217cb93a386Sopenharmony_ci {131072, 196607} // Supplementary_Ideographic_Plane 218cb93a386Sopenharmony_ci }}; 219cb93a386Sopenharmony_ci for (auto range : ranges) { 220cb93a386Sopenharmony_ci if (range.first <= unichar && range.second > unichar) { 221cb93a386Sopenharmony_ci return true; 222cb93a386Sopenharmony_ci } 223cb93a386Sopenharmony_ci } 224cb93a386Sopenharmony_ci return false; 225cb93a386Sopenharmony_ci } 226cb93a386Sopenharmony_ci 227cb93a386Sopenharmony_ci bool computeCodeUnitFlags(char utf8[], 228cb93a386Sopenharmony_ci int utf8Units, 229cb93a386Sopenharmony_ci bool replaceTabs, 230cb93a386Sopenharmony_ci SkTArray<SkUnicode::CodeUnitFlags, true>* results) override { 231cb93a386Sopenharmony_ci results->clear(); 232cb93a386Sopenharmony_ci results->push_back_n(utf8Units + 1, CodeUnitFlags::kNoCodeUnitFlag); 233cb93a386Sopenharmony_ci for (auto& lineBreak : fData->fLineBreaks) { 234cb93a386Sopenharmony_ci (*results)[lineBreak.pos] |= 235cb93a386Sopenharmony_ci lineBreak.breakType == LineBreakType::kHardLineBreak 236cb93a386Sopenharmony_ci ? CodeUnitFlags::kHardLineBreakBefore 237cb93a386Sopenharmony_ci : CodeUnitFlags::kSoftLineBreakBefore; 238cb93a386Sopenharmony_ci } 239cb93a386Sopenharmony_ci for (auto& grapheme : fData->fGraphemeBreaks) { 240cb93a386Sopenharmony_ci (*results)[grapheme] |= CodeUnitFlags::kGraphemeStart; 241cb93a386Sopenharmony_ci } 242cb93a386Sopenharmony_ci const char* current = utf8; 243cb93a386Sopenharmony_ci const char* end = utf8 + utf8Units; 244cb93a386Sopenharmony_ci while (current < end) { 245cb93a386Sopenharmony_ci auto before = current - utf8; 246cb93a386Sopenharmony_ci SkUnichar unichar = SkUTF::NextUTF8(¤t, end); 247cb93a386Sopenharmony_ci if (unichar < 0) unichar = 0xFFFD; 248cb93a386Sopenharmony_ci auto after = current - utf8; 249cb93a386Sopenharmony_ci if (replaceTabs && SkUnicode_client::isTabulation(unichar)) { 250cb93a386Sopenharmony_ci results->at(before) |= SkUnicode::kTabulation; 251cb93a386Sopenharmony_ci if (replaceTabs) { 252cb93a386Sopenharmony_ci unichar = ' '; 253cb93a386Sopenharmony_ci utf8[before] = ' '; 254cb93a386Sopenharmony_ci } 255cb93a386Sopenharmony_ci } 256cb93a386Sopenharmony_ci for (auto i = before; i < after; ++i) { 257cb93a386Sopenharmony_ci if (SkUnicode_client::isSpace(unichar)) { 258cb93a386Sopenharmony_ci results->at(i) |= SkUnicode::kPartOfIntraWordBreak; 259cb93a386Sopenharmony_ci } 260cb93a386Sopenharmony_ci if (SkUnicode_client::isWhitespace(unichar)) { 261cb93a386Sopenharmony_ci results->at(i) |= SkUnicode::kPartOfWhiteSpaceBreak; 262cb93a386Sopenharmony_ci } 263cb93a386Sopenharmony_ci if (SkUnicode_client::isControl(unichar)) { 264cb93a386Sopenharmony_ci results->at(i) |= SkUnicode::kControl; 265cb93a386Sopenharmony_ci } 266cb93a386Sopenharmony_ci if (SkUnicode_client::isIdeographic(unichar)) { 267cb93a386Sopenharmony_ci results->at(i) |= SkUnicode::kIdeographic; 268cb93a386Sopenharmony_ci } 269cb93a386Sopenharmony_ci } 270cb93a386Sopenharmony_ci } 271cb93a386Sopenharmony_ci return true; 272cb93a386Sopenharmony_ci } 273cb93a386Sopenharmony_ci 274cb93a386Sopenharmony_ci bool computeCodeUnitFlags(char16_t utf16[], int utf16Units, bool replaceTabs, 275cb93a386Sopenharmony_ci SkTArray<SkUnicode::CodeUnitFlags, true>* results) override { 276cb93a386Sopenharmony_ci results->clear(); 277cb93a386Sopenharmony_ci results->push_back_n(utf16Units + 1, CodeUnitFlags::kNoCodeUnitFlag); 278cb93a386Sopenharmony_ci for (auto& lineBreak : fData->fLineBreaks) { 279cb93a386Sopenharmony_ci (*results)[lineBreak.pos] |= 280cb93a386Sopenharmony_ci lineBreak.breakType == LineBreakType::kHardLineBreak 281cb93a386Sopenharmony_ci ? CodeUnitFlags::kHardLineBreakBefore 282cb93a386Sopenharmony_ci : CodeUnitFlags::kSoftLineBreakBefore; 283cb93a386Sopenharmony_ci } 284cb93a386Sopenharmony_ci for (auto& grapheme : fData->fGraphemeBreaks) { 285cb93a386Sopenharmony_ci (*results)[grapheme] |= CodeUnitFlags::kGraphemeStart; 286cb93a386Sopenharmony_ci } 287cb93a386Sopenharmony_ci return true; 288cb93a386Sopenharmony_ci } 289cb93a386Sopenharmony_ci 290cb93a386Sopenharmony_ci bool getWords(const char utf8[], int utf8Units, const char* locale, std::vector<Position>* results) override { 291cb93a386Sopenharmony_ci *results = fData->fWords; 292cb93a386Sopenharmony_ci return true; 293cb93a386Sopenharmony_ci } 294cb93a386Sopenharmony_ci 295cb93a386Sopenharmony_ci SkString toUpper(const SkString& str) override { 296cb93a386Sopenharmony_ci SkASSERT(false); 297cb93a386Sopenharmony_ci return SkString(fData->fText8.data(), fData->fText8.size()); 298cb93a386Sopenharmony_ci } 299cb93a386Sopenharmony_ci 300cb93a386Sopenharmony_ci void reorderVisual(const BidiLevel runLevels[], 301cb93a386Sopenharmony_ci int levelsCount, 302cb93a386Sopenharmony_ci int32_t logicalFromVisual[]) override { 303cb93a386Sopenharmony_ci SkUnicode_IcuBidi::bidi_reorderVisual(runLevels, levelsCount, logicalFromVisual); 304cb93a386Sopenharmony_ci } 305cb93a386Sopenharmony_ciprivate: 306cb93a386Sopenharmony_ci friend class SkBreakIterator_client; 307cb93a386Sopenharmony_ci 308cb93a386Sopenharmony_ci std::shared_ptr<Data> fData; 309cb93a386Sopenharmony_ci}; 310cb93a386Sopenharmony_ci 311cb93a386Sopenharmony_ciclass SkBreakIterator_client: public SkBreakIterator { 312cb93a386Sopenharmony_ci std::shared_ptr<SkUnicode_client::Data> fData; 313cb93a386Sopenharmony_ci Position fLastResult; 314cb93a386Sopenharmony_ci Position fStart; 315cb93a386Sopenharmony_ci Position fEnd; 316cb93a386Sopenharmony_cipublic: 317cb93a386Sopenharmony_ci explicit SkBreakIterator_client(std::shared_ptr<SkUnicode_client::Data> data) : fData(data) { } 318cb93a386Sopenharmony_ci Position first() override 319cb93a386Sopenharmony_ci { return fData->fLineBreaks[fStart + (fLastResult = 0)].pos; } 320cb93a386Sopenharmony_ci Position current() override 321cb93a386Sopenharmony_ci { return fData->fLineBreaks[fStart + fLastResult].pos; } 322cb93a386Sopenharmony_ci Position next() override 323cb93a386Sopenharmony_ci { return fData->fLineBreaks[fStart + fLastResult + 1].pos; } 324cb93a386Sopenharmony_ci Status status() override { 325cb93a386Sopenharmony_ci return fData->fLineBreaks[fStart + fLastResult].breakType == 326cb93a386Sopenharmony_ci SkUnicode::LineBreakType::kHardLineBreak 327cb93a386Sopenharmony_ci ? SkUnicode::CodeUnitFlags::kHardLineBreakBefore 328cb93a386Sopenharmony_ci : SkUnicode::CodeUnitFlags::kSoftLineBreakBefore; 329cb93a386Sopenharmony_ci } 330cb93a386Sopenharmony_ci bool isDone() override { return fStart + fLastResult == fEnd; } 331cb93a386Sopenharmony_ci bool setText(const char utftext8[], int utf8Units) override { 332cb93a386Sopenharmony_ci SkASSERT(utftext8 >= fData->fText8.data() && 333cb93a386Sopenharmony_ci utf8Units <= SkToS16(fData->fText8.size())); 334cb93a386Sopenharmony_ci fStart = utftext8 - fData->fText8.data(); 335cb93a386Sopenharmony_ci fEnd = fStart + utf8Units; 336cb93a386Sopenharmony_ci fLastResult = 0; 337cb93a386Sopenharmony_ci return true; 338cb93a386Sopenharmony_ci } 339cb93a386Sopenharmony_ci bool setText(const char16_t utftext16[], int utf16Units) override { 340cb93a386Sopenharmony_ci SkASSERT(utftext16 >= fData->fText16.data() && 341cb93a386Sopenharmony_ci utf16Units <= SkToS16(fData->fText16.size())); 342cb93a386Sopenharmony_ci fStart = utftext16 - fData->fText16.data(); 343cb93a386Sopenharmony_ci fEnd = fStart + utf16Units; 344cb93a386Sopenharmony_ci fLastResult = 0; 345cb93a386Sopenharmony_ci return true; 346cb93a386Sopenharmony_ci } 347cb93a386Sopenharmony_ci}; 348cb93a386Sopenharmony_cistd::unique_ptr<SkBidiIterator> SkUnicode_client::makeBidiIterator(const uint16_t text[], int count, 349cb93a386Sopenharmony_ci SkBidiIterator::Direction dir) { 350cb93a386Sopenharmony_ci return SkUnicode::makeBidiIterator(text, count, dir); 351cb93a386Sopenharmony_ci} 352cb93a386Sopenharmony_cistd::unique_ptr<SkBidiIterator> SkUnicode_client::makeBidiIterator(const char text[], 353cb93a386Sopenharmony_ci int count, 354cb93a386Sopenharmony_ci SkBidiIterator::Direction dir) { 355cb93a386Sopenharmony_ci return SkUnicode::makeBidiIterator(text, count, dir); 356cb93a386Sopenharmony_ci} 357cb93a386Sopenharmony_cistd::unique_ptr<SkBreakIterator> SkUnicode_client::makeBreakIterator(const char locale[], 358cb93a386Sopenharmony_ci BreakType breakType) { 359cb93a386Sopenharmony_ci return std::make_unique<SkBreakIterator_client>(fData); 360cb93a386Sopenharmony_ci} 361cb93a386Sopenharmony_cistd::unique_ptr<SkBreakIterator> SkUnicode_client::makeBreakIterator(BreakType breakType) { 362cb93a386Sopenharmony_ci return std::make_unique<SkBreakIterator_client>(fData); 363cb93a386Sopenharmony_ci} 364cb93a386Sopenharmony_ci 365cb93a386Sopenharmony_cistd::unique_ptr<SkUnicode> SkUnicode::MakeClientBasedUnicode( 366cb93a386Sopenharmony_ci SkSpan<char> text, 367cb93a386Sopenharmony_ci std::vector<SkUnicode::Position> words, 368cb93a386Sopenharmony_ci std::vector<SkUnicode::Position> graphemeBreaks, 369cb93a386Sopenharmony_ci std::vector<SkUnicode::LineBreakBefore> lineBreaks) { 370cb93a386Sopenharmony_ci return std::make_unique<SkUnicode_client>(text, words, graphemeBreaks, lineBreaks); 371cb93a386Sopenharmony_ci} 372cb93a386Sopenharmony_ci 373