Title: [129050] trunk/Source/WebCore
Revision
129050
Author
[email protected]
Date
2012-09-19 15:29:05 -0700 (Wed, 19 Sep 2012)

Log Message

[Chromium] HarfBuzzShaper should take into account combining characters
https://bugs.webkit.org/show_bug.cgi?id=97069

Reviewed by Tony Chang.

When dividing a text run into HarfBuzzRuns, try to find suitable SimpleFontData for
combining character sequence if there are one or more mark characters are followed.
If there is no combined glyphs in the font, use fallback font for mark characters.

No new tests.
In platform/chromium-linux/fast/text/international/complex-joining-using-gpos.html,
U+0947 (devanagari vowel sign e) should be displayed.
In fast/text/wide-zero-width-space.html, é and eĭ should look identical.

* platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp:
(WebCore):
(WebCore::fontDataForCombiningCharacterSequence): Added.
(WebCore::HarfBuzzShaper::collectHarfBuzzRuns): See above description.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (129049 => 129050)


--- trunk/Source/WebCore/ChangeLog	2012-09-19 22:23:25 UTC (rev 129049)
+++ trunk/Source/WebCore/ChangeLog	2012-09-19 22:29:05 UTC (rev 129050)
@@ -1,3 +1,24 @@
+2012-09-19  Kenichi Ishibashi  <[email protected]>
+
+        [Chromium] HarfBuzzShaper should take into account combining characters
+        https://bugs.webkit.org/show_bug.cgi?id=97069
+
+        Reviewed by Tony Chang.
+
+        When dividing a text run into HarfBuzzRuns, try to find suitable SimpleFontData for
+        combining character sequence if there are one or more mark characters are followed.
+        If there is no combined glyphs in the font, use fallback font for mark characters.
+
+        No new tests.
+        In platform/chromium-linux/fast/text/international/complex-joining-using-gpos.html,
+        U+0947 (devanagari vowel sign e) should be displayed.
+        In fast/text/wide-zero-width-space.html, &eacute; and e&#0301; should look identical.
+
+        * platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp:
+        (WebCore):
+        (WebCore::fontDataForCombiningCharacterSequence): Added.
+        (WebCore::HarfBuzzShaper::collectHarfBuzzRuns): See above description.
+
 2012-09-19  Tony Chang  <[email protected]>
 
         Remove RenderIFrame::updateLogicalHeight and RenderIFrame::updateLogicalWidth

Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp (129049 => 129050)


--- trunk/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp	2012-09-19 22:23:25 UTC (rev 129049)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp	2012-09-19 22:29:05 UTC (rev 129050)
@@ -229,8 +229,23 @@
     return point + m_startOffset;
 }
 
+static const SimpleFontData* fontDataForCombiningCharacterSequence(const Font* font, const UChar* characters, size_t length)
+{
+    UErrorCode error = U_ZERO_ERROR;
+    Vector<UChar, 4> normalizedCharacters(length);
+    int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error);
+    // Should fallback if we have an error or no composition occurred.
+    if (U_FAILURE(error) || (static_cast<size_t>(normalizedLength) == length))
+        return 0;
+    UChar32 normalizedCharacter;
+    size_t index = 0;
+    U16_NEXT(&normalizedCharacters[0], index, static_cast<size_t>(normalizedLength), normalizedCharacter);
+    return font->glyphDataForCharacter(normalizedCharacter, false).fontData;
+}
+
 bool HarfBuzzShaper::collectHarfBuzzRuns()
 {
+    const UChar* normalizedBufferEnd = m_normalizedBuffer.get() + m_normalizedBufferLength;
     SurrogatePairAwareTextIterator iterator(m_normalizedBuffer.get(), 0, m_normalizedBufferLength, m_normalizedBufferLength);
     UChar32 character;
     unsigned clusterLength = 0;
@@ -245,18 +260,40 @@
         return false;
 
     do {
+        const UChar* currentCharacterPosition = iterator.characters();
         const SimpleFontData* currentFontData = nextFontData;
         UScriptCode currentScript = nextScript;
 
         for (iterator.advance(clusterLength); iterator.consume(character, clusterLength); iterator.advance(clusterLength)) {
-            nextFontData = m_font->glyphDataForCharacter(character, false).fontData;
-            if (nextFontData != currentFontData)
-                break;
+            if (Font::treatAsZeroWidthSpace(character))
+                continue;
+            if (U_GET_GC_MASK(character) & U_GC_M_MASK) {
+                int markLength = clusterLength;
+                const UChar* markCharactersEnd = iterator.characters() + clusterLength;
+                while (markCharactersEnd < normalizedBufferEnd) {
+                    UChar32 nextCharacter;
+                    int nextCharacterLength = 0;
+                    U16_NEXT(markCharactersEnd, nextCharacterLength, normalizedBufferEnd - markCharactersEnd, nextCharacter);
+                    if (!(U_GET_GC_MASK(nextCharacter) & U_GC_M_MASK))
+                        break;
+                    markLength += nextCharacterLength;
+                    markCharactersEnd += nextCharacterLength;
+                }
+                nextFontData = fontDataForCombiningCharacterSequence(m_font, currentCharacterPosition, markCharactersEnd - currentCharacterPosition);
+                if (nextFontData)
+                    clusterLength = markLength;
+                else
+                    nextFontData = m_font->glyphDataForCharacter(character, false).fontData;
+            } else
+                nextFontData = m_font->glyphDataForCharacter(character, false).fontData;
+
             nextScript = uscript_getScript(character, &errorCode);
             if (U_FAILURE(errorCode))
                 return false;
-            if ((currentScript != nextScript) && (currentScript != USCRIPT_INHERITED))
+            if ((nextFontData != currentFontData) || ((currentScript != nextScript) && (nextScript != USCRIPT_INHERITED)))
                 break;
+            if (nextScript == USCRIPT_INHERITED)
+                nextScript = currentScript;
         }
         unsigned numCharactersOfCurrentRun = iterator.currentCharacter() - startIndexOfCurrentRun;
         m_harfbuzzRuns.append(HarfBuzzRun::create(currentFontData, startIndexOfCurrentRun, numCharactersOfCurrentRun, m_run.direction()));
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to