Yet another workaround Thai \n problem (same as txtlib)
Bug: skia:10881
Change-Id: If451b662646e66e5d699ca0cca3795f5e078b84e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332257
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
diff --git a/modules/skparagraph/samples/SampleParagraph.cpp b/modules/skparagraph/samples/SampleParagraph.cpp
index 5d95400..ebb8870 100644
--- a/modules/skparagraph/samples/SampleParagraph.cpp
+++ b/modules/skparagraph/samples/SampleParagraph.cpp
@@ -3122,6 +3122,36 @@
using INHERITED = Sample;
};
+class ParagraphView51 : public ParagraphView_Base {
+protected:
+ SkString name() override { return SkString("Paragraph51"); }
+
+ void onDrawContent(SkCanvas* canvas) override {
+ canvas->clear(SK_ColorWHITE);
+
+ auto fontCollection = sk_make_sp<FontCollection>();
+ fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
+ fontCollection->enableFontFallback();
+
+ ParagraphStyle paragraph_style;
+ TextStyle text_style;
+ text_style.setColor(SK_ColorBLACK);
+ text_style.setFontFamilies({SkString("Roboto")});
+ text_style.setFontSize(16);
+ ParagraphBuilderImpl builder(paragraph_style, fontCollection);
+ builder.pushStyle(text_style);
+ builder.addText(u"\u0e41\u0e2a\u0e19\u0e2a\u0e31\nabc");
+ builder.pop();
+ auto paragraph = builder.Build();
+ paragraph->layout(1000);
+ paragraph->paint(canvas, 0, 0);
+ }
+
+private:
+ using INHERITED = Sample;
+};
+
+
} // namespace
//////////////////////////////////////////////////////////////////////////////
@@ -3173,3 +3203,4 @@
DEF_SAMPLE(return new ParagraphView48();)
DEF_SAMPLE(return new ParagraphView49();)
DEF_SAMPLE(return new ParagraphView50();)
+DEF_SAMPLE(return new ParagraphView51();)
diff --git a/modules/skparagraph/test.html b/modules/skparagraph/test.html
index 31616cf..b488ee0 100644
--- a/modules/skparagraph/test.html
+++ b/modules/skparagraph/test.html
@@ -27,8 +27,8 @@
</div>
-->
<div style="width:10mm; height: 100mm;"></div>
- <div style="text-align: left; background-color: lightgray; color: darkblue;font-family: Roboto; font-size: 30mm; " >
- >Sͬ͑̀͐̈͒̈́̋̎ͮͩ̽̓ͬ̂̆̔͗́̓ͣͧ͊ͫ͛̉͌̐̑ͪ͗̚͝҉̴͉͢k̡̊̓ͫͭͩ͂͊ͨͪͬ̑ͫ̍̌̄͛̌̂̑̂̋̊̔ͫ͛̽̑ͨ̍ͭ̓̀ͪͪ̉͐͗̌̓̃̚͟͝҉̢͏̫̞̙͇͖̮͕̗̟͕͇͚̻͈̣̻̪͉̰̲̣̫ͅͅP̴̅̍͒̿͗͗̇ͩ̃͆͌̀̽͏̧̡͕͖̝̖̼̺̰̣̬͔͖͔̼͙̞̦̫͓̘͜a̸̴̸̴̢̢̨̨̫͍͓̥̼̭̼̻̤̯̙̤̻̠͚̍̌͋̂ͦͨ̽̇͌͌͆̀̽̎͒̄ͪ̐ͦ̈ͫ͐͗̓̚̚͜ͅr͐͐ͤͫ̐ͥ͂̈́̿́ͮ̃͗̓̏ͫ̀̿͏̸̵̧́͘̕͟͝͠͞͠҉̷̧͚͢͟a̓̽̎̄͗̔͛̄̐͊͛ͫ͂͌̂̂̈̈̓̔̅̅̄͊̉́ͪ̑̄͆ͬ̍͆ͭ͋̐ͬ͏̷̵̨̢̩̹̖͓̥̳̰͔̱̬͖̙͓̙͇̀̀̕͜͟͟͢͟͜͠͡g̨̅̇ͦ͋̂ͦͨͭ̓͐͆̏̂͛̉ͧ̑ͫ̐̒͛ͫ̍̒͛́̚҉̷̨̛̛̀͜͢͞҉̩̘̲͍͎̯̹̝̭̗̱͇͉̲̱͔̯̠̹̥̻͉̲̜̤̰̪̗̺̖̺r̷͌̓̇̅ͭ̀̐̃̃ͭ͑͗̉̈̇̈́ͥ̓ͣ́ͤ͂ͤ͂̏͌̆̚҉̴̸̧̢̢̛̫͉̦̥̤̙͈͉͈͉͓̙̗̟̳̜͈̗̺̟̠̠͖͓̖̪͕̠̕̕͝ͅả̸̴̡̡̧͠͞͡͞҉̛̕͟͏̷̘̪̱͈̲͉̞̠̞̪̫͎̲̬̖̀̀͟͝͞͞͠p̛͂̈͐̚͠҉̵̸̡̢̢̩̹͙̯͖̙̙̮̥̙͚̠͔̥̭̮̞̣̪̬̥̠̖̝̥̪͎́̀̕͜͡͡ͅͅh̵̷̵̡̛ͤ̂͌̐̓̐̋̋͊̒̆̽́̀̀̀͢͠͞͞҉̷̸̢̕҉͚̯͖̫̜̞̟̠̱͉̝̲̹̼͉̟͉̩̮͔̤͖̞̭̙̹̬ͅ<
+ <div style="text-align: left; background-color: lightgray; color: darkblue;font-family: Roboto; font-size: 130mm; " >
+แสธสั
</div>
</body>
diff --git a/modules/skshaper/src/SkUnicode_icu.cpp b/modules/skshaper/src/SkUnicode_icu.cpp
index 806900d..7636fdd 100644
--- a/modules/skshaper/src/SkUnicode_icu.cpp
+++ b/modules/skshaper/src/SkUnicode_icu.cpp
@@ -305,7 +305,7 @@
}
static bool extractPositions
- (const char utf8[], int utf8Units, BreakType type, std::function<void(int, int)> add) {
+ (const char utf8[], int utf8Units, BreakType type, std::function<void(int, int)> setBreak) {
UErrorCode status = U_ZERO_ERROR;
UText sUtf8UText = UTEXT_INITIALIZER;
@@ -331,9 +331,27 @@
auto iter = iterator.get();
int32_t pos = ubrk_first(iter);
while (pos != UBRK_DONE) {
- add(pos, ubrk_getRuleStatus(iter));
+ auto status = type == SkUnicode::BreakType::kLines
+ ? UBRK_LINE_SOFT
+ : ubrk_getRuleStatus(iter);
+ setBreak(pos, status);
pos = ubrk_next(iter);
}
+
+ if (type == SkUnicode::BreakType::kLines) {
+ // This is a workaround for https://bugs.chromium.org/p/skia/issues/detail?id=10715
+ // (ICU line break iterator does not work correctly on Thai text with new lines)
+ // So, we only use the iterator to collect soft line breaks and
+ // scan the text for all hard line breaks ourselves
+ const char* end = utf8 + utf8Units;
+ const char* ch = utf8;
+ while (ch < end) {
+ auto unichar = utf8_next(&ch, end);
+ if (isHardLineBreak(unichar)) {
+ setBreak(ch - utf8, UBRK_LINE_HARD);
+ }
+ }
+ }
return true;
}
@@ -409,6 +427,11 @@
return u_isWhitespace(utf8);
}
+ static bool isHardLineBreak(SkUnichar utf8) {
+ auto property = u_getIntPropertyValue(utf8, UCHAR_LINE_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);
@@ -432,7 +455,7 @@
return extractPositions(utf8, utf8Units, BreakType::kLines,
[results](int pos, int status) {
- results->emplace_back(pos,status == UBRK_LINE_HARD
+ results->emplace_back(pos, status == UBRK_LINE_HARD
? LineBreakType::kHardLineBreak
: LineBreakType::kSoftLineBreak);
});