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>
This commit is contained in:
Ben Wagner 2018-08-31 17:48:19 -04:00 committed by Skia Commit-Bot
parent b84576af0a
commit a900ad5400

View File

@ -271,29 +271,29 @@ public:
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 @@ SkPoint SkShaper::shape(SkTextBlobBuilder* builder,
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 @@ SkPoint SkShaper::shape(SkTextBlobBuilder* builder,
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;