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;
};