diff options
author | Fabrice Di Meglio <fdimeglio@google.com> | 2012-01-31 13:30:40 -0800 |
---|---|---|
committer | Fabrice Di Meglio <fdimeglio@google.com> | 2012-02-02 19:07:02 -0800 |
commit | ab8c73882e0c572f42a5c73ebabf18706b8cc7b6 (patch) | |
tree | 6f1880590c999ddfeac900760873e14e829b02e2 /core/jni/android | |
parent | cf0c7d1031ea213c1b728aca972522afcd4a92c3 (diff) | |
download | frameworks_base-ab8c73882e0c572f42a5c73ebabf18706b8cc7b6.zip frameworks_base-ab8c73882e0c572f42a5c73ebabf18706b8cc7b6.tar.gz frameworks_base-ab8c73882e0c572f42a5c73ebabf18706b8cc7b6.tar.bz2 |
Fix bug #5929529 Parentheses aren't correctly rendered in RTL context
- do BiDi mirrored char mirroring in TextLayoutCache
- see BiDi mirrored chars list at:
http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedBinaryProperties.txt
Change-Id: Ia0af0e252dbb0c55cc689bc9db34e05591bb6ee8
Diffstat (limited to 'core/jni/android')
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index c797a73..a1997a2 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -37,6 +37,8 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutEngine); +static KeyedVector<UChar, UChar> gBidiMirrored; + //-------------------------------------------------------------------------------------------------- TextLayoutCache::TextLayoutCache(TextLayoutShaper* shaper) : @@ -350,6 +352,23 @@ TextLayoutShaper::TextLayoutShaper() : mShaperItemGlyphArraySize(0) { mShaperItem.font = &mFontRec; mShaperItem.font->userData = &mShapingPaint; + + // Fill the BiDi mirrored chars map + // See: http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedBinaryProperties.txt + gBidiMirrored.add('(', ')'); + gBidiMirrored.add(')', '('); + gBidiMirrored.add('[', ']'); + gBidiMirrored.add(']', '['); + gBidiMirrored.add('{', '}'); + gBidiMirrored.add('}', '{'); + gBidiMirrored.add('<', '>'); + gBidiMirrored.add('>', '<'); + gBidiMirrored.add(0x00ab, 0x00bb); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + gBidiMirrored.add(0x00bb, 0x00ab); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + gBidiMirrored.add(0x2039, 0x203a); // SINGLE LEFT-POINTING ANGLE QUOTATION MARK + gBidiMirrored.add(0x203a, 0x2039); // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + gBidiMirrored.add(0x2264, 0x2265); // LESS-THAN OR EQUAL TO + gBidiMirrored.add(0x2265, 0x2264); // GREATER-THAN OR EQUAL TO } TextLayoutShaper::~TextLayoutShaper() { @@ -577,6 +596,31 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* chars } } + // Reverse "BiDi mirrored chars" in RTL mode only + // See: http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedBinaryProperties.txt + // This is a workaround because Harfbuzz is not able to do mirroring in all cases and + // script-run splitting with Harfbuzz is splitting on parenthesis + if (isRTL) { + for (ssize_t i = 0; i < ssize_t(count); i++) { + UChar ch = chars[i]; + ssize_t index = gBidiMirrored.indexOfKey(ch); + // Skip non "BiDi mirrored" chars + if (index < 0) { + continue; + } + if (!useNormalizedString) { + useNormalizedString = true; + mNormalizedString.setTo(false /* not terminated*/, chars, count); + } + UChar result = gBidiMirrored.valueAt(index); + mNormalizedString.setCharAt(i, result); +#if DEBUG_GLYPHS + ALOGD("Rewriting codepoint '%d' to '%d' at position %d", + ch, mNormalizedString[i], int(i)); +#endif + } + } + #if DEBUG_GLYPHS if (useNormalizedString) { ALOGD("Will use normalized string '%s', length = %d", |