22
33#include " modules/skparagraph/src/Iterators.h"
44#include " modules/skparagraph/src/OneLineShaper.h"
5- #include " modules/skparagraph/src/ParagraphUtil.h "
5+ #include < unicode/uchar.h >
66#include < algorithm>
77#include < unordered_set>
8+ #include " src/utils/SkUTF.h"
89
910namespace skia {
1011namespace textlayout {
1112
13+ namespace {
14+
15+ SkUnichar utf8_next (const char ** ptr, const char * end) {
16+ SkUnichar val = SkUTF::NextUTF8 (ptr, end);
17+ return val < 0 ? 0xFFFD : val;
18+ }
19+
20+ }
21+
1222void OneLineShaper::commitRunBuffer (const RunInfo&) {
1323
1424 fCurrentRun ->commit ();
@@ -303,8 +313,8 @@ void OneLineShaper::sortOutGlyphs(std::function<void(GlyphRange)>&& sortOutUnres
303313 block.end = i;
304314 } else {
305315 const char * cluster = text.begin () + clusterIndex (i);
306- SkUnichar codepoint = nextUtf8Unit (&cluster, text.end ());
307- if (isControl (codepoint)) {
316+ SkUnichar codepoint = utf8_next (&cluster, text.end ());
317+ if (u_iscntrl (codepoint)) {
308318 // This codepoint does not have to be resolved; let's pretend it's resolved
309319 if (block.start == EMPTY_INDEX) {
310320 // Keep skipping resolved code points
@@ -409,7 +419,7 @@ void OneLineShaper::matchResolvedFonts(const TextStyle& textStyle,
409419 // We have the global cache for all already found typefaces for SkUnichar
410420 // but we still need to keep track of all SkUnichars used in this unresolved block
411421 SkTHashSet<SkUnichar> alreadyTried;
412- SkUnichar unicode = nextUtf8Unit (&ch, unresolvedText.end ());
422+ SkUnichar unicode = utf8_next (&ch, unresolvedText.end ());
413423 while (true ) {
414424
415425 sk_sp<SkTypeface> typeface;
@@ -447,7 +457,7 @@ void OneLineShaper::matchResolvedFonts(const TextStyle& textStyle,
447457
448458 // We can stop here or we can switch to another DIFFERENT codepoint
449459 while (ch != unresolvedText.end ()) {
450- unicode = nextUtf8Unit (&ch, unresolvedText.end ());
460+ unicode = utf8_next (&ch, unresolvedText.end ());
451461 auto found = alreadyTried.find (unicode);
452462 if (found == nullptr ) {
453463 alreadyTried.add (unicode);
@@ -462,6 +472,10 @@ void OneLineShaper::matchResolvedFonts(const TextStyle& textStyle,
462472
463473bool OneLineShaper::iterateThroughShapingRegions (const ShapeVisitor& shape) {
464474
475+ if (!fParagraph ->getBidiRegions ()) {
476+ return false ;
477+ }
478+
465479 size_t bidiIndex = 0 ;
466480
467481 SkScalar advanceX = 0 ;
@@ -471,20 +485,20 @@ bool OneLineShaper::iterateThroughShapingRegions(const ShapeVisitor& shape) {
471485 // Shape the text by bidi regions
472486 while (bidiIndex < fParagraph ->fBidiRegions .size ()) {
473487 BidiRegion& bidiRegion = fParagraph ->fBidiRegions [bidiIndex];
474- auto start = std::max (bidiRegion.start , placeholder.fTextBefore .start );
475- auto end = std::min (bidiRegion.end , placeholder.fTextBefore .end );
488+ auto start = std::max (bidiRegion.text . start , placeholder.fTextBefore .start );
489+ auto end = std::min (bidiRegion.text . end , placeholder.fTextBefore .end );
476490
477491 // Set up the iterators (the style iterator points to a bigger region that it could
478492 TextRange textRange (start, end);
479493 auto blockRange = fParagraph ->findAllBlocks (textRange);
480494 SkSpan<Block> styleSpan (fParagraph ->blocks (blockRange));
481495
482496 // Shape the text between placeholders
483- if (!shape (textRange, styleSpan, advanceX, start, bidiRegion.level )) {
497+ if (!shape (textRange, styleSpan, advanceX, start, bidiRegion.direction )) {
484498 return false ;
485499 }
486500
487- if (end == bidiRegion.end ) {
501+ if (end == bidiRegion.text . end ) {
488502 ++bidiIndex;
489503 } else /* if (end == placeholder.fTextBefore.end)*/ {
490504 break ;
0 commit comments