Make fallback font iterator in shaper cache fallback.
Most of the time when doing fallback there is a simple ping pong between
the requested font and a given fallback font. Use the fallback entry as
a cache of one. This greatly speeds up the example layout.
In the future more work will be done on caching.
Change-Id: I3efe819d6d08d096715cf505cc8d894a282a745b
Reviewed-on: https://skia-review.googlesource.com/151100
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/modules/skshaper/src/SkShaper_harfbuzz.cpp b/modules/skshaper/src/SkShaper_harfbuzz.cpp
index c15395b..2b20426 100644
--- a/modules/skshaper/src/SkShaper_harfbuzz.cpp
+++ b/modules/skshaper/src/SkShaper_harfbuzz.cpp
@@ -271,29 +271,29 @@
SkUnichar u = utf8_next(&fCurrent, fEnd);
// If the starting typeface can handle this character, use it.
if (fTypeface->charsToGlyphs(&u, SkTypeface::kUTF32_Encoding, nullptr, 1)) {
- fFallbackTypeface.reset();
+ fCurrentTypeface = fTypeface.get();
+ fCurrentHBFont = fHBFont;
+ // If the current fallback can handle this character, use it.
+ } else if (fFallbackTypeface &&
+ fFallbackTypeface->charsToGlyphs(&u, SkTypeface::kUTF32_Encoding, nullptr, 1))
+ {
+ fCurrentTypeface = fFallbackTypeface.get();
+ fCurrentHBFont = fFallbackHBFont.get();
// If not, try to find a fallback typeface
} else {
fFallbackTypeface.reset(fFallbackMgr->matchFamilyStyleCharacter(
nullptr, fTypeface->fontStyle(), nullptr, 0, u));
- }
-
- if (fFallbackTypeface) {
fFallbackHBFont = create_hb_font(fFallbackTypeface.get());
fCurrentTypeface = fFallbackTypeface.get();
fCurrentHBFont = fFallbackHBFont.get();
- } else {
- fFallbackHBFont.reset();
- fCurrentTypeface = fTypeface.get();
- fCurrentHBFont = fHBFont;
}
while (fCurrent < fEnd) {
const char* prev = fCurrent;
u = utf8_next(&fCurrent, fEnd);
- // If using a fallback and the initial typeface has this character, stop fallback.
- if (fFallbackTypeface &&
+ // If not using initial typeface and initial typeface has this character, stop fallback.
+ if (fCurrentTypeface != fTypeface.get() &&
fTypeface->charsToGlyphs(&u, SkTypeface::kUTF32_Encoding, nullptr, 1))
{
fCurrent = prev;
@@ -673,6 +673,7 @@
previousBreak = glyphIterator;
}
SkScalar glyphWidth = glyph->fAdvance.fX;
+ // TODO: if the glyph is non-visible it can be added.
if (widthSoFar + glyphWidth < width) {
widthSoFar += glyphWidth;
glyphIterator.next();
@@ -680,12 +681,14 @@
continue;
}
+ // TODO: for both of these emergency break cases
+ // don't break grapheme clusters and pull in any zero width or non-visible
if (widthSoFar == 0) {
// Adding just this glyph is too much, just break with this glyph
glyphIterator.next();
previousBreak = glyphIterator;
} else if (!previousBreakValid) {
- // No break opprotunity found yet, just break without this glyph
+ // No break opportunity found yet, just break without this glyph
previousBreak = glyphIterator;
}
glyphIterator = previousBreak;