OSDN Git Service

Support "Vertical Writing Mode".
authorclaireho <chinglanho@gmail.com>
Tue, 20 Sep 2011 20:56:32 +0000 (13:56 -0700)
committerclaireho <chinglanho@gmail.com>
Tue, 20 Sep 2011 21:11:30 +0000 (14:11 -0700)
Bug 5094208 - Browser does not handle Japanese text in vertical writing mode.
This changeset syncs up with Chrome's implementation for vertical text rendering. It
1. Adds fontOrientation and textOrientation to FontPlatformData.
2. Re-layout the text in drawGlyphs for vertical writing mode.

Change-Id: Icac88a464b4b25b05c758a4e24c1827e0a7a0c91

Source/WebCore/platform/graphics/android/FontAndroid.cpp
Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp
Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp
Source/WebCore/platform/graphics/android/FontDataAndroid.cpp
Source/WebCore/platform/graphics/android/FontPlatformData.h
Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp

index 674938b..e01fd83 100644 (file)
@@ -183,8 +183,10 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
     SkScalar                    y = SkFloatToScalar(point.y());
     const GlyphBufferGlyph*     glyphs = glyphBuffer.glyphs(from);
     const GlyphBufferAdvance*   adv = glyphBuffer.advances(from);
-    SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
+    SkAutoSTMalloc<32, SkPoint> storage(numGlyphs), storage2(numGlyphs), storage3(numGlyphs);
     SkPoint*                    pos = storage.get();
+    SkPoint*                    vPosBegin = storage2.get();
+    SkPoint*                    vPosEnd = storage3.get();
 
     SkCanvas* canvas = gc->platformContext()->mCanvas;
 
@@ -221,12 +223,28 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
                                 localCount * sizeof(uint16_t),
                                 &pos[localIndex], paint);
     } else {
+        bool isVertical = font->platformData().orientation() == Vertical;
         for (int i = 0; i < numGlyphs; i++) {
             pos[i].set(x, y);
-            x += SkFloatToScalar(adv[i].width());
             y += SkFloatToScalar(adv[i].height());
+            if (isVertical) {
+                SkScalar myWidth = SkFloatToScalar(adv[i].width());
+                vPosBegin[i].set(x + myWidth, y);
+                vPosEnd[i].set(x + myWidth, y - myWidth);
+                x += myWidth;
+
+                SkPath path;
+                path.reset();
+                path.moveTo(vPosBegin[i]);
+                path.lineTo(vPosEnd[i]);
+                canvas->drawTextOnPath(glyphs + i, 2, path, 0, paint);
+            }
+            else {
+                x += SkFloatToScalar(adv[i].width());
+            }
         }
-        canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint);
+        if (!isVertical)
+            canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint);
     }
 }
 
index 20ffd17..4fc3b4e 100644 (file)
@@ -177,7 +177,9 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
 
         result = new FontPlatformData(tf, fontDescription.computedSize(),
                             (style & SkTypeface::kBold) && !tf->isBold(),
-                            (style & SkTypeface::kItalic) && !tf->isItalic());
+                            (style & SkTypeface::kItalic) && !tf->isItalic(),
+                            fontDescription.orientation(),
+                            fontDescription.textOrientation());
     }
 
     tf->unref();
index 72fac68..4279ce8 100644 (file)
@@ -45,7 +45,8 @@ FontCustomPlatformData::~FontCustomPlatformData()
     // the unref is enough to release the font data...
 }
 
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic,
+    FontOrientation fontOrientation, TextOrientation textOrientation, FontWidthVariant, FontRenderingMode)
 {
     // turn bold/italic into fakeBold/fakeItalic
     if (m_typeface != NULL) {
@@ -54,7 +55,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
         if (m_typeface->isItalic() == italic)
             italic = false;
     }
-    return FontPlatformData(m_typeface, size, bold, italic);
+    return FontPlatformData(m_typeface, size, bold, italic, fontOrientation, textOrientation);
 }
 
 FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
index 1f19b6d..c6dd174 100644 (file)
@@ -32,6 +32,7 @@
 #include "SimpleFontData.h"
 #include "FloatRect.h"
 #include "FontDescription.h"
+#include "SkFontHost.h"
 #include "SkPaint.h"
 #include "SkTypeface.h"
 #include "SkTime.h"
@@ -57,6 +58,16 @@ void SimpleFontData::platformInit()
     m_fontMetrics.setXHeight(SkScalarToFloat(-skiaFontMetrics.fAscent) * 0.56f);   // hack I stole from the window's port
     m_fontMetrics.setLineSpacing(a + d);
     m_fontMetrics.setLineGap(SkScalarToFloat(skiaFontMetrics.fLeading));
+
+    if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
+        static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
+        static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G');
+        const SkFontID fontID = m_platformData.uniqueID();
+        size_t vheaSize = SkFontHost::GetTableSize(fontID, vheaTag);
+        size_t vorgSize = SkFontHost::GetTableSize(fontID, vorgTag);
+        if ((vheaSize > 0) || (vorgSize > 0))
+            m_hasVerticalGlyphs = true;
+    }
 }
 
 void SimpleFontData::platformCharWidthInit()
index 56ce6e9..5c3313e 100644 (file)
@@ -31,6 +31,7 @@
 #define FontPlatformData_h
 
 #include "FontOrientation.h"
+#include "TextOrientation.h"
 #include <wtf/text/StringImpl.h>
 
 #ifndef NDEBUG
@@ -52,7 +53,8 @@ public:
 
     FontPlatformData();
     FontPlatformData(const FontPlatformData&);
-    FontPlatformData(SkTypeface*, float textSize, bool fakeBold, bool fakeItalic);
+    FontPlatformData(SkTypeface*, float textSize, bool fakeBold, bool fakeItalic,
+                     FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight);
     FontPlatformData(const FontPlatformData& src, float textSize);
     FontPlatformData(float size, bool syntheticBold, bool syntheticOblique);
     FontPlatformData(const FontPlatformData& src, SkTypeface* typeface);
@@ -65,9 +67,8 @@ public:
         return mTypeface == hashTableDeletedFontValue();
     }
 
-    FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
-    void setOrientation(FontOrientation) { } // FIXME: Implement.
-
+    FontOrientation orientation() const { return mOrientation; }
+    void setOrientation(FontOrientation orientation) { mOrientation = orientation; }
     FontPlatformData& operator=(const FontPlatformData&);
     bool operator==(const FontPlatformData& a) const;
 
@@ -114,6 +115,8 @@ private:
     float       mTextSize;
     bool        mFakeBold;
     bool        mFakeItalic;
+    FontOrientation mOrientation;
+    TextOrientation mTextOrientation;
     mutable RefPtr<RefCountedHarfbuzzFace> m_harfbuzzFace;
 
     static SkTypeface* hashTableDeletedFontValue() {
index 8e77b5b..1185fa7 100644 (file)
@@ -92,13 +92,17 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src)
     mFakeBold   = src.mFakeBold;
     mFakeItalic = src.mFakeItalic;
     m_harfbuzzFace = src.m_harfbuzzFace;
+    mOrientation = src.mOrientation;
+    mTextOrientation = src.mTextOrientation;
 
     inc_count();
     trace(2);
 }
 
-FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic)
-    : mTypeface(tf), mTextSize(textSize), mFakeBold(fakeBold), mFakeItalic(fakeItalic)
+FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic,
+    FontOrientation orientation, TextOrientation textOrientation)
+    : mTypeface(tf), mTextSize(textSize), mFakeBold(fakeBold), mFakeItalic(fakeItalic),
+      mOrientation(orientation), mTextOrientation(textOrientation)
 {
     if (hashTableDeletedFontValue() != mTypeface) {
         SkSafeRef(mTypeface);
@@ -110,7 +114,7 @@ FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold
 
 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
     : mTypeface(src.mTypeface), mTextSize(textSize), mFakeBold(src.mFakeBold), mFakeItalic(src.mFakeItalic),
-      m_harfbuzzFace(src.m_harfbuzzFace)
+      m_harfbuzzFace(src.m_harfbuzzFace), mOrientation(src.mOrientation), mTextOrientation(src.mTextOrientation)
 {
     if (hashTableDeletedFontValue() != mTypeface) {
         SkSafeRef(mTypeface);
@@ -129,7 +133,8 @@ FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
 
 FontPlatformData::FontPlatformData(const FontPlatformData& src, SkTypeface* tf)
     : mTypeface(tf), mTextSize(src.mTextSize), mFakeBold(src.mFakeBold),
-      mFakeItalic(src.mFakeItalic)
+      mFakeItalic(src.mFakeItalic), mOrientation(src.mOrientation),
+      mTextOrientation(src.mTextOrientation)
 {
     if (hashTableDeletedFontValue() != mTypeface) {
         SkSafeRef(mTypeface);
@@ -165,6 +170,8 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
     mFakeBold   = src.mFakeBold;
     mFakeItalic = src.mFakeItalic;
     m_harfbuzzFace = src.m_harfbuzzFace;
+    mOrientation = src.mOrientation;
+    mTextOrientation = src.mTextOrientation;
 
     return *this;
 }
@@ -204,7 +211,9 @@ bool FontPlatformData::operator==(const FontPlatformData& a) const
     return  mTypeface == a.mTypeface &&
             mTextSize == a.mTextSize &&
             mFakeBold == a.mFakeBold &&
-            mFakeItalic == a.mFakeItalic;
+            mFakeItalic == a.mFakeItalic &&
+            mOrientation == a.mOrientation &&
+            mTextOrientation == a.mTextOrientation;
 }
 
 unsigned FontPlatformData::hash() const
@@ -219,7 +228,8 @@ unsigned FontPlatformData::hash() const
 
     uint32_t sizeAsInt = *reinterpret_cast<const uint32_t*>(&mTextSize);
 
-    h ^= 0x01010101 * (((int)mFakeBold << 1) | (int)mFakeItalic);
+    h ^= 0x01010101 * ((static_cast<int>(mTextOrientation) << 3) | (static_cast<int>(mOrientation) << 2) |
+         ((int)mFakeBold << 1) | (int)mFakeItalic);
     h ^= sizeAsInt;
     return h;
 }