From f952161b874fd2e9af474b9fd2ebcca1f3bb4555 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 8 Aug 2014 15:25:57 -0400 Subject: Choose same font for Emoji keycap and its base character The U+20E3 COMBINING KEYCAP is used in our fonts to generate an emoji rendering of ASCII numbers and letters through GSUB. For that to work we need to choose the same (Emoji) font for the character coming *before* the COMBINING KEYCAP character. This is a special-case of a broader need to choose fonts per grapheme cluster as opposed to per character, but for now, special-case U+20E3. Bug: 7557244 Change-Id: I958e5a01068df8495bbb9bc3b9ed871cea1838b6 --- libs/minikin/FontCollection.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'libs') diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp index a6977fd..009584e 100644 --- a/libs/minikin/FontCollection.cpp +++ b/libs/minikin/FontCollection.cpp @@ -152,9 +152,11 @@ const FontCollection::FontInstance* FontCollection::getInstanceForChar(uint32_t const uint32_t NBSP = 0xa0; const uint32_t ZWJ = 0x200c; const uint32_t ZWNJ = 0x200d; +const uint32_t KEYCAP = 0x20e3; + // Characters where we want to continue using existing font run instead of // recomputing the best match in the fallback list. -static const uint32_t stickyWhitelist[] = { '!', ',', '.', ':', ';', '?', NBSP, ZWJ, ZWNJ }; +static const uint32_t stickyWhitelist[] = { '!', ',', '.', ':', ';', '?', NBSP, ZWJ, ZWNJ, KEYCAP }; static bool isStickyWhitelisted(uint32_t c) { for (size_t i = 0; i < sizeof(stickyWhitelist) / sizeof(stickyWhitelist[0]); i++) { @@ -185,6 +187,19 @@ void FontCollection::itemize(const uint16_t *string, size_t string_size, FontSty || !(isStickyWhitelisted(ch) && lastInstance->mCoverage->get(ch))) { const FontInstance* instance = getInstanceForChar(ch, lang, variant); if (i == 0 || instance != lastInstance) { + size_t start = i; + // Workaround for Emoji keycap until we implement per-cluster font + // selection: if keycap is found in a different font that also + // supports previous char, attach previous char to the new run. + // Only handles non-surrogate characters. + // Bug 7557244. + if (ch == KEYCAP && i && instance && instance->mCoverage->get(string[i - 1])) { + run->end--; + if (run->start == run->end) { + result->pop_back(); + } + start--; + } Run dummy; result->push_back(dummy); run = &result->back(); @@ -194,7 +209,7 @@ void FontCollection::itemize(const uint16_t *string, size_t string_size, FontSty run->fakedFont = instance->mFamily->getClosestMatch(style); } lastInstance = instance; - run->start = i; + run->start = start; } } run->end = i + nShorts; -- cgit v1.2.3