summaryrefslogtreecommitdiffstats
path: root/libs
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 /libs
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
Diffstat (limited to 'libs')
-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;