Title: [114032] trunk/Source/WebCore
Revision
114032
Author
[email protected]
Date
2012-04-12 14:06:50 -0700 (Thu, 12 Apr 2012)

Log Message

https://bugs.webkit.org/show_bug.cgi?id=83817
        
This patch modifies RenderText so that it scans all of its characters up front to
determine whether or not the simple code path can be used for measurement/rendering
of the text for the whole run.
        
TextRun now has an additional field that indicates that the character scan is not
required, since the entire RenderText is known to be simple. This boolean is set
when constructing the TextRun from the places that make TextRuns from RenderTexts.
        
The character scan has been refactored into a static Font method so that it can be
called by RenderText. The scan of individual TextRuns is also done using the same method
so that the code is shared.

Reviewed by Dan Bernstein.

* platform/graphics/Font.cpp:
(WebCore::Font::codePath):
(WebCore::Font::characterRangeCodePath):
* platform/graphics/Font.h:
* platform/graphics/TextRun.h:
(WebCore::TextRun::TextRun):
(WebCore::TextRun::characterScanForCodePath):
(WebCore::TextRun::setCharacterScanForCodePath):
(TextRun):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::constructTextRun):
* rendering/RenderBlockLineLayout.cpp:
(WebCore::textWidth):
* rendering/RenderText.cpp:
(WebCore::RenderText::RenderText):
(WebCore::RenderText::widthFromCache):
(WebCore::RenderText::setTextInternal):
(WebCore::RenderText::width):
(WebCore::RenderText::computeCanUseSimpleFontCodePath):
(WebCore):
* rendering/RenderText.h:
(RenderText):
(WebCore::RenderText::canUseSimpleFontCodePath):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (114031 => 114032)


--- trunk/Source/WebCore/ChangeLog	2012-04-12 20:56:47 UTC (rev 114031)
+++ trunk/Source/WebCore/ChangeLog	2012-04-12 21:06:50 UTC (rev 114032)
@@ -1,3 +1,45 @@
+2012-04-12  David Hyatt  <[email protected]>
+
+        https://bugs.webkit.org/show_bug.cgi?id=83817
+        
+        This patch modifies RenderText so that it scans all of its characters up front to
+        determine whether or not the simple code path can be used for measurement/rendering
+        of the text for the whole run.
+        
+        TextRun now has an additional field that indicates that the character scan is not
+        required, since the entire RenderText is known to be simple. This boolean is set
+        when constructing the TextRun from the places that make TextRuns from RenderTexts.
+        
+        The character scan has been refactored into a static Font method so that it can be
+        called by RenderText. The scan of individual TextRuns is also done using the same method
+        so that the code is shared.
+
+        Reviewed by Dan Bernstein.
+
+        * platform/graphics/Font.cpp:
+        (WebCore::Font::codePath):
+        (WebCore::Font::characterRangeCodePath):
+        * platform/graphics/Font.h:
+        * platform/graphics/TextRun.h:
+        (WebCore::TextRun::TextRun):
+        (WebCore::TextRun::characterScanForCodePath):
+        (WebCore::TextRun::setCharacterScanForCodePath):
+        (TextRun):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::constructTextRun):
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::textWidth):
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::RenderText):
+        (WebCore::RenderText::widthFromCache):
+        (WebCore::RenderText::setTextInternal):
+        (WebCore::RenderText::width):
+        (WebCore::RenderText::computeCanUseSimpleFontCodePath):
+        (WebCore):
+        * rendering/RenderText.h:
+        (RenderText):
+        (WebCore::RenderText::canUseSimpleFontCodePath):
+
 2012-04-12  Levi Weintraub  <[email protected]>
 
         Make AccessibilityObject::size non-virtual and fix platform accessibility code's LayoutUnit usage

Modified: trunk/Source/WebCore/platform/graphics/Font.cpp (114031 => 114032)


--- trunk/Source/WebCore/platform/graphics/Font.cpp	2012-04-12 20:56:47 UTC (rev 114031)
+++ trunk/Source/WebCore/platform/graphics/Font.cpp	2012-04-12 21:06:50 UTC (rev 114032)
@@ -266,17 +266,27 @@
 
     if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings()->size() > 0)
         return Complex;
+    
+    if (run.length() > 1 && typesettingFeatures())
+        return Complex;
 
-    CodePath result = Simple;
+    if (!run.characterScanForCodePath())
+        return Simple;
 
-    // Start from 0 since drawing and highlighting also measure the characters before run->from
+    // Start from 0 since drawing and highlighting also measure the characters before run->from.
+    return characterRangeCodePath(run.characters(), run.length());
+}
+
+Font::CodePath Font::characterRangeCodePath(const UChar* characters, unsigned len)
+{
     // FIXME: Should use a UnicodeSet in ports where ICU is used. Note that we 
     // can't simply use UnicodeCharacter Property/class because some characters
     // are not 'combining', but still need to go to the complex path.
     // Alternatively, we may as well consider binary search over a sorted
     // list of ranges.
-    for (int i = 0; i < run.length(); i++) {
-        const UChar c = run[i];
+    CodePath result = Simple;
+    for (unsigned i = 0; i < len; i++) {
+        const UChar c = characters[i];
         if (c < 0x2E5) // U+02E5 through U+02E9 (Modifier Letters : Tone letters)  
             continue;
         if (c <= 0x2E9) 
@@ -383,10 +393,10 @@
         if (c <= 0xDBFF) {
             // High surrogate
 
-            if (i == run.length() - 1)
+            if (i == len - 1)
                 continue;
 
-            UChar next = run[++i];
+            UChar next = characters[++i];
             if (!U16_IS_TRAIL(next))
                 continue;
 
@@ -418,10 +428,6 @@
         if (c <= 0xFE2F)
             return Complex;
     }
-
-    if (run.length() > 1 && typesettingFeatures())
-        return Complex;
-
     return result;
 }
 

Modified: trunk/Source/WebCore/platform/graphics/Font.h (114031 => 114032)


--- trunk/Source/WebCore/platform/graphics/Font.h	2012-04-12 20:56:47 UTC (rev 114031)
+++ trunk/Source/WebCore/platform/graphics/Font.h	2012-04-12 21:06:50 UTC (rev 114032)
@@ -193,7 +193,8 @@
 
     enum CodePath { Auto, Simple, Complex, SimpleWithGlyphOverflow };
     CodePath codePath(const TextRun&) const;
-
+    static CodePath characterRangeCodePath(const UChar*, unsigned len);
+    
 private:
     enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
 

Modified: trunk/Source/WebCore/platform/graphics/TextRun.h (114031 => 114032)


--- trunk/Source/WebCore/platform/graphics/TextRun.h	2012-04-12 20:56:47 UTC (rev 114031)
+++ trunk/Source/WebCore/platform/graphics/TextRun.h	2012-04-12 21:06:50 UTC (rev 114032)
@@ -58,7 +58,7 @@
 
     typedef unsigned RoundingHacks;
 
-    TextRun(const UChar* c, int len, bool allowTabs = false, float xpos = 0, float expansion = 0, ExpansionBehavior expansionBehavior = AllowTrailingExpansion | ForbidLeadingExpansion, TextDirection direction = LTR, bool directionalOverride = false, RoundingHacks roundingHacks = RunRounding | WordRounding)
+    TextRun(const UChar* c, int len, bool allowTabs = false, float xpos = 0, float expansion = 0, ExpansionBehavior expansionBehavior = AllowTrailingExpansion | ForbidLeadingExpansion, TextDirection direction = LTR, bool directionalOverride = false, bool characterScanForCodePath = true, RoundingHacks roundingHacks = RunRounding | WordRounding)
         : m_characters(c)
         , m_charactersLength(len)
         , m_len(len)
@@ -71,13 +71,14 @@
         , m_allowTabs(allowTabs)
         , m_direction(direction)
         , m_directionalOverride(directionalOverride)
+        , m_characterScanForCodePath(characterScanForCodePath)
         , m_applyRunRounding((roundingHacks & RunRounding) && s_allowsRoundingHacks)
         , m_applyWordRounding((roundingHacks & WordRounding) && s_allowsRoundingHacks)
         , m_disableSpacing(false)
     {
     }
 
-    TextRun(const String& s, bool allowTabs = false, float xpos = 0, float expansion = 0, ExpansionBehavior expansionBehavior = AllowTrailingExpansion | ForbidLeadingExpansion, TextDirection direction = LTR, bool directionalOverride = false, RoundingHacks roundingHacks = RunRounding | WordRounding)
+    TextRun(const String& s, bool allowTabs = false, float xpos = 0, float expansion = 0, ExpansionBehavior expansionBehavior = AllowTrailingExpansion | ForbidLeadingExpansion, TextDirection direction = LTR, bool directionalOverride = false, bool characterScanForCodePath = true, RoundingHacks roundingHacks = RunRounding | WordRounding)
         : m_characters(s.characters())
         , m_charactersLength(s.length())
         , m_len(s.length())
@@ -90,6 +91,7 @@
         , m_allowTabs(allowTabs)
         , m_direction(direction)
         , m_directionalOverride(directionalOverride)
+        , m_characterScanForCodePath(characterScanForCodePath)
         , m_applyRunRounding((roundingHacks & RunRounding) && s_allowsRoundingHacks)
         , m_applyWordRounding((roundingHacks & WordRounding) && s_allowsRoundingHacks)
         , m_disableSpacing(false)
@@ -122,6 +124,7 @@
     bool rtl() const { return m_direction == RTL; }
     bool ltr() const { return m_direction == LTR; }
     bool directionalOverride() const { return m_directionalOverride; }
+    bool characterScanForCodePath() const { return m_characterScanForCodePath; }
     bool applyRunRounding() const { return m_applyRunRounding; }
     bool applyWordRounding() const { return m_applyWordRounding; }
     bool spacingDisabled() const { return m_disableSpacing; }
@@ -130,6 +133,7 @@
     void disableRoundingHacks() { m_applyRunRounding = m_applyWordRounding = false; }
     void setDirection(TextDirection direction) { m_direction = direction; }
     void setDirectionalOverride(bool override) { m_directionalOverride = override; }
+    void setCharacterScanForCodePath(bool scan) { m_characterScanForCodePath = scan; }
 
     class RenderingContext : public RefCounted<RenderingContext> {
     public:
@@ -167,6 +171,7 @@
     bool m_allowTabs;
     TextDirection m_direction;
     bool m_directionalOverride; // Was this direction set by an override character.
+    bool m_characterScanForCodePath;
     bool m_applyRunRounding;
     bool m_applyWordRounding;
     bool m_disableSpacing;

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (114031 => 114032)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2012-04-12 20:56:47 UTC (rev 114031)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2012-04-12 21:06:50 UTC (rev 114032)
@@ -1325,7 +1325,7 @@
 
     ASSERT(maximumLength >= length);
 
-    TextRun run(characters, length, textRenderer->allowTabs(), textPos(), expansion(), expansionBehavior(), direction(), dirOverride() || style->rtlOrdering() == VisualOrder);
+    TextRun run(characters, length, textRenderer->allowTabs(), textPos(), expansion(), expansionBehavior(), direction(), dirOverride() || style->rtlOrdering() == VisualOrder, !textRenderer->canUseSimpleFontCodePath());
     if (textRunNeedsRenderingContext(font))
         run.setRenderingContext(SVGTextRunRenderingContext::create(textRenderer));
 

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (114031 => 114032)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-04-12 20:56:47 UTC (rev 114031)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-04-12 21:06:50 UTC (rev 114032)
@@ -1947,6 +1947,7 @@
     run.setCharactersLength(text->textLength() - from);
     ASSERT(run.charactersLength() >= run.length());
 
+    run.setCharacterScanForCodePath(!text->canUseSimpleFontCodePath());
     run.setAllowTabs(!collapseWhiteSpace);
     run.setXPos(xPos);
     return font.width(run);

Modified: trunk/Source/WebCore/rendering/RenderText.cpp (114031 => 114032)


--- trunk/Source/WebCore/rendering/RenderText.cpp	2012-04-12 20:56:47 UTC (rev 114031)
+++ trunk/Source/WebCore/rendering/RenderText.cpp	2012-04-12 21:06:50 UTC (rev 114032)
@@ -146,6 +146,7 @@
      , m_linesDirty(false)
      , m_containsReversedText(false)
      , m_isAllASCII(m_text.containsOnlyASCII())
+     , m_canUseSimpleFontCodePath(computeCanUseSimpleFontCodePath())
      , m_knownToHaveNoOverflowAndNoFallbackFonts(false)
      , m_needsTranscoding(false)
 {
@@ -760,6 +761,7 @@
     run.setCharactersLength(textLength() - start);
     ASSERT(run.charactersLength() >= run.length());
 
+    run.setCharacterScanForCodePath(!canUseSimpleFontCodePath());
     run.setAllowTabs(allowTabs());
     run.setXPos(xPos);
     return f.width(run, fallbackFonts, glyphOverflow);
@@ -1330,6 +1332,7 @@
     ASSERT(!isBR() || (textLength() == 1 && m_text[0] == '\n'));
 
     m_isAllASCII = m_text.containsOnlyASCII();
+    m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath();
 }
 
 void RenderText::secureText(UChar mask)
@@ -1473,6 +1476,7 @@
         run.setCharactersLength(textLength() - from);
         ASSERT(run.charactersLength() >= run.length());
 
+        run.setCharacterScanForCodePath(!canUseSimpleFontCodePath());
         run.setAllowTabs(allowTabs());
         run.setXPos(xPos);
         w = f.width(run, fallbackFonts, glyphOverflow);
@@ -1793,6 +1797,13 @@
     return result;
 }
 
+bool RenderText::computeCanUseSimpleFontCodePath() const
+{
+    if (isAllASCII())
+        return true;
+    return Font::characterRangeCodePath(characters(), length()) == Font::Simple;
+}
+
 #ifndef NDEBUG
 
 void RenderText::checkConsistency() const

Modified: trunk/Source/WebCore/rendering/RenderText.h (114031 => 114032)


--- trunk/Source/WebCore/rendering/RenderText.h	2012-04-12 20:56:47 UTC (rev 114031)
+++ trunk/Source/WebCore/rendering/RenderText.h	2012-04-12 21:06:50 UTC (rev 114032)
@@ -129,7 +129,8 @@
 
     virtual void computePreferredLogicalWidths(float leadWidth);
     bool isAllCollapsibleWhitespace();
-    
+
+    bool canUseSimpleFontCodePath() const { return m_canUseSimpleFontCodePath; }
     bool knownToHaveNoOverflowAndNoFallbackFonts() const { return m_knownToHaveNoOverflowAndNoFallbackFonts; }
 
     void removeAndDestroyTextBoxes();
@@ -148,6 +149,8 @@
 private:
     void computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow&);
 
+    bool computeCanUseSimpleFontCodePath() const;
+    
     // Make length() private so that callers that have a RenderText*
     // will use the more efficient textLength() instead, while
     // callers with a RenderObject* can continue to use length().
@@ -186,6 +189,7 @@
                            // or removed).
     bool m_containsReversedText : 1;
     bool m_isAllASCII : 1;
+    bool m_canUseSimpleFontCodePath : 1;
     mutable bool m_knownToHaveNoOverflowAndNoFallbackFonts : 1;
     bool m_needsTranscoding : 1;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to