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

Side by Side Diff: third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h

Issue 2532393006: Fix break-all/word-break are applied to inline elements (Closed)
Patch Set: Support parent style at element boundaries Created 4 years 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
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/css3-text/css3-word-break/word-break-break-all-in-span-expected.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
4 * All right reserved. 4 * All right reserved.
5 * Copyright (C) 2010 Google Inc. All rights reserved. 5 * Copyright (C) 2010 Google Inc. All rights reserved.
6 * Copyright (C) 2013 Adobe Systems Incorporated. 6 * Copyright (C) 2013 Adobe Systems Incorporated.
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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 void setCurrentCharacterIsSpace(UChar); 154 void setCurrentCharacterIsSpace(UChar);
155 void skipTrailingWhitespace(InlineIterator&, const LineInfo&); 155 void skipTrailingWhitespace(InlineIterator&, const LineInfo&);
156 bool shouldMidWordBreak(UChar, 156 bool shouldMidWordBreak(UChar,
157 LineLayoutText, 157 LineLayoutText,
158 const Font&, 158 const Font&,
159 float& charWidth, 159 float& charWidth,
160 float& widthFromLastBreakingOpportunity, 160 float& widthFromLastBreakingOpportunity,
161 bool breakAll, 161 bool breakAll,
162 int& nextBreakablePositionForBreakAll); 162 int& nextBreakablePositionForBreakAll);
163 bool rewindToMidWordBreak(WordMeasurement&, int end, float width); 163 bool rewindToMidWordBreak(WordMeasurement&, int end, float width);
164 bool canMidWordBreakBefore(LineLayoutText);
164 bool rewindToFirstMidWordBreak(LineLayoutText, 165 bool rewindToFirstMidWordBreak(LineLayoutText,
165 const ComputedStyle&, 166 const ComputedStyle&,
166 const Font&, 167 const Font&,
167 bool breakAll, 168 bool breakAll,
168 WordMeasurement&); 169 WordMeasurement&);
169 bool rewindToMidWordBreak(LineLayoutText, 170 bool rewindToMidWordBreak(LineLayoutText,
170 const ComputedStyle&, 171 const ComputedStyle&,
171 const Font&, 172 const Font&,
172 bool breakAll, 173 bool breakAll,
173 WordMeasurement&); 174 WordMeasurement&);
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 wordMeasurement.width = width; 748 wordMeasurement.width = width;
748 749
749 m_current.moveTo(m_current.getLineLayoutItem(), end, 750 m_current.moveTo(m_current.getLineLayoutItem(), end,
750 m_current.nextBreakablePosition()); 751 m_current.nextBreakablePosition());
751 setCurrentCharacterIsSpace(m_current.current()); 752 setCurrentCharacterIsSpace(m_current.current());
752 m_lineBreak.moveTo(m_current.getLineLayoutItem(), end, 753 m_lineBreak.moveTo(m_current.getLineLayoutItem(), end,
753 m_current.nextBreakablePosition()); 754 m_current.nextBreakablePosition());
754 return true; 755 return true;
755 } 756 }
756 757
758 ALWAYS_INLINE bool BreakingContext::canMidWordBreakBefore(LineLayoutText text) {
759 // No break opportunities at the beginning of a line.
760 if (!m_width.currentWidth())
761 return false;
762 // If this text node is not the first child of an inline, the parent and the
763 // preivous have the same style.
764 if (text.previousSibling())
765 return true;
766 // Element boundaries belong to the parent of the element.
767 // TODO(kojii): Not all cases of element boundaries are supported yet.
768 // crbug.com/282134
769 if (LineLayoutItem element = text.parent()) {
770 if (LineLayoutItem parent = element.parent()) {
771 const ComputedStyle& parentStyle = parent.styleRef();
772 return parentStyle.autoWrap() &&
773 ((parentStyle.breakWords() && !m_width.committedWidth()) ||
774 parentStyle.wordBreak() == BreakAllWordBreak);
775 }
776 }
777 return false;
778 }
779
757 ALWAYS_INLINE bool BreakingContext::rewindToFirstMidWordBreak( 780 ALWAYS_INLINE bool BreakingContext::rewindToFirstMidWordBreak(
758 LineLayoutText text, 781 LineLayoutText text,
759 const ComputedStyle& style, 782 const ComputedStyle& style,
760 const Font& font, 783 const Font& font,
761 bool breakAll, 784 bool breakAll,
762 WordMeasurement& wordMeasurement) { 785 WordMeasurement& wordMeasurement) {
763 int start = wordMeasurement.startOffset; 786 int start = wordMeasurement.startOffset;
764 int end; 787 int end = canMidWordBreakBefore(text) ? start : start + 1;
765 if (breakAll) { 788 if (breakAll) {
766 LazyLineBreakIterator lineBreakIterator(text.text(), style.locale()); 789 LazyLineBreakIterator lineBreakIterator(text.text(), style.locale());
767 end = -1; 790 int nextBreakable = -1;
768 lineBreakIterator.isBreakable(start + 1, end, LineBreakType::BreakAll); 791 lineBreakIterator.isBreakable(end, nextBreakable, LineBreakType::BreakAll);
769 if (end < 0) 792 if (nextBreakable < 0)
770 return false; 793 return false;
771 } else { 794 end = nextBreakable;
772 end = start + 1;
773 } 795 }
774 if (end >= wordMeasurement.endOffset) 796 if (end >= wordMeasurement.endOffset)
775 return false; 797 return false;
776 798
777 float width = textWidth(text, start, end - start, font, 799 float width = textWidth(text, start, end - start, font,
778 m_width.currentWidth(), m_collapseWhiteSpace); 800 m_width.currentWidth(), m_collapseWhiteSpace);
801 // If the first break opportunity doesn't fit, and if there's a break
802 // opportunity in previous runs, break at the opportunity.
803 if (!m_width.fitsOnLine(width) && m_width.committedWidth())
804 return false;
779 return rewindToMidWordBreak(wordMeasurement, end, width); 805 return rewindToMidWordBreak(wordMeasurement, end, width);
780 } 806 }
781 807
782 ALWAYS_INLINE bool BreakingContext::rewindToMidWordBreak( 808 ALWAYS_INLINE bool BreakingContext::rewindToMidWordBreak(
783 LineLayoutText text, 809 LineLayoutText text,
784 const ComputedStyle& style, 810 const ComputedStyle& style,
785 const Font& font, 811 const Font& font,
786 bool breakAll, 812 bool breakAll,
787 WordMeasurement& wordMeasurement) { 813 WordMeasurement& wordMeasurement) {
788 int start = wordMeasurement.startOffset; 814 int start = wordMeasurement.startOffset;
789 int len = wordMeasurement.endOffset - start; 815 int len = wordMeasurement.endOffset - start;
790 if (!len) 816 if (!len)
791 return false; 817 return false;
792 if (m_width.availableWidth() <= LayoutUnit::epsilon()) 818 float xPosToBreak = m_width.availableWidth() - m_width.currentWidth();
819 if (xPosToBreak <= LayoutUnit::epsilon()) {
820 // There were no space left. Skip computing how many characters can fit.
793 return rewindToFirstMidWordBreak(text, style, font, breakAll, 821 return rewindToFirstMidWordBreak(text, style, font, breakAll,
794 wordMeasurement); 822 wordMeasurement);
823 }
795 824
796 TextRun run = constructTextRun(font, text, start, len, style); 825 TextRun run = constructTextRun(font, text, start, len, style);
797 run.setTabSize(!m_collapseWhiteSpace, style.getTabSize()); 826 run.setTabSize(!m_collapseWhiteSpace, style.getTabSize());
798 run.setXPos(m_width.currentWidth()); 827 run.setXPos(m_width.currentWidth());
799 828
800 // TODO(kojii): should be replaced with safe-to-break when hb is ready. 829 // TODO(kojii): should be replaced with safe-to-break when hb is ready.
801 float x = 830 xPosToBreak += LayoutUnit::epsilon();
802 m_width.availableWidth() + LayoutUnit::epsilon() - m_width.currentWidth();
803 if (run.rtl()) 831 if (run.rtl())
804 x = wordMeasurement.width - x; 832 xPosToBreak = wordMeasurement.width - xPosToBreak;
805 len = font.offsetForPosition(run, x, false); 833 len = font.offsetForPosition(run, xPosToBreak, false);
806 if (!len && !m_width.currentWidth()) 834 if (!len) {
835 // No characters can fit in the available space.
807 return rewindToFirstMidWordBreak(text, style, font, breakAll, 836 return rewindToFirstMidWordBreak(text, style, font, breakAll,
808 wordMeasurement); 837 wordMeasurement);
838 }
809 839
810 int end = start + len; 840 int end = start + len;
811 if (breakAll) { 841 if (breakAll) {
812 end = lastBreakablePositionForBreakAll(text, style, start, end); 842 end = lastBreakablePositionForBreakAll(text, style, start, end);
813 if (!end) 843 if (!end)
814 return false; 844 return false;
815 len = end - start; 845 len = end - start;
816 } 846 }
817 FloatRect rect = font.selectionRectForText(run, FloatPoint(), 0, 0, len); 847 FloatRect rect = font.selectionRectForText(run, FloatPoint(), 0, 0, len);
818 return rewindToMidWordBreak(wordMeasurement, end, rect.width()); 848 return rewindToMidWordBreak(wordMeasurement, end, rect.width());
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 1521
1492 if (style.getTextIndentType() == TextIndentHanging) 1522 if (style.getTextIndentType() == TextIndentHanging)
1493 indentText = indentText == IndentText ? DoNotIndentText : IndentText; 1523 indentText = indentText == IndentText ? DoNotIndentText : IndentText;
1494 1524
1495 return indentText; 1525 return indentText;
1496 } 1526 }
1497 1527
1498 } // namespace blink 1528 } // namespace blink
1499 1529
1500 #endif // BreakingContextInlineHeaders_h 1530 #endif // BreakingContextInlineHeaders_h
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/css3-text/css3-word-break/word-break-break-all-in-span-expected.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698