[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

xji at chromium.org xji at chromium.org
Wed Dec 22 14:50:31 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 283cc46bc5112016dd57e58a57dd030f967aa55e
Author: xji at chromium.org <xji at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 21 21:43:16 2010 +0000

    2010-10-21  Xiaomei Ji  <xji at chromium.org>
    
            Reviewed by David Levin.
    
            Performance improvement for FontLinux.
            https://bugs.webkit.org/show_bug.cgi?id=47019
    
            Reduce the number of calls for the normalization function because converting
            to NFC form is very expensive.
    
            Combine space normalization and character mirroring into one text scan.
    
            Test: platform/chromium/fast/text/font-linux-normalize.html
    
            * platform/graphics/chromium/FontLinux.cpp:
            (WebCore::TextRunWalker::TextRunWalker):
            (WebCore::TextRunWalker::~TextRunWalker):
            (WebCore::TextRunWalker::getNormalizedTextRun):
            (WebCore::TextRunWalker::normalizeSpacesAndMirrorChars):
    2010-10-21  Xiaomei Ji  <xji at chromium.org>
    
            Reviewed by David Levin.
    
            Performance improvement for FontLinux.
            https://bugs.webkit.org/show_bug.cgi?id=47019
    
            Reduce the number of calls for the normalization function because converting
            to NFC form is very expensive.
    
            Combine space normalization and character mirroring into one text scan.
    
            * platform/chromium/fast/text/font-linux-normalize-expected.txt: Added.
            * platform/chromium/fast/text/font-linux-normalize.html: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@70266 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index df12a03..d25a30c 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
+2010-10-21  Xiaomei Ji  <xji at chromium.org>
+
+        Reviewed by David Levin.
+
+        Performance improvement for FontLinux.
+        https://bugs.webkit.org/show_bug.cgi?id=47019
+        
+        Reduce the number of calls for the normalization function because converting
+        to NFC form is very expensive.
+    
+        Combine space normalization and character mirroring into one text scan.
+
+        * platform/chromium/fast/text/font-linux-normalize-expected.txt: Added.
+        * platform/chromium/fast/text/font-linux-normalize.html: Added.
+
 2010-10-21  Adam Roben  <aroben at apple.com>
 
         Test that the plugin's HWND is invalidated when NPN_InvalidateRect is
diff --git a/LayoutTests/platform/chromium/fast/text/font-linux-normalize-expected.txt b/LayoutTests/platform/chromium/fast/text/font-linux-normalize-expected.txt
new file mode 100644
index 0000000..7b825fd
--- /dev/null
+++ b/LayoutTests/platform/chromium/fast/text/font-linux-normalize-expected.txt
@@ -0,0 +1 @@
+क़उ	ä
diff --git a/LayoutTests/platform/chromium/fast/text/font-linux-normalize.html b/LayoutTests/platform/chromium/fast/text/font-linux-normalize.html
new file mode 100644
index 0000000..3e0b437
--- /dev/null
+++ b/LayoutTests/platform/chromium/fast/text/font-linux-normalize.html
@@ -0,0 +1,48 @@
+<html>
+<head>
+<script>
+function log(str) {
+    var li = document.createElement("li");
+    li.appendChild(document.createTextNode(str));
+    var console = document.getElementById("console");
+    console.appendChild(li);
+}
+
+function convertStringToUnicode(string)
+{
+    var returnValue = " (character in Unicode value): ";
+    for (var i = 0; i < string.length; ++i)
+    {
+        returnValue += " " + string.charCodeAt(i);
+    }
+    return returnValue;
+}
+
+function assertEqual(test_name, actual, expected)
+{
+    if (actual != expected) {
+        log("==================================");
+        log("FAILED: " + test_name);
+        var actual_string = "actual" + convertStringToUnicode(actual);
+        var expected_string = "expected" + convertStringToUnicode(expected);
+        log(actual_string);
+        log(expected_string);
+    }
+}
+
+onload = function()
+{
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+    var div = document.getElementById("div");
+    var string = div.innerHTML;
+    //should be rendered as "\u0958\u0909 \u00e4" in html.
+    assertEqual("devanagari + a with diaeresis", string, "\u0915\u093c\u0909\u0009a\u0308");
+}
+</script>
+</head>
+<body>
+<div id="div">&#x915;&#x093c;&#x0909;&#x9;a&#x308;</div>
+<ul id="console"></ul>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index a5ad514..edaf791 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,23 @@
+2010-10-21  Xiaomei Ji  <xji at chromium.org>
+
+        Reviewed by David Levin.
+
+        Performance improvement for FontLinux.
+        https://bugs.webkit.org/show_bug.cgi?id=47019
+        
+        Reduce the number of calls for the normalization function because converting
+        to NFC form is very expensive.
+    
+        Combine space normalization and character mirroring into one text scan.
+
+        Test: platform/chromium/fast/text/font-linux-normalize.html
+
+        * platform/graphics/chromium/FontLinux.cpp:
+        (WebCore::TextRunWalker::TextRunWalker):
+        (WebCore::TextRunWalker::~TextRunWalker):
+        (WebCore::TextRunWalker::getNormalizedTextRun):
+        (WebCore::TextRunWalker::normalizeSpacesAndMirrorChars):
+
 2010-10-21  David Hyatt  <hyatt at apple.com>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index f38273c..e73747f 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, Google Inc. All rights reserved.
+ * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -220,8 +220,6 @@ public:
     const FontPlatformData* fontPlatformDataForScriptRun() { return reinterpret_cast<FontPlatformData*>(m_item.font->userData); }
 
 private:
-    const TextRun& getTextRun(const TextRun&);
-    const TextRun& getNormalizedTextRun(const TextRun&);
     void setupFontForScriptRun();
     HB_FontRec* allocHarfbuzzFont();
     void deleteGlyphArrays();
@@ -229,7 +227,9 @@ private:
     void resetGlyphArrays();
     void shapeGlyphs();
     void setGlyphXPositions(bool);
-    void mirrorCharacters(UChar*, const UChar*, int) const;
+
+    static void normalizeSpacesAndMirrorChars(const UChar* source, bool rtl, UChar* destination, int length);
+    static const TextRun& getNormalizedTextRun(const TextRun& originalRun, OwnPtr<TextRun>& normalizedRun, OwnArrayPtr<UChar>& normalizedBuffer);
 
     // This matches the logic in RenderBlock::findNextLineBreak
     static bool isCodepointSpace(HB_UChar16 c) { return c == ' ' || c == '\t'; }
@@ -264,11 +264,13 @@ TextRunWalker::TextRunWalker(const TextRun& run, unsigned startingX, const Font*
     : m_font(font)
     , m_startingX(startingX)
     , m_offsetX(m_startingX)
-    , m_run(getTextRun(run))
+    , m_run(getNormalizedTextRun(run, m_normalizedRun, m_normalizedBuffer))
     , m_iterateBackwards(m_run.rtl())
     , m_wordSpacingAdjustment(0)
     , m_padding(0)
+    , m_padPerWordBreak(0)
     , m_padError(0)
+    , m_letterSpacing(0)
 {
     // Do not use |run| inside this constructor. Use |m_run| instead.
 
@@ -286,17 +288,8 @@ TextRunWalker::TextRunWalker(const TextRun& run, unsigned startingX, const Font*
 
     m_item.item.bidiLevel = m_run.rtl();
 
-    int length = m_run.length();
-    m_item.stringLength = length;
-
-    if (!m_item.item.bidiLevel)
-        m_item.string = m_run.characters();
-    else {
-        // Assume mirrored character is in the same Unicode multilingual plane as the original one.
-        UChar* string = new UChar[length];
-        mirrorCharacters(string, m_run.characters(), length);
-        m_item.string = string;
-    }
+    m_item.string = m_run.characters();
+    m_item.stringLength = m_run.length();
 
     reset();
 }
@@ -306,8 +299,6 @@ TextRunWalker::~TextRunWalker()
     fastFree(m_item.font);
     deleteGlyphArrays();
     delete[] m_item.log_clusters;
-    if (m_item.item.bidiLevel)
-        delete[] m_item.string;
 }
 
 bool TextRunWalker::isWordBreak(unsigned index, bool isRTL)
@@ -408,51 +399,6 @@ float TextRunWalker::widthOfFullRun()
     return widthSum;
 }
 
-const TextRun& TextRunWalker::getTextRun(const TextRun& originalRun)
-{
-    // Normalize the text run in two ways:
-    // 1) Convert the |originalRun| to NFC normalized form if combining diacritical marks
-    // (U+0300..) are used in the run. This conversion is necessary since most OpenType
-    // fonts (e.g., Arial) don't have substitution rules for the diacritical marks in
-    // their GSUB tables.
-    //
-    // Note that we don't use the icu::Normalizer::isNormalized(UNORM_NFC) API here since
-    // the API returns FALSE (= not normalized) for complex runs that don't require NFC
-    // normalization (e.g., Arabic text). Unless the run contains the diacritical marks,
-    // Harfbuzz will do the same thing for us using the GSUB table.
-    // 2) Convert spacing characters into plain spaces, as some fonts will provide glyphs
-    // for characters like '\n' otherwise.
-    for (int i = 0; i < originalRun.length(); ++i) {
-        UChar ch = originalRun[i];
-        UBlockCode block = ::ublock_getCode(ch);
-        if (block == UBLOCK_COMBINING_DIACRITICAL_MARKS || (Font::treatAsSpace(ch) && ch != ' '))
-            return getNormalizedTextRun(originalRun);
-    }
-    return originalRun;
-}
-
-const TextRun& TextRunWalker::getNormalizedTextRun(const TextRun& originalRun)
-{
-    icu::UnicodeString normalizedString;
-    UErrorCode error = U_ZERO_ERROR;
-    icu::Normalizer::normalize(icu::UnicodeString(originalRun.characters(), originalRun.length()), UNORM_NFC, 0 /* no options */, normalizedString, error);
-    if (U_FAILURE(error))
-        return originalRun;
-
-    m_normalizedBuffer.set(new UChar[normalizedString.length() + 1]);
-    normalizedString.extract(m_normalizedBuffer.get(), normalizedString.length() + 1, error);
-    ASSERT(U_SUCCESS(error));
-
-    for (int i = 0; i < normalizedString.length(); ++i) {
-        if (Font::treatAsSpace(m_normalizedBuffer[i]))
-            m_normalizedBuffer[i] = ' ';
-    }
-
-    m_normalizedRun.set(new TextRun(originalRun));
-    m_normalizedRun->setText(m_normalizedBuffer.get(), normalizedString.length());
-    return *m_normalizedRun;
-}
-
 void TextRunWalker::setupFontForScriptRun()
 {
     const FontData* fontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
@@ -595,7 +541,7 @@ void TextRunWalker::setGlyphXPositions(bool isRTL)
     m_offsetX += m_pixelWidth;
 }
 
-void TextRunWalker::mirrorCharacters(UChar* destination, const UChar* source, int length) const
+void TextRunWalker::normalizeSpacesAndMirrorChars(const UChar* source, bool rtl, UChar* destination, int length)
 {
     int position = 0;
     bool error = false;
@@ -604,13 +550,68 @@ void TextRunWalker::mirrorCharacters(UChar* destination, const UChar* source, in
         UChar32 character;
         int nextPosition = position;
         U16_NEXT(source, nextPosition, length, character);
-        character = u_charMirror(character);
+        if (Font::treatAsSpace(character))
+            character = ' ';
+        else if (rtl)
+            character = u_charMirror(character);
         U16_APPEND(destination, position, length, character, error);
         ASSERT(!error);
         position = nextPosition;
     }
 }
 
+const TextRun& TextRunWalker::getNormalizedTextRun(const TextRun& originalRun, OwnPtr<TextRun>& normalizedRun, OwnArrayPtr<UChar>& normalizedBuffer)
+{
+    // Normalize the text run in three ways:
+    // 1) Convert the |originalRun| to NFC normalized form if combining diacritical marks
+    // (U+0300..) are used in the run. This conversion is necessary since most OpenType
+    // fonts (e.g., Arial) don't have substitution rules for the diacritical marks in
+    // their GSUB tables.
+    //
+    // Note that we don't use the icu::Normalizer::isNormalized(UNORM_NFC) API here since
+    // the API returns FALSE (= not normalized) for complex runs that don't require NFC
+    // normalization (e.g., Arabic text). Unless the run contains the diacritical marks,
+    // Harfbuzz will do the same thing for us using the GSUB table.
+    // 2) Convert spacing characters into plain spaces, as some fonts will provide glyphs
+    // for characters like '\n' otherwise.
+    // 3) Convert mirrored characters such as parenthesis for rtl text.
+ 
+    // Convert to NFC form if the text has diacritical marks.
+    icu::UnicodeString normalizedString;
+    UErrorCode error = U_ZERO_ERROR;
+
+    for (int16_t i = 0; i < originalRun.length(); ++i) {
+        UChar ch = originalRun[i];
+        if (::ublock_getCode(ch) == UBLOCK_COMBINING_DIACRITICAL_MARKS) {
+            icu::Normalizer::normalize(icu::UnicodeString(originalRun.characters(),
+                                       originalRun.length()), UNORM_NFC, 0 /* no options */,
+                                       normalizedString, error);
+            if (U_FAILURE(error))
+                return originalRun;
+            break;
+        }
+    }
+
+    // Normalize space and mirror parenthesis for rtl text.
+    int normalizedBufferLength;
+    const UChar* sourceText;
+    if (normalizedString.isEmpty()) {
+        normalizedBufferLength = originalRun.length();
+        sourceText = originalRun.characters();
+    } else {
+        normalizedBufferLength = normalizedString.length();
+        sourceText = normalizedString.getBuffer();
+    }
+
+    normalizedBuffer.set(new UChar[normalizedBufferLength + 1]);
+
+    normalizeSpacesAndMirrorChars(sourceText, originalRun.rtl(), normalizedBuffer.get(), normalizedBufferLength);
+
+    normalizedRun.set(new TextRun(originalRun));
+    normalizedRun->setText(normalizedBuffer.get(), normalizedBufferLength);
+    return *normalizedRun;
+}
+
 static void setupForTextPainting(SkPaint* paint, SkColor color)
 {
     paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list