diff options
author | Raph Levien <raph@google.com> | 2014-06-19 01:51:47 -0700 |
---|---|---|
committer | Raph Levien <raph@google.com> | 2014-06-19 09:03:01 -0700 |
commit | bb601b67dd05947f92cc23092bfb8a059c2e3377 (patch) | |
tree | 1376224b210e33c0cea96730c475319e646f40b7 | |
parent | 3276dee361e91d65013ad3f1894796623308f4e6 (diff) | |
download | android_frameworks_minikin-bb601b67dd05947f92cc23092bfb8a059c2e3377.tar.gz android_frameworks_minikin-bb601b67dd05947f92cc23092bfb8a059c2e3377.tar.bz2 android_frameworks_minikin-bb601b67dd05947f92cc23092bfb8a059c2e3377.zip |
Make font runs less sticky
Fixes b/15734816 In the text "Wi-Fi", "-Fi" appears bolder than "Wi"
The problem was caused by "stickiness" in choosing fonts, where layout
would prefer using a font used for preceding characters as long as it
mapped the following characters in a run, in favor of the "best match"
rules. This patch adds a whitelist for making the stickiness more
conservative, only applying it for characters necessary for correct
shaping (ZWJ and ZWNJ in particular) and basic punctuation, where it is
desirable to match the style of the preceding text.
Change-Id: I1cf116879f074a5a71c351846707bfdd07b0d320
-rw-r--r-- | libs/minikin/FontCollection.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp index 45e5d06..348c5dc 100644 --- a/libs/minikin/FontCollection.cpp +++ b/libs/minikin/FontCollection.cpp @@ -147,6 +147,20 @@ const FontCollection::FontInstance* FontCollection::getInstanceForChar(uint32_t return bestInstance; } +const uint32_t NBSP = 0xa0; +const uint32_t ZWJ = 0x200c; +const uint32_t ZWNJ = 0x200d; +// 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 bool isStickyWhitelisted(uint32_t c) { + for (size_t i = 0; i < sizeof(stickyWhitelist) / sizeof(stickyWhitelist[0]); i++) { + if (stickyWhitelist[i] == c) return true; + } + return false; +} + void FontCollection::itemize(const uint16_t *string, size_t string_size, FontStyle style, vector<Run>* result) const { FontLanguage lang = style.getLanguage(); @@ -164,8 +178,9 @@ void FontCollection::itemize(const uint16_t *string, size_t string_size, FontSty nShorts = 2; } } - // Continue using existing font as long as it has coverage. - if (lastInstance == NULL || !lastInstance->mCoverage->get(ch)) { + // Continue using existing font as long as it has coverage and is whitelisted + if (lastInstance == NULL + || !(isStickyWhitelisted(ch) && lastInstance->mCoverage->get(ch))) { const FontInstance* instance = getInstanceForChar(ch, lang, variant); if (i == 0 || instance != lastInstance) { Run dummy; |