Changeset 211228 in webkit
- Timestamp:
- Jan 26, 2017 1:19:38 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r211222 r211228 1 2017-01-26 Zalan Bujtas <zalan@apple.com> 2 3 Simple line layout: Add support for -webkit-hyphenate-limit-lines 4 https://bugs.webkit.org/show_bug.cgi?id=167446 5 <rdar://problem/30194030> 6 7 Reviewed by Antti Koivisto. 8 9 * fast/text/simple-line-layout-hyphen-limit-lines-expected.html: Added. 10 * fast/text/simple-line-layout-hyphen-limit-lines.html: Added. 11 * fast/text/simple-line-layout-hyphen-limit-lines2-expected.html: Added. 12 * fast/text/simple-line-layout-hyphen-limit-lines2.html: Added. 13 * platform/mac/fast/text/hyphenate-limit-lines-expected.txt: progression 14 1 15 2017-01-26 Zalan Bujtas <zalan@apple.com> 2 16 -
trunk/LayoutTests/platform/mac/fast/text/hyphenate-limit-lines-expected.txt
r177774 r211228 1 layer at (0,0) size 785x10 661 layer at (0,0) size 785x1035 2 2 RenderView at (0,0) size 785x600 3 layer at (0,0) size 785x10 664 RenderBlock {HTML} at (0,0) size 785x10 663 layer at (0,0) size 785x1035 4 RenderBlock {HTML} at (0,0) size 785x1035 5 5 RenderBody {BODY} at (8,8) size 769x584 6 6 RenderBlock (floating) {DIV} at (4,0) size 202x498 [border: (1px solid #ADD8E6)] … … 48 48 text run at (1,466) width 109: "vented by " 49 49 text run at (109,466) width 61: "Plato." 50 RenderBlock (floating) {DIV} at (424,0) size 202x 529[border: (1px solid #ADD8E6)]51 RenderText {#text} at (1,1) size 200x 52750 RenderBlock (floating) {DIV} at (424,0) size 202x498 [border: (1px solid #ADD8E6)] 51 RenderText {#text} at (1,1) size 200x496 52 52 text run at (1,1) width 200: "also the division of" 53 53 text run at (1,32) width 200: "the mind into the" … … 58 58 text run at (1,156) width 200: "pleasures and de" + hyphen string "-" 59 59 text run at (1,187) width 200: "sires into neces" + hyphen string "-" 60 text run at (1,218) width 200: "sary and" 61 text run at (1,249) width 154: "unnecessary\x{2014}" 60 text run at (1,218) width 108: "sary and " 61 text run at (108,218) width 93: "unneces" + hyphen string "-" 62 text run at (1,249) width 200: "sary\x{2014}these and" 63 text run at (1,280) width 200: "other great forms" 64 text run at (1,311) width 200: "of thought are all" 65 text run at (1,342) width 129: "of them " 66 text run at (129,342) width 72: "to be" 67 text run at (1,373) width 200: "found in the Re" + hyphen string "-" 68 text run at (1,404) width 200: "public, and were" 69 text run at (1,435) width 200: "probably first in" + hyphen string "-" 70 text run at (1,466) width 109: "vented by " 71 text run at (109,466) width 61: "Plato." 72 RenderBlock (floating) {DIV} at (4,498) size 202x498 [border: (1px solid #ADD8E6)] 73 RenderText {#text} at (1,1) size 200x496 74 text run at (1,1) width 200: "also the division of" 75 text run at (1,32) width 200: "the mind into the" 76 text run at (1,63) width 200: "rational, concupis" + hyphen string "-" 77 text run at (1,94) width 112: "cent, and " 78 text run at (112,94) width 89: "irascible" 79 text run at (1,125) width 200: "elements, or of" 80 text run at (1,156) width 200: "pleasures and de" + hyphen string "-" 81 text run at (1,187) width 200: "sires into neces" + hyphen string "-" 82 text run at (1,218) width 108: "sary and " 83 text run at (108,218) width 93: "unneces" + hyphen string "-" 84 text run at (1,249) width 200: "sary\x{2014}these and" 85 text run at (1,280) width 200: "other great forms" 86 text run at (1,311) width 200: "of thought are all" 87 text run at (1,342) width 129: "of them " 88 text run at (129,342) width 72: "to be" 89 text run at (1,373) width 200: "found in the Re" + hyphen string "-" 90 text run at (1,404) width 200: "public, and were" 91 text run at (1,435) width 200: "probably first in" + hyphen string "-" 92 text run at (1,466) width 109: "vented by " 93 text run at (109,466) width 61: "Plato." 94 RenderBlock (floating) {DIV} at (214,498) size 202x529 [border: (1px solid #ADD8E6)] 95 RenderText {#text} at (1,1) size 200x527 96 text run at (1,1) width 200: "also the division of" 97 text run at (1,32) width 200: "the mind into the" 98 text run at (1,63) width 86: "rational," 99 text run at (1,94) width 200: "concupiscent, and" 100 text run at (1,125) width 200: "irascible elements," 101 text run at (1,156) width 200: "or of pleasures and" 102 text run at (1,187) width 200: "desires into" 103 text run at (1,218) width 200: "necessary and" 104 text run at (1,249) width 200: "unnecessary\x{2014}" 62 105 text run at (1,280) width 200: "these and other" 63 106 text run at (1,311) width 200: "great forms of" … … 69 112 text run at (1,466) width 200: "first invented by" 70 113 text run at (1,497) width 60: "Plato." 71 RenderBlock (floating) {DIV} at (4,529) size 202x498 [border: (1px solid #ADD8E6)]72 RenderText {#text} at (1,1) size 200x49673 text run at (1,1) width 200: "also the division of"74 text run at (1,32) width 200: "the mind into the"75 text run at (1,63) width 200: "rational, concupis" + hyphen string "-"76 text run at (1,94) width 112: "cent, and "77 text run at (112,94) width 89: "irascible"78 text run at (1,125) width 200: "elements, or of"79 text run at (1,156) width 200: "pleasures and de" + hyphen string "-"80 text run at (1,187) width 200: "sires into"81 text run at (1,218) width 166: "necessary and "82 text run at (166,218) width 35: "un" + hyphen string "-"83 text run at (1,249) width 181: "necessary\x{2014}these"84 text run at (1,280) width 200: "and other great"85 text run at (1,311) width 200: "forms of thought"86 text run at (1,342) width 180: "are all of them "87 text run at (180,342) width 21: "to"88 text run at (1,373) width 200: "be found in the"89 text run at (1,404) width 200: "Republic, and"90 text run at (1,435) width 200: "were probably first"91 text run at (1,466) width 129: "invented by "92 text run at (129,466) width 61: "Plato."93 RenderBlock (floating) {DIV} at (214,529) size 202x529 [border: (1px solid #ADD8E6)]94 RenderText {#text} at (1,1) size 200x52795 text run at (1,1) width 200: "also the division of"96 text run at (1,32) width 200: "the mind into the"97 text run at (1,63) width 86: "rational,"98 text run at (1,94) width 200: "concupiscent, and"99 text run at (1,125) width 200: "irascible elements,"100 text run at (1,156) width 200: "or of pleasures and"101 text run at (1,187) width 200: "desires into"102 text run at (1,218) width 200: "necessary and"103 text run at (1,249) width 154: "unnecessary\x{2014}"104 text run at (1,280) width 200: "these and other"105 text run at (1,311) width 200: "great forms of"106 text run at (1,342) width 200: "thought are all of"107 text run at (1,373) width 67: "them "108 text run at (67,373) width 134: "to be found"109 text run at (1,404) width 200: "in the Republic,"110 text run at (1,435) width 200: "and were probably"111 text run at (1,466) width 200: "first invented by"112 text run at (1,497) width 60: "Plato." -
trunk/Source/WebCore/ChangeLog
r211227 r211228 1 2017-01-26 Zalan Bujtas <zalan@apple.com> 2 3 Simple line layout: Add support for -webkit-hyphenate-limit-lines 4 https://bugs.webkit.org/show_bug.cgi?id=167446 5 <rdar://problem/30194030> 6 7 Reviewed by Antti Koivisto. 8 9 Now we can set the limit on the number of lines that a word can split across through hyphenation. 10 11 Tests: fast/text/simple-line-layout-hyphen-limit-lines.html 12 fast/text/simple-line-layout-hyphen-limit-lines2.html 13 14 * rendering/SimpleLineLayout.cpp: 15 (WebCore::SimpleLineLayout::canUseForStyle): 16 (WebCore::SimpleLineLayout::splitFragmentToFitLine): 17 (WebCore::SimpleLineLayout::printReason): 18 * rendering/SimpleLineLayoutTextFragmentIterator.cpp: 19 (WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style): 20 * rendering/SimpleLineLayoutTextFragmentIterator.h: 21 (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::TextFragment): 22 (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::wrappingWithHyphenCounter): 23 (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::splitWithHyphen): The right side of the split has +1 on the wrapping counter. 24 1 25 2017-01-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 26 -
trunk/Source/WebCore/rendering/SimpleLineLayout.cpp
r211222 r211228 87 87 FlowHasLineAlignEdges = 1LLU << 21, 88 88 FlowHasLineSnap = 1LLU << 22, 89 FlowHasHypensLineLimit = 1LLU << 23, 90 FlowHasTextEmphasisFillOrMark = 1LLU << 24, 91 FlowHasTextShadow = 1LLU << 25, 92 FlowHasPseudoFirstLine = 1LLU << 26, 93 FlowHasPseudoFirstLetter = 1LLU << 27, 94 FlowHasTextCombine = 1LLU << 28, 95 FlowHasTextFillBox = 1LLU << 29, 96 FlowHasBorderFitLines = 1LLU << 30, 97 FlowHasNonAutoLineBreak = 1LLU << 31, 98 FlowHasNonAutoTrailingWord = 1LLU << 32, 99 FlowHasSVGFont = 1LLU << 33, 100 FlowTextIsEmpty = 1LLU << 34, 101 FlowTextHasSoftHyphen = 1LLU << 35, 102 FlowTextHasDirectionCharacter = 1LLU << 36, 103 FlowIsMissingPrimaryFont = 1LLU << 37, 104 FlowFontIsMissingGlyph = 1LLU << 38, 105 FlowTextIsCombineText = 1LLU << 39, 106 FlowTextIsRenderCounter = 1LLU << 40, 107 FlowTextIsRenderQuote = 1LLU << 41, 108 FlowTextIsTextFragment = 1LLU << 42, 109 FlowTextIsSVGInlineText = 1LLU << 43, 110 FlowFontIsNotSimple = 1LLU << 44, 111 FeatureIsDisabled = 1LLU << 45, 112 FlowHasNoParent = 1LLU << 46, 113 FlowHasNoChild = 1LLU << 47, 114 FlowChildIsSelected = 1LLU << 48, 115 FlowHasHangingPunctuation = 1LLU << 49, 116 EndOfReasons = 1LLU << 50 89 FlowHasTextEmphasisFillOrMark = 1LLU << 23, 90 FlowHasTextShadow = 1LLU << 24, 91 FlowHasPseudoFirstLine = 1LLU << 25, 92 FlowHasPseudoFirstLetter = 1LLU << 26, 93 FlowHasTextCombine = 1LLU << 27, 94 FlowHasTextFillBox = 1LLU << 28, 95 FlowHasBorderFitLines = 1LLU << 29, 96 FlowHasNonAutoLineBreak = 1LLU << 30, 97 FlowHasNonAutoTrailingWord = 1LLU << 31, 98 FlowHasSVGFont = 1LLU << 32, 99 FlowTextIsEmpty = 1LLU << 33, 100 FlowTextHasSoftHyphen = 1LLU << 34, 101 FlowTextHasDirectionCharacter = 1LLU << 35, 102 FlowIsMissingPrimaryFont = 1LLU << 36, 103 FlowFontIsMissingGlyph = 1LLU << 37, 104 FlowTextIsCombineText = 1LLU << 38, 105 FlowTextIsRenderCounter = 1LLU << 39, 106 FlowTextIsRenderQuote = 1LLU << 40, 107 FlowTextIsTextFragment = 1LLU << 41, 108 FlowTextIsSVGInlineText = 1LLU << 42, 109 FlowFontIsNotSimple = 1LLU << 43, 110 FeatureIsDisabled = 1LLU << 44, 111 FlowHasNoParent = 1LLU << 45, 112 FlowHasNoChild = 1LLU << 46, 113 FlowChildIsSelected = 1LLU << 47, 114 FlowHasHangingPunctuation = 1LLU << 48, 115 EndOfReasons = 1LLU << 49 117 116 }; 118 117 const unsigned NoReason = 0; … … 238 237 if (style.lineSnap() != LineSnapNone) 239 238 SET_REASON_AND_RETURN_IF_NEEDED(FlowHasLineSnap, reasons, includeReasons); 240 if (style.hyphenationLimitLines() != RenderStyle::initialHyphenationLimitLines())241 SET_REASON_AND_RETURN_IF_NEEDED(FlowHasHypensLineLimit, reasons, includeReasons);242 239 if (style.textEmphasisFill() != TextEmphasisFillFilled || style.textEmphasisMark() != TextEmphasisMarkNone) 243 240 SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextEmphasisFillOrMark, reasons, includeReasons); … … 618 615 } 619 616 617 static std::optional<unsigned> hyphenPositionForFragment(unsigned splitPosition, TextFragmentIterator::TextFragment& fragmentToSplit, 618 const TextFragmentIterator& textFragmentIterator, float availableWidth) 619 { 620 auto& style = textFragmentIterator.style(); 621 bool shouldHyphenate = style.shouldHyphenate && (!style.hyphenLimitLines || fragmentToSplit.wrappingWithHyphenCounter() < *style.hyphenLimitLines); 622 if (!shouldHyphenate) 623 return std::nullopt; 624 625 if (!enoughWidthForHyphenation(availableWidth, style.font.pixelSize())) 626 return std::nullopt; 627 628 // We might be able to fit the hyphen at the split position. 629 auto splitPositionWithHyphen = splitPosition; 630 // Find a splitting position where hyphen surely fits. 631 unsigned start = fragmentToSplit.start(); 632 auto leftSideWidth = textFragmentIterator.textWidth(start, splitPosition, 0); 633 while (leftSideWidth + style.hyphenStringWidth > availableWidth) { 634 if (--splitPositionWithHyphen <= start) 635 return std::nullopt; // No space for hyphen. 636 leftSideWidth -= textFragmentIterator.textWidth(splitPositionWithHyphen, splitPositionWithHyphen + 1, 0); 637 } 638 ASSERT(splitPositionWithHyphen > start); 639 return textFragmentIterator.lastHyphenPosition(fragmentToSplit, splitPositionWithHyphen + 1); 640 } 641 620 642 static TextFragmentIterator::TextFragment splitFragmentToFitLine(TextFragmentIterator::TextFragment& fragmentToSplit, float availableWidth, bool keepAtLeastOneCharacter, const TextFragmentIterator& textFragmentIterator) 621 643 { … … 627 649 }); 628 650 unsigned splitPosition = (*it); 629 auto& style = textFragmentIterator.style();630 651 // Does first character fit this line? 631 if (splitPosition == fragmentToSplit.start()) {652 if (splitPosition == start) { 632 653 if (keepAtLeastOneCharacter) 633 654 ++splitPosition; 634 } else if (style.shouldHyphenate && enoughWidthForHyphenation(availableWidth, style.font.pixelSize())) { 635 // We might be able to fit the hyphen at the split position. 636 auto splitPositionWithHyphen = splitPosition; 637 // Find a splitting position where hyphen surely fits. 638 auto leftSideWidth = textFragmentIterator.textWidth(start, splitPosition, 0); 639 while (leftSideWidth + style.hyphenStringWidth > availableWidth) { 640 if (--splitPositionWithHyphen <= start) 641 break; // No space for hyphen. 642 leftSideWidth -= textFragmentIterator.textWidth(splitPositionWithHyphen, splitPositionWithHyphen + 1, 0); 643 } 644 if (splitPositionWithHyphen > start) { 645 if (auto hyphenPosition = textFragmentIterator.lastHyphenPosition(fragmentToSplit, splitPositionWithHyphen + 1)) 646 return fragmentToSplit.splitWithHyphen(*hyphenPosition, textFragmentIterator); 647 } 648 } 655 } else if (auto hyphenPosition = hyphenPositionForFragment(splitPosition, fragmentToSplit, textFragmentIterator, availableWidth)) 656 return fragmentToSplit.splitWithHyphen(*hyphenPosition, textFragmentIterator); 649 657 return fragmentToSplit.split(splitPosition, textFragmentIterator); 650 658 } … … 990 998 stream << "-webkit-line-snap property"; 991 999 break; 992 case FlowHasHypensLineLimit:993 stream << "-webkit-hyphenate-limit-lines property";994 break;995 1000 case FlowHasTextEmphasisFillOrMark: 996 1001 stream << "text-emphasis (fill/mark)"; -
trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp
r211222 r211228 54 54 , locale(style.locale()) 55 55 { 56 if (style.hyphenationLimitLines() > -1) 57 hyphenLimitLines = style.hyphenationLimitLines(); 56 58 } 57 59 -
trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h
r211222 r211228 44 44 enum Type { ContentEnd, SoftLineBreak, HardLineBreak, Whitespace, NonWhitespace }; 45 45 TextFragment() = default; 46 TextFragment(unsigned start, unsigned end, float width, Type type, bool isLastInRenderer = false, bool overlapsToNextRenderer = false, bool isCollapsed = false, bool isCollapsible = false , bool hasHyphen = false)46 TextFragment(unsigned start, unsigned end, float width, Type type, bool isLastInRenderer = false, bool overlapsToNextRenderer = false, bool isCollapsed = false, bool isCollapsible = false) 47 47 : m_start(start) 48 48 , m_end(end) … … 53 53 , m_isCollapsed(isCollapsed) 54 54 , m_isCollapsible(isCollapsible) 55 , m_hasHyphen(hasHyphen)56 55 { 57 56 } … … 67 66 bool isCollapsible() const { return m_isCollapsible; } 68 67 bool hasHyphen() const { return m_hasHyphen; } 68 unsigned wrappingWithHyphenCounter() const { return m_hyphenationCounter; } 69 69 70 70 bool isEmpty() const { return start() == end() && !isLineBreak(); } … … 94 94 bool m_isCollapsible { false }; 95 95 bool m_hasHyphen { false }; 96 unsigned m_hyphenationCounter { 0 }; 96 97 }; 97 98 TextFragment nextTextFragment(float xPosition = 0); … … 122 123 unsigned hyphenLimitAfter; 123 124 AtomicString locale; 125 std::optional<unsigned> hyphenLimitLines; 124 126 }; 125 127 const Style& style() const { return m_style; } … … 169 171 ASSERT(textFragmentIterator.style().shouldHyphenate); 170 172 auto rightSide = split(hyphenPosition, textFragmentIterator); 173 rightSide.m_hyphenationCounter = m_hyphenationCounter + 1; 171 174 m_hasHyphen = true; 172 175 m_width += textFragmentIterator.style().hyphenStringWidth;
Note: See TracChangeset
for help on using the changeset viewer.