summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaph Levien <raph@google.com>2014-06-19 01:51:47 -0700
committerRaph Levien <raph@google.com>2014-06-19 09:03:01 -0700
commitbb601b67dd05947f92cc23092bfb8a059c2e3377 (patch)
tree1376224b210e33c0cea96730c475319e646f40b7
parent3276dee361e91d65013ad3f1894796623308f4e6 (diff)
downloadandroid_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.cpp19
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;