Title: [126907] trunk/Source/WebCore
Revision
126907
Author
[email protected]
Date
2012-08-28 11:52:17 -0700 (Tue, 28 Aug 2012)

Log Message

OPENTYPE_VERTICAL support for Chromium Win
https://bugs.webkit.org/show_bug.cgi?id=94822

Patch by Koji Ishii <[email protected]> on 2012-08-28
Reviewed by Tony Chang.

To fix bug 51450 - Glyphs in vertical text tests are rotated 90 degrees clockwise on Chromium Windows,
this patch adds support of OPENTYPE_VERTICAL feature for Chromium Windows.
Since enabling OPENTYPE_VERTICAL feature would require rather a big number of tests to rebaseline,
the actual fix is separated into this patch, and the feature will be enabled in bug 51450,
so that it is easier to revert on any perf regressions, as suggested by Tony in comment #50 of bug 51450.

All changes in this patch are behind #if ENABLE(OPENTYPE_VERTICAL) and therefore no tests are included in this patch.
All tests in fast/writing-modes currently skipped will be enabled in bug 51450.

* WebCore.gyp/WebCore.gyp: Added platform/graphics/opentype/OpenType*.
* WebCore.gypi: Ditto.
* platform/graphics/FontCache.h: SKia uses uint32_t as FontFileKey.
* platform/graphics/GlyphPageTreeNode.cpp:
(WebCore::fill): Replace vertical alternate glyphs if vertical flow.
* platform/graphics/SimpleFontData.cpp: Added m_verticalData.
(WebCore::SimpleFontData::SimpleFontData):
* platform/graphics/SimpleFontData.h:
(WebCore::SimpleFontData::verticalData):
(SimpleFontData):
(WebCore::SimpleFontData::widthForGlyph):
* platform/graphics/chromium/FontChromiumWin.cpp:
(WebCore::Font::drawGlyphs): Draw glyphs verticaly if font->verticalData().
* platform/graphics/chromium/FontPlatformDataChromiumWin.cpp:
(WebCore::FontPlatformData::verticalData): Added.
(WebCore):
(WebCore::FontPlatformData::openTypeTable): Added.
* platform/graphics/chromium/FontPlatformDataChromiumWin.h:
(WebCore):
(FontPlatformData): Added verticalData() and openTypeTable().

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (126906 => 126907)


--- trunk/Source/WebCore/ChangeLog	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/ChangeLog	2012-08-28 18:52:17 UTC (rev 126907)
@@ -1,3 +1,40 @@
+2012-08-28  Koji Ishii  <[email protected]>
+
+        OPENTYPE_VERTICAL support for Chromium Win
+        https://bugs.webkit.org/show_bug.cgi?id=94822
+
+        Reviewed by Tony Chang.
+
+        To fix bug 51450 - Glyphs in vertical text tests are rotated 90 degrees clockwise on Chromium Windows,
+        this patch adds support of OPENTYPE_VERTICAL feature for Chromium Windows.
+        Since enabling OPENTYPE_VERTICAL feature would require rather a big number of tests to rebaseline,
+        the actual fix is separated into this patch, and the feature will be enabled in bug 51450,
+        so that it is easier to revert on any perf regressions, as suggested by Tony in comment #50 of bug 51450.
+
+        All changes in this patch are behind #if ENABLE(OPENTYPE_VERTICAL) and therefore no tests are included in this patch.
+        All tests in fast/writing-modes currently skipped will be enabled in bug 51450.
+
+        * WebCore.gyp/WebCore.gyp: Added platform/graphics/opentype/OpenType*.
+        * WebCore.gypi: Ditto.
+        * platform/graphics/FontCache.h: SKia uses uint32_t as FontFileKey.
+        * platform/graphics/GlyphPageTreeNode.cpp:
+        (WebCore::fill): Replace vertical alternate glyphs if vertical flow.
+        * platform/graphics/SimpleFontData.cpp: Added m_verticalData.
+        (WebCore::SimpleFontData::SimpleFontData):
+        * platform/graphics/SimpleFontData.h:
+        (WebCore::SimpleFontData::verticalData):
+        (SimpleFontData):
+        (WebCore::SimpleFontData::widthForGlyph):
+        * platform/graphics/chromium/FontChromiumWin.cpp:
+        (WebCore::Font::drawGlyphs): Draw glyphs verticaly if font->verticalData().
+        * platform/graphics/chromium/FontPlatformDataChromiumWin.cpp:
+        (WebCore::FontPlatformData::verticalData): Added.
+        (WebCore):
+        (WebCore::FontPlatformData::openTypeTable): Added.
+        * platform/graphics/chromium/FontPlatformDataChromiumWin.h:
+        (WebCore):
+        (FontPlatformData): Added verticalData() and openTypeTable().
+
 2012-08-28  Andy Estes  <[email protected]>
 
         Add header guards to WebTileCacheLayer.h.

Modified: trunk/Source/WebCore/WebCore.gyp/WebCore.gyp (126906 => 126907)


--- trunk/Source/WebCore/WebCore.gyp/WebCore.gyp	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/WebCore.gyp/WebCore.gyp	2012-08-28 18:52:17 UTC (rev 126907)
@@ -1844,6 +1844,10 @@
           'sources/': [
             ['exclude', 'Posix\\.cpp$'],
 
+            ['include', 'platform/graphics/opentype/OpenTypeTypes\\.h$'],
+            ['include', 'platform/graphics/opentype/OpenTypeVerticalData\\.cpp$'],
+            ['include', 'platform/graphics/opentype/OpenTypeVerticalData\\.h$'],
+
             # The Chromium Win currently uses GlyphPageTreeNodeChromiumWin.cpp from
             # platform/graphics/chromium, included by regex above, instead.
             ['exclude', 'platform/graphics/skia/FontCacheSkia\\.cpp$'],

Modified: trunk/Source/WebCore/WebCore.gypi (126906 => 126907)


--- trunk/Source/WebCore/WebCore.gypi	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/WebCore.gypi	2012-08-28 18:52:17 UTC (rev 126907)
@@ -3873,8 +3873,11 @@
             'platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp',
             'platform/graphics/opentype/OpenTypeSanitizer.cpp',
             'platform/graphics/opentype/OpenTypeSanitizer.h',
+            'platform/graphics/opentype/OpenTypeTypes.h',
             'platform/graphics/opentype/OpenTypeUtilities.cpp',
             'platform/graphics/opentype/OpenTypeUtilities.h',
+            'platform/graphics/opentype/OpenTypeVerticalData.cpp',
+            'platform/graphics/opentype/OpenTypeVerticalData.h',
             'platform/graphics/openvg/EGLDisplayOpenVG.cpp',
             'platform/graphics/openvg/EGLDisplayOpenVG.h',
             'platform/graphics/openvg/EGLUtils.h',

Modified: trunk/Source/WebCore/platform/graphics/FontCache.h (126906 => 126907)


--- trunk/Source/WebCore/platform/graphics/FontCache.h	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/platform/graphics/FontCache.h	2012-08-28 18:52:17 UTC (rev 126907)
@@ -106,7 +106,11 @@
 #endif
 
 #if ENABLE(OPENTYPE_VERTICAL)
+#if USE(SKIA)
+    typedef uint32_t FontFileKey;
+#else
     typedef AtomicString FontFileKey;
+#endif
     OpenTypeVerticalData* getVerticalData(const FontFileKey&, const FontPlatformData&);
 #endif
 

Modified: trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp (126906 => 126907)


--- trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp	2012-08-28 18:52:17 UTC (rev 126907)
@@ -29,6 +29,7 @@
 #include "config.h"
 #include "GlyphPageTreeNode.h"
 
+#include "OpenTypeVerticalData.h"
 #include "PlatformString.h"
 #include "SegmentedFontData.h"
 #include "SimpleFontData.h"
@@ -130,7 +131,12 @@
     if (SimpleFontData::AdditionalFontData* additionalFontData = fontData->fontData())
         return additionalFontData->fillSVGGlyphPage(pageToFill, offset, length, buffer, bufferLength, fontData);
 #endif
-    return pageToFill->fill(offset, length, buffer, bufferLength, fontData);
+    bool hasGlyphs = pageToFill->fill(offset, length, buffer, bufferLength, fontData);
+#if ENABLE(OPENTYPE_VERTICAL)
+    if (hasGlyphs && fontData->verticalData())
+        fontData->verticalData()->substituteWithVerticalGlyphs(fontData, pageToFill, offset, length);
+#endif
+    return hasGlyphs;
 }
 
 void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNumber)

Modified: trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp (126906 => 126907)


--- trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp	2012-08-28 18:52:17 UTC (rev 126907)
@@ -32,6 +32,7 @@
 
 #include "Font.h"
 #include "FontCache.h"
+#include "OpenTypeVerticalData.h"
 
 #include <wtf/MathExtras.h>
 #include <wtf/UnusedParam.h>
@@ -49,11 +50,20 @@
     , m_isLoading(isLoading)
     , m_isTextOrientationFallback(isTextOrientationFallback)
     , m_isBrokenIdeographFallback(false)
+#if ENABLE(OPENTYPE_VERTICAL)
+    , m_verticalData(0)
+#endif
     , m_hasVerticalGlyphs(false)
 {
     platformInit();
     platformGlyphInit();
     platformCharWidthInit();
+#if ENABLE(OPENTYPE_VERTICAL)
+    if (platformData.orientation() == Vertical && !isTextOrientationFallback) {
+        m_verticalData = platformData.verticalData();
+        m_hasVerticalGlyphs = m_verticalData && m_verticalData->hasVerticalMetrics();
+    }
+#endif
 }
 
 SimpleFontData::SimpleFontData(PassOwnPtr<AdditionalFontData> fontData, float fontSize, bool syntheticBold, bool syntheticItalic)
@@ -64,6 +74,9 @@
     , m_isLoading(false)
     , m_isTextOrientationFallback(false)
     , m_isBrokenIdeographFallback(false)
+#if ENABLE(OPENTYPE_VERTICAL)
+    , m_verticalData(0)
+#endif
     , m_hasVerticalGlyphs(false)
 {
     m_fontData->initializeFontData(this, fontSize);

Modified: trunk/Source/WebCore/platform/graphics/SimpleFontData.h (126906 => 126907)


--- trunk/Source/WebCore/platform/graphics/SimpleFontData.h	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/platform/graphics/SimpleFontData.h	2012-08-28 18:52:17 UTC (rev 126907)
@@ -88,7 +88,7 @@
 
     const FontPlatformData& platformData() const { return m_platformData; }
 #if ENABLE(OPENTYPE_VERTICAL)
-    const OpenTypeVerticalData* verticalData() const { return 0; } // FIXME: implement
+    const OpenTypeVerticalData* verticalData() const { return m_verticalData; }
 #endif
 
     SimpleFontData* smallCapsFontData(const FontDescription&) const;
@@ -229,6 +229,9 @@
 
     mutable OwnPtr<GlyphMetricsMap<FloatRect> > m_glyphToBoundsMap;
     mutable GlyphMetricsMap<float> m_glyphToWidthMap;
+#if ENABLE(OPENTYPE_VERTICAL)
+    const OpenTypeVerticalData* m_verticalData;
+#endif
 
     bool m_treatAsFixedPitch;
     bool m_isCustomFont;  // Whether or not we are custom font loaded via @font-face
@@ -317,6 +320,14 @@
 
     if (m_fontData)
         width = m_fontData->widthForSVGGlyph(glyph, m_platformData.size());
+#if ENABLE(OPENTYPE_VERTICAL)
+    else if (m_verticalData)
+#if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROMIUM)
+        width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset;
+#else
+        width = m_verticalData->advanceHeight(this, glyph);
+#endif
+#endif
     else
         width = platformWidthForGlyph(glyph);
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp (126906 => 126907)


--- trunk/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp	2012-08-28 18:52:17 UTC (rev 126907)
@@ -390,15 +390,56 @@
     // We draw the glyphs in chunks to avoid having to do a heap allocation for
     // the arrays of characters and advances.
     const int kMaxBufferLength = 256;
-    Vector<WORD, kMaxBufferLength> glyphs;
     Vector<int, kMaxBufferLength> advances;
     int glyphIndex = 0;  // The starting glyph of the current chunk.
 
+    float horizontalOffset = point.x(); // The floating point offset of the left side of the current glyph.
+#if ENABLE(OPENTYPE_VERTICAL)
+    const OpenTypeVerticalData* verticalData = font->verticalData();
+    if (verticalData) {
+        Vector<FloatPoint, kMaxBufferLength> translations;
+        Vector<GOFFSET, kMaxBufferLength> offsets;
+
+        // Skia doesn't have matrix for glyph coordinate space, so we rotate back the CTM.
+        AffineTransform savedMatrix = graphicsContext->getCTM();
+        graphicsContext->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y()));
+        graphicsContext->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y()));
+
+        const FontMetrics& metrics = font->fontMetrics();
+        SkScalar verticalOriginX = SkFloatToScalar(point.x() + metrics.floatAscent() - metrics.floatAscent(IdeographicBaseline));
+        while (glyphIndex < numGlyphs) {
+            // How many chars will be in this chunk?
+            int curLen = std::min(kMaxBufferLength, numGlyphs - glyphIndex);
+
+            const Glyph* glyphs = glyphBuffer.glyphs(from + glyphIndex);
+            translations.resize(curLen);
+            verticalData->getVerticalTranslationsForGlyphs(font, &glyphs[0], curLen, reinterpret_cast<float*>(&translations[0]));
+            // To position glyphs vertically, we use offsets instead of advances.
+            advances.resize(curLen);
+            advances.fill(0);
+            offsets.resize(curLen);
+            float currentWidth = 0;
+            for (int i = 0; i < curLen; ++i, ++glyphIndex) {
+                offsets[i].du = lroundf(translations[i].x());
+                offsets[i].dv = -lroundf(currentWidth - translations[i].y());
+                currentWidth += glyphBuffer.advanceAt(from + glyphIndex);
+            }
+            SkPoint origin;
+            origin.set(verticalOriginX, SkFloatToScalar(point.y() + horizontalOffset - point.x()));
+            horizontalOffset += currentWidth;
+            paintSkiaText(graphicsContext, font->platformData(), curLen, &glyphs[0], &advances[0], &offsets[0], &origin);
+        }
+
+        graphicsContext->setCTM(savedMatrix);
+        return;
+    }
+#endif
+
     // In order to round all offsets to the correct pixel boundary, this code keeps track of the absolute position
     // of each glyph in floating point units and rounds to integer advances at the last possible moment.
 
-    float horizontalOffset = point.x(); // The floating point offset of the left side of the current glyph.
     int lastHorizontalOffsetRounded = lroundf(horizontalOffset); // The rounded offset of the left side of the last glyph rendered.
+    Vector<WORD, kMaxBufferLength> glyphs;
     while (glyphIndex < numGlyphs) {
         // How many chars will be in this chunk?
         int curLen = std::min(kMaxBufferLength, numGlyphs - glyphIndex);

Modified: trunk/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.cpp (126906 => 126907)


--- trunk/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.cpp	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.cpp	2012-08-28 18:52:17 UTC (rev 126907)
@@ -191,6 +191,31 @@
     return m_scriptFontProperties;
 }
 
+#if ENABLE(OPENTYPE_VERTICAL)
+const OpenTypeVerticalData* FontPlatformData::verticalData() const
+{
+    SkFontID id = typeface()->uniqueID();
+    return fontCache()->getVerticalData(id, *this);
+}
+
+PassRefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const
+{
+    HWndDC hdc(0);
+    HGDIOBJ oldFont = SelectObject(hdc, hfont());
+
+    DWORD size = GetFontData(hdc, table, 0, 0, 0);
+    RefPtr<SharedBuffer> buffer;
+    if (size != GDI_ERROR) {
+        buffer = SharedBuffer::create(size);
+        DWORD result = GetFontData(hdc, table, 0, (PVOID)buffer->data(), size);
+        ASSERT(result == size);
+    }
+
+    SelectObject(hdc, oldFont);
+    return buffer.release();
+}
+#endif
+
 #ifndef NDEBUG
 String FontPlatformData::description() const
 {

Modified: trunk/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h (126906 => 126907)


--- trunk/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h	2012-08-28 18:42:07 UTC (rev 126906)
+++ trunk/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h	2012-08-28 18:52:17 UTC (rev 126907)
@@ -35,6 +35,7 @@
 #include "config.h"
 
 #include "FontOrientation.h"
+#include "SharedBuffer.h"
 #include "SkTypeface.h"
 #include <wtf/Forward.h>
 #include <wtf/PassRefPtr.h>
@@ -53,6 +54,9 @@
 SkTypeface* CreateTypefaceFromHFont(HFONT, int* size, int* lfQuality);
 
 class FontDescription;
+#if ENABLE(OPENTYPE_VERTICAL)
+class OpenTypeVerticalData;
+#endif
 
 class FontPlatformData {
 public:
@@ -92,6 +96,11 @@
         return m_font == other.m_font && m_size == other.m_size && m_orientation == other.m_orientation;
     }
 
+#if ENABLE(OPENTYPE_VERTICAL)
+    const OpenTypeVerticalData* verticalData() const;
+    PassRefPtr<SharedBuffer> openTypeTable(uint32_t table) const;
+#endif
+
 #ifndef NDEBUG
     String description() const;
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to