summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
authorRaph Levien <raph@google.com>2012-05-02 10:41:14 -0700
committerRaph Levien <raph@google.com>2012-05-02 12:00:12 -0700
commit1637dcd16cd314574a58602337a2c7222130b1b9 (patch)
tree06171194995ad686062a4dc4fbc7ac0ad51dd4c0 /core/jni
parentb294435b5c6e0fee8c431ed3f6d77427d3d79dde (diff)
downloadframeworks_base-1637dcd16cd314574a58602337a2c7222130b1b9.zip
frameworks_base-1637dcd16cd314574a58602337a2c7222130b1b9.tar.gz
frameworks_base-1637dcd16cd314574a58602337a2c7222130b1b9.tar.bz2
Use paint typeface for shaping when it supports the requested script.
This is a hackish but workable fix for bug 6415796. Change-Id: Iaba91e1e53e688a3ee05a1fdb68fd05102e369f2
Diffstat (limited to 'core/jni')
-rw-r--r--core/jni/android/graphics/TextLayoutCache.cpp68
-rw-r--r--core/jni/android/graphics/TextLayoutCache.h3
2 files changed, 46 insertions, 25 deletions
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 0d36edf..2bd36c3 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -739,18 +739,18 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* chars
#endif
}
-
-size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
- // Reset kerning
- mShaperItem.kerning_applied = false;
-
- // Update Harfbuzz Shaper
- mShaperItem.item.bidiLevel = isRTL;
-
- SkTypeface* typeface = paint->getTypeface();
-
+/**
+ * Return the first typeface in the logical change, starting with this typeface,
+ * that contains the specified unichar, or NULL if none is found.
+ *
+ * Note that this function does _not_ increment the reference count on the typeface, as the
+ * assumption is that its lifetime is managed elsewhere - in particular, the fallback typefaces
+ * for the default font live in a global cache.
+ */
+SkTypeface* TextLayoutShaper::typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface,
+ SkUnichar unichar, HB_Script script) {
// Set the correct Typeface depending on the script
- switch (mShaperItem.item.script) {
+ switch (script) {
case HB_Script_Arabic:
typeface = getCachedTypeface(&mArabicTypeface, TYPEFACE_ARABIC);
#if DEBUG_GLYPHS
@@ -815,32 +815,31 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
break;
default:
- if (!typeface) {
- typeface = mDefaultTypeface;
-#if DEBUG_GLYPHS
- ALOGD("Using Default Typeface");
-#endif
- } else {
#if DEBUG_GLYPHS
+ if (typeface) {
ALOGD("Using Paint Typeface");
-#endif
}
+#endif
break;
}
+ return typeface;
+}
- mShapingPaint.setTypeface(typeface);
- mShaperItem.face = getCachedHBFace(typeface);
+size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
+ // Reset kerning
+ mShaperItem.kerning_applied = false;
-#if DEBUG_GLYPHS
- ALOGD("Run typeface = %p, uniqueID = %d, hb_face = %p",
- typeface, typeface->uniqueID(), mShaperItem.face);
-#endif
+ // Update Harfbuzz Shaper
+ mShaperItem.item.bidiLevel = isRTL;
+
+ SkTypeface* typeface = paint->getTypeface();
// Get the glyphs base count for offsetting the glyphIDs returned by Harfbuzz
// This is needed as the Typeface used for shaping can be not the default one
// when we are shaping any script that needs to use a fallback Font.
// If we are a "common" script we dont need to shift
size_t baseGlyphCount = 0;
+ SkUnichar firstUnichar = 0;
switch (mShaperItem.item.script) {
case HB_Script_Arabic:
case HB_Script_Hebrew:
@@ -850,7 +849,7 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
case HB_Script_Thai:{
const uint16_t* text16 = (const uint16_t*)(mShaperItem.string + mShaperItem.item.pos);
const uint16_t* text16End = text16 + mShaperItem.item.length;
- SkUnichar firstUnichar = SkUTF16_NextUnichar(&text16);
+ firstUnichar = SkUTF16_NextUnichar(&text16);
while (firstUnichar == ' ' && text16 < text16End) {
firstUnichar = SkUTF16_NextUnichar(&text16);
}
@@ -861,6 +860,25 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
break;
}
+ // We test the baseGlyphCount to see if the typeface supports the requested script
+ if (baseGlyphCount != 0) {
+ typeface = typefaceForUnichar(paint, typeface, firstUnichar, mShaperItem.item.script);
+ }
+
+ if (!typeface) {
+ typeface = mDefaultTypeface;
+#if DEBUG_GLYPHS
+ ALOGD("Using Default Typeface");
+#endif
+ }
+ mShapingPaint.setTypeface(typeface);
+ mShaperItem.face = getCachedHBFace(typeface);
+
+#if DEBUG_GLYPHS
+ ALOGD("Run typeface = %p, uniqueID = %d, hb_face = %p",
+ typeface, typeface->uniqueID(), mShaperItem.face);
+#endif
+
// Shape
assert(mShaperItem.item.length > 0); // Harfbuzz will overwrite other memory if length is 0.
ensureShaperItemGlyphArrays(mShaperItem.item.length * 3 / 2);
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 3c834a4..7d7caac 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -217,6 +217,9 @@ private:
*/
UnicodeString mBuffer;
+ SkTypeface* typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface,
+ SkUnichar unichar, HB_Script script);
+
size_t shapeFontRun(const SkPaint* paint, bool isRTL);
void computeValues(const SkPaint* paint, const UChar* chars,