Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |