Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: Source/core/layout/LayoutText.cpp

Issue 1179723002: Store glyph bounds in WordMeasurement to avoid slow path width calc (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: For review Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * (C) 1999 Lars Knoll (knoll@kde.org) 2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Dirk Mueller (mueller@kde.org) 3 * (C) 2000 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) 6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 20 matching lines...) Expand all
31 #include "core/editing/iterators/TextIterator.h" 31 #include "core/editing/iterators/TextIterator.h"
32 #include "core/frame/FrameView.h" 32 #include "core/frame/FrameView.h"
33 #include "core/frame/Settings.h" 33 #include "core/frame/Settings.h"
34 #include "core/html/parser/TextResourceDecoder.h" 34 #include "core/html/parser/TextResourceDecoder.h"
35 #include "core/layout/LayoutBlock.h" 35 #include "core/layout/LayoutBlock.h"
36 #include "core/layout/LayoutTextCombine.h" 36 #include "core/layout/LayoutTextCombine.h"
37 #include "core/layout/LayoutView.h" 37 #include "core/layout/LayoutView.h"
38 #include "core/layout/TextRunConstructor.h" 38 #include "core/layout/TextRunConstructor.h"
39 #include "core/layout/line/AbstractInlineTextBox.h" 39 #include "core/layout/line/AbstractInlineTextBox.h"
40 #include "core/layout/line/EllipsisBox.h" 40 #include "core/layout/line/EllipsisBox.h"
41 #include "core/layout/line/GlyphOverflow.h"
41 #include "core/layout/line/InlineTextBox.h" 42 #include "core/layout/line/InlineTextBox.h"
42 #include "core/paint/DeprecatedPaintLayer.h" 43 #include "core/paint/DeprecatedPaintLayer.h"
43 #include "platform/fonts/Character.h" 44 #include "platform/fonts/Character.h"
44 #include "platform/fonts/FontCache.h" 45 #include "platform/fonts/FontCache.h"
45 #include "platform/geometry/FloatQuad.h" 46 #include "platform/geometry/FloatQuad.h"
46 #include "platform/text/BidiResolver.h" 47 #include "platform/text/BidiResolver.h"
47 #include "platform/text/TextBreakIterator.h" 48 #include "platform/text/TextBreakIterator.h"
48 #include "platform/text/TextRunIterator.h" 49 #include "platform/text/TextRunIterator.h"
49 #include "wtf/text/StringBuffer.h" 50 #include "wtf/text/StringBuffer.h"
50 #include "wtf/text/StringBuilder.h" 51 #include "wtf/text/StringBuilder.h"
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 left = std::max(left, leftEdge); 701 left = std::max(left, leftEdge);
701 left = std::min(left, rootRight - caretWidth()); 702 left = std::min(left, rootRight - caretWidth());
702 } else { 703 } else {
703 left = std::min(left, rightEdge - caretWidthRightOfOffset); 704 left = std::min(left, rightEdge - caretWidthRightOfOffset);
704 left = std::max(left, rootLeft); 705 left = std::max(left, rootLeft);
705 } 706 }
706 707
707 return LayoutRect(style()->isHorizontalWritingMode() ? IntRect(left, top, ca retWidth(), height) : IntRect(top, left, height, caretWidth())); 708 return LayoutRect(style()->isHorizontalWritingMode() ? IntRect(left, top, ca retWidth(), height) : IntRect(top, left, height, caretWidth()));
708 } 709 }
709 710
710 ALWAYS_INLINE float LayoutText::widthFromCache(const Font& f, int start, int len , float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallb ackFonts, GlyphOverflow* glyphOverflow) const 711 ALWAYS_INLINE float LayoutText::widthFromFont(const Font& f, int start, int len, float leadWidth, float textWidthSoFar, TextDirection textDirection, HashSet<con st SimpleFontData*>* fallbackFonts, FloatRect* glyphBoundsAccumulation) const
711 { 712 {
712 if (style()->hasTextCombine() && isCombineText()) { 713 if (style()->hasTextCombine() && isCombineText()) {
713 const LayoutTextCombine* combineText = toLayoutTextCombine(this); 714 const LayoutTextCombine* combineText = toLayoutTextCombine(this);
714 if (combineText->isCombined()) 715 if (combineText->isCombined())
715 return combineText->combinedTextWidth(f); 716 return combineText->combinedTextWidth(f);
716 } 717 }
717 718
718 TextRun run = constructTextRun(const_cast<LayoutText*>(this), f, this, start , len, styleRef(), textDirection); 719 TextRun run = constructTextRun(const_cast<LayoutText*>(this), f, this, start , len, styleRef(), textDirection);
719 run.setCharactersLength(textLength() - start); 720 run.setCharactersLength(textLength() - start);
720 ASSERT(run.charactersLength() >= run.length()); 721 ASSERT(run.charactersLength() >= run.length());
721 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimple : TextRun: :ForceComplex); 722 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimple : TextRun: :ForceComplex);
722 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 723 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
723 run.setXPos(xPos); 724 run.setXPos(leadWidth + textWidthSoFar);
724 return f.width(run, fallbackFonts, glyphOverflow); 725
726 FloatRect newGlyphBounds;
727 float result = f.width(run, fallbackFonts, glyphBoundsAccumulation ? &newGly phBounds : nullptr);
728 if (glyphBoundsAccumulation) {
729 newGlyphBounds.move(textWidthSoFar, 0);
730 glyphBoundsAccumulation->unite(newGlyphBounds);
731 }
732 return result;
725 } 733 }
726 734
727 void LayoutText::trimmedPrefWidths(LayoutUnit leadWidthLayoutUnit, 735 void LayoutText::trimmedPrefWidths(LayoutUnit leadWidthLayoutUnit,
728 LayoutUnit& firstLineMinWidth, bool& hasBreakableStart, 736 LayoutUnit& firstLineMinWidth, bool& hasBreakableStart,
729 LayoutUnit& lastLineMinWidth, bool& hasBreakableEnd, 737 LayoutUnit& lastLineMinWidth, bool& hasBreakableEnd,
730 bool& hasBreakableChar, bool& hasBreak, 738 bool& hasBreakableChar, bool& hasBreak,
731 LayoutUnit& firstLineMaxWidth, LayoutUnit& lastLineMaxWidth, 739 LayoutUnit& firstLineMaxWidth, LayoutUnit& lastLineMaxWidth,
732 LayoutUnit& minWidth, LayoutUnit& maxWidth, bool& stripFrontSpaces, 740 LayoutUnit& minWidth, LayoutUnit& maxWidth, bool& stripFrontSpaces,
733 TextDirection direction) 741 TextDirection direction)
734 { 742 {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 const Font& f = style()->font(); // FIXME: This ignores first-line. 802 const Font& f = style()->font(); // FIXME: This ignores first-line.
795 bool firstLine = true; 803 bool firstLine = true;
796 firstLineMaxWidth = floatMaxWidth; 804 firstLineMaxWidth = floatMaxWidth;
797 lastLineMaxWidth = floatMaxWidth; 805 lastLineMaxWidth = floatMaxWidth;
798 for (int i = 0; i < len; i++) { 806 for (int i = 0; i < len; i++) {
799 int linelen = 0; 807 int linelen = 0;
800 while (i + linelen < len && text[i + linelen] != newlineCharacter) 808 while (i + linelen < len && text[i + linelen] != newlineCharacter)
801 linelen++; 809 linelen++;
802 810
803 if (linelen) { 811 if (linelen) {
804 lastLineMaxWidth = widthFromCache(f, i, linelen, leadWidth + las tLineMaxWidth, direction, 0, 0); 812 lastLineMaxWidth = widthFromFont(f, i, linelen, leadWidth, lastL ineMaxWidth.toFloat(), direction, nullptr, nullptr);
805 if (firstLine) { 813 if (firstLine) {
806 firstLine = false; 814 firstLine = false;
807 leadWidth = 0.f; 815 leadWidth = 0.f;
808 firstLineMaxWidth = lastLineMaxWidth; 816 firstLineMaxWidth = lastLineMaxWidth;
809 } 817 }
810 i += linelen; 818 i += linelen;
811 } else if (firstLine) { 819 } else if (firstLine) {
812 firstLineMaxWidth = LayoutUnit(); 820 firstLineMaxWidth = LayoutUnit();
813 firstLine = false; 821 firstLine = false;
814 leadWidth = 0.f; 822 leadWidth = 0.f;
(...skipping 23 matching lines...) Expand all
838 { 846 {
839 if (preferredLogicalWidthsDirty()) 847 if (preferredLogicalWidthsDirty())
840 const_cast<LayoutText*>(this)->computePreferredLogicalWidths(0); 848 const_cast<LayoutText*>(this)->computePreferredLogicalWidths(0);
841 849
842 return m_maxWidth; 850 return m_maxWidth;
843 } 851 }
844 852
845 void LayoutText::computePreferredLogicalWidths(float leadWidth) 853 void LayoutText::computePreferredLogicalWidths(float leadWidth)
846 { 854 {
847 HashSet<const SimpleFontData*> fallbackFonts; 855 HashSet<const SimpleFontData*> fallbackFonts;
848 GlyphOverflow glyphOverflow; 856 FloatRect glyphBounds;
849 computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphOverflow); 857 computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphBounds);
850
851 // We shouldn't change our mind once we "know".
852 ASSERT(!m_knownToHaveNoOverflowAndNoFallbackFonts || (fallbackFonts.isEmpty( ) && glyphOverflow.isZero()));
853 m_knownToHaveNoOverflowAndNoFallbackFonts = fallbackFonts.isEmpty() && glyph Overflow.isZero();
Xianzhu 2015/06/11 18:22:48 This is moved into the long form computePreferredL
854 } 858 }
855 859
856 static inline float hyphenWidth(LayoutText* layoutObject, const Font& font, Text Direction direction) 860 static inline float hyphenWidth(LayoutText* layoutObject, const Font& font, Text Direction direction)
857 { 861 {
858 const ComputedStyle& style = layoutObject->styleRef(); 862 const ComputedStyle& style = layoutObject->styleRef();
859 return font.width(constructTextRun(layoutObject, font, style.hyphenString(). string(), style, direction)); 863 return font.width(constructTextRun(layoutObject, font, style.hyphenString(). string(), style, direction));
860 } 864 }
861 865
862 void LayoutText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si mpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow) 866 void LayoutText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si mpleFontData*>& fallbackFonts, FloatRect& glyphBounds)
863 { 867 {
864 ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflow AndNoFallbackFonts); 868 ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflow AndNoFallbackFonts);
865 869
866 m_minWidth = 0; 870 m_minWidth = 0;
867 m_maxWidth = 0; 871 m_maxWidth = 0;
868 m_firstLineMinWidth = 0; 872 m_firstLineMinWidth = 0;
869 m_lastLineLineMinWidth = 0; 873 m_lastLineLineMinWidth = 0;
870 874
871 if (isBR()) 875 if (isBR())
872 return; 876 return;
(...skipping 14 matching lines...) Expand all
887 LazyLineBreakIterator breakIterator(m_text, styleToUse.locale()); 891 LazyLineBreakIterator breakIterator(m_text, styleToUse.locale());
888 bool needsWordSpacing = false; 892 bool needsWordSpacing = false;
889 bool ignoringSpaces = false; 893 bool ignoringSpaces = false;
890 bool isSpace = false; 894 bool isSpace = false;
891 bool firstWord = true; 895 bool firstWord = true;
892 bool firstLine = true; 896 bool firstLine = true;
893 int nextBreakable = -1; 897 int nextBreakable = -1;
894 int lastWordBoundary = 0; 898 int lastWordBoundary = 0;
895 float cachedWordTrailingSpaceWidth[2] = { 0, 0 }; // LTR, RTL 899 float cachedWordTrailingSpaceWidth[2] = { 0, 0 }; // LTR, RTL
896 900
897 int firstGlyphLeftOverflow = -1;
898
899 bool breakAll = (styleToUse.wordBreak() == BreakAllWordBreak || styleToUse.w ordBreak() == BreakWordBreak) && styleToUse.autoWrap(); 901 bool breakAll = (styleToUse.wordBreak() == BreakAllWordBreak || styleToUse.w ordBreak() == BreakWordBreak) && styleToUse.autoWrap();
900 bool keepAll = styleToUse.wordBreak() == KeepAllWordBreak && styleToUse.auto Wrap(); 902 bool keepAll = styleToUse.wordBreak() == KeepAllWordBreak && styleToUse.auto Wrap();
901 903
902 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; 904 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
903 BidiCharacterRun* run; 905 BidiCharacterRun* run;
904 TextDirection textDirection = styleToUse.direction(); 906 TextDirection textDirection = styleToUse.direction();
905 if (is8Bit() || isOverride(styleToUse.unicodeBidi())) { 907 if (is8Bit() || isOverride(styleToUse.unicodeBidi())) {
906 run = 0; 908 run = 0;
907 } else { 909 } else {
908 TextRun textRun(text()); 910 TextRun textRun(text());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 if (ignoringSpaces && !isSpace) 968 if (ignoringSpaces && !isSpace)
967 ignoringSpaces = false; 969 ignoringSpaces = false;
968 970
969 // Ignore spaces and soft hyphens 971 // Ignore spaces and soft hyphens
970 if (ignoringSpaces) { 972 if (ignoringSpaces) {
971 ASSERT(lastWordBoundary == i); 973 ASSERT(lastWordBoundary == i);
972 lastWordBoundary++; 974 lastWordBoundary++;
973 continue; 975 continue;
974 } 976 }
975 if (c == softHyphenCharacter) { 977 if (c == softHyphenCharacter) {
976 currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoun dary, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow); 978 currMaxWidth += widthFromFont(f, lastWordBoundary, i - lastWordBound ary, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBounds);
977 if (firstGlyphLeftOverflow < 0)
978 firstGlyphLeftOverflow = glyphOverflow.left;
979 lastWordBoundary = i + 1; 979 lastWordBoundary = i + 1;
980 continue; 980 continue;
981 } 981 }
982 982
983 bool hasBreak = breakIterator.isBreakable(i, nextBreakable, breakAll ? L ineBreakType::BreakAll : keepAll ? LineBreakType::KeepAll : LineBreakType::Norma l); 983 bool hasBreak = breakIterator.isBreakable(i, nextBreakable, breakAll ? L ineBreakType::BreakAll : keepAll ? LineBreakType::KeepAll : LineBreakType::Norma l);
984 bool betweenWords = true; 984 bool betweenWords = true;
985 int j = i; 985 int j = i;
986 while (c != newlineCharacter && c != spaceCharacter && c != tabulationCh aracter && (c != softHyphenCharacter)) { 986 while (c != newlineCharacter && c != spaceCharacter && c != tabulationCh aracter && (c != softHyphenCharacter)) {
987 j++; 987 j++;
988 if (j == len) 988 if (j == len)
(...skipping 19 matching lines...) Expand all
1008 float wordTrailingSpaceWidth = 0; 1008 float wordTrailingSpaceWidth = 0;
1009 if (isSpace && (f.fontDescription().typesettingFeatures() & Kerning) ) { 1009 if (isSpace && (f.fontDescription().typesettingFeatures() & Kerning) ) {
1010 ASSERT(textDirection >=0 && textDirection <= 1); 1010 ASSERT(textDirection >=0 && textDirection <= 1);
1011 if (!cachedWordTrailingSpaceWidth[textDirection]) 1011 if (!cachedWordTrailingSpaceWidth[textDirection])
1012 cachedWordTrailingSpaceWidth[textDirection] = f.width(constr uctTextRun(this, f, &spaceCharacter, 1, styleToUse, textDirection)) + wordSpacin g; 1012 cachedWordTrailingSpaceWidth[textDirection] = f.width(constr uctTextRun(this, f, &spaceCharacter, 1, styleToUse, textDirection)) + wordSpacin g;
1013 wordTrailingSpaceWidth = cachedWordTrailingSpaceWidth[textDirect ion]; 1013 wordTrailingSpaceWidth = cachedWordTrailingSpaceWidth[textDirect ion];
1014 } 1014 }
1015 1015
1016 float w; 1016 float w;
1017 if (wordTrailingSpaceWidth && isSpace) { 1017 if (wordTrailingSpaceWidth && isSpace) {
1018 w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth; 1018 w = widthFromFont(f, i, wordLen + 1, leadWidth, currMaxWidth, te xtDirection, &fallbackFonts, &glyphBounds) - wordTrailingSpaceWidth;
1019 } else { 1019 } else {
1020 w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, text Direction, &fallbackFonts, &glyphOverflow); 1020 w = widthFromFont(f, i, wordLen, leadWidth, currMaxWidth, textDi rection, &fallbackFonts, &glyphBounds);
1021 if (c == softHyphenCharacter) 1021 if (c == softHyphenCharacter)
1022 currMinWidth += hyphenWidth(this, f, textDirection); 1022 currMinWidth += hyphenWidth(this, f, textDirection);
1023 } 1023 }
1024 1024
1025 if (firstGlyphLeftOverflow < 0)
1026 firstGlyphLeftOverflow = glyphOverflow.left;
1027 currMinWidth += w; 1025 currMinWidth += w;
1028 if (betweenWords) { 1026 if (betweenWords) {
1029 if (lastWordBoundary == i) 1027 if (lastWordBoundary == i)
1030 currMaxWidth += w; 1028 currMaxWidth += w;
1031 else 1029 else
1032 currMaxWidth += widthFromCache(f, lastWordBoundary, j - last WordBoundary, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOve rflow); 1030 currMaxWidth += widthFromFont(f, lastWordBoundary, j - lastW ordBoundary, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBound s);
1033 lastWordBoundary = j; 1031 lastWordBoundary = j;
1034 } 1032 }
1035 1033
1036 bool isCollapsibleWhiteSpace = (j < len) && styleToUse.isCollapsible WhiteSpace(c); 1034 bool isCollapsibleWhiteSpace = (j < len) && styleToUse.isCollapsible WhiteSpace(c);
1037 if (j < len && styleToUse.autoWrap()) 1035 if (j < len && styleToUse.autoWrap())
1038 m_hasBreakableChar = true; 1036 m_hasBreakableChar = true;
1039 1037
1040 // Add in wordSpacing to our currMaxWidth, but not if this is the la st word on a line or the 1038 // Add in wordSpacing to our currMaxWidth, but not if this is the la st word on a line or the
1041 // last word in the run. 1039 // last word in the run.
1042 if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) && !contains OnlyWhitespace(j, len-j)) 1040 if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) && !contains OnlyWhitespace(j, len-j))
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 currMaxWidth = 0; 1079 currMaxWidth = 0;
1082 } else { 1080 } else {
1083 TextRun run = constructTextRun(this, f, this, i, 1, styleToUse, textDirection); 1081 TextRun run = constructTextRun(this, f, this, i, 1, styleToUse, textDirection);
1084 run.setCharactersLength(len - i); 1082 run.setCharactersLength(len - i);
1085 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimpl e : TextRun::ForceComplex); 1083 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimpl e : TextRun::ForceComplex);
1086 ASSERT(run.charactersLength() >= run.length()); 1084 ASSERT(run.charactersLength() >= run.length());
1087 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize( )); 1085 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize( ));
1088 run.setXPos(leadWidth + currMaxWidth); 1086 run.setXPos(leadWidth + currMaxWidth);
1089 1087
1090 currMaxWidth += f.width(run); 1088 currMaxWidth += f.width(run);
1091 glyphOverflow.right = 0;
1092 needsWordSpacing = isSpace && !previousCharacterIsSpace && i == len - 1; 1089 needsWordSpacing = isSpace && !previousCharacterIsSpace && i == len - 1;
1093 } 1090 }
1094 ASSERT(lastWordBoundary == i); 1091 ASSERT(lastWordBoundary == i);
1095 lastWordBoundary++; 1092 lastWordBoundary++;
1096 } 1093 }
1097 } 1094 }
1098 if (run) 1095 if (run)
1099 bidiResolver.runs().deleteRuns(); 1096 bidiResolver.runs().deleteRuns();
1100 1097
1101 if (firstGlyphLeftOverflow > 0)
1102 glyphOverflow.left = firstGlyphLeftOverflow;
1103
1104 if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord)) 1098 if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord))
1105 currMaxWidth += wordSpacing; 1099 currMaxWidth += wordSpacing;
1106 1100
1107 m_minWidth = std::max(currMinWidth, m_minWidth); 1101 m_minWidth = std::max(currMinWidth, m_minWidth);
1108 m_maxWidth = std::max(currMaxWidth, m_maxWidth); 1102 m_maxWidth = std::max(currMaxWidth, m_maxWidth);
1109 1103
1110 if (!styleToUse.autoWrap()) 1104 if (!styleToUse.autoWrap())
1111 m_minWidth = m_maxWidth; 1105 m_minWidth = m_maxWidth;
1112 1106
1113 if (styleToUse.whiteSpace() == PRE) { 1107 if (styleToUse.whiteSpace() == PRE) {
1114 if (firstLine) 1108 if (firstLine)
1115 m_firstLineMinWidth = m_maxWidth; 1109 m_firstLineMinWidth = m_maxWidth;
1116 m_lastLineLineMinWidth = currMaxWidth; 1110 m_lastLineLineMinWidth = currMaxWidth;
1117 } 1111 }
1118 1112
1113 if (styleToUse.lineBoxContain() & LineBoxContainGlyphs) {
1114 // We shouldn't change our mind once we "know".
1115 ASSERT(!m_knownToHaveNoOverflowAndNoFallbackFonts);
1116 } else {
1117 GlyphOverflow glyphOverflow;
1118 glyphOverflow.setFromBounds(glyphBounds, f.fontMetrics().floatAscent(), f.fontMetrics().floatDescent(), m_maxWidth);
1119 // We shouldn't change our mind once we "know".
1120 ASSERT(!m_knownToHaveNoOverflowAndNoFallbackFonts || (fallbackFonts.isEm pty() && glyphOverflow.isZero()));
1121 m_knownToHaveNoOverflowAndNoFallbackFonts = fallbackFonts.isEmpty() && g lyphOverflow.isZero();
1122 }
1123
1119 clearPreferredLogicalWidthsDirty(); 1124 clearPreferredLogicalWidthsDirty();
1120 } 1125 }
1121 1126
1122 bool LayoutText::isAllCollapsibleWhitespace() const 1127 bool LayoutText::isAllCollapsibleWhitespace() const
1123 { 1128 {
1124 unsigned length = textLength(); 1129 unsigned length = textLength();
1125 if (is8Bit()) { 1130 if (is8Bit()) {
1126 for (unsigned i = 0; i < length; ++i) { 1131 for (unsigned i = 0; i < length; ++i) {
1127 if (!style()->isCollapsibleWhiteSpace(characters8()[i])) 1132 if (!style()->isCollapsibleWhiteSpace(characters8()[i]))
1128 return false; 1133 return false;
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 m_lastTextBox = s->prevTextBox(); 1458 m_lastTextBox = s->prevTextBox();
1454 else 1459 else
1455 s->nextTextBox()->setPreviousTextBox(s->prevTextBox()); 1460 s->nextTextBox()->setPreviousTextBox(s->prevTextBox());
1456 s->destroy(); 1461 s->destroy();
1457 return; 1462 return;
1458 } 1463 }
1459 1464
1460 m_containsReversedText |= !s->isLeftToRightDirection(); 1465 m_containsReversedText |= !s->isLeftToRightDirection();
1461 } 1466 }
1462 1467
1463 float LayoutText::width(unsigned from, unsigned len, LayoutUnit xPos, TextDirect ion textDirection, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts , GlyphOverflow* glyphOverflow) const 1468 float LayoutText::width(unsigned from, unsigned len, LayoutUnit xPos, TextDirect ion textDirection, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts , FloatRect* glyphBounds) const
1464 { 1469 {
1465 if (from >= textLength()) 1470 if (from >= textLength())
1466 return 0; 1471 return 0;
1467 1472
1468 if (from + len > textLength()) 1473 if (from + len > textLength())
1469 len = textLength() - from; 1474 len = textLength() - from;
1470 1475
1471 return width(from, len, style(firstLine)->font(), xPos, textDirection, fallb ackFonts, glyphOverflow); 1476 return width(from, len, style(firstLine)->font(), xPos, textDirection, fallb ackFonts, glyphBounds);
1472 } 1477 }
1473 1478
1474 float LayoutText::width(unsigned from, unsigned len, const Font& f, LayoutUnit x Pos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const 1479 float LayoutText::width(unsigned from, unsigned len, const Font& f, LayoutUnit x Pos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallbackFonts, FloatRect* glyphBounds) const
1475 { 1480 {
1476 ASSERT(from + len <= textLength()); 1481 ASSERT(from + len <= textLength());
1477 if (!textLength()) 1482 if (!textLength())
1478 return 0; 1483 return 0;
1479 1484
1480 float w; 1485 float w;
1481 if (&f == &style()->font()) { 1486 if (&f == &style()->font()) {
1482 if (!style()->preserveNewline() && !from && len == textLength() && (!gly phOverflow || !glyphOverflow->computeBounds)) { 1487 if (!style()->preserveNewline() && !from && len == textLength()) {
1483 if (fallbackFonts) { 1488 if (fallbackFonts) {
1484 ASSERT(glyphOverflow); 1489 ASSERT(glyphBounds);
1485 if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAnd NoFallbackFonts) { 1490 if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAnd NoFallbackFonts)
1486 const_cast<LayoutText*>(this)->computePreferredLogicalWidths (0, *fallbackFonts, *glyphOverflow); 1491 const_cast<LayoutText*>(this)->computePreferredLogicalWidths (0, *fallbackFonts, *glyphBounds);
1487 // We shouldn't change our mind once we "know". 1492 else
1488 ASSERT(!m_knownToHaveNoOverflowAndNoFallbackFonts 1493 *glyphBounds = FloatRect(0, -f.fontMetrics().floatAscent(), m_maxWidth, f.fontMetrics().floatHeight());
1489 || (fallbackFonts->isEmpty() && glyphOverflow->isZero()) );
1490 m_knownToHaveNoOverflowAndNoFallbackFonts = fallbackFonts->i sEmpty() && glyphOverflow->isZero();
1491 }
1492 w = m_maxWidth; 1494 w = m_maxWidth;
1493 } else { 1495 } else {
1494 w = maxLogicalWidth(); 1496 w = maxLogicalWidth();
1495 } 1497 }
1496 } else { 1498 } else {
1497 w = widthFromCache(f, from, len, xPos.toFloat(), textDirection, fall backFonts, glyphOverflow); 1499 w = widthFromFont(f, from, len, xPos.toFloat(), 0, textDirection, fa llbackFonts, glyphBounds);
1498 } 1500 }
1499 } else { 1501 } else {
1500 TextRun run = constructTextRun(const_cast<LayoutText*>(this), f, this, f rom, len, styleRef(), textDirection); 1502 TextRun run = constructTextRun(const_cast<LayoutText*>(this), f, this, f rom, len, styleRef(), textDirection);
1501 run.setCharactersLength(textLength() - from); 1503 run.setCharactersLength(textLength() - from);
1502 ASSERT(run.charactersLength() >= run.length()); 1504 ASSERT(run.charactersLength() >= run.length());
1503 1505
1504 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimple : Text Run::ForceComplex); 1506 run.setCodePath(canUseSimpleFontCodePath() ? TextRun::ForceSimple : Text Run::ForceComplex);
1505 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 1507 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
1506 run.setXPos(xPos.toFloat()); 1508 run.setXPos(xPos.toFloat());
1507 w = f.width(run, fallbackFonts, glyphOverflow); 1509 w = f.width(run, fallbackFonts, glyphBounds);
1508 } 1510 }
1509 1511
1510 return w; 1512 return w;
1511 } 1513 }
1512 1514
1513 IntRect LayoutText::linesBoundingBox() const 1515 IntRect LayoutText::linesBoundingBox() const
1514 { 1516 {
1515 IntRect result; 1517 IntRect result;
1516 1518
1517 ASSERT(!firstTextBox() == !lastTextBox()); // Either both are null or both e xist. 1519 ASSERT(!firstTextBox() == !lastTextBox()); // Either both are null or both e xist.
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1858 } 1860 }
1859 1861
1860 void LayoutText::invalidateDisplayItemClients(const LayoutBoxModelObject& paintI nvalidationContainer) const 1862 void LayoutText::invalidateDisplayItemClients(const LayoutBoxModelObject& paintI nvalidationContainer) const
1861 { 1863 {
1862 LayoutObject::invalidateDisplayItemClients(paintInvalidationContainer); 1864 LayoutObject::invalidateDisplayItemClients(paintInvalidationContainer);
1863 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) 1865 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
1864 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box); 1866 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box);
1865 } 1867 }
1866 1868
1867 } // namespace blink 1869 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698