| 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 23 matching lines...) Expand all Loading... |
| 34 #include "core/layout/LayoutBlock.h" | 34 #include "core/layout/LayoutBlock.h" |
| 35 #include "core/layout/LayoutTextCombine.h" | 35 #include "core/layout/LayoutTextCombine.h" |
| 36 #include "core/layout/LayoutView.h" | 36 #include "core/layout/LayoutView.h" |
| 37 #include "core/layout/api/LineLayoutBox.h" | 37 #include "core/layout/api/LineLayoutBox.h" |
| 38 #include "core/layout/line/AbstractInlineTextBox.h" | 38 #include "core/layout/line/AbstractInlineTextBox.h" |
| 39 #include "core/layout/line/EllipsisBox.h" | 39 #include "core/layout/line/EllipsisBox.h" |
| 40 #include "core/layout/line/GlyphOverflow.h" | 40 #include "core/layout/line/GlyphOverflow.h" |
| 41 #include "core/layout/line/InlineTextBox.h" | 41 #include "core/layout/line/InlineTextBox.h" |
| 42 #include "core/paint/PaintLayer.h" | 42 #include "core/paint/PaintLayer.h" |
| 43 #include "platform/LayoutTestSupport.h" | 43 #include "platform/LayoutTestSupport.h" |
| 44 #include "platform/fonts/CharacterRange.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/Character.h" | 48 #include "platform/text/Character.h" |
| 49 #include "platform/text/Hyphenation.h" |
| 48 #include "platform/text/TextBreakIterator.h" | 50 #include "platform/text/TextBreakIterator.h" |
| 49 #include "platform/text/TextRunIterator.h" | 51 #include "platform/text/TextRunIterator.h" |
| 50 #include "wtf/text/CharacterNames.h" | 52 #include "wtf/text/CharacterNames.h" |
| 51 #include "wtf/text/StringBuffer.h" | 53 #include "wtf/text/StringBuffer.h" |
| 52 #include "wtf/text/StringBuilder.h" | 54 #include "wtf/text/StringBuilder.h" |
| 53 | 55 |
| 54 using namespace WTF; | 56 using namespace WTF; |
| 55 using namespace Unicode; | 57 using namespace Unicode; |
| 56 | 58 |
| 57 namespace blink { | 59 namespace blink { |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 return m_maxWidth; | 858 return m_maxWidth; |
| 857 } | 859 } |
| 858 | 860 |
| 859 void LayoutText::computePreferredLogicalWidths(float leadWidth) | 861 void LayoutText::computePreferredLogicalWidths(float leadWidth) |
| 860 { | 862 { |
| 861 HashSet<const SimpleFontData*> fallbackFonts; | 863 HashSet<const SimpleFontData*> fallbackFonts; |
| 862 FloatRect glyphBounds; | 864 FloatRect glyphBounds; |
| 863 computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphBounds); | 865 computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphBounds); |
| 864 } | 866 } |
| 865 | 867 |
| 868 static float maxWordFragmentWidth(LayoutText* layoutText, |
| 869 const ComputedStyle& style, const Font& font, TextDirection textDirection, |
| 870 Hyphenation& hyphenation, unsigned wordOffset, unsigned wordLength, |
| 871 int& suffixStart) |
| 872 { |
| 873 suffixStart = 0; |
| 874 if (wordLength <= Hyphenation::minimumSuffixLength) |
| 875 return 0; |
| 876 |
| 877 Vector<size_t, 8> hyphenLocations = hyphenation.hyphenLocations( |
| 878 layoutText->text().createView(wordOffset, wordLength)); |
| 879 if (hyphenLocations.isEmpty()) |
| 880 return 0; |
| 881 |
| 882 float minimumFragmentWidthToConsider = Hyphenation::minimumPrefixWidth(font)
; |
| 883 float maxFragmentWidth = 0; |
| 884 TextRun run = constructTextRun(font, layoutText, wordOffset, wordLength, sty
le, textDirection); |
| 885 size_t end = wordLength; |
| 886 for (size_t start : hyphenLocations) { |
| 887 float fragmentWidth = font.getCharacterRange(run, start, end).width(); |
| 888 |
| 889 if (fragmentWidth <= minimumFragmentWidthToConsider) |
| 890 continue; |
| 891 |
| 892 maxFragmentWidth = std::max(maxFragmentWidth, fragmentWidth); |
| 893 end = start; |
| 894 } |
| 895 suffixStart = hyphenLocations.first(); |
| 896 return maxFragmentWidth + layoutText->hyphenWidth(font, textDirection); |
| 897 } |
| 898 |
| 866 void LayoutText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
mpleFontData*>& fallbackFonts, FloatRect& glyphBounds) | 899 void LayoutText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
mpleFontData*>& fallbackFonts, FloatRect& glyphBounds) |
| 867 { | 900 { |
| 868 ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflow
AndNoFallbackFonts); | 901 ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflow
AndNoFallbackFonts); |
| 869 | 902 |
| 870 m_minWidth = 0; | 903 m_minWidth = 0; |
| 871 m_maxWidth = 0; | 904 m_maxWidth = 0; |
| 872 m_firstLineMinWidth = 0; | 905 m_firstLineMinWidth = 0; |
| 873 m_lastLineLineMinWidth = 0; | 906 m_lastLineLineMinWidth = 0; |
| 874 | 907 |
| 875 if (isBR()) | 908 if (isBR()) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 894 bool isSpace = false; | 927 bool isSpace = false; |
| 895 bool firstWord = true; | 928 bool firstWord = true; |
| 896 bool firstLine = true; | 929 bool firstLine = true; |
| 897 int nextBreakable = -1; | 930 int nextBreakable = -1; |
| 898 int lastWordBoundary = 0; | 931 int lastWordBoundary = 0; |
| 899 float cachedWordTrailingSpaceWidth[2] = { 0, 0 }; // LTR, RTL | 932 float cachedWordTrailingSpaceWidth[2] = { 0, 0 }; // LTR, RTL |
| 900 | 933 |
| 901 bool breakAll = (styleToUse.wordBreak() == BreakAllWordBreak || styleToUse.w
ordBreak() == BreakWordBreak) && styleToUse.autoWrap(); | 934 bool breakAll = (styleToUse.wordBreak() == BreakAllWordBreak || styleToUse.w
ordBreak() == BreakWordBreak) && styleToUse.autoWrap(); |
| 902 bool keepAll = styleToUse.wordBreak() == KeepAllWordBreak && styleToUse.auto
Wrap(); | 935 bool keepAll = styleToUse.wordBreak() == KeepAllWordBreak && styleToUse.auto
Wrap(); |
| 903 | 936 |
| 937 Hyphenation* hyphenation = styleToUse.getHyphens() == HyphensAuto |
| 938 ? Hyphenation::get(f.getFontDescription().locale()) : nullptr; |
| 939 bool disableSoftHyphen = styleToUse.getHyphens() == HyphensNone; |
| 940 float maxWordWidth = 0; |
| 941 if (!hyphenation) |
| 942 maxWordWidth = std::numeric_limits<float>::max(); |
| 943 |
| 904 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; | 944 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; |
| 905 BidiCharacterRun* run; | 945 BidiCharacterRun* run; |
| 906 TextDirection textDirection = styleToUse.direction(); | 946 TextDirection textDirection = styleToUse.direction(); |
| 907 if ((is8Bit() && textDirection == LTR) || isOverride(styleToUse.unicodeBidi(
))) { | 947 if ((is8Bit() && textDirection == LTR) || isOverride(styleToUse.unicodeBidi(
))) { |
| 908 run = 0; | 948 run = 0; |
| 909 } else { | 949 } else { |
| 910 TextRun textRun(text()); | 950 TextRun textRun(text()); |
| 911 BidiStatus status(textDirection, false); | 951 BidiStatus status(textDirection, false); |
| 912 bidiResolver.setStatus(status); | 952 bidiResolver.setStatus(status); |
| 913 bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&textRun,
0)); | 953 bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&textRun,
0)); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 | 1007 |
| 968 if (ignoringSpaces && !isSpace) | 1008 if (ignoringSpaces && !isSpace) |
| 969 ignoringSpaces = false; | 1009 ignoringSpaces = false; |
| 970 | 1010 |
| 971 // Ignore spaces and soft hyphens | 1011 // Ignore spaces and soft hyphens |
| 972 if (ignoringSpaces) { | 1012 if (ignoringSpaces) { |
| 973 ASSERT(lastWordBoundary == i); | 1013 ASSERT(lastWordBoundary == i); |
| 974 lastWordBoundary++; | 1014 lastWordBoundary++; |
| 975 continue; | 1015 continue; |
| 976 } | 1016 } |
| 977 if (c == softHyphenCharacter) { | 1017 if (c == softHyphenCharacter && !disableSoftHyphen) { |
| 978 currMaxWidth += widthFromFont(f, lastWordBoundary, i - lastWordBound
ary, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBounds); | 1018 currMaxWidth += widthFromFont(f, lastWordBoundary, i - lastWordBound
ary, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBounds); |
| 979 lastWordBoundary = i + 1; | 1019 lastWordBoundary = i + 1; |
| 980 continue; | 1020 continue; |
| 981 } | 1021 } |
| 982 | 1022 |
| 983 bool hasBreak = breakIterator.isBreakable(i, nextBreakable, breakAll ? L
ineBreakType::BreakAll : keepAll ? LineBreakType::KeepAll : LineBreakType::Norma
l); | 1023 bool hasBreak = breakIterator.isBreakable(i, nextBreakable, breakAll ? L
ineBreakType::BreakAll : keepAll ? LineBreakType::KeepAll : LineBreakType::Norma
l); |
| 984 bool betweenWords = true; | 1024 bool betweenWords = true; |
| 985 int j = i; | 1025 int j = i; |
| 986 while (c != newlineCharacter && c != spaceCharacter && c != tabulationCh
aracter && (c != softHyphenCharacter)) { | 1026 while (c != newlineCharacter && c != spaceCharacter && c != tabulationCh
aracter && (c != softHyphenCharacter || disableSoftHyphen)) { |
| 987 j++; | 1027 j++; |
| 988 if (j == len) | 1028 if (j == len) |
| 989 break; | 1029 break; |
| 990 c = uncheckedCharacterAt(j); | 1030 c = uncheckedCharacterAt(j); |
| 991 if (breakIterator.isBreakable(j, nextBreakable) && characterAt(j - 1
) != softHyphenCharacter) | 1031 if (breakIterator.isBreakable(j, nextBreakable) && characterAt(j - 1
) != softHyphenCharacter) |
| 992 break; | 1032 break; |
| 993 if (breakAll) { | 1033 if (breakAll) { |
| 994 betweenWords = false; | 1034 betweenWords = false; |
| 995 break; | 1035 break; |
| 996 } | 1036 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1011 if (!cachedWordTrailingSpaceWidth[textDirection]) | 1051 if (!cachedWordTrailingSpaceWidth[textDirection]) |
| 1012 cachedWordTrailingSpaceWidth[textDirection] = f.width(constr
uctTextRun(f, &spaceCharacter, 1, styleToUse, textDirection)) + wordSpacing; | 1052 cachedWordTrailingSpaceWidth[textDirection] = f.width(constr
uctTextRun(f, &spaceCharacter, 1, styleToUse, textDirection)) + wordSpacing; |
| 1013 wordTrailingSpaceWidth = cachedWordTrailingSpaceWidth[textDirect
ion]; | 1053 wordTrailingSpaceWidth = cachedWordTrailingSpaceWidth[textDirect
ion]; |
| 1014 } | 1054 } |
| 1015 | 1055 |
| 1016 float w; | 1056 float w; |
| 1017 if (wordTrailingSpaceWidth && isSpace) { | 1057 if (wordTrailingSpaceWidth && isSpace) { |
| 1018 w = widthFromFont(f, i, wordLen + 1, leadWidth, currMaxWidth, te
xtDirection, &fallbackFonts, &glyphBounds) - wordTrailingSpaceWidth; | 1058 w = widthFromFont(f, i, wordLen + 1, leadWidth, currMaxWidth, te
xtDirection, &fallbackFonts, &glyphBounds) - wordTrailingSpaceWidth; |
| 1019 } else { | 1059 } else { |
| 1020 w = widthFromFont(f, i, wordLen, leadWidth, currMaxWidth, textDi
rection, &fallbackFonts, &glyphBounds); | 1060 w = widthFromFont(f, i, wordLen, leadWidth, currMaxWidth, textDi
rection, &fallbackFonts, &glyphBounds); |
| 1021 if (c == softHyphenCharacter) | 1061 if (c == softHyphenCharacter && !disableSoftHyphen) |
| 1022 currMinWidth += hyphenWidth(f, textDirection); | 1062 currMinWidth += hyphenWidth(f, textDirection); |
| 1023 } | 1063 } |
| 1024 | 1064 |
| 1065 if (w > maxWordWidth) { |
| 1066 int suffixStart; |
| 1067 float maxFragmentWidth = maxWordFragmentWidth(this, styleToUse,
f, textDirection, *hyphenation, i, wordLen, suffixStart); |
| 1068 if (suffixStart) { |
| 1069 float suffixWidth; |
| 1070 if (wordTrailingSpaceWidth && isSpace) |
| 1071 suffixWidth = widthFromFont(f, i + suffixStart, wordLen
- suffixStart + 1, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyp
hBounds) - wordTrailingSpaceWidth; |
| 1072 else |
| 1073 suffixWidth = widthFromFont(f, i + suffixStart, wordLen
- suffixStart, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBou
nds); |
| 1074 maxFragmentWidth = std::max(maxFragmentWidth, suffixWidth); |
| 1075 currMinWidth += maxFragmentWidth - w; |
| 1076 maxWordWidth = std::max(maxWordWidth, maxFragmentWidth); |
| 1077 } else { |
| 1078 maxWordWidth = w; |
| 1079 } |
| 1080 } |
| 1081 |
| 1025 currMinWidth += w; | 1082 currMinWidth += w; |
| 1026 if (betweenWords) { | 1083 if (betweenWords) { |
| 1027 if (lastWordBoundary == i) | 1084 if (lastWordBoundary == i) |
| 1028 currMaxWidth += w; | 1085 currMaxWidth += w; |
| 1029 else | 1086 else |
| 1030 currMaxWidth += widthFromFont(f, lastWordBoundary, j - lastW
ordBoundary, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBound
s); | 1087 currMaxWidth += widthFromFont(f, lastWordBoundary, j - lastW
ordBoundary, leadWidth, currMaxWidth, textDirection, &fallbackFonts, &glyphBound
s); |
| 1031 lastWordBoundary = j; | 1088 lastWordBoundary = j; |
| 1032 } | 1089 } |
| 1033 | 1090 |
| 1034 bool isCollapsibleWhiteSpace = (j < len) && styleToUse.isCollapsible
WhiteSpace(c); | 1091 bool isCollapsibleWhiteSpace = (j < len) && styleToUse.isCollapsible
WhiteSpace(c); |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1699 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 1756 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { |
| 1700 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box, in
validationReason); | 1757 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box, in
validationReason); |
| 1701 if (box->truncation() != cNoTruncation) { | 1758 if (box->truncation() != cNoTruncation) { |
| 1702 if (EllipsisBox* ellipsisBox = box->root().ellipsisBox()) | 1759 if (EllipsisBox* ellipsisBox = box->root().ellipsisBox()) |
| 1703 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(
*ellipsisBox, invalidationReason); | 1760 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(
*ellipsisBox, invalidationReason); |
| 1704 } | 1761 } |
| 1705 } | 1762 } |
| 1706 } | 1763 } |
| 1707 | 1764 |
| 1708 } // namespace blink | 1765 } // namespace blink |
| OLD | NEW |