diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/rendering/RenderText.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/rendering/RenderText.cpp | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp index aa919e0..307db64 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp @@ -61,7 +61,7 @@ RenderText::RenderText(Node* node, PassRefPtr<StringImpl> str) , m_linesDirty(false) , m_containsReversedText(false) , m_isAllASCII(m_text.containsOnlyASCII()) - , m_knownNotToUseFallbackFonts(false) + , m_knownToHaveNoOverflowAndNoFallbackFonts(false) { ASSERT(m_text); @@ -106,7 +106,7 @@ void RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl // need to relayout. if (diff == StyleDifferenceLayout) { setNeedsLayoutAndPrefWidthsRecalc(); - m_knownNotToUseFallbackFonts = false; + m_knownToHaveNoOverflowAndNoFallbackFonts = false; } ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE; @@ -428,7 +428,7 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e return IntRect(left, top, caretWidth, height); } -ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts) const +ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII) { int monospaceCharacterWidth = f.spaceWidth(); @@ -460,7 +460,7 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, return w; } - return f.width(TextRun(text()->characters() + start, len, allowTabs(), xPos), fallbackFonts); + return f.width(TextRun(text()->characters() + start, len, allowTabs(), xPos), fallbackFonts, glyphOverflow); } void RenderText::trimmedPrefWidths(int leadWidth, @@ -531,7 +531,7 @@ void RenderText::trimmedPrefWidths(int leadWidth, linelen++; if (linelen) { - endMaxW = widthFromCache(f, i, linelen, leadWidth + endMaxW, 0); + endMaxW = widthFromCache(f, i, linelen, leadWidth + endMaxW, 0, 0); if (firstLine) { firstLine = false; leadWidth = 0; @@ -576,14 +576,15 @@ int RenderText::maxPrefWidth() const void RenderText::calcPrefWidths(int leadWidth) { HashSet<const SimpleFontData*> fallbackFonts; - calcPrefWidths(leadWidth, fallbackFonts); - if (fallbackFonts.isEmpty()) - m_knownNotToUseFallbackFonts = true; + GlyphOverflow glyphOverflow; + calcPrefWidths(leadWidth, fallbackFonts, glyphOverflow); + if (fallbackFonts.isEmpty() && !glyphOverflow.left && !glyphOverflow.right && !glyphOverflow.top && !glyphOverflow.bottom) + m_knownToHaveNoOverflowAndNoFallbackFonts = true; } -void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts) +void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow) { - ASSERT(m_hasTab || prefWidthsDirty() || !m_knownNotToUseFallbackFonts); + ASSERT(m_hasTab || prefWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts); m_minWidth = 0; m_beginMinWidth = 0; @@ -613,6 +614,8 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f int nextBreakable = -1; int lastWordBoundary = 0; + int firstGlyphLeftOverflow = -1; + bool breakNBSP = style()->autoWrap() && style()->nbspMode() == SPACE; bool breakAll = (style()->wordBreak() == BreakAllWordBreak || style()->wordBreak() == BreakWordBreak) && style()->autoWrap(); @@ -655,7 +658,9 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f lastWordBoundary++; continue; } else if (c == softHyphen) { - currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts); + currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow); + if (firstGlyphLeftOverflow < 0) + firstGlyphLeftOverflow = glyphOverflow.left; lastWordBoundary = i + 1; continue; } @@ -678,13 +683,15 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f int wordLen = j - i; if (wordLen) { - int w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts); + int w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow); + if (firstGlyphLeftOverflow < 0) + firstGlyphLeftOverflow = glyphOverflow.left; currMinWidth += w; if (betweenWords) { if (lastWordBoundary == i) currMaxWidth += w; else - currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts); + currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow); lastWordBoundary = j; } @@ -737,6 +744,7 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f currMaxWidth = 0; } else { currMaxWidth += f.width(TextRun(txt + i, 1, allowTabs(), leadWidth + currMaxWidth)); + glyphOverflow.right = 0; needsWordSpacing = isSpace && !previousCharacterIsSpace && i == len - 1; } ASSERT(lastWordBoundary == i); @@ -744,6 +752,9 @@ void RenderText::calcPrefWidths(int leadWidth, HashSet<const SimpleFontData*>& f } } + if (firstGlyphLeftOverflow > 0) + glyphOverflow.left = firstGlyphLeftOverflow; + if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord)) currMaxWidth += wordSpacing; @@ -1019,7 +1030,7 @@ void RenderText::setText(PassRefPtr<StringImpl> text, bool force) setTextInternal(text); setNeedsLayoutAndPrefWidthsRecalc(); - m_knownNotToUseFallbackFonts = false; + m_knownToHaveNoOverflowAndNoFallbackFonts = false; AXObjectCache* axObjectCache = document()->axObjectCache(); if (axObjectCache->accessibilityEnabled()) @@ -1085,7 +1096,7 @@ void RenderText::positionLineBox(InlineBox* box) m_containsReversedText |= s->direction() == RTL; } -unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts) const +unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { if (from >= textLength()) return 0; @@ -1093,10 +1104,10 @@ unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine if (from + len > textLength()) len = textLength() - from; - return width(from, len, style(firstLine)->font(), xPos, fallbackFonts); + return width(from, len, style(firstLine)->font(), xPos, fallbackFonts, glyphOverflow); } -unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos, HashSet<const SimpleFontData*>* fallbackFonts) const +unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { ASSERT(from + len <= textLength()); if (!characters()) @@ -1106,18 +1117,19 @@ unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos, if (&f == &style()->font()) { if (!style()->preserveNewline() && !from && len == textLength()) { if (fallbackFonts) { - if (prefWidthsDirty() || !m_knownNotToUseFallbackFonts) { - const_cast<RenderText*>(this)->calcPrefWidths(0, *fallbackFonts); - if (fallbackFonts->isEmpty()) - m_knownNotToUseFallbackFonts = true; + ASSERT(glyphOverflow); + if (prefWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts) { + const_cast<RenderText*>(this)->calcPrefWidths(0, *fallbackFonts, *glyphOverflow); + if (fallbackFonts->isEmpty() && !glyphOverflow->left && !glyphOverflow->right && !glyphOverflow->top && !glyphOverflow->bottom) + m_knownToHaveNoOverflowAndNoFallbackFonts = true; } w = m_maxWidth; } else w = maxPrefWidth(); } else - w = widthFromCache(f, from, len, xPos, fallbackFonts); + w = widthFromCache(f, from, len, xPos, fallbackFonts, glyphOverflow); } else - w = f.width(TextRun(text()->characters() + from, len, allowTabs(), xPos), fallbackFonts); + w = f.width(TextRun(text()->characters() + from, len, allowTabs(), xPos), fallbackFonts, glyphOverflow); return w; } |