Title: [115373] trunk/Source/WebCore
Revision
115373
Author
[email protected]
Date
2012-04-26 14:51:00 -0700 (Thu, 26 Apr 2012)

Log Message

[chromium] Complex text support for Android.
https://bugs.webkit.org/show_bug.cgi?id=84431

Complex text support is different on Android from other platforms.
There are 2 kinds of font on Android: system fonts and fallback fonts.
System fonts have a name, and are accessible in FontPlatformData.
Fallback fonts do not have specific names, so they are not accessible
from WebKit directly. There is one font for each script support.
To feed Harfbuzz, use a trick to get correct SkTypeface based on script.

Patch by Hao Zheng <[email protected]> on 2012-04-26
Reviewed by Tony Chang.

No new tests. Current tests are runnable on Android.

* platform/graphics/FontCache.h:
(FontCache): Make ComplexTextController friend of FontCache on Android.
* platform/graphics/chromium/FontCacheAndroid.cpp:
(WebCore::FontCache::createFontPlatformData):
* platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp:
(WebCore::ComplexTextController::getComplexFontPlatformData):
(WebCore):
(WebCore::ComplexTextController::setupFontForScriptRun):
* platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.h:
(ComplexTextController):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (115372 => 115373)


--- trunk/Source/WebCore/ChangeLog	2012-04-26 21:40:14 UTC (rev 115372)
+++ trunk/Source/WebCore/ChangeLog	2012-04-26 21:51:00 UTC (rev 115373)
@@ -1,3 +1,30 @@
+2012-04-26  Hao Zheng  <[email protected]>
+
+        [chromium] Complex text support for Android.
+        https://bugs.webkit.org/show_bug.cgi?id=84431
+
+        Complex text support is different on Android from other platforms.
+        There are 2 kinds of font on Android: system fonts and fallback fonts.
+        System fonts have a name, and are accessible in FontPlatformData.
+        Fallback fonts do not have specific names, so they are not accessible
+        from WebKit directly. There is one font for each script support.
+        To feed Harfbuzz, use a trick to get correct SkTypeface based on script.
+
+        Reviewed by Tony Chang.
+
+        No new tests. Current tests are runnable on Android.
+
+        * platform/graphics/FontCache.h:
+        (FontCache): Make ComplexTextController friend of FontCache on Android.
+        * platform/graphics/chromium/FontCacheAndroid.cpp:
+        (WebCore::FontCache::createFontPlatformData):
+        * platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp:
+        (WebCore::ComplexTextController::getComplexFontPlatformData):
+        (WebCore):
+        (WebCore::ComplexTextController::setupFontForScriptRun):
+        * platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.h:
+        (ComplexTextController):
+
 2012-04-26  Kentaro Hara  <[email protected]>
 
         [V8] Pass Isolate to wrap() (Part2)

Modified: trunk/Source/WebCore/platform/graphics/FontCache.h (115372 => 115373)


--- trunk/Source/WebCore/platform/graphics/FontCache.h	2012-04-26 21:40:14 UTC (rev 115372)
+++ trunk/Source/WebCore/platform/graphics/FontCache.h	2012-04-26 21:51:00 UTC (rev 115373)
@@ -130,7 +130,7 @@
     // Don't purge if this count is > 0;
     int m_purgePreventCount;
 
-#if USE(CORE_TEXT)
+#if USE(CORE_TEXT) || OS(ANDROID)
     friend class ComplexTextController;
 #endif
     friend class SimpleFontData; // For getCachedFontData(const FontPlatformData*)

Modified: trunk/Source/WebCore/platform/graphics/chromium/FontCacheAndroid.cpp (115372 => 115373)


--- trunk/Source/WebCore/platform/graphics/chromium/FontCacheAndroid.cpp	2012-04-26 21:40:14 UTC (rev 115372)
+++ trunk/Source/WebCore/platform/graphics/chromium/FontCacheAndroid.cpp	2012-04-26 21:51:00 UTC (rev 115373)
@@ -39,7 +39,7 @@
 #include "SimpleFontData.h"
 
 #include "SkPaint.h"
-#include "SkTypeface.h"
+#include "SkTypeface_android.h"
 #include "SkUtils.h"
 
 #include <unicode/locid.h>
@@ -164,33 +164,46 @@
     if (fontDescription.italic())
         style |= SkTypeface::kItalic;
 
-    SkTypeface* typeface = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
+    SkTypeface* typeface = 0;
     FontPlatformData* result = 0;
+    FallbackScripts fallbackScript = SkGetFallbackScriptFromID(name);
+    if (SkTypeface_ValidScript(fallbackScript)) {
+        typeface = SkCreateTypefaceForScript(fallbackScript);
+        if (typeface)
+            result = new FontPlatformData(typeface, name, fontDescription.computedSize(),
+                                          (style & SkTypeface::kBold) && !typeface->isBold(),
+                                          (style & SkTypeface::kItalic) && !typeface->isItalic(),
+                                          fontDescription.orientation(),
+                                          fontDescription.textOrientation());
+    } else {
+        typeface = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
 
-    // CreateFromName always returns a typeface, falling back to a default font
-    // if the one requested could not be found. Calling Equal() with a null
-    // pointer will compare the returned font against the default, with the
-    // caveat that the default is always of normal style. When that happens,
-    // ignore the default font and allow WebCore to provide the next font on the
-    // CSS fallback list. The only exception to this occurs when the family name
-    // is a commonly used generic family, which is the case when called by
-    // getSimilarFontPlatformData() or getLastResortFallbackFont(). In that case
-    // the default font is an acceptable result.
+        // CreateFromName always returns a typeface, falling back to a default font
+        // if the one requested could not be found. Calling Equal() with a null
+        // pointer will compare the returned font against the default, with the
+        // caveat that the default is always of normal style. When that happens,
+        // ignore the default font and allow WebCore to provide the next font on the
+        // CSS fallback list. The only exception to this occurs when the family name
+        // is a commonly used generic family, which is the case when called by
+        // getSimilarFontPlatformData() or getLastResortFallbackFont(). In that case
+        // the default font is an acceptable result.
 
-    if (!SkTypeface::Equal(typeface, 0) || isFallbackFamily(family.string())) {
-        if (style != SkTypeface::kNormal) {
-            typeface->unref();
-            typeface = SkTypeface::CreateFromName(name, static_cast<SkTypeface::Style>(style));
+        if (!SkTypeface::Equal(typeface, 0) || isFallbackFamily(family.string())) {
+            // We had to use normal styling to see if this was a default font. If
+            // we need bold or italic, replace with the corrected typeface.
+            if (style != SkTypeface::kNormal) {
+                typeface->unref();
+                typeface = SkTypeface::CreateFromName(name, static_cast<SkTypeface::Style>(style));
+            }
+            result = new FontPlatformData(typeface, name, fontDescription.computedSize(),
+                                          (style & SkTypeface::kBold) && !typeface->isBold(),
+                                          (style & SkTypeface::kItalic) && !typeface->isItalic(),
+                                          fontDescription.orientation(),
+                                          fontDescription.textOrientation());
         }
-
-        result = new FontPlatformData(typeface, name, fontDescription.computedSize(),
-                                      (style & SkTypeface::kBold) && !typeface->isBold(),
-                                      (style & SkTypeface::kItalic) && !typeface->isItalic(),
-                                      fontDescription.orientation(),
-                                      fontDescription.textOrientation());
     }
 
-    typeface->unref();
+    SkSafeUnref(typeface);
     return result;
 }
 

Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp (115372 => 115373)


--- trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp	2012-04-26 21:40:14 UTC (rev 115372)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp	2012-04-26 21:51:00 UTC (rev 115373)
@@ -36,6 +36,11 @@
 #include "SurrogatePairAwareTextIterator.h"
 #include "TextRun.h"
 
+#if OS(ANDROID)
+#include "FontCache.h"
+#include "SkTypeface_android.h"
+#endif
+
 extern "C" {
 #include "harfbuzz-unicode.h"
 }
@@ -191,6 +196,53 @@
     return characters[0];
 }
 
+const FontPlatformData* ComplexTextController::getComplexFontPlatformData()
+{
+#if OS(ANDROID)
+    // There are 2 kinds of font on Android: system fonts and fallback fonts.
+    // System fonts have a name, and are accessible in FontPlatformData.
+    // Fallback fonts do not have specific names, so they are not accessible
+    // from WebKit directly. To feed Harfbuzz, use a trick to get correct
+    // SkTypeface based on script.
+    FallbackScripts fallbackScript = kFallbackScriptNumber; // invalid script value.
+    switch (m_item.item.script) {
+    case HB_Script_Arabic:
+        fallbackScript = kArabic_FallbackScript;
+        break;
+    case HB_Script_Hebrew:
+        if (m_font->fontDescription().weight() >= FontWeightBold)
+            fallbackScript = kHebrewBold_FallbackScript;
+        else
+            fallbackScript = kHebrewRegular_FallbackScript;
+        break;
+    case HB_Script_Thai:
+        fallbackScript = kThai_FallbackScript;
+        break;
+    case HB_Script_Armenian:
+        fallbackScript = kArmenian_FallbackScript;
+        break;
+    case HB_Script_Georgian:
+        fallbackScript = kGeorgian_FallbackScript;
+        break;
+    case HB_Script_Devanagari:
+        fallbackScript = kDevanagari_FallbackScript;
+        break;
+    case HB_Script_Bengali:
+        fallbackScript = kBengali_FallbackScript;
+        break;
+    case HB_Script_Tamil:
+        fallbackScript = kTamil_FallbackScript;
+        break;
+    default:
+        return 0;
+    }
+    return fontCache()->getCachedFontPlatformData(m_font->fontDescription(), SkGetFallbackScriptID(fallbackScript), true);
+#else
+    // Only Android needs the extra logic.
+    return 0;
+#endif
+}
+
 void ComplexTextController::setupFontForScriptRun()
 {
     FontDataVariant fontDataVariant = AutoVariant;
@@ -205,23 +257,26 @@
         m_item.item.pos = 0;
         fontDataVariant = SmallCapsVariant;
     }
-    UChar32 current = surrogatePairAwareFirstCharacter(static_cast<const UChar*>(&m_item.string[m_item.item.pos]), m_item.item.length - m_item.item.pos);
-    const FontData* fontData = m_font->glyphDataForCharacter(current, false, fontDataVariant).fontData;
-    const FontPlatformData& platformData = fontData->fontDataForCharacter(' ')->platformData();
-    m_item.face = platformData.harfbuzzFace()->face();
+    const FontPlatformData* platformData = getComplexFontPlatformData();
+    if (!platformData) {
+        UChar32 current = surrogatePairAwareFirstCharacter(static_cast<const UChar*>(&m_item.string[m_item.item.pos]), m_item.item.length - m_item.item.pos);
+        const FontData* fontData = m_font->glyphDataForCharacter(current, false, fontDataVariant).fontData;
+        platformData = &fontData->fontDataForCharacter(' ')->platformData();
+    }
+    m_item.face = platformData->harfbuzzFace()->face();
     // We only need to setup font features at the beginning of the run.
     if (!m_item.item.pos)
         setupFontFeatures(m_font->fontDescription().featureSettings(), m_item.face);
-    void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData);
+    void* opaquePlatformData = const_cast<FontPlatformData*>(platformData);
     m_item.font->userData = opaquePlatformData;
 
-    int size = platformData.size();
+    int size = platformData->size();
     m_item.font->x_ppem = size;
     m_item.font->y_ppem = size;
     // x_ and y_scale are the conversion factors from font design space (fEmSize) to 1/64th of device pixels in 16.16 format.
     const int devicePixelFraction = 64;
     const int multiplyFor16Dot16 = 1 << 16;
-    int scale = devicePixelFraction * size * multiplyFor16Dot16 / platformData.emSizeInFontUnits();
+    int scale = devicePixelFraction * size * multiplyFor16Dot16 / platformData->emSizeInFontUnits();
     m_item.font->x_scale = scale;
     m_item.font->y_scale = scale;
 }

Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.h (115372 => 115373)


--- trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.h	2012-04-26 21:40:14 UTC (rev 115372)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.h	2012-04-26 21:51:00 UTC (rev 115373)
@@ -105,6 +105,7 @@
     // Return the width (in px) of the current script run.
     unsigned width() const { return m_pixelWidth; }
 
+    const FontPlatformData* getComplexFontPlatformData();
     void setupFontForScriptRun();
     void deleteGlyphArrays();
     void createGlyphArrays(int);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to