From 6141db3846356efbdea093756701c89bd5155421 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Mon, 11 Jul 2016 13:59:58 -0700 Subject: [PATCH] Don't count zero width space in hasGlyph layout For sequences that may form ligatures (ie not just a a base character plus variation selector pair), hasGlyph requests a layout and then counts the glyph. In some cases, when the source string contains a variation selector, the layout contains space glyphs with no associated width, which causes a "false" result. This patch filters out such zero width spaces. Bug: 30056285 Change-Id: I9b5db4aa5ad24bf43e237c98b610fd269f2b91c9 --- core/jni/android/graphics/Paint.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index b586c43aacea5..67c94fba1de93 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -769,6 +769,21 @@ namespace PaintGlue { return false; } + // Don't count glyphs that are the recommended "space" glyph and are zero width. + // This logic makes assumptions about HarfBuzz layout, but does correctly handle + // cases where ligatures form and zero width space glyphs are left in as + // placeholders. + static size_t countNonSpaceGlyphs(const minikin::Layout& layout) { + size_t count = 0; + static unsigned int kSpaceGlyphId = 3; + for (size_t i = 0; i < layout.nGlyphs(); i++) { + if (layout.getGlyphId(i) != kSpaceGlyphId || layout.getCharAdvance(i) != 0.0) { + count++; + } + } + return count; + } + // Returns true if the given string is exact one pair of regional indicators. static bool isFlag(const jchar* str, size_t length) { const jchar RI_LEAD_SURROGATE = 0xD83C; @@ -832,7 +847,7 @@ namespace PaintGlue { minikin::Layout layout; MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, str.get(), 0, str.size(), str.size()); - size_t nGlyphs = layout.nGlyphs(); + size_t nGlyphs = countNonSpaceGlyphs(layout); if (nGlyphs != 1 && nChars > 1) { // multiple-character input, and was not a ligature // TODO: handle ZWJ/ZWNJ characters specially so we can detect certain ligatures