21using SkUnicodeBidi = std::unique_ptr<UBiDi, SkBidiFactory::BidiCloseCallback>;
26 : fBidi(
std::move(bidi)), fBidiFact(
std::move(fact)) {}
28 Position
getLength()
override {
return fBidiFact->bidi_getLength(fBidi.get()); }
30 Level
getLevelAt(Position
pos)
override {
return fBidiFact->bidi_getLevelAt(fBidi.get(),
pos); }
41 UErrorCode status = U_ZERO_ERROR;
43 if (U_FAILURE(status)) {
51 this->
bidi_setPara(bidi.get(), (
const UChar*)utf16, utf16Units, bidiLevel,
nullptr, &status);
52 if (U_FAILURE(status)) {
56 return std::unique_ptr<SkBidiIterator>(
57 new SkBidiIterator_icu(std::move(bidi),
sk_ref_sp(
this)));
64 if (!SkTFitsIn<int32_t>(utf8Units)) {
65 SkDEBUGF(
"Bidi error: text too long");
72 SkDEBUGF(
"Bidi error: Invalid utf8 input");
75 std::unique_ptr<uint16_t[]> utf16(
new uint16_t[utf16Units]);
85 return val < 0 ? 0xFFFD : val;
91 std::vector<SkUnicode::BidiRegion>* bidiRegions)
const {
96 UErrorCode status = U_ZERO_ERROR;
98 if (U_FAILURE(status)) {
107 bidi.get(), (
const UChar*)utf16.c_str(), utf16.size(), bidiLevel,
nullptr, &status);
108 if (U_FAILURE(status)) {
114 const char* start8 = utf8;
115 const char* end8 = utf8 + utf8Units;
127 bidiRegions->emplace_back(0, utf8Units, this->
bidi_getLevelAt(bidi.get(), 0));
131 while (pos16 < end16) {
134 currentLevel = level;
135 }
else if (level != currentLevel) {
137 bidiRegions->emplace_back(pos8,
end, currentLevel);
138 currentLevel = level;
146 bidiRegions->emplace_back(pos8,
end, currentLevel);
sk_sp< T > sk_ref_sp(T *obj)
static SkUnichar utf8_next(const char **ptr, const char *end)
std::unique_ptr< SkBidiIterator > SkUnicodeBidi
static SkUnichar utf8_next(const char **ptr, const char *end)
bool ExtractBidi(const char utf8[], int utf8Units, SkUnicode::TextDirection dir, std::vector< SkUnicode::BidiRegion > *bidiRegions) const
virtual void bidi_setPara(UBiDi *bidi, const UChar *text, int32_t length, UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels, UErrorCode *status) const =0
virtual SkBidiIterator::Level bidi_getLevelAt(const UBiDi *bidi, int pos) const =0
virtual SkBidiIterator::Position bidi_getLength(const UBiDi *bidi) const =0
std::unique_ptr< SkBidiIterator > MakeIterator(const uint16_t utf16[], int utf16Units, SkBidiIterator::Direction dir) const
virtual UBiDi * bidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode) const =0
virtual BidiCloseCallback bidi_close_callback() const =0
virtual UBiDiDirection bidi_getDirection(const UBiDi *bidi) const =0
virtual const char * errorName(UErrorCode status) const =0
virtual Level getLevelAt(Position)=0
virtual Position getLength()=0
static std::u16string convertUtf8ToUtf16(const char *utf8, int utf8Units)
SK_SPI int UTF8ToUTF16(uint16_t dst[], int dstCapacity, const char src[], size_t srcByteLength)
SK_SPI SkUnichar NextUTF8(const char **ptr, const char *end)
SK_SPI size_t ToUTF16(SkUnichar uni, uint16_t utf16[2]=nullptr)