From ae9d0e0517eae9b95ef4cba1be0a5ee51a5476e7 Mon Sep 17 00:00:00 2001 From: John Daggett Date: Thu, 20 Mar 2014 14:43:30 +0800 Subject: [PATCH] Bug 921858 - check for spaces in textrun before skipping word cache. r=jfkthame --- gfx/thebes/gfxFont.cpp | 39 +++++++++++++++++++++++++++++++-------- gfx/thebes/gfxFont.h | 4 ++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 58788e6e76a8..544fc5ff0217 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -2346,7 +2346,7 @@ gfxFont::HasSubstitutionRulesWithSpaceLookups(int32_t aRunScript) } bool -gfxFont::BypassShapedWordCache(int32_t aRunScript) +gfxFont::SpaceMayParticipateInShaping(int32_t aRunScript) { // We record the presence of space-dependent features in the font entry // so that subsequent instantiations for the same font face won't @@ -3690,6 +3690,21 @@ gfxFont::ShapeTextWithoutWordCache(gfxContext *aContext, inline static bool IsChar8Bit(uint8_t /*aCh*/) { return true; } inline static bool IsChar8Bit(char16_t aCh) { return aCh < 0x100; } +inline static bool HasSpaces(const uint8_t *aString, uint32_t aLen) +{ + return memchr(aString, 0x20, aLen) != nullptr; +} + +inline static bool HasSpaces(const char16_t *aString, uint32_t aLen) +{ + for (const char16_t *ch = aString; ch < aString + aLen; ch++) { + if (*ch == 0x20) { + return true; + } + } + return false; +} + template bool gfxFont::SplitAndInitTextRun(gfxContext *aContext, @@ -3720,16 +3735,24 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext, } #endif - if (BypassShapedWordCache(aRunScript)) { - TEXT_PERF_INCR(tp, wordCacheSpaceRules); - return ShapeTextWithoutWordCache(aContext, aString + aRunStart, - aRunStart, aRunLength, aRunScript, - aTextRun); + uint32_t wordCacheCharLimit = + gfxPlatform::GetPlatform()->WordCacheCharLimit(); + + // If spaces can participate in shaping (e.g. within lookups for automatic + // fractions), need to shape without using the word cache which segments + // textruns on space boundaries. Word cache can be used if the textrun + // is short enough to fit in the word cache and it lacks spaces. + if (SpaceMayParticipateInShaping(aRunScript)) { + if (aRunLength > wordCacheCharLimit || + HasSpaces(aString + aRunStart, aRunLength)) { + TEXT_PERF_INCR(tp, wordCacheSpaceRules); + return ShapeTextWithoutWordCache(aContext, aString + aRunStart, + aRunStart, aRunLength, aRunScript, + aTextRun); + } } InitWordCache(); - uint32_t wordCacheCharLimit = - gfxPlatform::GetPlatform()->WordCacheCharLimit(); // the only flags we care about for ShapedWord construction/caching uint32_t flags = aTextRun->GetFlags(); diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 5c26412310be..d566c8c304d9 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1807,8 +1807,8 @@ protected: // whether font contains substitution lookups containing spaces bool HasSubstitutionRulesWithSpaceLookups(int32_t aRunScript); - // whether to use word cache or not - bool BypassShapedWordCache(int32_t aRunScript); + // do spaces participate in shaping rules? if so, can't used word cache + bool SpaceMayParticipateInShaping(int32_t aRunScript); // For 8-bit text, expand to 16-bit and then call the following method. bool ShapeText(gfxContext *aContext,