Revert "Small changes for SkText that are not in experimental directory"
This reverts commit 92f1bc0083
.
Reason for revert: Blocking Android roll.
Original change's description:
> Small changes for SkText that are not in experimental directory
>
> (also made utf 8<->16 conversion static on SkUnicode)
>
> Change-Id: Ie64d18ad21a35ec10bd0b350fb7887fb78a419d8
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/448140
> Reviewed-by: Mike Reed <reed@google.com>
> Commit-Queue: Julia Lavrova <jlavrova@google.com>
Change-Id: Ieb9eb0495dddfc0f9e9e74861b24efc0201fd520
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/448656
Auto-Submit: Brian Osman <brianosman@google.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
This commit is contained in:
parent
7d19065eef
commit
481a58dfe0
1
BUILD.gn
1
BUILD.gn
@ -1981,7 +1981,6 @@ if (skia_enable_tools) {
|
|||||||
":test",
|
":test",
|
||||||
":tool_utils",
|
":tool_utils",
|
||||||
"experimental/skrive:tests",
|
"experimental/skrive:tests",
|
||||||
"experimental/sktext:tests",
|
|
||||||
"modules/skottie:tests",
|
"modules/skottie:tests",
|
||||||
"modules/skparagraph:tests",
|
"modules/skparagraph:tests",
|
||||||
"modules/sksg:tests",
|
"modules/sksg:tests",
|
||||||
|
@ -24,7 +24,7 @@ std::unique_ptr<UnicodeText> Text::parse(SkSpan<uint16_t> utf16) {
|
|||||||
// Fill out all code unit properties
|
// Fill out all code unit properties
|
||||||
unicodeText->fCodeUnitProperties.push_back_n(utf16.size() + 1, CodeUnitFlags::kNoCodeUnitFlag);
|
unicodeText->fCodeUnitProperties.push_back_n(utf16.size() + 1, CodeUnitFlags::kNoCodeUnitFlag);
|
||||||
unicodeText->fUnicode->forEachCodepoint(unicodeText->fText8.c_str(), unicodeText->fText8.size(),
|
unicodeText->fUnicode->forEachCodepoint(unicodeText->fText8.c_str(), unicodeText->fText8.size(),
|
||||||
[&unicodeText, &utf16Index](SkUnichar unichar, int32_t start, int32_t end, size_t count) {
|
[&unicodeText, &utf16Index](SkUnichar unichar, int32_t start, int32_t end) {
|
||||||
for (auto i = start; i < end; ++i) {
|
for (auto i = start; i < end; ++i) {
|
||||||
unicodeText->fUTF16FromUTF8[i] = utf16Index;
|
unicodeText->fUTF16FromUTF8[i] = utf16Index;
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ std::unique_ptr<UnicodeText> Text::parse(SkSpan<uint16_t> utf16) {
|
|||||||
// Get white spaces
|
// Get white spaces
|
||||||
// TODO: It's a bug. We need to operate on utf16 indexes everywhere
|
// TODO: It's a bug. We need to operate on utf16 indexes everywhere
|
||||||
unicodeText->fUnicode->forEachCodepoint(unicodeText->fText8.c_str(), unicodeText->fText8.size(),
|
unicodeText->fUnicode->forEachCodepoint(unicodeText->fText8.c_str(), unicodeText->fText8.size(),
|
||||||
[&unicodeText](SkUnichar unichar, int32_t start, int32_t end, size_t count) {
|
[&unicodeText](SkUnichar unichar, int32_t start, int32_t end) {
|
||||||
if (unicodeText->fUnicode->isWhitespace(unichar)) {
|
if (unicodeText->fUnicode->isWhitespace(unichar)) {
|
||||||
for (auto i = start; i < end; ++i) {
|
for (auto i = start; i < end; ++i) {
|
||||||
unicodeText->fCodeUnitProperties[i] |= CodeUnitFlags::kPartOfWhiteSpace;
|
unicodeText->fCodeUnitProperties[i] |= CodeUnitFlags::kPartOfWhiteSpace;
|
||||||
|
@ -267,7 +267,7 @@ bool ParagraphImpl::computeCodeUnitProperties() {
|
|||||||
|
|
||||||
// Get all spaces
|
// Get all spaces
|
||||||
fUnicode->forEachCodepoint(fText.c_str(), fText.size(),
|
fUnicode->forEachCodepoint(fText.c_str(), fText.size(),
|
||||||
[this](SkUnichar unichar, int32_t start, int32_t end, int32_t count) {
|
[this](SkUnichar unichar, int32_t start, int32_t end) {
|
||||||
if (fUnicode->isWhitespace(unichar)) {
|
if (fUnicode->isWhitespace(unichar)) {
|
||||||
for (auto i = start; i < end; ++i) {
|
for (auto i = start; i < end; ++i) {
|
||||||
fCodeUnitProperties[i] |= CodeUnitFlags::kPartOfWhiteSpaceBreak;
|
fCodeUnitProperties[i] |= CodeUnitFlags::kPartOfWhiteSpaceBreak;
|
||||||
|
@ -115,6 +115,7 @@ class SKUNICODE_API SkUnicode {
|
|||||||
virtual bool isControl(SkUnichar utf8) = 0;
|
virtual bool isControl(SkUnichar utf8) = 0;
|
||||||
virtual bool isWhitespace(SkUnichar utf8) = 0;
|
virtual bool isWhitespace(SkUnichar utf8) = 0;
|
||||||
virtual bool isSpace(SkUnichar utf8) = 0;
|
virtual bool isSpace(SkUnichar utf8) = 0;
|
||||||
|
virtual SkString convertUtf16ToUtf8(const std::u16string& utf16) = 0;
|
||||||
virtual SkString toUpper(const SkString&) = 0;
|
virtual SkString toUpper(const SkString&) = 0;
|
||||||
|
|
||||||
// Methods used in SkShaper and SkText
|
// Methods used in SkShaper and SkText
|
||||||
@ -137,43 +138,6 @@ class SKUNICODE_API SkUnicode {
|
|||||||
virtual bool getGraphemes
|
virtual bool getGraphemes
|
||||||
(const char utf8[], int utf8Units, std::vector<Position>* results) = 0;
|
(const char utf8[], int utf8Units, std::vector<Position>* results) = 0;
|
||||||
|
|
||||||
static SkString convertUtf16ToUtf8(const char16_t * utf16, int utf16Units) {
|
|
||||||
|
|
||||||
int utf8Units = SkUTF::UTF16ToUTF8(nullptr, 0, (uint16_t*)utf16, utf16Units);
|
|
||||||
if (utf8Units < 0) {
|
|
||||||
SkDEBUGF("Convert error: Invalid utf16 input");
|
|
||||||
return SkString();
|
|
||||||
}
|
|
||||||
SkAutoTArray<char> utf8(utf8Units);
|
|
||||||
SkDEBUGCODE(int dstLen =) SkUTF::UTF16ToUTF8(utf8.data(), utf8Units, (uint16_t*)utf16, utf16Units);
|
|
||||||
SkASSERT(dstLen == utf8Units);
|
|
||||||
|
|
||||||
return SkString(utf8.data(), utf8Units);
|
|
||||||
}
|
|
||||||
|
|
||||||
static SkString convertUtf16ToUtf8(const std::u16string& utf16) {
|
|
||||||
return convertUtf16ToUtf8(utf16.c_str(), utf16.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::u16string convertUtf8ToUtf16(const char* utf8, int utf8Units) {
|
|
||||||
|
|
||||||
int utf16Units = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, utf8Units);
|
|
||||||
if (utf16Units < 0) {
|
|
||||||
SkDEBUGF("Convert error: Invalid utf8 input");
|
|
||||||
return std::u16string();
|
|
||||||
}
|
|
||||||
|
|
||||||
SkAutoTArray<uint16_t> utf16(utf16Units);
|
|
||||||
SkDEBUGCODE(int dstLen =) SkUTF::UTF8ToUTF16(utf16.data(), utf16Units, utf8, utf8Units);
|
|
||||||
SkASSERT(dstLen == utf16Units);
|
|
||||||
|
|
||||||
return std::u16string((char16_t *)utf16.data(), utf16Units);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::u16string convertUtf8ToUtf16(const SkString& utf8) {
|
|
||||||
return convertUtf8ToUtf16(utf8.c_str(), utf8.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
void forEachCodepoint(const char* utf8, int32_t utf8Units, Callback&& callback) {
|
void forEachCodepoint(const char* utf8, int32_t utf8Units, Callback&& callback) {
|
||||||
const char* current = utf8;
|
const char* current = utf8;
|
||||||
@ -183,9 +147,7 @@ class SKUNICODE_API SkUnicode {
|
|||||||
SkUnichar unichar = SkUTF::NextUTF8(¤t, end);
|
SkUnichar unichar = SkUTF::NextUTF8(¤t, end);
|
||||||
if (unichar < 0) unichar = 0xFFFD;
|
if (unichar < 0) unichar = 0xFFFD;
|
||||||
auto after = current - utf8;
|
auto after = current - utf8;
|
||||||
uint16_t buffer[2];
|
callback(unichar, before, after);
|
||||||
size_t count = SkUTF::ToUTF16(unichar, buffer);
|
|
||||||
callback(unichar, before, after, count);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,11 +282,15 @@ class SkUnicode_icu : public SkUnicode {
|
|||||||
std::vector<BidiRegion>* bidiRegions) {
|
std::vector<BidiRegion>* bidiRegions) {
|
||||||
|
|
||||||
// Convert to UTF16 since for now bidi iterator only operates on utf16
|
// Convert to UTF16 since for now bidi iterator only operates on utf16
|
||||||
auto utf16 = convertUtf8ToUtf16(utf8, utf8Units);
|
std::unique_ptr<uint16_t[]> utf16;
|
||||||
|
auto utf16Units = utf8ToUtf16(utf8, utf8Units, &utf16);
|
||||||
|
if (utf16Units < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Create bidi iterator
|
// Create bidi iterator
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
SkUnicodeBidi bidi(sk_ubidi_openSized(utf16.size(), 0, &status));
|
SkUnicodeBidi bidi(sk_ubidi_openSized(utf16Units, 0, &status));
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
SkDEBUGF("Bidi error: %s", sk_u_errorName(status));
|
SkDEBUGF("Bidi error: %s", sk_u_errorName(status));
|
||||||
return false;
|
return false;
|
||||||
@ -295,7 +299,7 @@ class SkUnicode_icu : public SkUnicode {
|
|||||||
uint8_t bidiLevel = (dir == TextDirection::kLTR) ? UBIDI_LTR : UBIDI_RTL;
|
uint8_t bidiLevel = (dir == TextDirection::kLTR) ? UBIDI_LTR : UBIDI_RTL;
|
||||||
// The required lifetime of utf16 isn't well documented.
|
// The required lifetime of utf16 isn't well documented.
|
||||||
// It appears it isn't used after ubidi_setPara except through ubidi_getText.
|
// It appears it isn't used after ubidi_setPara except through ubidi_getText.
|
||||||
sk_ubidi_setPara(bidi.get(), (const UChar*)utf16.c_str(), utf16.size(), bidiLevel, nullptr,
|
sk_ubidi_setPara(bidi.get(), (const UChar*)utf16.get(), utf16Units, bidiLevel, nullptr,
|
||||||
&status);
|
&status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
SkDEBUGF("Bidi error: %s", sk_u_errorName(status));
|
SkDEBUGF("Bidi error: %s", sk_u_errorName(status));
|
||||||
@ -413,6 +417,30 @@ class SkUnicode_icu : public SkUnicode {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int utf8ToUtf16(const char* utf8, size_t utf8Units, std::unique_ptr<uint16_t[]>* utf16) {
|
||||||
|
int utf16Units = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, utf8Units);
|
||||||
|
if (utf16Units < 0) {
|
||||||
|
SkDEBUGF("Convert error: Invalid utf8 input");
|
||||||
|
return utf16Units;
|
||||||
|
}
|
||||||
|
*utf16 = std::unique_ptr<uint16_t[]>(new uint16_t[utf16Units]);
|
||||||
|
SkDEBUGCODE(int dstLen =) SkUTF::UTF8ToUTF16(utf16->get(), utf16Units, utf8, utf8Units);
|
||||||
|
SkASSERT(dstLen == utf16Units);
|
||||||
|
return utf16Units;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int utf16ToUtf8(const uint16_t* utf16, size_t utf16Units, std::unique_ptr<char[]>* utf8) {
|
||||||
|
int utf8Units = SkUTF::UTF16ToUTF8(nullptr, 0, utf16, utf16Units);
|
||||||
|
if (utf8Units < 0) {
|
||||||
|
SkDEBUGF("Convert error: Invalid utf16 input");
|
||||||
|
return utf8Units;
|
||||||
|
}
|
||||||
|
*utf8 = std::unique_ptr<char[]>(new char[utf8Units]);
|
||||||
|
SkDEBUGCODE(int dstLen =) SkUTF::UTF16ToUTF8(utf8->get(), utf8Units, utf16, utf16Units);
|
||||||
|
SkASSERT(dstLen == utf8Units);
|
||||||
|
return utf8Units;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~SkUnicode_icu() override { }
|
~SkUnicode_icu() override { }
|
||||||
std::unique_ptr<SkBidiIterator> makeBidiIterator(const uint16_t text[], int count,
|
std::unique_ptr<SkBidiIterator> makeBidiIterator(const uint16_t text[], int count,
|
||||||
@ -460,12 +488,26 @@ public:
|
|||||||
return property == U_LB_LINE_FEED || property == U_LB_MANDATORY_BREAK;
|
return property == U_LB_LINE_FEED || property == U_LB_MANDATORY_BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkString convertUtf16ToUtf8(const std::u16string& utf16) override {
|
||||||
|
std::unique_ptr<char[]> utf8;
|
||||||
|
auto utf8Units = SkUnicode_icu::utf16ToUtf8((uint16_t*)utf16.data(), utf16.size(), &utf8);
|
||||||
|
if (utf8Units >= 0) {
|
||||||
|
return SkString(utf8.get(), utf8Units);
|
||||||
|
} else {
|
||||||
|
return SkString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SkString toUpper(const SkString& str) override {
|
SkString toUpper(const SkString& str) override {
|
||||||
// Convert to UTF16 since that's what ICU wants.
|
// Convert to UTF16 since that's what ICU wants.
|
||||||
auto str16 = convertUtf8ToUtf16(str.c_str(), str.size());
|
std::unique_ptr<uint16_t[]> str16;
|
||||||
|
const auto str16len = utf8ToUtf16(str.c_str(), str.size(), &str16);
|
||||||
|
if (str16len <= 0) {
|
||||||
|
return SkString();
|
||||||
|
}
|
||||||
|
|
||||||
UErrorCode icu_err = U_ZERO_ERROR;
|
UErrorCode icu_err = U_ZERO_ERROR;
|
||||||
const auto upper16len = sk_u_strToUpper(nullptr, 0, (UChar*)(str16.c_str()), str16.size(),
|
const auto upper16len = sk_u_strToUpper(nullptr, 0, (UChar*)(str16.get()), str16len,
|
||||||
nullptr, &icu_err);
|
nullptr, &icu_err);
|
||||||
if (icu_err != U_BUFFER_OVERFLOW_ERROR || upper16len <= 0) {
|
if (icu_err != U_BUFFER_OVERFLOW_ERROR || upper16len <= 0) {
|
||||||
return SkString();
|
return SkString();
|
||||||
@ -474,13 +516,17 @@ public:
|
|||||||
SkAutoSTArray<128, uint16_t> upper16(upper16len);
|
SkAutoSTArray<128, uint16_t> upper16(upper16len);
|
||||||
icu_err = U_ZERO_ERROR;
|
icu_err = U_ZERO_ERROR;
|
||||||
sk_u_strToUpper((UChar*)(upper16.get()), SkToS32(upper16.size()),
|
sk_u_strToUpper((UChar*)(upper16.get()), SkToS32(upper16.size()),
|
||||||
(UChar*)(str16.c_str()), str16.size(),
|
(UChar*)(str16.get()), str16len,
|
||||||
nullptr, &icu_err);
|
nullptr, &icu_err);
|
||||||
SkASSERT(!U_FAILURE(icu_err));
|
SkASSERT(!U_FAILURE(icu_err));
|
||||||
|
|
||||||
// ... and back to utf8 'cause that's what we want.
|
// ... and back to utf8 'cause that's what we want.
|
||||||
auto upper8 = convertUtf16ToUtf8(str16);
|
std::unique_ptr<char[]> upper8;
|
||||||
return upper8;
|
auto upper8len = utf16ToUtf8(upper16.data(), upper16.size(), &upper8);
|
||||||
|
|
||||||
|
return upper8len >= 0
|
||||||
|
? SkString(upper8.get(), upper8len)
|
||||||
|
: SkString();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getBidiRegions(const char utf8[],
|
bool getBidiRegions(const char utf8[],
|
||||||
@ -505,8 +551,13 @@ public:
|
|||||||
bool getWords(const char utf8[], int utf8Units, std::vector<Position>* results) override {
|
bool getWords(const char utf8[], int utf8Units, std::vector<Position>* results) override {
|
||||||
|
|
||||||
// Convert to UTF16 since we want the results in utf16
|
// Convert to UTF16 since we want the results in utf16
|
||||||
auto utf16 = convertUtf8ToUtf16(utf8, utf8Units);
|
std::unique_ptr<uint16_t[]> utf16;
|
||||||
return extractWords((uint16_t*)utf16.c_str(), utf16.size(), results);
|
auto utf16Units = utf8ToUtf16(utf8, utf8Units, &utf16);
|
||||||
|
if (utf16Units < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return extractWords(utf16.get(), utf16Units, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getGraphemes(const char utf8[], int utf8Units, std::vector<Position>* results) override {
|
bool getGraphemes(const char utf8[], int utf8Units, std::vector<Position>* results) override {
|
||||||
|
Loading…
Reference in New Issue
Block a user