Supports Unicode variation selector
authorbashi@chromium.org <bashi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Dec 2011 11:57:05 +0000 (11:57 +0000)
committerbashi@chromium.org <bashi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Dec 2011 11:57:05 +0000 (11:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=50999

Reviewed by Nikolas Zimmermann.

Source/WebCore:

Adds SimpleFontData::updateGlyphWithVariationSelector() which substitutes the
glyph in question based on the selector. WidthIterator::advance() calls it
when an unicode variation selector follows the character.

Test: fast/text/unicode-variation-selector.html

* platform/graphics/SimpleFontData.h: Added updateGlyphWithVariationSelector().
* platform/graphics/SurrogatePairAwareTextIterator.cpp:
(WebCore::isUnicodeBMPVariationSelector): Added.
(WebCore::isUnicodeSupplementaryVariationSelector): Added.
(WebCore::SurrogatePairAwareTextIterator::hasTrailingVariationSelector): Added.
* platform/graphics/SurrogatePairAwareTextIterator.h:
* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::advance): Changed to detect variation selectors.
* platform/graphics/chromium/SimpleFontDataChromiumWin.cpp:
(WebCore::SimpleFontData::updateGlyphWithVariationSelector): Added.
* platform/graphics/chromium/SimpleFontDataLinux.cpp:
(WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
* platform/graphics/freetype/SimpleFontDataFreeType.cpp:
(WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
* platform/graphics/mac/SimpleFontDataMac.mm:
(WebCore::decomposeToUTF16): Ditto.
(WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
* platform/graphics/pango/SimpleFontDataPango.cpp:
(WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
* platform/graphics/qt/SimpleFontDataQt.cpp:
(WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
* platform/graphics/win/SimpleFontDataWin.cpp:
(WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
* platform/graphics/wince/SimpleFontDataWinCE.cpp:
(WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
* platform/graphics/wx/SimpleFontDataWx.cpp:
(WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.

LayoutTests:

Add test for unicode variation selector support.
A tiny font (gw432047.ttf), which comes from glyphwiki.org and is used by Mozilla, is added for the test.

* fast/text/resources/gw432047-license.txt: Added.
* fast/text/resources/gw432047.ttf: Added.
* fast/text/unicode-variation-selector.html: Added.
* platform/chromium/test_expectations.txt: Added fast/text/unicode-variation-selector.html. This test need rebaseline.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@102915 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
LayoutTests/ChangeLog [changed mode: 0755->0644]
LayoutTests/fast/text/resources/gw432047-license.txt [new file with mode: 0644]
LayoutTests/fast/text/resources/gw432047.ttf [new file with mode: 0644]
LayoutTests/fast/text/unicode-variation-selector.html [new file with mode: 0644]
LayoutTests/platform/chromium/test_expectations.txt
Source/WebCore/ChangeLog [changed mode: 0755->0644]
Source/WebCore/platform/graphics/SimpleFontData.h
Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp
Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h
Source/WebCore/platform/graphics/WidthIterator.cpp
Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp

old mode 100755 (executable)
new mode 100644 (file)
index c22c85d..07ac898
@@ -1,3 +1,18 @@
+2011-12-15  Kenichi Ishibashi  <bashi@chromium.org>
+
+        Supports Unicode variation selector
+        https://bugs.webkit.org/show_bug.cgi?id=50999
+
+        Reviewed by Nikolas Zimmermann.
+
+        Add test for unicode variation selector support.
+        A tiny font (gw432047.ttf), which comes from glyphwiki.org and is used by Mozilla, is added for the test.
+
+        * fast/text/resources/gw432047-license.txt: Added.
+        * fast/text/resources/gw432047.ttf: Added.
+        * fast/text/unicode-variation-selector.html: Added.
+        * platform/chromium/test_expectations.txt: Added fast/text/unicode-variation-selector.html. This test need rebaseline.
+
 2011-12-15  Alexander Pavlov  <apavlov@chromium.org>
 
         [v8] Expose the "filter" property in V8CSSStyleDeclaration
diff --git a/LayoutTests/fast/text/resources/gw432047-license.txt b/LayoutTests/fast/text/resources/gw432047-license.txt
new file mode 100644 (file)
index 0000000..b47419f
--- /dev/null
@@ -0,0 +1,11 @@
+<http://en.glyphwiki.org/wiki/GlyphWiki:License>\r
+'''This document is a direct translation of the October 8th, 2008 revision of the Japanese original at ([[GlyphWiki:データ・記事のライセンス]]). This translation is provided as a service, and should not be taken to be a definitive statement. Please be aware that in case the Japanese original and the English version differ, the Japanese original takes precedence.'''\r
+\r
+*Data and article usage licence\r
+\r
+The glyphs registered at the GlyphWiki, as well as the articles, can be freely used by anyone. Reuse of this data, such as reproduction or modification of the glyps, is permitted. The are no specific restrictions with regards to displaying the author's name. Reuse of GlyphWiki data as the basis for a new font, or direct usage of fonts and glyphs copied from GlyphWiki in published work is allowed. GlyphWiki does not hold copyright on any citations used throughout GlyphWiki articles. Please consult their respective licences when reusing such content.\r
+\r
+<http://glyphwiki.org/wiki/GlyphWiki:%E3%83%87%E3%83%BC%E3%82%BF%E3%83%BB%E8%A8%98%E4%BA%8B%E3%81%AE%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9>\r
+*データ及び記事のライセンス\r
+\r
+グリフウィキに登録されているグリフデータおよび記事は、誰もが自由に利用できることとします。複製、改変などの二次利用を認めるものとします。著作者表示も特に制限を設けません。新しいフォントのベースデータとして用いることや、そのままコピーしたものをフォントとして著作物とすることを妨げません。記事中に引用されている部分については、グリフウィキには著作権はありませんので引用元のライセンスを確認してください。\r
diff --git a/LayoutTests/fast/text/resources/gw432047.ttf b/LayoutTests/fast/text/resources/gw432047.ttf
new file mode 100644 (file)
index 0000000..b33d9ef
Binary files /dev/null and b/LayoutTests/fast/text/resources/gw432047.ttf differ
diff --git a/LayoutTests/fast/text/unicode-variation-selector.html b/LayoutTests/fast/text/unicode-variation-selector.html
new file mode 100644 (file)
index 0000000..674f88d
--- /dev/null
@@ -0,0 +1,20 @@
+<style>
+@font-face {
+    font-family: ivsfont;
+    src: url(resources/gw432047.ttf);
+}
+.ivs {
+    font-family: ivsfont;
+}
+</style>
+<p>
+This page ensures that WebKit can render unicode variation selector correctly.  On platforms which support UVSes, the glyphs of U+845B should be different. On platforms which don't support UVSes, they should be identical.  In addition, any glyphs (including the last resort glyph) should not appear after the U+845B on all platforms.
+</p>
+<div>
+Glyph for code point U+845B without UVS:
+<span style="font-family: ivsfont;">&#x845b;</span>
+</div>
+<div>
+Glyph for code point U+845B with UVS:
+<span style="font-family: ivsfont;" id='ivs-holder'>&#x845b;&#xE0100;</span>
+</div>
index bad94f9..84c1c62 100644 (file)
@@ -4007,3 +4007,6 @@ BUGWK74374 WIN : fast/forms/select-listbox-multiple-no-focusring.html = PASS IMA
 BUGWK68859 DEBUG : fast/dynamic/crash-paint-no-documentElement-renderer.html = CRASH
 
 BUGWK74555 : fast/images/move-image-to-new-document.html = TEXT TIMEOUT
+
+// Need rebaseline on Mac.
+BUGWK50999 : fast/text/unicode-variation-selector.html = MISSING FAIL
old mode 100755 (executable)
new mode 100644 (file)
index 8a3d7b3..9b7104d
@@ -1,3 +1,44 @@
+2011-12-15  Kenichi Ishibashi  <bashi@chromium.org>
+
+        Supports Unicode variation selector
+        https://bugs.webkit.org/show_bug.cgi?id=50999
+
+        Reviewed by Nikolas Zimmermann.
+
+        Adds SimpleFontData::updateGlyphWithVariationSelector() which substitutes the
+        glyph in question based on the selector. WidthIterator::advance() calls it
+        when an unicode variation selector follows the character.
+
+        Test: fast/text/unicode-variation-selector.html
+
+        * platform/graphics/SimpleFontData.h: Added updateGlyphWithVariationSelector().
+        * platform/graphics/SurrogatePairAwareTextIterator.cpp:
+        (WebCore::isUnicodeBMPVariationSelector): Added.
+        (WebCore::isUnicodeSupplementaryVariationSelector): Added.
+        (WebCore::SurrogatePairAwareTextIterator::hasTrailingVariationSelector): Added.
+        * platform/graphics/SurrogatePairAwareTextIterator.h:
+        * platform/graphics/WidthIterator.cpp:
+        (WebCore::WidthIterator::advance): Changed to detect variation selectors.
+        * platform/graphics/chromium/SimpleFontDataChromiumWin.cpp:
+        (WebCore::SimpleFontData::updateGlyphWithVariationSelector): Added.
+        * platform/graphics/chromium/SimpleFontDataLinux.cpp:
+        (WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
+        * platform/graphics/freetype/SimpleFontDataFreeType.cpp:
+        (WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
+        * platform/graphics/mac/SimpleFontDataMac.mm:
+        (WebCore::decomposeToUTF16): Ditto.
+        (WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
+        * platform/graphics/pango/SimpleFontDataPango.cpp:
+        (WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
+        * platform/graphics/qt/SimpleFontDataQt.cpp:
+        (WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
+        * platform/graphics/win/SimpleFontDataWin.cpp:
+        (WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
+        * platform/graphics/wince/SimpleFontDataWinCE.cpp:
+        (WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
+        * platform/graphics/wx/SimpleFontDataWx.cpp:
+        (WebCore::SimpleFontData::updateGlyphWithVariationSelector): Ditto.
+
 2011-12-15  Alexander Pavlov  <apavlov@chromium.org>
 
         [v8] Expose the "filter" property in V8CSSStyleDeclaration
index dd86f00..de4a56b 100644 (file)
@@ -158,6 +158,7 @@ public:
 
     const GlyphData& missingGlyphData() const { return m_missingGlyphData; }
     void setMissingGlyphData(const GlyphData& glyphData) { m_missingGlyphData = glyphData; }
+    void updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph&) const;
 
 #ifndef NDEBUG
     virtual String description() const;
index ac0bae3..119b3a4 100644 (file)
@@ -32,6 +32,21 @@ using namespace Unicode;
 
 namespace WebCore {
 
+inline static bool isUnicodeBMPVariationSelector(UChar character)
+{
+    return (0x180B <= character && character <= 0x180D) || (0xFE00 <= character && character <= 0xFE0F);
+}
+
+inline static bool isUnicodeSupplementaryVariationSelector(UChar lead, UChar trail)
+{
+    // A non-BMP variation selector character is in the range of U+E0100 to U+E01EF.
+    // It can be a surrogate pair in which the high surrogate is 0xDB40 and
+    // the low surrogate is in the range of U16_TRAIL(0xE0100 - 0x10000) to U16_TRAIL(0xE01EF - 0x10000).
+    static const UChar trailStart = U16_TRAIL(0xE0100 - 0x10000);
+    static const UChar trailEnd = U16_TRAIL(0xE01EF - 0x10000);
+    return lead == 0xDB40 && trailStart <= trail && trail <= trailEnd;
+}
+
 SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator(const UChar* characters, int currentCharacter, int lastCharacter, int endCharacter)
     : m_characters(characters)
     , m_currentCharacter(currentCharacter)
@@ -83,6 +98,21 @@ bool SurrogatePairAwareTextIterator::consume(UChar32& character, unsigned& clust
     return true;
 }
 
+bool SurrogatePairAwareTextIterator::hasTrailingVariationSelector(UChar32& selector, unsigned& clusterLength)
+{
+    if (static_cast<int>(m_currentCharacter + clusterLength) < m_endCharacter && isUnicodeBMPVariationSelector(m_characters[clusterLength])) {
+        selector = m_characters[clusterLength];
+        clusterLength += 1;
+        return true;
+    }
+    if (static_cast<int>(m_currentCharacter + clusterLength + 1) < m_endCharacter && isUnicodeSupplementaryVariationSelector(m_characters[clusterLength], m_characters[clusterLength + 1])) {
+        selector = U16_GET_SUPPLEMENTARY(m_characters[clusterLength], m_characters[clusterLength + 1]);
+        clusterLength += 2;
+        return true;
+    }
+    return false;
+}
+
 void SurrogatePairAwareTextIterator::advance(unsigned advanceLength)
 {
     m_characters += advanceLength;
index 1d56eb8..8dcea8d 100644 (file)
@@ -32,6 +32,7 @@ public:
     SurrogatePairAwareTextIterator(const UChar*, int currentCharacter, int lastCharacter, int endCharacter);
 
     bool consume(UChar32& character, unsigned& clusterLength);
+    bool hasTrailingVariationSelector(UChar32& selector, unsigned& clusterLength);
     void advance(unsigned advanceLength);
 
     int currentCharacter() const { return m_currentCharacter; }
index d749a4f..06826be 100644 (file)
@@ -115,6 +115,13 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
 
         ASSERT(fontData);
 
+        // If a variation selector follows, update glyph with the selector if possible.
+        UChar32 selector = 0;
+        if (textIterator.hasTrailingVariationSelector(selector, clusterLength)) {
+            fontData->updateGlyphWithVariationSelector(character, selector, glyph);
+            advanceLength = clusterLength;
+        }
+
         // Now that we have a glyph and font data, get its width.
         float width;
         if (character == '\t' && m_run.allowTabs()) {
index 78ad56a..9681746 100644 (file)
@@ -199,4 +199,9 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
     return static_cast<float>(width);
 }
 
+void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const
+{
+    // FIXME: Implement.
+}
+
 }  // namespace WebCore
index 002988d..0345cb6 100644 (file)
@@ -237,4 +237,9 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
     return round(SkScalarToFloat(width));
 }
 
+void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const
+{
+    // FIXME: Implement.
+}
+
 }  // namespace WebCore
index 5d6e7fb..3cc6be7 100644 (file)
@@ -162,4 +162,9 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
     return w;    
 }
 
+void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const
+{
+    // FIXME: Implement.
+}
+
 }
index 54c03f8..17f2264 100644 (file)
@@ -467,4 +467,32 @@ bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters
     return true;
 }
 
+static inline void decomposeToUTF16(UChar* buffer, unsigned& length, const UChar32 character)
+{
+    if (U_IS_BMP(character)) {
+        buffer[length] = character;
+        ++length;
+        return;
+    }
+
+    buffer[length] = U16_LEAD(character);
+    buffer[length + 1] = U16_TRAIL(character);
+    length += 2;
+}
+
+void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const
+{
+    unsigned length = 0;
+    UChar buffer[4];
+
+    decomposeToUTF16(buffer, length, character);
+    decomposeToUTF16(buffer, length, selector);
+    ASSERT(length <= 4);
+
+    CGGlyph glyphs[4];
+    wkGetGlyphsForCharacters(platformData().cgFont(), buffer, glyphs, length);
+    if (glyphs[0])
+        glyph = glyphs[0];
+}
+
 } // namespace WebCore
index ee8ee0f..d6428d9 100644 (file)
@@ -160,4 +160,9 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
     return width;    
 }
 
+void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const
+{
+    // FIXME: Implement.
+}
+
 }
index e95b8c5..4ff23be 100644 (file)
@@ -189,4 +189,9 @@ void SimpleFontData::platformDestroy()
 {
 }
 
+void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const
+{
+    // FIXME: Implement.
+}
+
 }
index de6687f..a49abe2 100644 (file)
@@ -282,4 +282,9 @@ SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
     return m_scriptFontProperties;
 }
 
+void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const
+{
+    // FIXME: Implement.
+}
+
 }
index e3b8424..1ba6690 100644 (file)
@@ -180,4 +180,9 @@ void SimpleFontData::platformCharWidthInit()
     m_maxCharWidth = (tm.tmMaxCharWidth * m_platformData.size() + 36) / 72;
 }
 
+void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const
+{
+    // FIXME: Implement.
+}
+
 } // namespace WebCore
index cb7fb3d..d98ecbd 100644 (file)
@@ -194,4 +194,9 @@ float SimpleFontData::widthForGDIGlyph(Glyph glyph) const
 }
 #endif
 
+void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const
+{
+    // FIXME: Implement.
+}
+
 }