OLD | NEW |
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 * Copyright (C) 2013 Adobe Systems Incorporated. | 5 * Copyright (C) 2013 Adobe Systems Incorporated. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 #include "wtf/Vector.h" | 45 #include "wtf/Vector.h" |
46 | 46 |
47 namespace blink { | 47 namespace blink { |
48 | 48 |
49 // We don't let our line box tree for a single line get any deeper than this. | 49 // We don't let our line box tree for a single line get any deeper than this. |
50 const unsigned cMaxLineDepth = 200; | 50 const unsigned cMaxLineDepth = 200; |
51 | 51 |
52 class BreakingContext { | 52 class BreakingContext { |
53 STACK_ALLOCATED(); | 53 STACK_ALLOCATED(); |
54 public: | 54 public: |
55 BreakingContext(InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidt
h& lineWidth, LayoutTextInfo& inLayoutTextInfo, FloatingObject* inLastFloatFromP
reviousLine, bool appliedStartWidth, LineLayoutBlockFlow block) | 55 BreakingContext(InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidt
h& lineWidth, LayoutTextInfo& inLayoutTextInfo, bool appliedStartWidth, LineLayo
utBlockFlow block) |
56 : m_resolver(resolver) | 56 : m_resolver(resolver) |
57 , m_current(resolver.position()) | 57 , m_current(resolver.position()) |
58 , m_lineBreak(resolver.position()) | 58 , m_lineBreak(resolver.position()) |
59 , m_block(block) | 59 , m_block(block) |
60 , m_lastObject(m_current.getLineLayoutItem()) | 60 , m_lastObject(m_current.getLineLayoutItem()) |
61 , m_nextObject(nullptr) | 61 , m_nextObject(nullptr) |
62 , m_currentStyle(nullptr) | 62 , m_currentStyle(nullptr) |
63 , m_blockStyle(block.style()) | 63 , m_blockStyle(block.style()) |
64 , m_lineInfo(inLineInfo) | 64 , m_lineInfo(inLineInfo) |
65 , m_layoutTextInfo(inLayoutTextInfo) | 65 , m_layoutTextInfo(inLayoutTextInfo) |
66 , m_lastFloatFromPreviousLine(inLastFloatFromPreviousLine) | |
67 , m_width(lineWidth) | 66 , m_width(lineWidth) |
68 , m_currWS(NORMAL) | 67 , m_currWS(NORMAL) |
69 , m_lastWS(NORMAL) | 68 , m_lastWS(NORMAL) |
70 , m_preservesNewline(false) | 69 , m_preservesNewline(false) |
71 , m_atStart(true) | 70 , m_atStart(true) |
72 , m_ignoringSpaces(false) | 71 , m_ignoringSpaces(false) |
73 , m_currentCharacterIsSpace(false) | 72 , m_currentCharacterIsSpace(false) |
74 , m_appliedStartWidth(appliedStartWidth) | 73 , m_appliedStartWidth(appliedStartWidth) |
75 , m_includeEndWidth(true) | 74 , m_includeEndWidth(true) |
76 , m_autoWrap(false) | 75 , m_autoWrap(false) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 LineLayoutItem m_lastObject; | 128 LineLayoutItem m_lastObject; |
130 LineLayoutItem m_nextObject; | 129 LineLayoutItem m_nextObject; |
131 | 130 |
132 const ComputedStyle* m_currentStyle; | 131 const ComputedStyle* m_currentStyle; |
133 const ComputedStyle* m_blockStyle; | 132 const ComputedStyle* m_blockStyle; |
134 | 133 |
135 LineInfo& m_lineInfo; | 134 LineInfo& m_lineInfo; |
136 | 135 |
137 LayoutTextInfo& m_layoutTextInfo; | 136 LayoutTextInfo& m_layoutTextInfo; |
138 | 137 |
139 FloatingObject* m_lastFloatFromPreviousLine; | |
140 | |
141 LineWidth m_width; | 138 LineWidth m_width; |
142 | 139 |
143 EWhiteSpace m_currWS; | 140 EWhiteSpace m_currWS; |
144 EWhiteSpace m_lastWS; | 141 EWhiteSpace m_lastWS; |
145 | 142 |
146 bool m_preservesNewline; | 143 bool m_preservesNewline; |
147 bool m_atStart; | 144 bool m_atStart; |
148 bool m_ignoringSpaces; | 145 bool m_ignoringSpaces; |
149 bool m_currentCharacterIsSpace; | 146 bool m_currentCharacterIsSpace; |
150 bool m_appliedStartWidth; | 147 bool m_appliedStartWidth; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 LineLayoutItem br = m_current.getLineLayoutItem(); | 295 LineLayoutItem br = m_current.getLineLayoutItem(); |
299 m_lineBreak.moveToStartOf(br); | 296 m_lineBreak.moveToStartOf(br); |
300 m_lineBreak.increment(); | 297 m_lineBreak.increment(); |
301 | 298 |
302 // A <br> always breaks a line, so don't let the line be collapsed | 299 // A <br> always breaks a line, so don't let the line be collapsed |
303 // away. Also, the space at the end of a line with a <br> does not | 300 // away. Also, the space at the end of a line with a <br> does not |
304 // get collapsed away. It only does this if the previous line broke | 301 // get collapsed away. It only does this if the previous line broke |
305 // cleanly. Otherwise the <br> has no effect on whether the line is | 302 // cleanly. Otherwise the <br> has no effect on whether the line is |
306 // empty or not. | 303 // empty or not. |
307 if (m_startingNewParagraph) | 304 if (m_startingNewParagraph) |
308 m_lineInfo.setEmpty(false, m_block, &m_width); | 305 m_lineInfo.setEmpty(false); |
309 m_trailingObjects.clear(); | 306 m_trailingObjects.clear(); |
310 m_lineInfo.setPreviousLineBrokeCleanly(true); | 307 m_lineInfo.setPreviousLineBrokeCleanly(true); |
311 | 308 |
312 // A <br> with clearance always needs a linebox in case the lines below
it get dirtied later and | 309 // A <br> with clearance always needs a linebox in case the lines below
it get dirtied later and |
313 // need to check for floats to clear - so if we're ignoring spaces, stop
ignoring them and add a | 310 // need to check for floats to clear - so if we're ignoring spaces, stop
ignoring them and add a |
314 // run for this object. | 311 // run for this object. |
315 if (m_ignoringSpaces && m_currentStyle->clear() != ClearNone) | 312 if (m_ignoringSpaces && m_currentStyle->clear() != ClearNone) |
316 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, br); | 313 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, br); |
317 | 314 |
318 if (!m_lineInfo.isEmpty()) | 315 if (!m_lineInfo.isEmpty()) |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 | 387 |
391 inline void BreakingContext::handleFloat() | 388 inline void BreakingContext::handleFloat() |
392 { | 389 { |
393 LineLayoutBox floatBox(m_current.getLineLayoutItem()); | 390 LineLayoutBox floatBox(m_current.getLineLayoutItem()); |
394 FloatingObject* floatingObject = m_block.insertFloatingObject(floatBox); | 391 FloatingObject* floatingObject = m_block.insertFloatingObject(floatBox); |
395 // check if it fits in the current line. | 392 // check if it fits in the current line. |
396 // If it does, position it now, otherwise, position | 393 // If it does, position it now, otherwise, position |
397 // it after moving to next line (in newLine() func) | 394 // it after moving to next line (in newLine() func) |
398 // FIXME: Bug 110372: Properly position multiple stacked floats with non-rec
tangular shape outside. | 395 // FIXME: Bug 110372: Properly position multiple stacked floats with non-rec
tangular shape outside. |
399 if (m_floatsFitOnLine && m_width.fitsOnLine(m_block.logicalWidthForFloat(*fl
oatingObject).toFloat(), ExcludeWhitespace)) { | 396 if (m_floatsFitOnLine && m_width.fitsOnLine(m_block.logicalWidthForFloat(*fl
oatingObject).toFloat(), ExcludeWhitespace)) { |
400 m_block.positionNewFloatOnLine(*floatingObject, m_lastFloatFromPreviousL
ine, m_lineInfo, m_width); | 397 m_block.positionNewFloats(&m_width); |
401 if (m_lineBreak.getLineLayoutItem() == m_current.getLineLayoutItem()) { | 398 if (m_lineBreak.getLineLayoutItem() == m_current.getLineLayoutItem()) { |
402 ASSERT(!m_lineBreak.offset()); | 399 ASSERT(!m_lineBreak.offset()); |
403 m_lineBreak.increment(); | 400 m_lineBreak.increment(); |
404 } | 401 } |
405 } else { | 402 } else { |
406 m_floatsFitOnLine = false; | 403 m_floatsFitOnLine = false; |
407 } | 404 } |
408 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for floating element. | 405 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for floating element. |
409 m_layoutTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); | 406 m_layoutTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); |
410 } | 407 } |
(...skipping 26 matching lines...) Expand all Loading... |
437 // This should only end up being called on empty inlines | 434 // This should only end up being called on empty inlines |
438 ASSERT(m_current.getLineLayoutItem()); | 435 ASSERT(m_current.getLineLayoutItem()); |
439 | 436 |
440 LineLayoutInline flowBox(m_current.getLineLayoutItem()); | 437 LineLayoutInline flowBox(m_current.getLineLayoutItem()); |
441 | 438 |
442 bool requiresLineBox = alwaysRequiresLineBox(m_current.getLineLayoutItem()); | 439 bool requiresLineBox = alwaysRequiresLineBox(m_current.getLineLayoutItem()); |
443 if (requiresLineBox || requiresLineBoxForContent(flowBox, m_lineInfo)) { | 440 if (requiresLineBox || requiresLineBoxForContent(flowBox, m_lineInfo)) { |
444 // An empty inline that only has line-height, vertical-align or font-met
rics will | 441 // An empty inline that only has line-height, vertical-align or font-met
rics will |
445 // not force linebox creation (and thus affect the height of the line) i
f the rest of the line is empty. | 442 // not force linebox creation (and thus affect the height of the line) i
f the rest of the line is empty. |
446 if (requiresLineBox) | 443 if (requiresLineBox) |
447 m_lineInfo.setEmpty(false, m_block, &m_width); | 444 m_lineInfo.setEmpty(false); |
448 if (m_ignoringSpaces) { | 445 if (m_ignoringSpaces) { |
449 // If we are in a run of ignored spaces then ensure we get a linebox
if lineboxes are eventually | 446 // If we are in a run of ignored spaces then ensure we get a linebox
if lineboxes are eventually |
450 // created for the line... | 447 // created for the line... |
451 m_trailingObjects.clear(); | 448 m_trailingObjects.clear(); |
452 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, m_current.get
LineLayoutItem()); | 449 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, m_current.get
LineLayoutItem()); |
453 } else if (m_blockStyle->collapseWhiteSpace() && m_resolver.position().g
etLineLayoutItem() == m_current.getLineLayoutItem() | 450 } else if (m_blockStyle->collapseWhiteSpace() && m_resolver.position().g
etLineLayoutItem() == m_current.getLineLayoutItem() |
454 && shouldSkipWhitespaceAfterStartObject(m_block, m_current.getLineLa
youtItem(), m_lineMidpointState)) { | 451 && shouldSkipWhitespaceAfterStartObject(m_block, m_current.getLineLa
youtItem(), m_lineMidpointState)) { |
455 // If this object is at the start of the line, we need to behave lik
e list markers and | 452 // If this object is at the start of the line, we need to behave lik
e list markers and |
456 // start ignoring spaces. | 453 // start ignoring spaces. |
457 m_currentCharacterIsSpace = true; | 454 m_currentCharacterIsSpace = true; |
(...skipping 19 matching lines...) Expand all Loading... |
477 // or if the replaced element is ruby that can break before. | 474 // or if the replaced element is ruby that can break before. |
478 if ((m_autoWrap || ComputedStyle::autoWrap(m_lastWS)) && (!m_current.getLine
LayoutItem().isImage() || m_allowImagesToBreak) | 475 if ((m_autoWrap || ComputedStyle::autoWrap(m_lastWS)) && (!m_current.getLine
LayoutItem().isImage() || m_allowImagesToBreak) |
479 && (!m_current.getLineLayoutItem().isRubyRun() || LineLayoutRubyRun(m_cu
rrent.getLineLayoutItem()).canBreakBefore(m_layoutTextInfo.m_lineBreakIterator))
) { | 476 && (!m_current.getLineLayoutItem().isRubyRun() || LineLayoutRubyRun(m_cu
rrent.getLineLayoutItem()).canBreakBefore(m_layoutTextInfo.m_lineBreakIterator))
) { |
480 m_width.commit(); | 477 m_width.commit(); |
481 m_lineBreak.moveToStartOf(m_current.getLineLayoutItem()); | 478 m_lineBreak.moveToStartOf(m_current.getLineLayoutItem()); |
482 } | 479 } |
483 | 480 |
484 if (m_ignoringSpaces) | 481 if (m_ignoringSpaces) |
485 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.getLi
neLayoutItem(), 0)); | 482 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.getLi
neLayoutItem(), 0)); |
486 | 483 |
487 m_lineInfo.setEmpty(false, m_block, &m_width); | 484 m_lineInfo.setEmpty(false); |
488 m_ignoringSpaces = false; | 485 m_ignoringSpaces = false; |
489 m_currentCharacterIsSpace = false; | 486 m_currentCharacterIsSpace = false; |
490 m_trailingObjects.clear(); | 487 m_trailingObjects.clear(); |
491 | 488 |
492 // Optimize for a common case. If we can't find whitespace after the list | 489 // Optimize for a common case. If we can't find whitespace after the list |
493 // item, then this is all moot. | 490 // item, then this is all moot. |
494 LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox)
+ m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedB
ox) + inlineLogicalWidthFromAncestorsIfNeeded(m_current.getLineLayoutItem()); | 491 LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox)
+ m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedB
ox) + inlineLogicalWidthFromAncestorsIfNeeded(m_current.getLineLayoutItem()); |
495 if (m_current.getLineLayoutItem().isListMarker()) { | 492 if (m_current.getLineLayoutItem().isListMarker()) { |
496 if (m_blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfterStart
Object(m_block, m_current.getLineLayoutItem(), m_lineMidpointState)) { | 493 if (m_blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfterStart
Object(m_block, m_current.getLineLayoutItem(), m_lineMidpointState)) { |
497 // Like with inline flows, we start ignoring spaces to make sure tha
t any | 494 // Like with inline flows, we start ignoring spaces to make sure tha
t any |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 : 0; | 707 : 0; |
711 | 708 |
712 UChar lastCharacter = m_layoutTextInfo.m_lineBreakIterator.lastCharacter(); | 709 UChar lastCharacter = m_layoutTextInfo.m_lineBreakIterator.lastCharacter(); |
713 UChar secondToLastCharacter = m_layoutTextInfo.m_lineBreakIterator.secondToL
astCharacter(); | 710 UChar secondToLastCharacter = m_layoutTextInfo.m_lineBreakIterator.secondToL
astCharacter(); |
714 for (; m_current.offset() < layoutText.textLength(); m_current.fastIncrement
InTextNode()) { | 711 for (; m_current.offset() < layoutText.textLength(); m_current.fastIncrement
InTextNode()) { |
715 bool previousCharacterIsSpace = m_currentCharacterIsSpace; | 712 bool previousCharacterIsSpace = m_currentCharacterIsSpace; |
716 UChar c = m_current.current(); | 713 UChar c = m_current.current(); |
717 m_currentCharacterIsSpace = c == spaceCharacter || c == tabulationCharac
ter || (!m_preservesNewline && (c == newlineCharacter)); | 714 m_currentCharacterIsSpace = c == spaceCharacter || c == tabulationCharac
ter || (!m_preservesNewline && (c == newlineCharacter)); |
718 | 715 |
719 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace) { | 716 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace) { |
720 m_lineInfo.setEmpty(false, m_block, &m_width); | 717 m_lineInfo.setEmpty(false); |
721 m_width.setTrailingWhitespaceWidth(0); | 718 m_width.setTrailingWhitespaceWidth(0); |
722 } | 719 } |
723 | 720 |
724 if (c == softHyphenCharacter && m_autoWrap && !hyphenWidth) { | 721 if (c == softHyphenCharacter && m_autoWrap && !hyphenWidth) { |
725 hyphenWidth = layoutText.hyphenWidth(font, textDirectionFromUnicode(
m_resolver.position().direction())); | 722 hyphenWidth = layoutText.hyphenWidth(font, textDirectionFromUnicode(
m_resolver.position().direction())); |
726 m_width.addUncommittedWidth(hyphenWidth); | 723 m_width.addUncommittedWidth(hyphenWidth); |
727 } | 724 } |
728 | 725 |
729 bool applyWordSpacing = false; | 726 bool applyWordSpacing = false; |
730 | 727 |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 | 1093 |
1097 if (style.getTextIndentType() == TextIndentHanging) | 1094 if (style.getTextIndentType() == TextIndentHanging) |
1098 indentText = indentText == IndentText ? DoNotIndentText : IndentText; | 1095 indentText = indentText == IndentText ? DoNotIndentText : IndentText; |
1099 | 1096 |
1100 return indentText; | 1097 return indentText; |
1101 } | 1098 } |
1102 | 1099 |
1103 } // namespace blink | 1100 } // namespace blink |
1104 | 1101 |
1105 #endif // BreakingContextInlineHeaders_h | 1102 #endif // BreakingContextInlineHeaders_h |
OLD | NEW |