summaryrefslogtreecommitdiffstats
path: root/core/jni/android
diff options
context:
space:
mode:
authorFabrice Di Meglio <fdimeglio@google.com>2012-01-31 13:30:40 -0800
committerFabrice Di Meglio <fdimeglio@google.com>2012-02-02 19:07:02 -0800
commitab8c73882e0c572f42a5c73ebabf18706b8cc7b6 (patch)
tree6f1880590c999ddfeac900760873e14e829b02e2 /core/jni/android
parentcf0c7d1031ea213c1b728aca972522afcd4a92c3 (diff)
downloadframeworks_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.cpp44
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",