2009-07-02 Adam Langley <agl@google.com>
authoragl@chromium.org <agl@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Jul 2009 22:40:31 +0000 (22:40 +0000)
committeragl@chromium.org <agl@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Jul 2009 22:40:31 +0000 (22:40 +0000)
        Reviewed by Eric Seidel.

        Chromium Linux: fix complex text rendering with line break characters.

        https://bugs.webkit.org/show_bug.cgi?id=26935

        If the CSS white-space property is inhibiting line breaking, we might
        find end-of-line characters rendered via the complex text path. Fonts
        don't provide glyphs for these code points so, if we find one, we
        simulate the space glyph being interposed in this case.  Because the
        input is variable-length per code point, we walk the input in step
        with the output.

        Covered by:
            LayoutTests/fast/text/international/bidi-linebreak-002.html
            LayoutTests/fast/text/international/bidi-linebreak-003.html
            LayoutTests/fast/text/international/hindi-whitespace.html

        * platform/graphics/chromium/HarfbuzzSkia.cpp:
        (WebCore::stringToGlyphs):

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

WebCore/ChangeLog
WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp

index 24b16d4b839469e0d9a85e1f4312340ad39fa9ca..fb9a5416ff590a17625afd8f18e22982e0c30b00 100644 (file)
@@ -1,3 +1,26 @@
+2009-07-02  Adam Langley  <agl@google.com>
+
+        Reviewed by Eric Seidel.
+
+        Chromium Linux: fix complex text rendering with line break characters.
+
+        https://bugs.webkit.org/show_bug.cgi?id=26935
+
+        If the CSS white-space property is inhibiting line breaking, we might
+        find end-of-line characters rendered via the complex text path. Fonts
+        don't provide glyphs for these code points so, if we find one, we
+        simulate the space glyph being interposed in this case.  Because the
+        input is variable-length per code point, we walk the input in step
+        with the output.
+
+        Covered by:
+            LayoutTests/fast/text/international/bidi-linebreak-002.html
+            LayoutTests/fast/text/international/bidi-linebreak-003.html
+            LayoutTests/fast/text/international/hindi-whitespace.html
+
+        * platform/graphics/chromium/HarfbuzzSkia.cpp:
+        (WebCore::stringToGlyphs):
+
 2009-07-02  Victor Wang  <victorw@chromium.org>
 
         Reviewed by Darin Fisher.
index 9fd09e1a7401876433579b8e938cc8845e521d56..621d674c33fdb1e823626ef00fa69ff068f1db05 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "config.h"
 
+#include "Font.h"
 #include "FontPlatformData.h"
 #include "wtf/OwnArrayPtr.h"
 
@@ -41,6 +42,7 @@
 
 extern "C" {
 #include "harfbuzz-shaper.h"
+#include "harfbuzz-unicode.h"
 }
 
 // This file implements the callbacks which Harfbuzz requires by using Skia
@@ -65,10 +67,29 @@ static HB_Bool stringToGlyphs(HB_Font hbFont, const HB_UChar16* characters, hb_u
 
     // HB_Glyph is 32-bit, but Skia outputs only 16-bit numbers. So our
     // |glyphs| array needs to be converted.
+    // Additionally, if the CSS white-space property is inhibiting line
+    // breaking, we might find end-of-line charactors rendered via the complex
+    // text path. Fonts don't provide glyphs for these code points so, if we
+    // find one, we simulate the space glyph being interposed in this case.
+    // Because the input is variable-length per code point, we walk the input
+    // in step with the output.
+    // FIXME: it seems that this logic is duplicated in CoreTextController and UniscribeController
+    ssize_t indexOfNextCodePoint = 0;
+    uint16_t spaceGlyphNumber = 0;
     for (int i = numGlyphs - 1; i >= 0; --i) {
+        const uint32_t currentCodePoint = utf16_to_code_point(characters, length, &indexOfNextCodePoint);
+
         uint16_t value;
         // We use a memcpy to avoid breaking strict aliasing rules.
         memcpy(&value, reinterpret_cast<char*>(glyphs) + sizeof(uint16_t) * i, sizeof(uint16_t));
+
+        if (!value && Font::treatAsSpace(currentCodePoint)) {
+            static const uint16_t spaceUTF16 = ' ';
+            if (!spaceGlyphNumber)
+                paint.textToGlyphs(&spaceUTF16, sizeof(spaceUTF16), &spaceGlyphNumber);
+            value = spaceGlyphNumber;
+        }
+
         glyphs[i] = value;
     }