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

Side by Side Diff: Source/core/rendering/RenderBlockLineLayout.cpp

Issue 17434006: Breaking whitespace in a white-space:pre-wrap should never go on the new line. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: address review feedback Created 7 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
« no previous file with comments | « LayoutTests/fast/text/whitespace/pre-wrap-no-space-at-start-of-line-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. All r ight reserved. 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ight reserved.
4 * Copyright (C) 2010 Google Inc. All rights reserved. 4 * Copyright (C) 2010 Google Inc. All rights reserved.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 2625 matching lines...) Expand 10 before | Expand all | Expand 10 after
2636 2636
2637 // This variable is used only if whitespace isn't set to PRE, and it tells u s whether 2637 // This variable is used only if whitespace isn't set to PRE, and it tells u s whether
2638 // or not we are currently ignoring whitespace. 2638 // or not we are currently ignoring whitespace.
2639 bool ignoringSpaces = false; 2639 bool ignoringSpaces = false;
2640 InlineIterator ignoreStart; 2640 InlineIterator ignoreStart;
2641 2641
2642 // This variable tracks whether the very last character we saw was a space. We use 2642 // This variable tracks whether the very last character we saw was a space. We use
2643 // this to detect when we encounter a second space so we know we have to ter minate 2643 // this to detect when we encounter a second space so we know we have to ter minate
2644 // a run. 2644 // a run.
2645 bool currentCharacterIsSpace = false; 2645 bool currentCharacterIsSpace = false;
2646 bool currentCharacterShouldCollapseIfPreWap = false;
2646 TrailingObjects trailingObjects; 2647 TrailingObjects trailingObjects;
2647 2648
2648 InlineIterator lBreak = resolver.position(); 2649 InlineIterator lBreak = resolver.position();
2649 2650
2650 // FIXME: It is error-prone to split the position object out like this. 2651 // FIXME: It is error-prone to split the position object out like this.
2651 // Teach this code to work with objects instead of this split tuple. 2652 // Teach this code to work with objects instead of this split tuple.
2652 InlineIterator current = resolver.position(); 2653 InlineIterator current = resolver.position();
2653 RenderObject* last = current.m_obj; 2654 RenderObject* last = current.m_obj;
2654 bool atStart = true; 2655 bool atStart = true;
2655 2656
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2767 // line box to affect the height of the line if the rest of the line is not empty. 2768 // line box to affect the height of the line if the rest of the line is not empty.
2768 if (requiresLineBox) 2769 if (requiresLineBox)
2769 lineInfo.setEmpty(false, m_block, &width); 2770 lineInfo.setEmpty(false, m_block, &width);
2770 if (ignoringSpaces) { 2771 if (ignoringSpaces) {
2771 trailingObjects.clear(); 2772 trailingObjects.clear();
2772 ensureLineBoxInsideIgnoredSpaces(lineMidpointState, current. m_obj); 2773 ensureLineBoxInsideIgnoredSpaces(lineMidpointState, current. m_obj);
2773 } else if (blockStyle->collapseWhiteSpace() && resolver.position ().m_obj == current.m_obj 2774 } else if (blockStyle->collapseWhiteSpace() && resolver.position ().m_obj == current.m_obj
2774 && shouldSkipWhitespaceAfterStartObject(m_block, current.m_o bj, lineMidpointState)) { 2775 && shouldSkipWhitespaceAfterStartObject(m_block, current.m_o bj, lineMidpointState)) {
2775 // Like with list markers, we start ignoring spaces to make sure that any 2776 // Like with list markers, we start ignoring spaces to make sure that any
2776 // additional spaces we see will be discarded. 2777 // additional spaces we see will be discarded.
2777 currentCharacterIsSpace = true; 2778 currentCharacterShouldCollapseIfPreWap = currentCharacterIsS pace = true;
2778 ignoringSpaces = true; 2779 ignoringSpaces = true;
2779 } 2780 }
2780 } 2781 }
2781 2782
2782 width.addUncommittedWidth(inlineLogicalWidth(current.m_obj) + border PaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox)); 2783 width.addUncommittedWidth(inlineLogicalWidth(current.m_obj) + border PaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox));
2783 } else if (current.m_obj->isReplaced()) { 2784 } else if (current.m_obj->isReplaced()) {
2784 RenderBox* replacedBox = toRenderBox(current.m_obj); 2785 RenderBox* replacedBox = toRenderBox(current.m_obj);
2785 2786
2786 if (atStart) 2787 if (atStart)
2787 width.updateAvailableWidth(replacedBox->logicalHeight()); 2788 width.updateAvailableWidth(replacedBox->logicalHeight());
2788 2789
2789 // Break on replaced elements if either has normal white-space. 2790 // Break on replaced elements if either has normal white-space.
2790 if ((autoWrap || RenderStyle::autoWrap(lastWS)) && (!current.m_obj-> isImage() || allowImagesToBreak)) { 2791 if ((autoWrap || RenderStyle::autoWrap(lastWS)) && (!current.m_obj-> isImage() || allowImagesToBreak)) {
2791 width.commit(); 2792 width.commit();
2792 lBreak.moveToStartOf(current.m_obj); 2793 lBreak.moveToStartOf(current.m_obj);
2793 } 2794 }
2794 2795
2795 if (ignoringSpaces) 2796 if (ignoringSpaces)
2796 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, current. m_obj, 0)); 2797 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, current. m_obj, 0));
2797 2798
2798 lineInfo.setEmpty(false, m_block, &width); 2799 lineInfo.setEmpty(false, m_block, &width);
2799 ignoringSpaces = false; 2800 ignoringSpaces = false;
2800 currentCharacterIsSpace = false; 2801 currentCharacterShouldCollapseIfPreWap = currentCharacterIsSpace = f alse;
2801 trailingObjects.clear(); 2802 trailingObjects.clear();
2802 2803
2803 // Optimize for a common case. If we can't find whitespace after the list 2804 // Optimize for a common case. If we can't find whitespace after the list
2804 // item, then this is all moot. 2805 // item, then this is all moot.
2805 LayoutUnit replacedLogicalWidth = m_block->logicalWidthForChild(repl acedBox) + m_block->marginStartForChild(replacedBox) + m_block->marginEndForChil d(replacedBox) + inlineLogicalWidth(current.m_obj); 2806 LayoutUnit replacedLogicalWidth = m_block->logicalWidthForChild(repl acedBox) + m_block->marginStartForChild(replacedBox) + m_block->marginEndForChil d(replacedBox) + inlineLogicalWidth(current.m_obj);
2806 if (current.m_obj->isListMarker()) { 2807 if (current.m_obj->isListMarker()) {
2807 if (blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfte rStartObject(m_block, current.m_obj, lineMidpointState)) { 2808 if (blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfte rStartObject(m_block, current.m_obj, lineMidpointState)) {
2808 // Like with inline flows, we start ignoring spaces to make sure that any 2809 // Like with inline flows, we start ignoring spaces to make sure that any
2809 // additional spaces we see will be discarded. 2810 // additional spaces we see will be discarded.
2810 currentCharacterIsSpace = true; 2811 currentCharacterShouldCollapseIfPreWap = currentCharacterIsS pace = true;
2811 ignoringSpaces = true; 2812 ignoringSpaces = true;
2812 } 2813 }
2813 if (toRenderListMarker(current.m_obj)->isInside()) 2814 if (toRenderListMarker(current.m_obj)->isInside())
2814 width.addUncommittedWidth(replacedLogicalWidth); 2815 width.addUncommittedWidth(replacedLogicalWidth);
2815 } else 2816 } else
2816 width.addUncommittedWidth(replacedLogicalWidth); 2817 width.addUncommittedWidth(replacedLogicalWidth);
2817 if (current.m_obj->isRubyRun()) 2818 if (current.m_obj->isRubyRun())
2818 width.applyOverhang(toRenderRubyRun(current.m_obj), last, next); 2819 width.applyOverhang(toRenderRubyRun(current.m_obj), last, next);
2819 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for replaced element. 2820 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for replaced element.
2820 renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCha racter); 2821 renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCha racter);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2881 TextLayout* textLayout = renderTextInfo.m_layout.get(); 2882 TextLayout* textLayout = renderTextInfo.m_layout.get();
2882 2883
2883 // Non-zero only when kerning is enabled and TextLayout isn't used, in which case we measure 2884 // Non-zero only when kerning is enabled and TextLayout isn't used, in which case we measure
2884 // words with their trailing space, then subtract its width. 2885 // words with their trailing space, then subtract its width.
2885 float wordTrailingSpaceWidth = (f.typesettingFeatures() & Kerning) & & !textLayout ? f.width(constructTextRun(t, f, &space, 1, style)) + wordSpacing : 0; 2886 float wordTrailingSpaceWidth = (f.typesettingFeatures() & Kerning) & & !textLayout ? f.width(constructTextRun(t, f, &space, 1, style)) + wordSpacing : 0;
2886 2887
2887 UChar lastCharacter = renderTextInfo.m_lineBreakIterator.lastCharact er(); 2888 UChar lastCharacter = renderTextInfo.m_lineBreakIterator.lastCharact er();
2888 UChar secondToLastCharacter = renderTextInfo.m_lineBreakIterator.sec ondToLastCharacter(); 2889 UChar secondToLastCharacter = renderTextInfo.m_lineBreakIterator.sec ondToLastCharacter();
2889 for (; current.m_pos < t->textLength(); current.fastIncrementInTextN ode()) { 2890 for (; current.m_pos < t->textLength(); current.fastIncrementInTextN ode()) {
2890 bool previousCharacterIsSpace = currentCharacterIsSpace; 2891 bool previousCharacterIsSpace = currentCharacterIsSpace;
2892 bool previousCharacterShouldCollapseIfPreWap = currentCharacterS houldCollapseIfPreWap;
2891 UChar c = current.current(); 2893 UChar c = current.current();
2892 currentCharacterIsSpace = c == ' ' || c == '\t' || (!preserveNew line && (c == '\n')); 2894 currentCharacterShouldCollapseIfPreWap = currentCharacterIsSpace = c == ' ' || c == '\t' || (!preserveNewline && (c == '\n'));
2893 2895
2894 if (!collapseWhiteSpace || !currentCharacterIsSpace) 2896 if (!collapseWhiteSpace || !currentCharacterIsSpace)
2895 lineInfo.setEmpty(false, m_block, &width); 2897 lineInfo.setEmpty(false, m_block, &width);
2896 2898
2897 if (c == softHyphen && autoWrap && !hyphenWidth && style->hyphen s() != HyphensNone) { 2899 if (c == softHyphen && autoWrap && !hyphenWidth && style->hyphen s() != HyphensNone) {
2898 hyphenWidth = measureHyphenWidth(t, f); 2900 hyphenWidth = measureHyphenWidth(t, f);
2899 width.addUncommittedWidth(hyphenWidth); 2901 width.addUncommittedWidth(hyphenWidth);
2900 } 2902 }
2901 2903
2902 bool applyWordSpacing = false; 2904 bool applyWordSpacing = false;
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 // Force creation of new InlineBoxes for each absolute posit ioned character (those that start new text chunks). 3068 // Force creation of new InlineBoxes for each absolute posit ioned character (those that start new text chunks).
3067 if (toRenderSVGInlineText(t)->characterStartsNewTextChunk(cu rrent.m_pos)) 3069 if (toRenderSVGInlineText(t)->characterStartsNewTextChunk(cu rrent.m_pos))
3068 ensureCharacterGetsLineBox(lineMidpointState, current); 3070 ensureCharacterGetsLineBox(lineMidpointState, current);
3069 } 3071 }
3070 3072
3071 if (currentCharacterIsSpace && !previousCharacterIsSpace) { 3073 if (currentCharacterIsSpace && !previousCharacterIsSpace) {
3072 ignoreStart.m_obj = current.m_obj; 3074 ignoreStart.m_obj = current.m_obj;
3073 ignoreStart.m_pos = current.m_pos; 3075 ignoreStart.m_pos = current.m_pos;
3074 } 3076 }
3075 3077
3076 if (!currentCharacterIsSpace && previousCharacterIsSpace) { 3078 if (!currentCharacterIsSpace && previousCharacterShouldCollapseI fPreWap) {
3077 if (autoWrap && currentStyle->breakOnlyAfterWhiteSpace()) 3079 if (autoWrap && currentStyle->breakOnlyAfterWhiteSpace())
3078 lBreak.moveTo(current.m_obj, current.m_pos, current.m_ne xtBreakablePosition); 3080 lBreak.moveTo(current.m_obj, current.m_pos, current.m_ne xtBreakablePosition);
3079 } 3081 }
3080 3082
3081 if (collapseWhiteSpace && currentCharacterIsSpace && !ignoringSp aces) 3083 if (collapseWhiteSpace && currentCharacterIsSpace && !ignoringSp aces)
3082 trailingObjects.setTrailingWhitespace(toRenderText(current.m _obj)); 3084 trailingObjects.setTrailingWhitespace(toRenderText(current.m _obj));
3083 else if (!currentStyle->collapseWhiteSpace() || !currentCharacte rIsSpace) 3085 else if (!currentStyle->collapseWhiteSpace() || !currentCharacte rIsSpace)
3084 trailingObjects.clear(); 3086 trailingObjects.clear();
3085 3087
3086 atStart = false; 3088 atStart = false;
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
3397 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver ticalPositionCache); 3399 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver ticalPositionCache);
3398 3400
3399 setLineGridBox(lineGridBox); 3401 setLineGridBox(lineGridBox);
3400 3402
3401 // FIXME: If any of the characteristics of the box change compared to the ol d one, then we need to do a deep dirtying 3403 // FIXME: If any of the characteristics of the box change compared to the ol d one, then we need to do a deep dirtying
3402 // (similar to what happens when the page height changes). Ideally, though, we only do this if someone is actually snapping 3404 // (similar to what happens when the page height changes). Ideally, though, we only do this if someone is actually snapping
3403 // to this grid. 3405 // to this grid.
3404 } 3406 }
3405 3407
3406 } 3408 }
OLDNEW
« no previous file with comments | « LayoutTests/fast/text/whitespace/pre-wrap-no-space-at-start-of-line-expected.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698