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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp

Issue 2395683002: Revert of Reformat comments in core/layout up until LayoutBox (Closed)
Patch Set: Created 4 years, 2 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
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. All r ight reserved.
4 * All right reserved.
5 * Copyright (C) 2010 Google Inc. All rights reserved. 4 * Copyright (C) 2010 Google Inc. All rights reserved.
6 * 5 *
7 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
10 * 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.
11 * 10 *
12 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 138
140 return LineLayoutInline(lineLayoutItem).createAndAppendInlineFlowBox(); 139 return LineLayoutInline(lineLayoutItem).createAndAppendInlineFlowBox();
141 } 140 }
142 141
143 static inline InlineTextBox* createInlineBoxForText(BidiRun& run, 142 static inline InlineTextBox* createInlineBoxForText(BidiRun& run,
144 bool isOnlyRun) { 143 bool isOnlyRun) {
145 ASSERT(run.m_lineLayoutItem.isText()); 144 ASSERT(run.m_lineLayoutItem.isText());
146 LineLayoutText text = LineLayoutText(run.m_lineLayoutItem); 145 LineLayoutText text = LineLayoutText(run.m_lineLayoutItem);
147 InlineTextBox* textBox = 146 InlineTextBox* textBox =
148 text.createInlineTextBox(run.m_start, run.m_stop - run.m_start); 147 text.createInlineTextBox(run.m_start, run.m_stop - run.m_start);
149 // We only treat a box as text for a <br> if we are on a line by ourself or in 148 // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode
150 // strict mode (Note the use of strict mode. In "almost strict" mode, we 149 // (Note the use of strict mode. In "almost strict" mode, we don't treat the box for <br> as text.)
151 // don't treat the box for <br> as text.)
152 if (text.isBR()) 150 if (text.isBR())
153 textBox->setIsText(isOnlyRun || text.document().inNoQuirksMode()); 151 textBox->setIsText(isOnlyRun || text.document().inNoQuirksMode());
154 textBox->setDirOverride( 152 textBox->setDirOverride(
155 run.dirOverride(text.style()->rtlOrdering() == VisualOrder)); 153 run.dirOverride(text.style()->rtlOrdering() == VisualOrder));
156 if (run.m_hasHyphen) 154 if (run.m_hasHyphen)
157 textBox->setHasHyphen(true); 155 textBox->setHasHyphen(true);
158 return textBox; 156 return textBox;
159 } 157 }
160 158
161 static inline void dirtyLineBoxesForObject(LayoutObject* o, bool fullLayout) { 159 static inline void dirtyLineBoxesForObject(LayoutObject* o, bool fullLayout) {
(...skipping 26 matching lines...) Expand all
188 ASSERT_WITH_SECURITY_IMPLICATION(lineLayoutItem.isLayoutInline() || 186 ASSERT_WITH_SECURITY_IMPLICATION(lineLayoutItem.isLayoutInline() ||
189 lineLayoutItem.isEqual(this)); 187 lineLayoutItem.isEqual(this));
190 188
191 LineLayoutInline inlineFlow(!lineLayoutItem.isEqual(this) ? lineLayoutItem 189 LineLayoutInline inlineFlow(!lineLayoutItem.isEqual(this) ? lineLayoutItem
192 : nullptr); 190 : nullptr);
193 191
194 // Get the last box we made for this layout object. 192 // Get the last box we made for this layout object.
195 parentBox = inlineFlow ? inlineFlow.lastLineBox() 193 parentBox = inlineFlow ? inlineFlow.lastLineBox()
196 : LineLayoutBlockFlow(lineLayoutItem).lastLineBox(); 194 : LineLayoutBlockFlow(lineLayoutItem).lastLineBox();
197 195
198 // If this box or its ancestor is constructed then it is from a previous 196 // If this box or its ancestor is constructed then it is from a previous lin e, and we need
199 // line, and we need to make a new box for our line. If this box or its 197 // to make a new box for our line. If this box or its ancestor is unconstru cted but it has
200 // ancestor is unconstructed but it has something following it on the line, 198 // something following it on the line, then we know we have to make a new bo x
201 // then we know we have to make a new box as well. In this situation our 199 // as well. In this situation our inline has actually been split in two on
202 // inline has actually been split in two on the same line (this can happen 200 // the same line (this can happen with very fancy language mixtures).
203 // with very fancy language mixtures).
204 bool constructedNewBox = false; 201 bool constructedNewBox = false;
205 bool allowedToConstructNewBox = 202 bool allowedToConstructNewBox =
206 !inlineFlow || inlineFlow.alwaysCreateLineBoxes(); 203 !inlineFlow || inlineFlow.alwaysCreateLineBoxes();
207 bool canUseExistingParentBox = 204 bool canUseExistingParentBox =
208 parentBox && !parentIsConstructedOrHaveNext(parentBox); 205 parentBox && !parentIsConstructedOrHaveNext(parentBox);
209 if (allowedToConstructNewBox && !canUseExistingParentBox) { 206 if (allowedToConstructNewBox && !canUseExistingParentBox) {
210 // We need to make a new box for this layout object. Once 207 // We need to make a new box for this layout object. Once
211 // made, we need to place it at the end of the current line. 208 // made, we need to place it at the end of the current line.
212 InlineBox* newBox = createInlineBoxForLayoutObject( 209 InlineBox* newBox = createInlineBoxForLayoutObject(
213 LineLayoutItem(lineLayoutItem), lineLayoutItem.isEqual(this)); 210 LineLayoutItem(lineLayoutItem), lineLayoutItem.isEqual(this));
214 ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox()); 211 ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox());
215 parentBox = toInlineFlowBox(newBox); 212 parentBox = toInlineFlowBox(newBox);
216 parentBox->setFirstLineStyleBit(lineInfo.isFirstLine()); 213 parentBox->setFirstLineStyleBit(lineInfo.isFirstLine());
217 parentBox->setIsHorizontal(isHorizontalWritingMode()); 214 parentBox->setIsHorizontal(isHorizontalWritingMode());
218 constructedNewBox = true; 215 constructedNewBox = true;
219 } 216 }
220 217
221 if (constructedNewBox || canUseExistingParentBox) { 218 if (constructedNewBox || canUseExistingParentBox) {
222 if (!result) 219 if (!result)
223 result = parentBox; 220 result = parentBox;
224 221
225 // If we have hit the block itself, then |box| represents the root 222 // If we have hit the block itself, then |box| represents the root
226 // inline box for the line, and it doesn't have to be appended to any 223 // inline box for the line, and it doesn't have to be appended to any pare nt
227 // parent inline. 224 // inline.
228 if (childBox) 225 if (childBox)
229 parentBox->addToLine(childBox); 226 parentBox->addToLine(childBox);
230 227
231 if (!constructedNewBox || lineLayoutItem.isEqual(this)) 228 if (!constructedNewBox || lineLayoutItem.isEqual(this))
232 break; 229 break;
233 230
234 childBox = parentBox; 231 childBox = parentBox;
235 } 232 }
236 233
237 // If we've exceeded our line depth, then jump straight to the root and skip 234 // If we've exceeded our line depth, then jump straight to the root and skip all the remaining
238 // all the remaining intermediate inline flows. 235 // intermediate inline flows.
239 lineLayoutItem = (++lineDepth >= cMaxLineDepth) ? LineLayoutItem(this) 236 lineLayoutItem = (++lineDepth >= cMaxLineDepth) ? LineLayoutItem(this)
240 : lineLayoutItem.parent(); 237 : lineLayoutItem.parent();
241 238
242 } while (true); 239 } while (true);
243 240
244 return result; 241 return result;
245 } 242 }
246 243
247 template <typename CharacterType> 244 template <typename CharacterType>
248 static inline bool endsWithASCIISpaces(const CharacterType* characters, 245 static inline bool endsWithASCIISpaces(const CharacterType* characters,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 299
303 ASSERT(box); 300 ASSERT(box);
304 if (!box) 301 if (!box)
305 continue; 302 continue;
306 303
307 if (!rootHasSelectedChildren && 304 if (!rootHasSelectedChildren &&
308 box->getLineLayoutItem().getSelectionState() != SelectionNone) 305 box->getLineLayoutItem().getSelectionState() != SelectionNone)
309 rootHasSelectedChildren = true; 306 rootHasSelectedChildren = true;
310 307
311 // If we have no parent box yet, or if the run is not simply a sibling, 308 // If we have no parent box yet, or if the run is not simply a sibling,
312 // then we need to construct inline boxes as necessary to properly enclose 309 // then we need to construct inline boxes as necessary to properly enclose t he
313 // the run's inline box. Segments can only be siblings at the root level, as 310 // run's inline box. Segments can only be siblings at the root level, as
314 // they are positioned separately. 311 // they are positioned separately.
315 if (!parentBox || 312 if (!parentBox ||
316 (parentBox->getLineLayoutItem() != r->m_lineLayoutItem.parent())) { 313 (parentBox->getLineLayoutItem() != r->m_lineLayoutItem.parent())) {
317 // Create new inline boxes all the way back to the appropriate insertion 314 // Create new inline boxes all the way back to the appropriate insertion p oint.
318 // point.
319 parentBox = createLineBoxes(r->m_lineLayoutItem.parent(), lineInfo, box); 315 parentBox = createLineBoxes(r->m_lineLayoutItem.parent(), lineInfo, box);
320 } else { 316 } else {
321 // Append the inline box to this line. 317 // Append the inline box to this line.
322 parentBox->addToLine(box); 318 parentBox->addToLine(box);
323 } 319 }
324 320
325 box->setBidiLevel(r->level()); 321 box->setBidiLevel(r->level());
326 322
327 if (box->isInlineTextBox()) { 323 if (box->isInlineTextBox()) {
328 if (AXObjectCache* cache = document().existingAXObjectCache()) 324 if (AXObjectCache* cache = document().existingAXObjectCache())
329 cache->inlineTextBoxesUpdated(r->m_lineLayoutItem); 325 cache->inlineTextBoxesUpdated(r->m_lineLayoutItem);
330 } 326 }
331 } 327 }
332 328
333 // We should have a root inline box. It should be unconstructed and 329 // We should have a root inline box. It should be unconstructed and
334 // be the last continuation of our line list. 330 // be the last continuation of our line list.
335 ASSERT(lastLineBox() && !lastLineBox()->isConstructed()); 331 ASSERT(lastLineBox() && !lastLineBox()->isConstructed());
336 332
337 // Set the m_selectedChildren flag on the root inline box if one of the leaf 333 // Set the m_selectedChildren flag on the root inline box if one of the leaf i nline box
338 // inline box from the bidi runs walk above has a selection state. 334 // from the bidi runs walk above has a selection state.
339 if (rootHasSelectedChildren) 335 if (rootHasSelectedChildren)
340 lastLineBox()->root().setHasSelectedChildren(true); 336 lastLineBox()->root().setHasSelectedChildren(true);
341 337
342 // Set bits on our inline flow boxes that indicate which sides should 338 // Set bits on our inline flow boxes that indicate which sides should
343 // paint borders/margins/padding. This knowledge will ultimately be used when 339 // paint borders/margins/padding. This knowledge will ultimately be used when
344 // we determine the horizontal positions and widths of all the inline boxes on 340 // we determine the horizontal positions and widths of all the inline boxes on
345 // the line. 341 // the line.
346 bool isLogicallyLastRunWrapped = 342 bool isLogicallyLastRunWrapped =
347 bidiRuns.logicallyLastRun()->m_lineLayoutItem && 343 bidiRuns.logicallyLastRun()->m_lineLayoutItem &&
348 bidiRuns.logicallyLastRun()->m_lineLayoutItem.isText() 344 bidiRuns.logicallyLastRun()->m_lineLayoutItem.isText()
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 return alignment; 383 return alignment;
388 } 384 }
389 385
390 static void updateLogicalWidthForLeftAlignedBlock( 386 static void updateLogicalWidthForLeftAlignedBlock(
391 bool isLeftToRightDirection, 387 bool isLeftToRightDirection,
392 BidiRun* trailingSpaceRun, 388 BidiRun* trailingSpaceRun,
393 LayoutUnit& logicalLeft, 389 LayoutUnit& logicalLeft,
394 LayoutUnit totalLogicalWidth, 390 LayoutUnit totalLogicalWidth,
395 LayoutUnit availableLogicalWidth) { 391 LayoutUnit availableLogicalWidth) {
396 // The direction of the block should determine what happens with wide lines. 392 // The direction of the block should determine what happens with wide lines.
397 // In particular with RTL blocks, wide lines should still spill out to the 393 // In particular with RTL blocks, wide lines should still spill out to the lef t.
398 // left.
399 if (isLeftToRightDirection) { 394 if (isLeftToRightDirection) {
400 if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) 395 if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
401 trailingSpaceRun->m_box->setLogicalWidth(std::max( 396 trailingSpaceRun->m_box->setLogicalWidth(std::max(
402 LayoutUnit(), trailingSpaceRun->m_box->logicalWidth() - 397 LayoutUnit(), trailingSpaceRun->m_box->logicalWidth() -
403 totalLogicalWidth + availableLogicalWidth)); 398 totalLogicalWidth + availableLogicalWidth));
404 return; 399 return;
405 } 400 }
406 401
407 if (trailingSpaceRun) 402 if (trailingSpaceRun)
408 trailingSpaceRun->m_box->setLogicalWidth(LayoutUnit()); 403 trailingSpaceRun->m_box->setLogicalWidth(LayoutUnit());
409 else if (totalLogicalWidth > availableLogicalWidth) 404 else if (totalLogicalWidth > availableLogicalWidth)
410 logicalLeft -= (totalLogicalWidth - availableLogicalWidth); 405 logicalLeft -= (totalLogicalWidth - availableLogicalWidth);
411 } 406 }
412 407
413 static void updateLogicalWidthForRightAlignedBlock( 408 static void updateLogicalWidthForRightAlignedBlock(
414 bool isLeftToRightDirection, 409 bool isLeftToRightDirection,
415 BidiRun* trailingSpaceRun, 410 BidiRun* trailingSpaceRun,
416 LayoutUnit& logicalLeft, 411 LayoutUnit& logicalLeft,
417 LayoutUnit& totalLogicalWidth, 412 LayoutUnit& totalLogicalWidth,
418 LayoutUnit availableLogicalWidth) { 413 LayoutUnit availableLogicalWidth) {
419 // Wide lines spill out of the block based off direction. 414 // Wide lines spill out of the block based off direction.
420 // So even if text-align is right, if direction is LTR, wide lines should 415 // So even if text-align is right, if direction is LTR, wide lines should over flow out of the right
421 // overflow out of the right side of the block. 416 // side of the block.
422 if (isLeftToRightDirection) { 417 if (isLeftToRightDirection) {
423 if (trailingSpaceRun) { 418 if (trailingSpaceRun) {
424 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth(); 419 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
425 trailingSpaceRun->m_box->setLogicalWidth(LayoutUnit()); 420 trailingSpaceRun->m_box->setLogicalWidth(LayoutUnit());
426 } 421 }
427 if (totalLogicalWidth < availableLogicalWidth) 422 if (totalLogicalWidth < availableLogicalWidth)
428 logicalLeft += availableLogicalWidth - totalLogicalWidth; 423 logicalLeft += availableLogicalWidth - totalLogicalWidth;
429 return; 424 return;
430 } 425 }
431 426
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 if (toInlineTextBox(run->m_box)->hasHyphen()) 536 if (toInlineTextBox(run->m_box)->hasHyphen())
542 hyphenWidth = LayoutUnit(layoutText.hyphenWidth(font, run->direction())); 537 hyphenWidth = LayoutUnit(layoutText.hyphenWidth(font, run->direction()));
543 538
544 float measuredWidth = 0; 539 float measuredWidth = 0;
545 FloatRect glyphBounds; 540 FloatRect glyphBounds;
546 541
547 bool kerningIsEnabled = 542 bool kerningIsEnabled =
548 font.getFontDescription().getTypesettingFeatures() & Kerning; 543 font.getFontDescription().getTypesettingFeatures() & Kerning;
549 544
550 #if OS(MACOSX) 545 #if OS(MACOSX)
551 // FIXME: Having any font feature settings enabled can lead to selection gaps 546 // FIXME: Having any font feature settings enabled can lead to selection gaps on
552 // on Chromium-mac. https://bugs.webkit.org/show_bug.cgi?id=113418 547 // Chromium-mac. https://bugs.webkit.org/show_bug.cgi?id=113418
553 bool canUseCachedWordMeasurements = 548 bool canUseCachedWordMeasurements =
554 font.canShapeWordByWord() && !font.getFontDescription().featureSettings(); 549 font.canShapeWordByWord() && !font.getFontDescription().featureSettings();
555 #else 550 #else
556 bool canUseCachedWordMeasurements = font.canShapeWordByWord(); 551 bool canUseCachedWordMeasurements = font.canShapeWordByWord();
557 #endif 552 #endif
558 553
559 if (canUseCachedWordMeasurements) { 554 if (canUseCachedWordMeasurements) {
560 int lastEndOffset = run->m_start; 555 int lastEndOffset = run->m_start;
561 size_t i = findWordMeasurement(layoutText, lastEndOffset, wordMeasurements, 556 size_t i = findWordMeasurement(layoutText, lastEndOffset, wordMeasurements,
562 wordMeasurementsIndex); 557 wordMeasurementsIndex);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 } 590 }
596 } 591 }
597 wordMeasurementsIndex = i; 592 wordMeasurementsIndex = i;
598 if (lastEndOffset != run->m_stop) { 593 if (lastEndOffset != run->m_stop) {
599 // If we don't have enough cached data, we'll measure the run again. 594 // If we don't have enough cached data, we'll measure the run again.
600 canUseCachedWordMeasurements = false; 595 canUseCachedWordMeasurements = false;
601 fallbackFonts.clear(); 596 fallbackFonts.clear();
602 } 597 }
603 } 598 }
604 599
605 // Don't put this into 'else' part of the above 'if' because 600 // Don't put this into 'else' part of the above 'if' because canUseCachedWordM easurements may be modified in the 'if' block.
606 // canUseCachedWordMeasurements may be modified in the 'if' block.
607 if (!canUseCachedWordMeasurements) 601 if (!canUseCachedWordMeasurements)
608 measuredWidth = layoutText.width( 602 measuredWidth = layoutText.width(
609 run->m_start, run->m_stop - run->m_start, xPos, run->direction(), 603 run->m_start, run->m_stop - run->m_start, xPos, run->direction(),
610 lineInfo.isFirstLine(), &fallbackFonts, &glyphBounds); 604 lineInfo.isFirstLine(), &fallbackFonts, &glyphBounds);
611 605
612 // Negative word-spacing and/or letter-spacing may cause some glyphs to 606 // Negative word-spacing and/or letter-spacing may cause some glyphs to overfl ow the left boundary and result
613 // overflow the left boundary and result negative measured width. Reset 607 // negative measured width. Reset measured width to 0 and adjust glyph bounds accordingly to cover the overflow.
614 // measured width to 0 and adjust glyph bounds accordingly to cover the
615 // overflow.
616 if (measuredWidth < 0) { 608 if (measuredWidth < 0) {
617 if (measuredWidth < glyphBounds.x()) { 609 if (measuredWidth < glyphBounds.x()) {
618 glyphBounds.expand(glyphBounds.x() - measuredWidth, 0); 610 glyphBounds.expand(glyphBounds.x() - measuredWidth, 0);
619 glyphBounds.setX(measuredWidth); 611 glyphBounds.setX(measuredWidth);
620 } 612 }
621 measuredWidth = 0; 613 measuredWidth = 0;
622 } 614 }
623 615
624 glyphOverflow.setFromBounds(glyphBounds, font.getFontMetrics().floatAscent(), 616 glyphOverflow.setFromBounds(glyphBounds, font.getFontMetrics().floatAscent(),
625 font.getFontMetrics().floatDescent(), 617 font.getFontMetrics().floatDescent(),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 LayoutUnit& availableLogicalWidth, 652 LayoutUnit& availableLogicalWidth,
661 unsigned expansionOpportunityCount) { 653 unsigned expansionOpportunityCount) {
662 TextDirection direction; 654 TextDirection direction;
663 if (rootInlineBox && 655 if (rootInlineBox &&
664 rootInlineBox->getLineLayoutItem().style()->unicodeBidi() == Plaintext) 656 rootInlineBox->getLineLayoutItem().style()->unicodeBidi() == Plaintext)
665 direction = rootInlineBox->direction(); 657 direction = rootInlineBox->direction();
666 else 658 else
667 direction = style()->direction(); 659 direction = style()->direction();
668 660
669 // Armed with the total width of the line (without justification), 661 // Armed with the total width of the line (without justification),
670 // we now examine our text-align property in order to determine where to 662 // we now examine our text-align property in order to determine where to posit ion the
671 // position the objects horizontally. The total width of the line can be 663 // objects horizontally. The total width of the line can be increased if we en d up
672 // increased if we end up justifying text. 664 // justifying text.
673 switch (textAlign) { 665 switch (textAlign) {
674 case LEFT: 666 case LEFT:
675 case WEBKIT_LEFT: 667 case WEBKIT_LEFT:
676 updateLogicalWidthForLeftAlignedBlock( 668 updateLogicalWidthForLeftAlignedBlock(
677 style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, 669 style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft,
678 totalLogicalWidth, availableLogicalWidth); 670 totalLogicalWidth, availableLogicalWidth);
679 break; 671 break;
680 case RIGHT: 672 case RIGHT:
681 case WEBKIT_RIGHT: 673 case WEBKIT_RIGHT:
682 updateLogicalWidthForRightAlignedBlock( 674 updateLogicalWidthForRightAlignedBlock(
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 const LineInfo& lineInfo, 738 const LineInfo& lineInfo,
747 BidiRun* firstRun, 739 BidiRun* firstRun,
748 BidiRun* trailingSpaceRun, 740 BidiRun* trailingSpaceRun,
749 bool reachedEnd, 741 bool reachedEnd,
750 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, 742 GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
751 VerticalPositionCache& verticalPositionCache, 743 VerticalPositionCache& verticalPositionCache,
752 WordMeasurements& wordMeasurements) { 744 WordMeasurements& wordMeasurements) {
753 ETextAlign textAlign = 745 ETextAlign textAlign =
754 textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak()); 746 textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak());
755 747
756 // CSS 2.1: "'Text-indent' only affects a line if it is the first formatted 748 // CSS 2.1: "'Text-indent' only affects a line if it is the first formatted li ne of an element. For example, the first line of an anonymous block
757 // line of an element. For example, the first line of an anonymous block
758 // box is only affected if it is the first child of its parent element." 749 // box is only affected if it is the first child of its parent element."
759 // CSS3 "text-indent", "each-line" affects the first line of the block 750 // CSS3 "text-indent", "each-line" affects the first line of the block contain er as well as each line after a forced line break,
760 // container as well as each line after a forced line break, but does not 751 // but does not affect lines after a soft wrap break.
761 // affect lines after a soft wrap break.
762 bool isFirstLine = 752 bool isFirstLine =
763 lineInfo.isFirstLine() && 753 lineInfo.isFirstLine() &&
764 !(isAnonymousBlock() && parent()->slowFirstChild() != this); 754 !(isAnonymousBlock() && parent()->slowFirstChild() != this);
765 bool isAfterHardLineBreak = 755 bool isAfterHardLineBreak =
766 lineBox->prevRootBox() && lineBox->prevRootBox()->endsWithBreak(); 756 lineBox->prevRootBox() && lineBox->prevRootBox()->endsWithBreak();
767 IndentTextOrNot indentText = 757 IndentTextOrNot indentText =
768 requiresIndent(isFirstLine, isAfterHardLineBreak, styleRef()); 758 requiresIndent(isFirstLine, isAfterHardLineBreak, styleRef());
769 LayoutUnit lineLogicalLeft; 759 LayoutUnit lineLogicalLeft;
770 LayoutUnit lineLogicalRight; 760 LayoutUnit lineLogicalRight;
771 LayoutUnit availableLogicalWidth; 761 LayoutUnit availableLogicalWidth;
772 updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, 762 updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight,
773 availableLogicalWidth, isFirstLine, indentText, 763 availableLogicalWidth, isFirstLine, indentText,
774 LayoutUnit()); 764 LayoutUnit());
775 bool needsWordSpacing; 765 bool needsWordSpacing;
776 766
777 if (firstRun && firstRun->m_lineLayoutItem.isAtomicInlineLevel()) { 767 if (firstRun && firstRun->m_lineLayoutItem.isAtomicInlineLevel()) {
778 LineLayoutBox layoutBox(firstRun->m_lineLayoutItem); 768 LineLayoutBox layoutBox(firstRun->m_lineLayoutItem);
779 updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, 769 updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight,
780 availableLogicalWidth, isFirstLine, indentText, 770 availableLogicalWidth, isFirstLine, indentText,
781 layoutBox.logicalHeight()); 771 layoutBox.logicalHeight());
782 } 772 }
783 773
784 computeInlineDirectionPositionsForSegment( 774 computeInlineDirectionPositionsForSegment(
785 lineBox, lineInfo, textAlign, lineLogicalLeft, availableLogicalWidth, 775 lineBox, lineInfo, textAlign, lineLogicalLeft, availableLogicalWidth,
786 firstRun, trailingSpaceRun, textBoxDataMap, verticalPositionCache, 776 firstRun, trailingSpaceRun, textBoxDataMap, verticalPositionCache,
787 wordMeasurements); 777 wordMeasurements);
788 // The widths of all runs are now known. We can now place every inline box 778 // The widths of all runs are now known. We can now place every inline box (an d
789 // (and compute accurate widths for the inline flow boxes). 779 // compute accurate widths for the inline flow boxes).
790 needsWordSpacing = lineBox->isLeftToRightDirection() ? false : true; 780 needsWordSpacing = lineBox->isLeftToRightDirection() ? false : true;
791 lineBox->placeBoxesInInlineDirection(lineLogicalLeft, needsWordSpacing); 781 lineBox->placeBoxesInInlineDirection(lineLogicalLeft, needsWordSpacing);
792 } 782 }
793 783
794 BidiRun* LayoutBlockFlow::computeInlineDirectionPositionsForSegment( 784 BidiRun* LayoutBlockFlow::computeInlineDirectionPositionsForSegment(
795 RootInlineBox* lineBox, 785 RootInlineBox* lineBox,
796 const LineInfo& lineInfo, 786 const LineInfo& lineInfo,
797 ETextAlign textAlign, 787 ETextAlign textAlign,
798 LayoutUnit& logicalLeft, 788 LayoutUnit& logicalLeft,
799 LayoutUnit& availableLogicalWidth, 789 LayoutUnit& availableLogicalWidth,
800 BidiRun* firstRun, 790 BidiRun* firstRun,
801 BidiRun* trailingSpaceRun, 791 BidiRun* trailingSpaceRun,
802 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, 792 GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
803 VerticalPositionCache& verticalPositionCache, 793 VerticalPositionCache& verticalPositionCache,
804 WordMeasurements& wordMeasurements) { 794 WordMeasurements& wordMeasurements) {
805 bool needsWordSpacing = true; 795 bool needsWordSpacing = true;
806 LayoutUnit totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth(); 796 LayoutUnit totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
807 bool isAfterExpansion = true; 797 bool isAfterExpansion = true;
808 ExpansionOpportunities expansions; 798 ExpansionOpportunities expansions;
809 LayoutObject* previousObject = nullptr; 799 LayoutObject* previousObject = nullptr;
810 TextJustify textJustify = style()->getTextJustify(); 800 TextJustify textJustify = style()->getTextJustify();
811 801
812 BidiRun* r = firstRun; 802 BidiRun* r = firstRun;
813 size_t wordMeasurementsIndex = 0; 803 size_t wordMeasurementsIndex = 0;
814 for (; r; r = r->next()) { 804 for (; r; r = r->next()) {
815 if (!r->m_box || r->m_lineLayoutItem.isOutOfFlowPositioned() || 805 if (!r->m_box || r->m_lineLayoutItem.isOutOfFlowPositioned() ||
816 r->m_box->isLineBreak()) { 806 r->m_box->isLineBreak()) {
817 continue; // Positioned objects are only participating to figure out 807 continue; // Positioned objects are only participating to figure out thei r
818 // their correct static x position. They have no effect on the 808 // correct static x position. They have no effect on the width.
819 // width. Similarly, line break boxes have no effect on the 809 // Similarly, line break boxes have no effect on the width.
820 // width.
821 } 810 }
822 if (r->m_lineLayoutItem.isText()) { 811 if (r->m_lineLayoutItem.isText()) {
823 LineLayoutText rt(r->m_lineLayoutItem); 812 LineLayoutText rt(r->m_lineLayoutItem);
824 if (textAlign == JUSTIFY && r != trailingSpaceRun && 813 if (textAlign == JUSTIFY && r != trailingSpaceRun &&
825 textJustify != TextJustifyNone) { 814 textJustify != TextJustifyNone) {
826 if (!isAfterExpansion) 815 if (!isAfterExpansion)
827 toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true); 816 toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true);
828 expansions.addRunWithExpansions(*r, isAfterExpansion, textJustify); 817 expansions.addRunWithExpansions(*r, isAfterExpansion, textJustify);
829 } 818 }
830 819
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 } 891 }
903 } 892 }
904 893
905 void LayoutBlockFlow::appendFloatingObjectToLastLine( 894 void LayoutBlockFlow::appendFloatingObjectToLastLine(
906 FloatingObject& floatingObject) { 895 FloatingObject& floatingObject) {
907 ASSERT(!floatingObject.originatingLine()); 896 ASSERT(!floatingObject.originatingLine());
908 floatingObject.setOriginatingLine(lastRootBox()); 897 floatingObject.setOriginatingLine(lastRootBox());
909 lastRootBox()->appendFloat(floatingObject.layoutObject()); 898 lastRootBox()->appendFloat(floatingObject.layoutObject());
910 } 899 }
911 900
912 // This function constructs line boxes for all of the text runs in the resolver 901 // This function constructs line boxes for all of the text runs in the resolver and computes their position.
913 // and computes their position.
914 RootInlineBox* LayoutBlockFlow::createLineBoxesFromBidiRuns( 902 RootInlineBox* LayoutBlockFlow::createLineBoxesFromBidiRuns(
915 unsigned bidiLevel, 903 unsigned bidiLevel,
916 BidiRunList<BidiRun>& bidiRuns, 904 BidiRunList<BidiRun>& bidiRuns,
917 const InlineIterator& end, 905 const InlineIterator& end,
918 LineInfo& lineInfo, 906 LineInfo& lineInfo,
919 VerticalPositionCache& verticalPositionCache, 907 VerticalPositionCache& verticalPositionCache,
920 BidiRun* trailingSpaceRun, 908 BidiRun* trailingSpaceRun,
921 WordMeasurements& wordMeasurements) { 909 WordMeasurements& wordMeasurements) {
922 if (!bidiRuns.runCount()) 910 if (!bidiRuns.runCount())
923 return nullptr; 911 return nullptr;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 textBoxDataMap); 949 textBoxDataMap);
962 950
963 return lineBox; 951 return lineBox;
964 } 952 }
965 953
966 static void deleteLineRange(LineLayoutState& layoutState, 954 static void deleteLineRange(LineLayoutState& layoutState,
967 RootInlineBox* startLine, 955 RootInlineBox* startLine,
968 RootInlineBox* stopLine = 0) { 956 RootInlineBox* stopLine = 0) {
969 RootInlineBox* boxToDelete = startLine; 957 RootInlineBox* boxToDelete = startLine;
970 while (boxToDelete && boxToDelete != stopLine) { 958 while (boxToDelete && boxToDelete != stopLine) {
971 // Note: deleteLineRange(firstRootBox()) is not identical to 959 // Note: deleteLineRange(firstRootBox()) is not identical to deleteLineBoxTr ee().
972 // deleteLineBoxTree(). deleteLineBoxTree uses nextLineBox() instead of 960 // deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when traver sing.
973 // nextRootBox() when traversing.
974 RootInlineBox* next = boxToDelete->nextRootBox(); 961 RootInlineBox* next = boxToDelete->nextRootBox();
975 boxToDelete->deleteLine(); 962 boxToDelete->deleteLine();
976 boxToDelete = next; 963 boxToDelete = next;
977 } 964 }
978 } 965 }
979 966
980 void LayoutBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState) { 967 void LayoutBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState) {
981 // We want to skip ahead to the first dirty line 968 // We want to skip ahead to the first dirty line
982 InlineBidiResolver resolver; 969 InlineBidiResolver resolver;
983 RootInlineBox* startLine = determineStartPosition(layoutState, resolver); 970 RootInlineBox* startLine = determineStartPosition(layoutState, resolver);
984 971
985 if (containsFloats()) 972 if (containsFloats())
986 layoutState.setLastFloat(m_floatingObjects->set().last().get()); 973 layoutState.setLastFloat(m_floatingObjects->set().last().get());
987 974
988 // We also find the first clean line and extract these lines. We will add 975 // We also find the first clean line and extract these lines. We will add the m back
989 // them back if we determine that we're able to synchronize after handling all 976 // if we determine that we're able to synchronize after handling all our dirty lines.
990 // our dirty lines.
991 InlineIterator cleanLineStart; 977 InlineIterator cleanLineStart;
992 BidiStatus cleanLineBidiStatus; 978 BidiStatus cleanLineBidiStatus;
993 if (!layoutState.isFullLayout() && startLine) 979 if (!layoutState.isFullLayout() && startLine)
994 determineEndPosition(layoutState, startLine, cleanLineStart, 980 determineEndPosition(layoutState, startLine, cleanLineStart,
995 cleanLineBidiStatus); 981 cleanLineBidiStatus);
996 982
997 if (startLine) 983 if (startLine)
998 deleteLineRange(layoutState, startLine); 984 deleteLineRange(layoutState, startLine);
999 985
1000 layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, 986 layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart,
1001 cleanLineBidiStatus); 987 cleanLineBidiStatus);
1002 linkToEndLineIfNeeded(layoutState); 988 linkToEndLineIfNeeded(layoutState);
1003 markDirtyFloatsForPaintInvalidation(layoutState.floats()); 989 markDirtyFloatsForPaintInvalidation(layoutState.floats());
1004 } 990 }
1005 991
1006 // Before restarting the layout loop with a new logicalHeight, remove all floats 992 // Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver.
1007 // that were added and reset the resolver.
1008 inline const InlineIterator& LayoutBlockFlow::restartLayoutRunsAndFloatsInRange( 993 inline const InlineIterator& LayoutBlockFlow::restartLayoutRunsAndFloatsInRange(
1009 LayoutUnit oldLogicalHeight, 994 LayoutUnit oldLogicalHeight,
1010 LayoutUnit newLogicalHeight, 995 LayoutUnit newLogicalHeight,
1011 FloatingObject* lastFloatFromPreviousLine, 996 FloatingObject* lastFloatFromPreviousLine,
1012 InlineBidiResolver& resolver, 997 InlineBidiResolver& resolver,
1013 const InlineIterator& oldEnd) { 998 const InlineIterator& oldEnd) {
1014 removeFloatingObjectsBelow(lastFloatFromPreviousLine, 999 removeFloatingObjectsBelow(lastFloatFromPreviousLine,
1015 oldLogicalHeight.toInt()); 1000 oldLogicalHeight.toInt());
1016 setLogicalHeight(newLogicalHeight); 1001 setLogicalHeight(newLogicalHeight);
1017 resolver.setPositionIgnoringNestedIsolates(oldEnd); 1002 resolver.setPositionIgnoringNestedIsolates(oldEnd);
(...skipping 10 matching lines...) Expand all
1028 FloatingObjectSetIterator end = floatingObjectSet.end(); 1013 FloatingObjectSetIterator end = floatingObjectSet.end();
1029 if (layoutState.lastFloat()) { 1014 if (layoutState.lastFloat()) {
1030 FloatingObjectSetIterator lastFloatIterator = 1015 FloatingObjectSetIterator lastFloatIterator =
1031 floatingObjectSet.find(layoutState.lastFloat()); 1016 floatingObjectSet.find(layoutState.lastFloat());
1032 ASSERT(lastFloatIterator != end); 1017 ASSERT(lastFloatIterator != end);
1033 ++lastFloatIterator; 1018 ++lastFloatIterator;
1034 it = lastFloatIterator; 1019 it = lastFloatIterator;
1035 } 1020 }
1036 for (; it != end; ++it) { 1021 for (; it != end; ++it) {
1037 FloatingObject& floatingObject = *it->get(); 1022 FloatingObject& floatingObject = *it->get();
1038 // If we've reached the start of clean lines any remaining floating children 1023 // If we've reached the start of clean lines any remaining floating children belong to them.
1039 // belong to them.
1040 if (cleanLineStart.getLineLayoutItem().isEqual( 1024 if (cleanLineStart.getLineLayoutItem().isEqual(
1041 floatingObject.layoutObject()) && 1025 floatingObject.layoutObject()) &&
1042 layoutState.endLine()) { 1026 layoutState.endLine()) {
1043 layoutState.setEndLineMatched(layoutState.endLineMatched() || 1027 layoutState.setEndLineMatched(layoutState.endLineMatched() ||
1044 matchedEndLine(layoutState, resolver, 1028 matchedEndLine(layoutState, resolver,
1045 cleanLineStart, 1029 cleanLineStart,
1046 cleanLineBidiStatus)); 1030 cleanLineBidiStatus));
1047 if (layoutState.endLineMatched()) { 1031 if (layoutState.endLineMatched()) {
1048 layoutState.setLastFloat(&floatingObject); 1032 layoutState.setLastFloat(&floatingObject);
1049 return; 1033 return;
(...skipping 21 matching lines...) Expand all
1071 const InlineIterator& cleanLineStart, 1055 const InlineIterator& cleanLineStart,
1072 const BidiStatus& cleanLineBidiStatus) { 1056 const BidiStatus& cleanLineBidiStatus) {
1073 const ComputedStyle& styleToUse = styleRef(); 1057 const ComputedStyle& styleToUse = styleRef();
1074 bool paginated = 1058 bool paginated =
1075 view()->layoutState() && view()->layoutState()->isPaginated(); 1059 view()->layoutState() && view()->layoutState()->isPaginated();
1076 LineMidpointState& lineMidpointState = resolver.midpointState(); 1060 LineMidpointState& lineMidpointState = resolver.midpointState();
1077 InlineIterator endOfLine = resolver.position(); 1061 InlineIterator endOfLine = resolver.position();
1078 LayoutTextInfo layoutTextInfo; 1062 LayoutTextInfo layoutTextInfo;
1079 VerticalPositionCache verticalPositionCache; 1063 VerticalPositionCache verticalPositionCache;
1080 1064
1081 // Pagination may require us to delete and re-create a line due to floats. 1065 // Pagination may require us to delete and re-create a line due to floats. Whe n this happens,
1082 // When this happens,
1083 // we need to store the pagination strut in the meantime. 1066 // we need to store the pagination strut in the meantime.
1084 LayoutUnit paginationStrutFromDeletedLine; 1067 LayoutUnit paginationStrutFromDeletedLine;
1085 1068
1086 LineBreaker lineBreaker(LineLayoutBlockFlow(this)); 1069 LineBreaker lineBreaker(LineLayoutBlockFlow(this));
1087 1070
1088 while (!endOfLine.atEnd()) { 1071 while (!endOfLine.atEnd()) {
1089 // The runs from the previous line should have been cleaned up. 1072 // The runs from the previous line should have been cleaned up.
1090 ASSERT(!resolver.runs().runCount()); 1073 ASSERT(!resolver.runs().runCount());
1091 1074
1092 // FIXME: Is this check necessary before the first iteration or can it be 1075 // FIXME: Is this check necessary before the first iteration or can it be mo ved to the end?
1093 // moved to the end?
1094 if (layoutState.endLine()) { 1076 if (layoutState.endLine()) {
1095 layoutState.setEndLineMatched(layoutState.endLineMatched() || 1077 layoutState.setEndLineMatched(layoutState.endLineMatched() ||
1096 matchedEndLine(layoutState, resolver, 1078 matchedEndLine(layoutState, resolver,
1097 cleanLineStart, 1079 cleanLineStart,
1098 cleanLineBidiStatus)); 1080 cleanLineBidiStatus));
1099 if (layoutState.endLineMatched()) { 1081 if (layoutState.endLineMatched()) {
1100 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 1082 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0),
1101 0); 1083 0);
1102 break; 1084 break;
1103 } 1085 }
1104 } 1086 }
1105 1087
1106 lineMidpointState.reset(); 1088 lineMidpointState.reset();
1107 1089
1108 layoutState.lineInfo().setEmpty(true); 1090 layoutState.lineInfo().setEmpty(true);
1109 layoutState.lineInfo().resetRunsFromLeadingWhitespace(); 1091 layoutState.lineInfo().resetRunsFromLeadingWhitespace();
1110 1092
1111 const InlineIterator previousEndofLine = endOfLine; 1093 const InlineIterator previousEndofLine = endOfLine;
1112 bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly(); 1094 bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly();
1113 FloatingObject* lastFloatFromPreviousLine = 1095 FloatingObject* lastFloatFromPreviousLine =
1114 (containsFloats()) ? m_floatingObjects->set().last().get() : 0; 1096 (containsFloats()) ? m_floatingObjects->set().last().get() : 0;
1115 1097
1116 WordMeasurements wordMeasurements; 1098 WordMeasurements wordMeasurements;
1117 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), 1099 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(),
1118 layoutTextInfo, wordMeasurements); 1100 layoutTextInfo, wordMeasurements);
1119 layoutTextInfo.m_lineBreakIterator.resetPriorContext(); 1101 layoutTextInfo.m_lineBreakIterator.resetPriorContext();
1120 if (resolver.position().atEnd()) { 1102 if (resolver.position().atEnd()) {
1121 // FIXME: We shouldn't be creating any runs in nextLineBreak to begin 1103 // FIXME: We shouldn't be creating any runs in nextLineBreak to begin with !
1122 // with! Once BidiRunList is separated from BidiResolver this will not be 1104 // Once BidiRunList is separated from BidiResolver this will not be needed .
1123 // needed.
1124 resolver.runs().deleteRuns(); 1105 resolver.runs().deleteRuns();
1125 resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced 1106 resolver
1126 // by an ASSERT (or just removed). 1107 .markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
1127 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0); 1108 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
1128 break; 1109 break;
1129 } 1110 }
1130 1111
1131 ASSERT(endOfLine != resolver.position()); 1112 ASSERT(endOfLine != resolver.position());
1132 RootInlineBox* lineBox = nullptr; 1113 RootInlineBox* lineBox = nullptr;
1133 1114
1134 // This is a short-cut for empty lines. 1115 // This is a short-cut for empty lines.
1135 if (layoutState.lineInfo().isEmpty()) { 1116 if (layoutState.lineInfo().isEmpty()) {
1136 ASSERT(!paginationStrutFromDeletedLine); 1117 ASSERT(!paginationStrutFromDeletedLine);
1137 if (lastRootBox()) 1118 if (lastRootBox())
1138 lastRootBox()->setLineBreakInfo(endOfLine.getLineLayoutItem(), 1119 lastRootBox()->setLineBreakInfo(endOfLine.getLineLayoutItem(),
1139 endOfLine.offset(), resolver.status()); 1120 endOfLine.offset(), resolver.status());
1140 resolver.runs().deleteRuns(); 1121 resolver.runs().deleteRuns();
1141 } else { 1122 } else {
1142 VisualDirectionOverride override = 1123 VisualDirectionOverride override =
1143 (styleToUse.rtlOrdering() == VisualOrder 1124 (styleToUse.rtlOrdering() == VisualOrder
1144 ? (styleToUse.direction() == LTR ? VisualLeftToRightOverride 1125 ? (styleToUse.direction() == LTR ? VisualLeftToRightOverride
1145 : VisualRightToLeftOverride) 1126 : VisualRightToLeftOverride)
1146 : NoVisualOverride); 1127 : NoVisualOverride);
1147 if (isNewUBAParagraph && styleToUse.unicodeBidi() == Plaintext && 1128 if (isNewUBAParagraph && styleToUse.unicodeBidi() == Plaintext &&
1148 !resolver.context()->parent()) { 1129 !resolver.context()->parent()) {
1149 TextDirection direction = determinePlaintextDirectionality( 1130 TextDirection direction = determinePlaintextDirectionality(
1150 resolver.position().root(), resolver.position().getLineLayoutItem(), 1131 resolver.position().root(), resolver.position().getLineLayoutItem(),
1151 resolver.position().offset()); 1132 resolver.position().offset());
1152 resolver.setStatus( 1133 resolver.setStatus(
1153 BidiStatus(direction, isOverride(styleToUse.unicodeBidi()))); 1134 BidiStatus(direction, isOverride(styleToUse.unicodeBidi())));
1154 } 1135 }
1155 // FIXME: This ownership is reversed. We should own the BidiRunList and 1136 // FIXME: This ownership is reversed. We should own the BidiRunList and pa ss it to createBidiRunsForLine.
1156 // pass it to createBidiRunsForLine.
1157 BidiRunList<BidiRun>& bidiRuns = resolver.runs(); 1137 BidiRunList<BidiRun>& bidiRuns = resolver.runs();
1158 constructBidiRunsForLine( 1138 constructBidiRunsForLine(
1159 resolver, bidiRuns, endOfLine, override, 1139 resolver, bidiRuns, endOfLine, override,
1160 layoutState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph); 1140 layoutState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph);
1161 ASSERT(resolver.position() == endOfLine); 1141 ASSERT(resolver.position() == endOfLine);
1162 1142
1163 BidiRun* trailingSpaceRun = resolver.trailingSpaceRun(); 1143 BidiRun* trailingSpaceRun = resolver.trailingSpaceRun();
1164 1144
1165 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) 1145 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated())
1166 bidiRuns.logicallyLastRun()->m_hasHyphen = true; 1146 bidiRuns.logicallyLastRun()->m_hasHyphen = true;
1167 1147
1168 // Now that the runs have been ordered, we create the line boxes. 1148 // Now that the runs have been ordered, we create the line boxes.
1169 // At the same time we figure out where border/padding/margin should be 1149 // At the same time we figure out where border/padding/margin should be ap plied for
1170 // applied for
1171 // inline flow boxes. 1150 // inline flow boxes.
1172 1151
1173 LayoutUnit oldLogicalHeight = logicalHeight(); 1152 LayoutUnit oldLogicalHeight = logicalHeight();
1174 lineBox = createLineBoxesFromBidiRuns( 1153 lineBox = createLineBoxesFromBidiRuns(
1175 resolver.status().context->level(), bidiRuns, endOfLine, 1154 resolver.status().context->level(), bidiRuns, endOfLine,
1176 layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, 1155 layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun,
1177 wordMeasurements); 1156 wordMeasurements);
1178 1157
1179 bidiRuns.deleteRuns(); 1158 bidiRuns.deleteRuns();
1180 resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced 1159 resolver
1181 // by an ASSERT (or just removed). 1160 .markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
1182 1161
1183 // If we decided to re-create the line due to pagination, we better have a 1162 // If we decided to re-create the line due to pagination, we better have a new line now.
1184 // new line now.
1185 ASSERT(lineBox || !paginationStrutFromDeletedLine); 1163 ASSERT(lineBox || !paginationStrutFromDeletedLine);
1186 1164
1187 if (lineBox) { 1165 if (lineBox) {
1188 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), 1166 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(),
1189 endOfLine.offset(), resolver.status()); 1167 endOfLine.offset(), resolver.status());
1190 if (paginated) { 1168 if (paginated) {
1191 if (paginationStrutFromDeletedLine) { 1169 if (paginationStrutFromDeletedLine) {
1192 // This is a line that got re-created because it got pushed to the 1170 // This is a line that got re-created because it got pushed to the n ext fragmentainer, and there
1193 // next fragmentainer, and there were floats in the vicinity that 1171 // were floats in the vicinity that affected the available width. Re store the pagination info
1194 // affected the available width. 1172 // for this line.
1195 // Restore the pagination info for this line.
1196 lineBox->setIsFirstAfterPageBreak(true); 1173 lineBox->setIsFirstAfterPageBreak(true);
1197 lineBox->setPaginationStrut(paginationStrutFromDeletedLine); 1174 lineBox->setPaginationStrut(paginationStrutFromDeletedLine);
1198 paginationStrutFromDeletedLine = LayoutUnit(); 1175 paginationStrutFromDeletedLine = LayoutUnit();
1199 } else { 1176 } else {
1200 LayoutUnit adjustment; 1177 LayoutUnit adjustment;
1201 adjustLinePositionForPagination(*lineBox, adjustment); 1178 adjustLinePositionForPagination(*lineBox, adjustment);
1202 if (adjustment) { 1179 if (adjustment) {
1203 LayoutUnit oldLineWidth = availableLogicalWidthForLine( 1180 LayoutUnit oldLineWidth = availableLogicalWidthForLine(
1204 oldLogicalHeight, layoutState.lineInfo().isFirstLine() 1181 oldLogicalHeight, layoutState.lineInfo().isFirstLine()
1205 ? IndentText 1182 ? IndentText
1206 : DoNotIndentText); 1183 : DoNotIndentText);
1207 lineBox->moveInBlockDirection(adjustment); 1184 lineBox->moveInBlockDirection(adjustment);
1208 if (availableLogicalWidthForLine( 1185 if (availableLogicalWidthForLine(
1209 oldLogicalHeight + adjustment, 1186 oldLogicalHeight + adjustment,
1210 layoutState.lineInfo().isFirstLine() 1187 layoutState.lineInfo().isFirstLine()
1211 ? IndentText 1188 ? IndentText
1212 : DoNotIndentText) != oldLineWidth) { 1189 : DoNotIndentText) != oldLineWidth) {
1213 // We have to delete this line, remove all floats that got 1190 // We have to delete this line, remove all floats that got added , and let line layout
1214 // added, and let line layout re-run. We had just calculated the 1191 // re-run. We had just calculated the pagination strut for this line, and we need to
1215 // pagination strut for this line, and we need to stow it away, 1192 // stow it away, so that we can re-apply it when the new line ha s been created.
1216 // so that we can re-apply it when the new line has been created .
1217 paginationStrutFromDeletedLine = lineBox->paginationStrut(); 1193 paginationStrutFromDeletedLine = lineBox->paginationStrut();
1218 ASSERT(paginationStrutFromDeletedLine); 1194 ASSERT(paginationStrutFromDeletedLine);
1219 // We're also going to assume that we're right after a page 1195 // We're also going to assume that we're right after a page brea k when re-creating this
1220 // break when re-creating this line, so it better be so. 1196 // line, so it better be so.
1221 ASSERT(lineBox->isFirstAfterPageBreak()); 1197 ASSERT(lineBox->isFirstAfterPageBreak());
1222 lineBox->deleteLine(); 1198 lineBox->deleteLine();
1223 endOfLine = restartLayoutRunsAndFloatsInRange( 1199 endOfLine = restartLayoutRunsAndFloatsInRange(
1224 oldLogicalHeight, oldLogicalHeight + adjustment, 1200 oldLogicalHeight, oldLogicalHeight + adjustment,
1225 lastFloatFromPreviousLine, resolver, previousEndofLine); 1201 lastFloatFromPreviousLine, resolver, previousEndofLine);
1226 } else { 1202 } else {
1227 setLogicalHeight(lineBox->lineBottomWithLeading()); 1203 setLogicalHeight(lineBox->lineBottomWithLeading());
1228 } 1204 }
1229 } 1205 }
1230 } 1206 }
1231 } 1207 }
1232 } 1208 }
1233 } 1209 }
1234 1210
1235 if (!paginationStrutFromDeletedLine) { 1211 if (!paginationStrutFromDeletedLine) {
1236 for (const auto& positionedObject : lineBreaker.positionedObjects()) { 1212 for (const auto& positionedObject : lineBreaker.positionedObjects()) {
1237 if (positionedObject.style()->isOriginalDisplayInlineType()) { 1213 if (positionedObject.style()->isOriginalDisplayInlineType()) {
1238 // Auto-positioend "inline" out-of-flow objects have already been 1214 // Auto-positioend "inline" out-of-flow objects have already been posi tioned,
1239 // positioned, but if we're paginated, we need to update their 1215 // but if we're paginated, we need to update their position now, since the line
1240 // position now, since the line they "belong" to may have been pushed 1216 // they "belong" to may have been pushed by a pagination strut.
1241 // by a pagination strut.
1242 if (paginated && lineBox) 1217 if (paginated && lineBox)
1243 positionedObject.layer()->setStaticBlockPosition( 1218 positionedObject.layer()->setStaticBlockPosition(
1244 lineBox->lineTopWithLeading()); 1219 lineBox->lineTopWithLeading());
1245 continue; 1220 continue;
1246 } 1221 }
1247 setStaticPositions(LineLayoutBlockFlow(this), positionedObject, 1222 setStaticPositions(LineLayoutBlockFlow(this), positionedObject,
1248 DoNotIndentText); 1223 DoNotIndentText);
1249 } 1224 }
1250 1225
1251 if (!layoutState.lineInfo().isEmpty()) 1226 if (!layoutState.lineInfo().isEmpty())
(...skipping 10 matching lines...) Expand all
1262 } 1237 }
1263 } 1238 }
1264 1239
1265 lineMidpointState.reset(); 1240 lineMidpointState.reset();
1266 resolver.setPosition(endOfLine, numberOfIsolateAncestors(endOfLine)); 1241 resolver.setPosition(endOfLine, numberOfIsolateAncestors(endOfLine));
1267 } 1242 }
1268 1243
1269 // The resolver runs should have been cleared, otherwise they're leaking. 1244 // The resolver runs should have been cleared, otherwise they're leaking.
1270 ASSERT(!resolver.runs().runCount()); 1245 ASSERT(!resolver.runs().runCount());
1271 1246
1272 // In case we already adjusted the line positions during this layout to avoid 1247 // In case we already adjusted the line positions during this layout to avoid widows
1273 // widows then we need to ignore the possibility of having a new widows 1248 // then we need to ignore the possibility of having a new widows situation.
1274 // situation. Otherwise, we risk leaving empty containers which is against the 1249 // Otherwise, we risk leaving empty containers which is against the block frag mentation principles.
1275 // block fragmentation principles.
1276 if (paginated && style()->widows() > 1 && !didBreakAtLineToAvoidWidow()) { 1250 if (paginated && style()->widows() > 1 && !didBreakAtLineToAvoidWidow()) {
1277 // Check the line boxes to make sure we didn't create unacceptable widows. 1251 // Check the line boxes to make sure we didn't create unacceptable widows.
1278 // However, we'll prioritize orphans - so nothing we do here should create 1252 // However, we'll prioritize orphans - so nothing we do here should create
1279 // a new orphan. 1253 // a new orphan.
1280 1254
1281 RootInlineBox* lineBox = lastRootBox(); 1255 RootInlineBox* lineBox = lastRootBox();
1282 1256
1283 // Count from the end of the block backwards, to see how many hanging 1257 // Count from the end of the block backwards, to see how many hanging
1284 // lines we have. 1258 // lines we have.
1285 RootInlineBox* firstLineInBlock = firstRootBox(); 1259 RootInlineBox* firstLineInBlock = firstRootBox();
(...skipping 18 matching lines...) Expand all
1304 1278
1305 // Count the number of lines in the previous page. 1279 // Count the number of lines in the previous page.
1306 lineBox = lineBox->prevRootBox(); 1280 lineBox = lineBox->prevRootBox();
1307 int numLinesInPreviousPage = 1; 1281 int numLinesInPreviousPage = 1;
1308 while (lineBox && lineBox != firstLineInBlock && 1282 while (lineBox && lineBox != firstLineInBlock &&
1309 !lineBox->isFirstAfterPageBreak()) { 1283 !lineBox->isFirstAfterPageBreak()) {
1310 ++numLinesInPreviousPage; 1284 ++numLinesInPreviousPage;
1311 lineBox = lineBox->prevRootBox(); 1285 lineBox = lineBox->prevRootBox();
1312 } 1286 }
1313 1287
1314 // If there was an explicit value for orphans, respect that. If not, we 1288 // If there was an explicit value for orphans, respect that. If not, we st ill
1315 // still shouldn't create a situation where we make an orphan bigger than 1289 // shouldn't create a situation where we make an orphan bigger than the in itial value.
1316 // the initial value. This means that setting widows implies we also care 1290 // This means that setting widows implies we also care about orphans, but given
1317 // about orphans, but given the specification says the initial orphan 1291 // the specification says the initial orphan value is non-zero, this is ok . The
1318 // value is non-zero, this is ok. The author is always free to set orphans 1292 // author is always free to set orphans explicitly as well.
1319 // explicitly as well.
1320 int orphans = style()->orphans(); 1293 int orphans = style()->orphans();
1321 int numLinesAvailable = numLinesInPreviousPage - orphans; 1294 int numLinesAvailable = numLinesInPreviousPage - orphans;
1322 if (numLinesAvailable <= 0) 1295 if (numLinesAvailable <= 0)
1323 return; 1296 return;
1324 1297
1325 int numLinesToTake = std::min(numLinesAvailable, numLinesNeeded); 1298 int numLinesToTake = std::min(numLinesAvailable, numLinesNeeded);
1326 // Wind back from our first widowed line. 1299 // Wind back from our first widowed line.
1327 lineBox = currentFirstLineOfNewPage; 1300 lineBox = currentFirstLineOfNewPage;
1328 for (int i = 0; i < numLinesToTake; ++i) 1301 for (int i = 0; i < numLinesToTake; ++i)
1329 lineBox = lineBox->prevRootBox(); 1302 lineBox = lineBox->prevRootBox();
1330 1303
1331 // We now want to break at this line. Remember for next layout and trigger 1304 // We now want to break at this line. Remember for next layout and trigger relayout.
1332 // relayout.
1333 setBreakAtLineToAvoidWidow(lineCount(lineBox)); 1305 setBreakAtLineToAvoidWidow(lineCount(lineBox));
1334 markLinesDirtyInBlockRange(lastRootBox()->lineBottomWithLeading(), 1306 markLinesDirtyInBlockRange(lastRootBox()->lineBottomWithLeading(),
1335 lineBox->lineBottomWithLeading(), lineBox); 1307 lineBox->lineBottomWithLeading(), lineBox);
1336 } 1308 }
1337 } 1309 }
1338 1310
1339 clearDidBreakAtLineToAvoidWidow(); 1311 clearDidBreakAtLineToAvoidWidow();
1340 } 1312 }
1341 1313
1342 void LayoutBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState) { 1314 void LayoutBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState) {
1343 if (layoutState.endLine()) { 1315 if (layoutState.endLine()) {
1344 if (layoutState.endLineMatched()) { 1316 if (layoutState.endLineMatched()) {
1345 bool paginated = 1317 bool paginated =
1346 view()->layoutState() && view()->layoutState()->isPaginated(); 1318 view()->layoutState() && view()->layoutState()->isPaginated();
1347 // Attach all the remaining lines, and then adjust their y-positions as 1319 // Attach all the remaining lines, and then adjust their y-positions as ne eded.
1348 // needed.
1349 LayoutUnit delta = logicalHeight() - layoutState.endLineLogicalTop(); 1320 LayoutUnit delta = logicalHeight() - layoutState.endLineLogicalTop();
1350 for (RootInlineBox* line = layoutState.endLine(); line; 1321 for (RootInlineBox* line = layoutState.endLine(); line;
1351 line = line->nextRootBox()) { 1322 line = line->nextRootBox()) {
1352 line->attachLine(); 1323 line->attachLine();
1353 if (paginated) { 1324 if (paginated) {
1354 delta -= line->paginationStrut(); 1325 delta -= line->paginationStrut();
1355 adjustLinePositionForPagination(*line, delta); 1326 adjustLinePositionForPagination(*line, delta);
1356 } 1327 }
1357 if (delta) 1328 if (delta)
1358 line->moveInBlockDirection(delta); 1329 line->moveInBlockDirection(delta);
1359 if (Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr()) { 1330 if (Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr()) {
1360 for (auto* box : *cleanLineFloats) { 1331 for (auto* box : *cleanLineFloats) {
1361 FloatingObject* floatingObject = insertFloatingObject(*box); 1332 FloatingObject* floatingObject = insertFloatingObject(*box);
1362 ASSERT(!floatingObject->originatingLine()); 1333 ASSERT(!floatingObject->originatingLine());
1363 floatingObject->setOriginatingLine(line); 1334 floatingObject->setOriginatingLine(line);
1364 setLogicalHeight(logicalTopForChild(*box) - 1335 setLogicalHeight(logicalTopForChild(*box) -
1365 marginBeforeForChild(*box) + delta); 1336 marginBeforeForChild(*box) + delta);
1366 positionNewFloats(); 1337 positionNewFloats();
1367 } 1338 }
1368 } 1339 }
1369 } 1340 }
1370 setLogicalHeight(lastRootBox()->lineBottomWithLeading()); 1341 setLogicalHeight(lastRootBox()->lineBottomWithLeading());
1371 } else { 1342 } else {
1372 // Delete all the remaining lines. 1343 // Delete all the remaining lines.
1373 deleteLineRange(layoutState, layoutState.endLine()); 1344 deleteLineRange(layoutState, layoutState.endLine());
1374 } 1345 }
1375 } 1346 }
1376 1347
1377 // In case we have a float on the last line, it might not be positioned up to 1348 // In case we have a float on the last line, it might not be positioned up to now.
1378 // now. This has to be done before adding in the bottom border/padding, or the 1349 // This has to be done before adding in the bottom border/padding, or the floa t will
1379 // float will
1380 // include the padding incorrectly. -dwh 1350 // include the padding incorrectly. -dwh
1381 if (positionNewFloats() && lastRootBox()) 1351 if (positionNewFloats() && lastRootBox())
1382 appendFloatsToLastLine(layoutState, InlineIterator(), InlineBidiResolver(), 1352 appendFloatsToLastLine(layoutState, InlineIterator(), InlineBidiResolver(),
1383 BidiStatus()); 1353 BidiStatus());
1384 } 1354 }
1385 1355
1386 void LayoutBlockFlow::markDirtyFloatsForPaintInvalidation( 1356 void LayoutBlockFlow::markDirtyFloatsForPaintInvalidation(
1387 Vector<FloatWithRect>& floats) { 1357 Vector<FloatWithRect>& floats) {
1388 size_t floatCount = floats.size(); 1358 size_t floatCount = floats.size();
1389 // Floats that did not have layout did not paint invalidations when we laid 1359 // Floats that did not have layout did not paint invalidations when we laid th em out. They would have
1390 // them out. They would have painted by now if they had moved, but if they 1360 // painted by now if they had moved, but if they stayed at (0, 0), they still need to be
1391 // stayed at (0, 0), they still need to be painted. 1361 // painted.
1392 for (size_t i = 0; i < floatCount; ++i) { 1362 for (size_t i = 0; i < floatCount; ++i) {
1393 LayoutBox* f = floats[i].object; 1363 LayoutBox* f = floats[i].object;
1394 if (!floats[i].everHadLayout) { 1364 if (!floats[i].everHadLayout) {
1395 if (!f->location().x() && !f->location().y()) 1365 if (!f->location().x() && !f->location().y())
1396 f->setShouldDoFullPaintInvalidation(); 1366 f->setShouldDoFullPaintInvalidation();
1397 } 1367 }
1398 insertFloatingObject(*f); 1368 insertFloatingObject(*f);
1399 } 1369 }
1400 positionNewFloats(); 1370 positionNewFloats();
1401 } 1371 }
1402 1372
1403 // InlineMinMaxIterator is a class that will iterate over all layout objects
1404 // that contribute to inline min/max width calculations. Note the following
1405 // about the way it walks:
1406 // (1) Positioned content is skipped (since it does not contribute to min/max
1407 // width of a block)
1408 // (2) We do not drill into the children of floats or replaced elements, since
1409 // you can't break in the middle of such an element.
1410 // (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side
1411 // can have distinct borders/margin/padding that contribute to the min/max
1412 // width.
1413 struct InlineMinMaxIterator { 1373 struct InlineMinMaxIterator {
1374 /* InlineMinMaxIterator is a class that will iterate over all layout objects t hat contribute to
1375 inline min/max width calculations. Note the following about the way it walks :
1376 (1) Positioned content is skipped (since it does not contribute to min/max wi dth of a block)
1377 (2) We do not drill into the children of floats or replaced elements, since y ou can't break
1378 in the middle of such an element.
1379 (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side c an have
1380 distinct borders/margin/padding that contribute to the min/max width.
1381 */
1414 LayoutObject* parent; 1382 LayoutObject* parent;
1415 LayoutObject* current; 1383 LayoutObject* current;
1416 bool endOfInline; 1384 bool endOfInline;
1417 1385
1418 InlineMinMaxIterator(LayoutObject* p, bool end = false) 1386 InlineMinMaxIterator(LayoutObject* p, bool end = false)
1419 : parent(p), current(p), endOfInline(end) {} 1387 : parent(p), current(p), endOfInline(end) {}
1420 1388
1421 LayoutObject* next(); 1389 LayoutObject* next();
1422 }; 1390 };
1423 1391
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 constructTextRun(font, &trailingWhitespaceChar, 1, text->styleRef(), 1481 constructTextRun(font, &trailingWhitespaceChar, 1, text->styleRef(),
1514 text->style()->direction()); 1482 text->style()->direction());
1515 float spaceWidth = font.width(run); 1483 float spaceWidth = font.width(run);
1516 inlineMax -= LayoutUnit::fromFloatCeil( 1484 inlineMax -= LayoutUnit::fromFloatCeil(
1517 spaceWidth + font.getFontDescription().wordSpacing()); 1485 spaceWidth + font.getFontDescription().wordSpacing());
1518 if (inlineMin > inlineMax) 1486 if (inlineMin > inlineMax)
1519 inlineMin = inlineMax; 1487 inlineMin = inlineMax;
1520 } 1488 }
1521 } 1489 }
1522 1490
1523 // When converting between floating point and LayoutUnits we risk losing 1491 // When converting between floating point and LayoutUnits we risk losing precisi on
1524 // precision with each conversion. When this occurs while accumulating our 1492 // with each conversion. When this occurs while accumulating our preferred width s,
1525 // preferred widths, we can wind up with a line width that's larger than our 1493 // we can wind up with a line width that's larger than our maxPreferredWidth due to
1526 // maxPreferredWidth due to pure float accumulation. 1494 // pure float accumulation.
1527 static inline LayoutUnit adjustFloatForSubPixelLayout(float value) { 1495 static inline LayoutUnit adjustFloatForSubPixelLayout(float value) {
1528 return LayoutUnit::fromFloatCeil(value); 1496 return LayoutUnit::fromFloatCeil(value);
1529 } 1497 }
1530 1498
1531 static inline void adjustMinMaxForInlineFlow(LayoutObject* child, 1499 static inline void adjustMinMaxForInlineFlow(LayoutObject* child,
1532 bool endOfInline, 1500 bool endOfInline,
1533 LayoutUnit& childMin, 1501 LayoutUnit& childMin,
1534 LayoutUnit& childMax) { 1502 LayoutUnit& childMax) {
1535 // Add in padding/border/margin from the appropriate side of 1503 // Add in padding/border/margin from the appropriate side of
1536 // the element. 1504 // the element.
(...skipping 12 matching lines...) Expand all
1549 LayoutUnit margins; 1517 LayoutUnit margins;
1550 if (startMargin.isFixed()) 1518 if (startMargin.isFixed())
1551 margins += adjustFloatForSubPixelLayout(startMargin.value()); 1519 margins += adjustFloatForSubPixelLayout(startMargin.value());
1552 if (endMargin.isFixed()) 1520 if (endMargin.isFixed())
1553 margins += adjustFloatForSubPixelLayout(endMargin.value()); 1521 margins += adjustFloatForSubPixelLayout(endMargin.value());
1554 childMin += margins; 1522 childMin += margins;
1555 childMax += margins; 1523 childMax += margins;
1556 } 1524 }
1557 1525
1558 // FIXME: This function should be broken into something less monolithic. 1526 // FIXME: This function should be broken into something less monolithic.
1559 // FIXME: The main loop here is very similar to LineBreaker::nextSegmentBreak. 1527 // FIXME: The main loop here is very similar to LineBreaker::nextSegmentBreak. T hey can probably reuse code.
1560 // They can probably reuse code.
1561 DISABLE_CFI_PERF 1528 DISABLE_CFI_PERF
1562 void LayoutBlockFlow::computeInlinePreferredLogicalWidths( 1529 void LayoutBlockFlow::computeInlinePreferredLogicalWidths(
1563 LayoutUnit& minLogicalWidth, 1530 LayoutUnit& minLogicalWidth,
1564 LayoutUnit& maxLogicalWidth) { 1531 LayoutUnit& maxLogicalWidth) {
1565 LayoutUnit inlineMax; 1532 LayoutUnit inlineMax;
1566 LayoutUnit inlineMin; 1533 LayoutUnit inlineMin;
1567 1534
1568 const ComputedStyle& styleToUse = styleRef(); 1535 const ComputedStyle& styleToUse = styleRef();
1569 LayoutBlock* containingBlock = this->containingBlock(); 1536 LayoutBlock* containingBlock = this->containingBlock();
1570 LayoutUnit cw = 1537 LayoutUnit cw =
1571 containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit(); 1538 containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit();
1572 1539
1573 // If we are at the start of a line, we want to ignore all white-space. 1540 // If we are at the start of a line, we want to ignore all white-space.
1574 // Also strip spaces if we previously had text that ended in a trailing space. 1541 // Also strip spaces if we previously had text that ended in a trailing space.
1575 bool stripFrontSpaces = true; 1542 bool stripFrontSpaces = true;
1576 LayoutObject* trailingSpaceChild = nullptr; 1543 LayoutObject* trailingSpaceChild = nullptr;
1577 1544
1578 // Firefox and Opera will allow a table cell to grow to fit an image inside it 1545 // Firefox and Opera will allow a table cell to grow to fit an image inside it under
1579 // under very specific cirucumstances (in order to match common WinIE 1546 // very specific cirucumstances (in order to match common WinIE layouts).
1580 // layouts). Not supporting the quirk has caused us to mis-layout some real 1547 // Not supporting the quirk has caused us to mis-layout some real sites. (See Bugzilla 10517.)
1581 // sites. (See Bugzilla 10517.)
1582 bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || 1548 bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() ||
1583 !styleToUse.logicalWidth().isIntrinsicOrAuto(); 1549 !styleToUse.logicalWidth().isIntrinsicOrAuto();
1584 1550
1585 bool autoWrap, oldAutoWrap; 1551 bool autoWrap, oldAutoWrap;
1586 autoWrap = oldAutoWrap = styleToUse.autoWrap(); 1552 autoWrap = oldAutoWrap = styleToUse.autoWrap();
1587 1553
1588 InlineMinMaxIterator childIterator(this); 1554 InlineMinMaxIterator childIterator(this);
1589 1555
1590 // Only gets added to the max preffered width once. 1556 // Only gets added to the max preffered width once.
1591 bool addedTextIndent = false; 1557 bool addedTextIndent = false;
1592 // Signals the text indent was more negative than the min preferred width 1558 // Signals the text indent was more negative than the min preferred width
1593 bool hasRemainingNegativeTextIndent = false; 1559 bool hasRemainingNegativeTextIndent = false;
1594 1560
1595 LayoutUnit textIndent = minimumValueForLength(styleToUse.textIndent(), cw); 1561 LayoutUnit textIndent = minimumValueForLength(styleToUse.textIndent(), cw);
1596 LayoutObject* prevFloat = nullptr; 1562 LayoutObject* prevFloat = nullptr;
1597 bool isPrevChildInlineFlow = false; 1563 bool isPrevChildInlineFlow = false;
1598 bool shouldBreakLineAfterText = false; 1564 bool shouldBreakLineAfterText = false;
1599 while (LayoutObject* child = childIterator.next()) { 1565 while (LayoutObject* child = childIterator.next()) {
1600 autoWrap = child->isAtomicInlineLevel() 1566 autoWrap = child->isAtomicInlineLevel()
1601 ? child->parent()->style()->autoWrap() 1567 ? child->parent()->style()->autoWrap()
1602 : child->style()->autoWrap(); 1568 : child->style()->autoWrap();
1603 1569
1604 if (!child->isBR()) { 1570 if (!child->isBR()) {
1605 // Step One: determine whether or not we need to go ahead and 1571 // Step One: determine whether or not we need to go ahead and
1606 // terminate our current line. Each discrete chunk can become 1572 // terminate our current line. Each discrete chunk can become
1607 // the new min-width, if it is the widest chunk seen so far, and 1573 // the new min-width, if it is the widest chunk seen so far, and
1608 // it can also become the max-width. 1574 // it can also become the max-width.
1609 // 1575
1610 // Children fall into three categories: 1576 // Children fall into three categories:
1611 // (1) An inline flow object. These objects always have a min/max of 0, 1577 // (1) An inline flow object. These objects always have a min/max of 0,
1612 // and are included in the iteration solely so that their margins can 1578 // and are included in the iteration solely so that their margins can
1613 // be added in. 1579 // be added in.
1614 // 1580 //
1615 // (2) An inline non-text non-flow object, e.g., an inline replaced 1581 // (2) An inline non-text non-flow object, e.g., an inline replaced elemen t.
1616 // element. These objects can always be on a line by themselves, so in 1582 // These objects can always be on a line by themselves, so in this situati on
1617 // this situation we need to go ahead and break the current line, and 1583 // we need to go ahead and break the current line, and then add in our own
1618 // then add in our own margins and min/max width on its own line, and 1584 // margins and min/max width on its own line, and then terminate the line.
1619 // then terminate the line.
1620 // 1585 //
1621 // (3) A text object. Text runs can have breakable characters at the 1586 // (3) A text object. Text runs can have breakable characters at the start ,
1622 // start, the middle or the end. They may also lose whitespace off the 1587 // the middle or the end. They may also lose whitespace off the front if
1623 // front if we're already ignoring whitespace. In order to compute 1588 // we're already ignoring whitespace. In order to compute accurate min-wid th
1624 // accurate min-width information, we need three pieces of 1589 // information, we need three pieces of information.
1625 // information. 1590 // (a) the min-width of the first non-breakable run. Should be 0 if the te xt string
1626 // (a) the min-width of the first non-breakable run. Should be 0 if 1591 // starts with whitespace.
1627 // the text string starts with whitespace. 1592 // (b) the min-width of the last non-breakable run. Should be 0 if the tex t string
1628 // (b) the min-width of the last non-breakable run. Should be 0 if the 1593 // ends with whitespace.
1629 // text string ends with whitespace. 1594 // (c) the min/max width of the string (trimmed for whitespace).
1630 // (c) the min/max width of the string (trimmed for whitespace).
1631 // 1595 //
1632 // If the text string starts with whitespace, then we need to go ahead and 1596 // If the text string starts with whitespace, then we need to go ahead and
1633 // terminate our current line (unless we're already in a whitespace 1597 // terminate our current line (unless we're already in a whitespace stripp ing
1634 // stripping mode. 1598 // mode.
1635 // 1599 //
1636 // If the text string has a breakable character in the middle, but didn't 1600 // If the text string has a breakable character in the middle, but didn't start
1637 // start with whitespace, then we add the width of the first non-breakable 1601 // with whitespace, then we add the width of the first non-breakable run a nd
1638 // run and then end the current line. We then need to use the intermediate 1602 // then end the current line. We then need to use the intermediate min/max width
1639 // min/max width values (if any of them are larger than our current 1603 // values (if any of them are larger than our current min/max). We then lo ok at
1640 // min/max). We then look at the width of the last non-breakable run and 1604 // the width of the last non-breakable run and use that to start a new lin e
1641 // use that to start a new line (unless we end in whitespace). 1605 // (unless we end in whitespace).
1642 LayoutUnit childMin; 1606 LayoutUnit childMin;
1643 LayoutUnit childMax; 1607 LayoutUnit childMax;
1644 1608
1645 if (!child->isText()) { 1609 if (!child->isText()) {
1646 // Case (1) and (2). Inline replaced and inline flow elements. 1610 // Case (1) and (2). Inline replaced and inline flow elements.
1647 if (child->isLayoutInline()) { 1611 if (child->isLayoutInline()) {
1648 adjustMinMaxForInlineFlow(child, childIterator.endOfInline, childMin, 1612 adjustMinMaxForInlineFlow(child, childIterator.endOfInline, childMin,
1649 childMax); 1613 childMax);
1650 inlineMin += childMin; 1614 inlineMin += childMin;
1651 inlineMax += childMax; 1615 inlineMax += childMax;
(...skipping 29 matching lines...) Expand all
1681 } 1645 }
1682 1646
1683 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak; 1647 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
1684 if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && 1648 if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) &&
1685 (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || 1649 (!isPrevChildInlineFlow || shouldBreakLineAfterText)) ||
1686 clearPreviousFloat) { 1650 clearPreviousFloat) {
1687 minLogicalWidth = std::max(minLogicalWidth, inlineMin); 1651 minLogicalWidth = std::max(minLogicalWidth, inlineMin);
1688 inlineMin = LayoutUnit(); 1652 inlineMin = LayoutUnit();
1689 } 1653 }
1690 1654
1691 // If we're supposed to clear the previous float, then terminate 1655 // If we're supposed to clear the previous float, then terminate maxwidt h as well.
1692 // maxwidth as well.
1693 if (clearPreviousFloat) { 1656 if (clearPreviousFloat) {
1694 maxLogicalWidth = std::max(maxLogicalWidth, inlineMax); 1657 maxLogicalWidth = std::max(maxLogicalWidth, inlineMax);
1695 inlineMax = LayoutUnit(); 1658 inlineMax = LayoutUnit();
1696 } 1659 }
1697 1660
1698 // Add in text-indent. This is added in only once. 1661 // Add in text-indent. This is added in only once.
1699 if (!addedTextIndent && !child->isFloating()) { 1662 if (!addedTextIndent && !child->isFloating()) {
1700 childMin += textIndent; 1663 childMin += textIndent;
1701 childMax += textIndent; 1664 childMax += textIndent;
1702 1665
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 bool hasBreakableChar, hasBreak; 1715 bool hasBreakableChar, hasBreak;
1753 LayoutUnit firstLineMinWidth, lastLineMinWidth; 1716 LayoutUnit firstLineMinWidth, lastLineMinWidth;
1754 bool hasBreakableStart, hasBreakableEnd; 1717 bool hasBreakableStart, hasBreakableEnd;
1755 LayoutUnit firstLineMaxWidth, lastLineMaxWidth; 1718 LayoutUnit firstLineMaxWidth, lastLineMaxWidth;
1756 t->trimmedPrefWidths(inlineMax, firstLineMinWidth, hasBreakableStart, 1719 t->trimmedPrefWidths(inlineMax, firstLineMinWidth, hasBreakableStart,
1757 lastLineMinWidth, hasBreakableEnd, 1720 lastLineMinWidth, hasBreakableEnd,
1758 hasBreakableChar, hasBreak, firstLineMaxWidth, 1721 hasBreakableChar, hasBreak, firstLineMaxWidth,
1759 lastLineMaxWidth, childMin, childMax, 1722 lastLineMaxWidth, childMin, childMax,
1760 stripFrontSpaces, styleToUse.direction()); 1723 stripFrontSpaces, styleToUse.direction());
1761 1724
1762 // This text object will not be laid out, but it may still provide a 1725 // This text object will not be laid out, but it may still provide a bre aking opportunity.
1763 // breaking opportunity.
1764 if (!hasBreak && !childMax) { 1726 if (!hasBreak && !childMax) {
1765 if (autoWrap && (hasBreakableStart || hasBreakableEnd)) { 1727 if (autoWrap && (hasBreakableStart || hasBreakableEnd)) {
1766 minLogicalWidth = std::max(minLogicalWidth, inlineMin); 1728 minLogicalWidth = std::max(minLogicalWidth, inlineMin);
1767 inlineMin = LayoutUnit(); 1729 inlineMin = LayoutUnit();
1768 } 1730 }
1769 continue; 1731 continue;
1770 } 1732 }
1771 1733
1772 if (stripFrontSpaces) 1734 if (stripFrontSpaces)
1773 trailingSpaceChild = child; 1735 trailingSpaceChild = child;
1774 else 1736 else
1775 trailingSpaceChild = nullptr; 1737 trailingSpaceChild = nullptr;
1776 1738
1777 // Add in text-indent. This is added in only once. 1739 // Add in text-indent. This is added in only once.
1778 LayoutUnit ti; 1740 LayoutUnit ti;
1779 if (!addedTextIndent || hasRemainingNegativeTextIndent) { 1741 if (!addedTextIndent || hasRemainingNegativeTextIndent) {
1780 ti = textIndent; 1742 ti = textIndent;
1781 childMin += ti; 1743 childMin += ti;
1782 firstLineMinWidth += ti; 1744 firstLineMinWidth += ti;
1783 1745
1784 // It the text indent negative and larger than the child minimum, we 1746 // It the text indent negative and larger than the child minimum, we r e-use the remainder
1785 // re-use the remainder in future minimum calculations, but using the 1747 // in future minimum calculations, but using the negative value again on the maximum
1786 // negative value again on the maximum will lead to under-counting the 1748 // will lead to under-counting the max pref width.
1787 // max pref width.
1788 if (!addedTextIndent) { 1749 if (!addedTextIndent) {
1789 childMax += ti; 1750 childMax += ti;
1790 firstLineMaxWidth += ti; 1751 firstLineMaxWidth += ti;
1791 addedTextIndent = true; 1752 addedTextIndent = true;
1792 } 1753 }
1793 1754
1794 if (childMin < LayoutUnit()) { 1755 if (childMin < LayoutUnit()) {
1795 textIndent = childMin; 1756 textIndent = childMin;
1796 hasRemainingNegativeTextIndent = true; 1757 hasRemainingNegativeTextIndent = true;
1797 } 1758 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1887 bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren; 1848 bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren;
1888 LineLayoutState layoutState(isFullLayout); 1849 LineLayoutState layoutState(isFullLayout);
1889 1850
1890 if (isFullLayout) { 1851 if (isFullLayout) {
1891 // Ensure the old line boxes will be erased. 1852 // Ensure the old line boxes will be erased.
1892 if (firstLineBox()) 1853 if (firstLineBox())
1893 setShouldDoFullPaintInvalidation(); 1854 setShouldDoFullPaintInvalidation();
1894 lineBoxes()->deleteLineBoxes(); 1855 lineBoxes()->deleteLineBoxes();
1895 } 1856 }
1896 1857
1897 // Text truncation kicks in if overflow isn't visible and text-overflow isn't 1858 // Text truncation kicks in if overflow isn't visible and text-overflow isn't 'clip'. If this is
1898 // 'clip'. If this is an anonymous block, we have to examine the parent. 1859 // an anonymous block, we have to examine the parent.
1899 // FIXME: CSS3 says that descendants that are clipped must also know how to 1860 // FIXME: CSS3 says that descendants that are clipped must also know how to tr uncate. This is insanely
1900 // truncate. This is insanely difficult to figure out in general (especially 1861 // difficult to figure out in general (especially in the middle of doing layou t), so we only handle the
1901 // in the middle of doing layout), so we only handle the simple case of an 1862 // simple case of an anonymous block truncating when its parent is clipped.
1902 // anonymous block truncating when its parent is clipped.
1903 bool hasTextOverflow = shouldTruncateOverflowingText(this); 1863 bool hasTextOverflow = shouldTruncateOverflowingText(this);
1904 1864
1905 // Walk all the lines and delete our ellipsis line boxes if they exist. 1865 // Walk all the lines and delete our ellipsis line boxes if they exist.
1906 if (hasTextOverflow) 1866 if (hasTextOverflow)
1907 deleteEllipsisLineBoxes(); 1867 deleteEllipsisLineBoxes();
1908 1868
1909 if (firstChild()) { 1869 if (firstChild()) {
1910 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd(); 1870 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd();
1911 walker.advance()) { 1871 walker.advance()) {
1912 LayoutObject* o = walker.current().layoutObject(); 1872 LayoutObject* o = walker.current().layoutObject();
1913 1873
1914 if (!layoutState.hasInlineChild() && o->isInline()) 1874 if (!layoutState.hasInlineChild() && o->isInline())
1915 layoutState.setHasInlineChild(true); 1875 layoutState.setHasInlineChild(true);
1916 1876
1917 if (o->isAtomicInlineLevel() || o->isFloating() || 1877 if (o->isAtomicInlineLevel() || o->isFloating() ||
1918 o->isOutOfFlowPositioned()) { 1878 o->isOutOfFlowPositioned()) {
1919 LayoutBox* box = toLayoutBox(o); 1879 LayoutBox* box = toLayoutBox(o);
1920 box->setMayNeedPaintInvalidation(); 1880 box->setMayNeedPaintInvalidation();
1921 1881
1922 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *box); 1882 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *box);
1923 1883
1924 if (o->isOutOfFlowPositioned()) { 1884 if (o->isOutOfFlowPositioned()) {
1925 o->containingBlock()->insertPositionedObject(box); 1885 o->containingBlock()->insertPositionedObject(box);
1926 } else if (o->isFloating()) { 1886 } else if (o->isFloating()) {
1927 layoutState.floats().append(FloatWithRect(box)); 1887 layoutState.floats().append(FloatWithRect(box));
1928 if (box->needsLayout()) { 1888 if (box->needsLayout()) {
1929 box->layout(); 1889 box->layout();
1930 // Dirty any lineboxes potentially affected by the float, but don't 1890 // Dirty any lineboxes potentially affected by the float, but don't search outside this
1931 // search outside this object as we are only interested in dirtying 1891 // object as we are only interested in dirtying lineboxes to which w e may attach the float.
1932 // lineboxes to which we may attach the float.
1933 dirtyLinesFromChangedChild(box, MarkOnlyThis); 1892 dirtyLinesFromChangedChild(box, MarkOnlyThis);
1934 } 1893 }
1935 } else if (isFullLayout || o->needsLayout()) { 1894 } else if (isFullLayout || o->needsLayout()) {
1936 // Atomic inline. 1895 // Atomic inline.
1937 box->dirtyLineBoxes(isFullLayout); 1896 box->dirtyLineBoxes(isFullLayout);
1938 o->layoutIfNeeded(); 1897 o->layoutIfNeeded();
1939 } 1898 }
1940 } else if (o->isText() || 1899 } else if (o->isText() ||
1941 (o->isLayoutInline() && !walker.atEndOfInline())) { 1900 (o->isLayoutInline() && !walker.atEndOfInline())) {
1942 if (!o->isText()) 1901 if (!o->isText())
(...skipping 30 matching lines...) Expand all
1973 1932
1974 // Now add in the bottom border/padding. 1933 // Now add in the bottom border/padding.
1975 setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + afterEdge); 1934 setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + afterEdge);
1976 1935
1977 if (!firstLineBox() && hasLineIfEmpty()) 1936 if (!firstLineBox() && hasLineIfEmpty())
1978 setLogicalHeight(logicalHeight() + 1937 setLogicalHeight(logicalHeight() +
1979 lineHeight(true, isHorizontalWritingMode() ? HorizontalLine 1938 lineHeight(true, isHorizontalWritingMode() ? HorizontalLine
1980 : VerticalLine, 1939 : VerticalLine,
1981 PositionOfInteriorLineBoxes)); 1940 PositionOfInteriorLineBoxes));
1982 1941
1983 // See if we have any lines that spill out of our block. If we do, then we 1942 // See if we have any lines that spill out of our block. If we do, then we wi ll possibly need to
1984 // will possibly need to truncate text. 1943 // truncate text.
1985 if (hasTextOverflow) 1944 if (hasTextOverflow)
1986 checkLinesForTextOverflow(); 1945 checkLinesForTextOverflow();
1987 1946
1988 // Ensure the new line boxes will be painted. 1947 // Ensure the new line boxes will be painted.
1989 if (isFullLayout && firstLineBox()) 1948 if (isFullLayout && firstLineBox())
1990 setShouldDoFullPaintInvalidation(); 1949 setShouldDoFullPaintInvalidation();
1991 } 1950 }
1992 1951
1993 RootInlineBox* LayoutBlockFlow::determineStartPosition( 1952 RootInlineBox* LayoutBlockFlow::determineStartPosition(
1994 LineLayoutState& layoutState, 1953 LineLayoutState& layoutState,
1995 InlineBidiResolver& resolver) { 1954 InlineBidiResolver& resolver) {
1996 RootInlineBox* curr = nullptr; 1955 RootInlineBox* curr = nullptr;
1997 RootInlineBox* last = nullptr; 1956 RootInlineBox* last = nullptr;
1998 RootInlineBox* firstLineBoxWithBreakAndClearance = 0; 1957 RootInlineBox* firstLineBoxWithBreakAndClearance = 0;
1999 1958
2000 // FIXME: This entire float-checking block needs to be broken into a new 1959 // FIXME: This entire float-checking block needs to be broken into a new funct ion.
2001 // function.
2002 if (!layoutState.isFullLayout()) { 1960 if (!layoutState.isFullLayout()) {
2003 // Paginate all of the clean lines. 1961 // Paginate all of the clean lines.
2004 bool paginated = 1962 bool paginated =
2005 view()->layoutState() && view()->layoutState()->isPaginated(); 1963 view()->layoutState() && view()->layoutState()->isPaginated();
2006 LayoutUnit paginationDelta; 1964 LayoutUnit paginationDelta;
2007 for (curr = firstRootBox(); curr && !curr->isDirty(); 1965 for (curr = firstRootBox(); curr && !curr->isDirty();
2008 curr = curr->nextRootBox()) { 1966 curr = curr->nextRootBox()) {
2009 if (paginated) { 1967 if (paginated) {
2010 paginationDelta -= curr->paginationStrut(); 1968 paginationDelta -= curr->paginationStrut();
2011 adjustLinePositionForPagination(*curr, paginationDelta); 1969 adjustLinePositionForPagination(*curr, paginationDelta);
2012 if (paginationDelta) { 1970 if (paginationDelta) {
2013 if (containsFloats() || !layoutState.floats().isEmpty()) { 1971 if (containsFloats() || !layoutState.floats().isEmpty()) {
2014 // FIXME: Do better eventually. For now if we ever shift because of 1972 // FIXME: Do better eventually. For now if we ever shift because of pagination and floats are present just go to a full layout.
2015 // pagination and floats are present just go to a full layout.
2016 layoutState.markForFullLayout(); 1973 layoutState.markForFullLayout();
2017 break; 1974 break;
2018 } 1975 }
2019 curr->moveInBlockDirection(paginationDelta); 1976 curr->moveInBlockDirection(paginationDelta);
2020 } 1977 }
2021 } 1978 }
2022 1979
2023 // If the linebox breaks cleanly and with clearance then dirty from at 1980 // If the linebox breaks cleanly and with clearance then dirty from at lea st this point onwards so that we can clear the correct floats without difficulty .
2024 // least this point onwards so that we can clear the correct floats
2025 // without difficulty.
2026 if (!firstLineBoxWithBreakAndClearance && lineBoxHasBRWithClearance(curr)) 1981 if (!firstLineBoxWithBreakAndClearance && lineBoxHasBRWithClearance(curr))
2027 firstLineBoxWithBreakAndClearance = curr; 1982 firstLineBoxWithBreakAndClearance = curr;
2028 1983
2029 if (layoutState.isFullLayout()) 1984 if (layoutState.isFullLayout())
2030 break; 1985 break;
2031 } 1986 }
2032 } 1987 }
2033 1988
2034 if (layoutState.isFullLayout()) { 1989 if (layoutState.isFullLayout()) {
2035 // If we encountered a new float and have inline children, mark ourself to 1990 // If we encountered a new float and have inline children, mark ourself to f orce us to issue paint invalidations.
2036 // force us to issue paint invalidations.
2037 if (layoutState.hasInlineChild() && !selfNeedsLayout()) { 1991 if (layoutState.hasInlineChild() && !selfNeedsLayout()) {
2038 setNeedsLayoutAndFullPaintInvalidation( 1992 setNeedsLayoutAndFullPaintInvalidation(
2039 LayoutInvalidationReason::FloatDescendantChanged, MarkOnlyThis); 1993 LayoutInvalidationReason::FloatDescendantChanged, MarkOnlyThis);
2040 setShouldDoFullPaintInvalidation(); 1994 setShouldDoFullPaintInvalidation();
2041 } 1995 }
2042 1996
2043 deleteLineBoxTree(); 1997 deleteLineBoxTree();
2044 curr = nullptr; 1998 curr = nullptr;
2045 ASSERT(!firstLineBox() && !lastLineBox()); 1999 ASSERT(!firstLineBox() && !lastLineBox());
2046 } else { 2000 } else {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2116 LineLayoutBlockFlow(this), 2070 LineLayoutBlockFlow(this),
2117 bidiFirstSkippingEmptyInlines(LineLayoutBlockFlow(this), 2071 bidiFirstSkippingEmptyInlines(LineLayoutBlockFlow(this),
2118 resolver.runs(), &resolver), 2072 resolver.runs(), &resolver),
2119 0); 2073 0);
2120 resolver.setPosition(iter, numberOfIsolateAncestors(iter)); 2074 resolver.setPosition(iter, numberOfIsolateAncestors(iter));
2121 } 2075 }
2122 return curr; 2076 return curr;
2123 } 2077 }
2124 2078
2125 bool LayoutBlockFlow::lineBoxHasBRWithClearance(RootInlineBox* curr) { 2079 bool LayoutBlockFlow::lineBoxHasBRWithClearance(RootInlineBox* curr) {
2126 // If the linebox breaks cleanly and with clearance then dirty from at least 2080 // If the linebox breaks cleanly and with clearance then dirty from at least t his point onwards so that we can clear the correct floats without difficulty.
2127 // this point onwards so that we can clear the correct floats without
2128 // difficulty.
2129 if (!curr->endsWithBreak()) 2081 if (!curr->endsWithBreak())
2130 return false; 2082 return false;
2131 InlineBox* lastBox = style()->isLeftToRightDirection() 2083 InlineBox* lastBox = style()->isLeftToRightDirection()
2132 ? curr->lastLeafChild() 2084 ? curr->lastLeafChild()
2133 : curr->firstLeafChild(); 2085 : curr->firstLeafChild();
2134 return lastBox && lastBox->getLineLayoutItem().isBR() && 2086 return lastBox && lastBox->getLineLayoutItem().isBR() &&
2135 lastBox->getLineLayoutItem().style()->clear() != ClearNone; 2087 lastBox->getLineLayoutItem().style()->clear() != ClearNone;
2136 } 2088 }
2137 2089
2138 void LayoutBlockFlow::determineEndPosition(LineLayoutState& layoutState, 2090 void LayoutBlockFlow::determineEndPosition(LineLayoutState& layoutState,
2139 RootInlineBox* startLine, 2091 RootInlineBox* startLine,
2140 InlineIterator& cleanLineStart, 2092 InlineIterator& cleanLineStart,
2141 BidiStatus& cleanLineBidiStatus) { 2093 BidiStatus& cleanLineBidiStatus) {
2142 ASSERT(!layoutState.endLine()); 2094 ASSERT(!layoutState.endLine());
2143 RootInlineBox* last = nullptr; 2095 RootInlineBox* last = nullptr;
2144 for (RootInlineBox* curr = startLine->nextRootBox(); curr; 2096 for (RootInlineBox* curr = startLine->nextRootBox(); curr;
2145 curr = curr->nextRootBox()) { 2097 curr = curr->nextRootBox()) {
2146 if (!curr->isDirty() && lineBoxHasBRWithClearance(curr)) 2098 if (!curr->isDirty() && lineBoxHasBRWithClearance(curr))
2147 return; 2099 return;
2148 2100
2149 if (curr->isDirty()) 2101 if (curr->isDirty())
2150 last = nullptr; 2102 last = nullptr;
2151 else if (!last) 2103 else if (!last)
2152 last = curr; 2104 last = curr;
2153 } 2105 }
2154 2106
2155 if (!last) 2107 if (!last)
2156 return; 2108 return;
2157 2109
2158 // At this point, |last| is the first line in a run of clean lines that ends 2110 // At this point, |last| is the first line in a run of clean lines that ends w ith the last line
2159 // with the last line in the block. 2111 // in the block.
2160 2112
2161 RootInlineBox* prev = last->prevRootBox(); 2113 RootInlineBox* prev = last->prevRootBox();
2162 cleanLineStart = 2114 cleanLineStart =
2163 InlineIterator(LineLayoutItem(this), LineLayoutItem(prev->lineBreakObj()), 2115 InlineIterator(LineLayoutItem(this), LineLayoutItem(prev->lineBreakObj()),
2164 prev->lineBreakPos()); 2116 prev->lineBreakPos());
2165 cleanLineBidiStatus = prev->lineBreakBidiStatus(); 2117 cleanLineBidiStatus = prev->lineBreakBidiStatus();
2166 layoutState.setEndLineLogicalTop(prev->lineBottomWithLeading()); 2118 layoutState.setEndLineLogicalTop(prev->lineBottomWithLeading());
2167 2119
2168 for (RootInlineBox* line = last; line; line = line->nextRootBox()) 2120 for (RootInlineBox* line = last; line; line = line->nextRootBox())
2169 line->extractLine(); // Disconnect all line boxes from their layout objects 2121 line->extractLine(); // Disconnect all line boxes from their layout objects while preserving
2170 // while preserving their connections to one another. 2122 // their connections to one another.
2171 2123
2172 layoutState.setEndLine(last); 2124 layoutState.setEndLine(last);
2173 } 2125 }
2174 2126
2175 bool LayoutBlockFlow::checkPaginationAndFloatsAtEndLine( 2127 bool LayoutBlockFlow::checkPaginationAndFloatsAtEndLine(
2176 LineLayoutState& layoutState) { 2128 LineLayoutState& layoutState) {
2177 if (!m_floatingObjects || !layoutState.endLine()) 2129 if (!m_floatingObjects || !layoutState.endLine())
2178 return true; 2130 return true;
2179 2131
2180 LayoutUnit lineDelta = logicalHeight() - layoutState.endLineLogicalTop(); 2132 LayoutUnit lineDelta = logicalHeight() - layoutState.endLineLogicalTop();
2181 2133
2182 bool paginated = 2134 bool paginated =
2183 view()->layoutState() && view()->layoutState()->isPaginated(); 2135 view()->layoutState() && view()->layoutState()->isPaginated();
2184 if (paginated) { 2136 if (paginated) {
2185 // Check all lines from here to the end, and see if the hypothetical new 2137 // Check all lines from here to the end, and see if the hypothetical new pos ition for the lines will result
2186 // position for the lines will result
2187 // in a different available line width. 2138 // in a different available line width.
2188 for (RootInlineBox* lineBox = layoutState.endLine(); lineBox; 2139 for (RootInlineBox* lineBox = layoutState.endLine(); lineBox;
2189 lineBox = lineBox->nextRootBox()) { 2140 lineBox = lineBox->nextRootBox()) {
2190 // This isn't the real move we're going to do, so don't update the line 2141 // This isn't the real move we're going to do, so don't update the line bo x's pagination
2191 // box's pagination strut yet. 2142 // strut yet.
2192 LayoutUnit oldPaginationStrut = lineBox->paginationStrut(); 2143 LayoutUnit oldPaginationStrut = lineBox->paginationStrut();
2193 lineDelta -= oldPaginationStrut; 2144 lineDelta -= oldPaginationStrut;
2194 adjustLinePositionForPagination(*lineBox, lineDelta); 2145 adjustLinePositionForPagination(*lineBox, lineDelta);
2195 lineBox->setPaginationStrut(oldPaginationStrut); 2146 lineBox->setPaginationStrut(oldPaginationStrut);
2196 } 2147 }
2197 } 2148 }
2198 if (!lineDelta) 2149 if (!lineDelta)
2199 return true; 2150 return true;
2200 2151
2201 // See if any floats end in the range along which we want to shift the lines 2152 // See if any floats end in the range along which we want to shift the lines v ertically.
2202 // vertically.
2203 LayoutUnit logicalTop = 2153 LayoutUnit logicalTop =
2204 std::min(logicalHeight(), layoutState.endLineLogicalTop()); 2154 std::min(logicalHeight(), layoutState.endLineLogicalTop());
2205 2155
2206 RootInlineBox* lastLine = layoutState.endLine(); 2156 RootInlineBox* lastLine = layoutState.endLine();
2207 while (RootInlineBox* nextLine = lastLine->nextRootBox()) 2157 while (RootInlineBox* nextLine = lastLine->nextRootBox())
2208 lastLine = nextLine; 2158 lastLine = nextLine;
2209 2159
2210 LayoutUnit logicalBottom = 2160 LayoutUnit logicalBottom =
2211 lastLine->lineBottomWithLeading() + absoluteValue(lineDelta); 2161 lastLine->lineBottomWithLeading() + absoluteValue(lineDelta);
2212 2162
(...skipping 14 matching lines...) Expand all
2227 const InlineBidiResolver& resolver, 2177 const InlineBidiResolver& resolver,
2228 const InlineIterator& endLineStart, 2178 const InlineIterator& endLineStart,
2229 const BidiStatus& endLineStatus) { 2179 const BidiStatus& endLineStatus) {
2230 if (resolver.position() == endLineStart) { 2180 if (resolver.position() == endLineStart) {
2231 if (resolver.status() != endLineStatus) 2181 if (resolver.status() != endLineStatus)
2232 return false; 2182 return false;
2233 2183
2234 return checkPaginationAndFloatsAtEndLine(layoutState); 2184 return checkPaginationAndFloatsAtEndLine(layoutState);
2235 } 2185 }
2236 2186
2237 // The first clean line doesn't match, but we can check a handful of following 2187 // The first clean line doesn't match, but we can check a handful of following lines to try
2238 // lines to try to match back up. 2188 // to match back up.
2239 static int numLines = 8; // The # of lines we're willing to match against. 2189 static int numLines = 8; // The # of lines we're willing to match against.
2240 RootInlineBox* originalEndLine = layoutState.endLine(); 2190 RootInlineBox* originalEndLine = layoutState.endLine();
2241 RootInlineBox* line = originalEndLine; 2191 RootInlineBox* line = originalEndLine;
2242 for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) { 2192 for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) {
2243 if (line->lineBreakObj() == resolver.position().getLineLayoutItem() && 2193 if (line->lineBreakObj() == resolver.position().getLineLayoutItem() &&
2244 line->lineBreakPos() == resolver.position().offset()) { 2194 line->lineBreakPos() == resolver.position().offset()) {
2245 // We have a match. 2195 // We have a match.
2246 if (line->lineBreakBidiStatus() != resolver.status()) 2196 if (line->lineBreakBidiStatus() != resolver.status())
2247 return false; // ...but the bidi state doesn't match. 2197 return false; // ...but the bidi state doesn't match.
2248 2198
(...skipping 22 matching lines...) Expand all
2271 InlineIterator it(LineLayoutBlockFlow(this), LineLayoutItem(inlineObj), 0); 2221 InlineIterator it(LineLayoutBlockFlow(this), LineLayoutItem(inlineObj), 0);
2272 // FIXME: We should pass correct value for WhitespacePosition. 2222 // FIXME: We should pass correct value for WhitespacePosition.
2273 while (!it.atEnd() && !requiresLineBox(it)) 2223 while (!it.atEnd() && !requiresLineBox(it))
2274 it.increment(); 2224 it.increment();
2275 2225
2276 return !it.atEnd(); 2226 return !it.atEnd();
2277 } 2227 }
2278 2228
2279 void LayoutBlockFlow::addOverflowFromInlineChildren() { 2229 void LayoutBlockFlow::addOverflowFromInlineChildren() {
2280 LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit(); 2230 LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit();
2281 // FIXME: Need to find another way to do this, since scrollbars could show 2231 // FIXME: Need to find another way to do this, since scrollbars could show whe n we don't want them to.
2282 // when we don't want them to.
2283 if (hasOverflowClip() && !endPadding && node() && 2232 if (hasOverflowClip() && !endPadding && node() &&
2284 isRootEditableElement(*node()) && style()->isLeftToRightDirection()) 2233 isRootEditableElement(*node()) && style()->isLeftToRightDirection())
2285 endPadding = LayoutUnit(1); 2234 endPadding = LayoutUnit(1);
2286 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { 2235 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
2287 addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding)); 2236 addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding));
2288 LayoutRect visualOverflow = 2237 LayoutRect visualOverflow =
2289 curr->visualOverflowRect(curr->lineTop(), curr->lineBottom()); 2238 curr->visualOverflowRect(curr->lineTop(), curr->lineBottom());
2290 addContentsVisualOverflow(visualOverflow); 2239 addContentsVisualOverflow(visualOverflow);
2291 } 2240 }
2292 2241
2293 if (!containsInlineWithOutlineAndContinuation()) 2242 if (!containsInlineWithOutlineAndContinuation())
2294 return; 2243 return;
2295 2244
2296 // Add outline rects of continuations of descendant inlines into visual 2245 // Add outline rects of continuations of descendant inlines into visual overfl ow of this block.
2297 // overflow of this block.
2298 LayoutRect outlineBoundsOfAllContinuations; 2246 LayoutRect outlineBoundsOfAllContinuations;
2299 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd(); 2247 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd();
2300 walker.advance()) { 2248 walker.advance()) {
2301 const LayoutObject& o = *walker.current().layoutObject(); 2249 const LayoutObject& o = *walker.current().layoutObject();
2302 if (!isInlineWithOutlineAndContinuation(o)) 2250 if (!isInlineWithOutlineAndContinuation(o))
2303 continue; 2251 continue;
2304 2252
2305 Vector<LayoutRect> outlineRects; 2253 Vector<LayoutRect> outlineRects;
2306 toLayoutInline(o).addOutlineRectsForContinuations( 2254 toLayoutInline(o).addOutlineRectsForContinuations(
2307 outlineRects, LayoutPoint(), 2255 outlineRects, LayoutPoint(),
2308 o.outlineRectsShouldIncludeBlockVisualOverflow()); 2256 o.outlineRectsShouldIncludeBlockVisualOverflow());
2309 if (!outlineRects.isEmpty()) { 2257 if (!outlineRects.isEmpty()) {
2310 LayoutRect outlineBounds = unionRectEvenIfEmpty(outlineRects); 2258 LayoutRect outlineBounds = unionRectEvenIfEmpty(outlineRects);
2311 outlineBounds.inflate(LayoutUnit(o.styleRef().outlineOutsetExtent())); 2259 outlineBounds.inflate(LayoutUnit(o.styleRef().outlineOutsetExtent()));
2312 outlineBoundsOfAllContinuations.unite(outlineBounds); 2260 outlineBoundsOfAllContinuations.unite(outlineBounds);
2313 } 2261 }
2314 } 2262 }
2315 addContentsVisualOverflow(outlineBoundsOfAllContinuations); 2263 addContentsVisualOverflow(outlineBoundsOfAllContinuations);
2316 } 2264 }
2317 2265
2318 void LayoutBlockFlow::deleteEllipsisLineBoxes() { 2266 void LayoutBlockFlow::deleteEllipsisLineBoxes() {
2319 ETextAlign textAlign = style()->textAlign(); 2267 ETextAlign textAlign = style()->textAlign();
2320 IndentTextOrNot indentText = IndentText; 2268 IndentTextOrNot indentText = IndentText;
2321 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { 2269 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
2322 if (curr->hasEllipsisBox()) { 2270 if (curr->hasEllipsisBox()) {
2323 curr->clearTruncation(); 2271 curr->clearTruncation();
2324 2272
2325 // Shift the line back where it belongs if we cannot accommodate an 2273 // Shift the line back where it belongs if we cannot accommodate an ellips is.
2326 // ellipsis.
2327 LayoutUnit logicalLeft = 2274 LayoutUnit logicalLeft =
2328 logicalLeftOffsetForLine(curr->lineTop(), indentText); 2275 logicalLeftOffsetForLine(curr->lineTop(), indentText);
2329 LayoutUnit availableLogicalWidth = 2276 LayoutUnit availableLogicalWidth =
2330 logicalRightOffsetForLine(curr->lineTop(), DoNotIndentText) - 2277 logicalRightOffsetForLine(curr->lineTop(), DoNotIndentText) -
2331 logicalLeft; 2278 logicalLeft;
2332 LayoutUnit totalLogicalWidth = curr->logicalWidth(); 2279 LayoutUnit totalLogicalWidth = curr->logicalWidth();
2333 updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, 2280 updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft,
2334 totalLogicalWidth, availableLogicalWidth, 2281 totalLogicalWidth, availableLogicalWidth,
2335 0); 2282 0);
2336 2283
(...skipping 10 matching lines...) Expand all
2347 const size_t fullStopStringLength = 3; 2294 const size_t fullStopStringLength = 3;
2348 const UChar fullStopString[] = {fullstopCharacter, fullstopCharacter, 2295 const UChar fullStopString[] = {fullstopCharacter, fullstopCharacter,
2349 fullstopCharacter}; 2296 fullstopCharacter};
2350 DEFINE_STATIC_LOCAL(AtomicString, fullstopCharacterStr, 2297 DEFINE_STATIC_LOCAL(AtomicString, fullstopCharacterStr,
2351 (fullStopString, fullStopStringLength)); 2298 (fullStopString, fullStopStringLength));
2352 DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, 2299 DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr,
2353 (&horizontalEllipsisCharacter, 1)); 2300 (&horizontalEllipsisCharacter, 1));
2354 AtomicString& selectedEllipsisStr = ellipsisStr; 2301 AtomicString& selectedEllipsisStr = ellipsisStr;
2355 2302
2356 const Font& firstLineFont = firstLineStyle()->font(); 2303 const Font& firstLineFont = firstLineStyle()->font();
2357 // FIXME: We should probably not hard-code the direction here. 2304 // FIXME: We should probably not hard-code the direction here. https://crbug.c om/333004
2358 // https://crbug.com/333004
2359 TextDirection ellipsisDirection = LTR; 2305 TextDirection ellipsisDirection = LTR;
2360 float firstLineEllipsisWidth = 0; 2306 float firstLineEllipsisWidth = 0;
2361 float ellipsisWidth = 0; 2307 float ellipsisWidth = 0;
2362 2308
2363 // As per CSS3 http://www.w3.org/TR/2003/CR-css3-text-20030514/ sequence of 2309 // As per CSS3 http://www.w3.org/TR/2003/CR-css3-text-20030514/ sequence of th ree
2364 // three Full Stops (002E) can be used. 2310 // Full Stops (002E) can be used.
2365 ASSERT(firstLineFont.primaryFont()); 2311 ASSERT(firstLineFont.primaryFont());
2366 if (firstLineFont.primaryFont()->glyphForCharacter( 2312 if (firstLineFont.primaryFont()->glyphForCharacter(
2367 horizontalEllipsisCharacter)) { 2313 horizontalEllipsisCharacter)) {
2368 firstLineEllipsisWidth = firstLineFont.width( 2314 firstLineEllipsisWidth = firstLineFont.width(
2369 constructTextRun(firstLineFont, &horizontalEllipsisCharacter, 1, 2315 constructTextRun(firstLineFont, &horizontalEllipsisCharacter, 1,
2370 *firstLineStyle(), ellipsisDirection)); 2316 *firstLineStyle(), ellipsisDirection));
2371 } else { 2317 } else {
2372 selectedEllipsisStr = fullstopCharacterStr; 2318 selectedEllipsisStr = fullstopCharacterStr;
2373 firstLineEllipsisWidth = firstLineFont.width( 2319 firstLineEllipsisWidth = firstLineFont.width(
2374 constructTextRun(firstLineFont, fullStopString, fullStopStringLength, 2320 constructTextRun(firstLineFont, fullStopString, fullStopStringLength,
2375 *firstLineStyle(), ellipsisDirection)); 2321 *firstLineStyle(), ellipsisDirection));
2376 } 2322 }
2377 ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : 0; 2323 ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : 0;
2378 2324
2379 if (!ellipsisWidth) { 2325 if (!ellipsisWidth) {
2380 ASSERT(font.primaryFont()); 2326 ASSERT(font.primaryFont());
2381 if (font.primaryFont()->glyphForCharacter(horizontalEllipsisCharacter)) { 2327 if (font.primaryFont()->glyphForCharacter(horizontalEllipsisCharacter)) {
2382 selectedEllipsisStr = ellipsisStr; 2328 selectedEllipsisStr = ellipsisStr;
2383 ellipsisWidth = 2329 ellipsisWidth =
2384 font.width(constructTextRun(font, &horizontalEllipsisCharacter, 1, 2330 font.width(constructTextRun(font, &horizontalEllipsisCharacter, 1,
2385 styleRef(), ellipsisDirection)); 2331 styleRef(), ellipsisDirection));
2386 } else { 2332 } else {
2387 selectedEllipsisStr = fullstopCharacterStr; 2333 selectedEllipsisStr = fullstopCharacterStr;
2388 ellipsisWidth = font.width( 2334 ellipsisWidth = font.width(
2389 constructTextRun(font, fullStopString, fullStopStringLength, 2335 constructTextRun(font, fullStopString, fullStopStringLength,
2390 styleRef(), ellipsisDirection)); 2336 styleRef(), ellipsisDirection));
2391 } 2337 }
2392 } 2338 }
2393 2339
2394 // For LTR text truncation, we want to get the right edge of our padding box, 2340 // For LTR text truncation, we want to get the right edge of our padding box, and then we want to see
2395 // and then we want to see if the right edge of a line box exceeds that. 2341 // if the right edge of a line box exceeds that. For RTL, we use the left edg e of the padding box and
2396 // For RTL, we use the left edge of the padding box and check the left edge of 2342 // check the left edge of the line box to see if it is less
2397 // the line box to see if it is less Include the scrollbar for overflow 2343 // Include the scrollbar for overflow blocks, which means we want to use "cont entWidth()"
2398 // blocks, which means we want to use "contentWidth()".
2399 bool ltr = style()->isLeftToRightDirection(); 2344 bool ltr = style()->isLeftToRightDirection();
2400 ETextAlign textAlign = style()->textAlign(); 2345 ETextAlign textAlign = style()->textAlign();
2401 IndentTextOrNot indentText = IndentText; 2346 IndentTextOrNot indentText = IndentText;
2402 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { 2347 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
2403 LayoutUnit currLogicalLeft = curr->logicalLeft(); 2348 LayoutUnit currLogicalLeft = curr->logicalLeft();
2404 LayoutUnit blockRightEdge = 2349 LayoutUnit blockRightEdge =
2405 logicalRightOffsetForLine(curr->lineTop(), indentText); 2350 logicalRightOffsetForLine(curr->lineTop(), indentText);
2406 LayoutUnit blockLeftEdge = 2351 LayoutUnit blockLeftEdge =
2407 logicalLeftOffsetForLine(curr->lineTop(), indentText); 2352 logicalLeftOffsetForLine(curr->lineTop(), indentText);
2408 LayoutUnit lineBoxEdge = 2353 LayoutUnit lineBoxEdge =
2409 ltr ? currLogicalLeft + curr->logicalWidth() : currLogicalLeft; 2354 ltr ? currLogicalLeft + curr->logicalWidth() : currLogicalLeft;
2410 if ((ltr && lineBoxEdge > blockRightEdge) || 2355 if ((ltr && lineBoxEdge > blockRightEdge) ||
2411 (!ltr && lineBoxEdge < blockLeftEdge)) { 2356 (!ltr && lineBoxEdge < blockLeftEdge)) {
2412 // This line spills out of our box in the appropriate direction. Now we 2357 // This line spills out of our box in the appropriate direction. Now we n eed to see if the line
2413 // need to see if the line can be truncated. In order for truncation to 2358 // can be truncated. In order for truncation to be possible, the line mus t have sufficient space to
2414 // be possible, the line must have sufficient space to accommodate our 2359 // accommodate our truncation string, and no replaced elements (images, ta bles) can overlap the ellipsis
2415 // truncation string, and no replaced elements (images, tables) can 2360 // space.
2416 // overlap the ellipsis space.
2417 2361
2418 LayoutUnit width(indentText == IndentText ? firstLineEllipsisWidth 2362 LayoutUnit width(indentText == IndentText ? firstLineEllipsisWidth
2419 : ellipsisWidth); 2363 : ellipsisWidth);
2420 LayoutUnit blockEdge = ltr ? blockRightEdge : blockLeftEdge; 2364 LayoutUnit blockEdge = ltr ? blockRightEdge : blockLeftEdge;
2421 if (curr->lineCanAccommodateEllipsis( 2365 if (curr->lineCanAccommodateEllipsis(
2422 ltr, blockEdge.toInt(), lineBoxEdge.toInt(), width.toInt())) { 2366 ltr, blockEdge.toInt(), lineBoxEdge.toInt(), width.toInt())) {
2423 LayoutUnit totalLogicalWidth = curr->placeEllipsis( 2367 LayoutUnit totalLogicalWidth = curr->placeEllipsis(
2424 selectedEllipsisStr, ltr, blockLeftEdge, blockRightEdge, width); 2368 selectedEllipsisStr, ltr, blockLeftEdge, blockRightEdge, width);
2425 LayoutUnit logicalLeft; // We are only interested in the delta from the 2369 LayoutUnit
2426 // base position. 2370 logicalLeft; // We are only interested in the delta from the base p osition.
2427 LayoutUnit availableLogicalWidth = blockRightEdge - blockLeftEdge; 2371 LayoutUnit availableLogicalWidth = blockRightEdge - blockLeftEdge;
2428 updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, 2372 updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft,
2429 totalLogicalWidth, availableLogicalWidth, 2373 totalLogicalWidth, availableLogicalWidth,
2430 0); 2374 0);
2431 if (ltr) 2375 if (ltr)
2432 curr->moveInInlineDirection(logicalLeft); 2376 curr->moveInInlineDirection(logicalLeft);
2433 else 2377 else
2434 curr->moveInInlineDirection( 2378 curr->moveInInlineDirection(
2435 logicalLeft - (availableLogicalWidth - totalLogicalWidth)); 2379 logicalLeft - (availableLogicalWidth - totalLogicalWidth));
2436 } 2380 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2480 case TASTART: 2424 case TASTART:
2481 applyIndentText = true; 2425 applyIndentText = true;
2482 break; 2426 break;
2483 default: 2427 default:
2484 applyIndentText = false; 2428 applyIndentText = false;
2485 } 2429 }
2486 2430
2487 if (applyIndentText) 2431 if (applyIndentText)
2488 return startOffsetForLine(position, indentText); 2432 return startOffsetForLine(position, indentText);
2489 2433
2490 // updateLogicalWidthForAlignment() handles the direction of the block so no 2434 // updateLogicalWidthForAlignment() handles the direction of the block so no n eed to consider it here
2491 // need to consider it here
2492 LayoutUnit totalLogicalWidth; 2435 LayoutUnit totalLogicalWidth;
2493 LayoutUnit logicalLeft = 2436 LayoutUnit logicalLeft =
2494 logicalLeftOffsetForLine(logicalHeight(), DoNotIndentText); 2437 logicalLeftOffsetForLine(logicalHeight(), DoNotIndentText);
2495 LayoutUnit availableLogicalWidth = 2438 LayoutUnit availableLogicalWidth =
2496 logicalRightOffsetForLine(logicalHeight(), DoNotIndentText) - logicalLeft; 2439 logicalRightOffsetForLine(logicalHeight(), DoNotIndentText) - logicalLeft;
2497 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, 2440 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft,
2498 totalLogicalWidth, availableLogicalWidth, 0); 2441 totalLogicalWidth, availableLogicalWidth, 0);
2499 2442
2500 if (!style()->isLeftToRightDirection()) 2443 if (!style()->isLeftToRightDirection())
2501 return logicalWidth() - logicalLeft; 2444 return logicalWidth() - logicalLeft;
2502 return logicalLeft; 2445 return logicalLeft;
2503 } 2446 }
2504 2447
2505 void LayoutBlockFlow::setShouldDoFullPaintInvalidationForFirstLine() { 2448 void LayoutBlockFlow::setShouldDoFullPaintInvalidationForFirstLine() {
2506 ASSERT(childrenInline()); 2449 ASSERT(childrenInline());
2507 if (RootInlineBox* firstRootBox = this->firstRootBox()) 2450 if (RootInlineBox* firstRootBox = this->firstRootBox())
2508 firstRootBox->setShouldDoFullPaintInvalidationRecursively(); 2451 firstRootBox->setShouldDoFullPaintInvalidationRecursively();
2509 } 2452 }
2510 2453
2511 bool LayoutBlockFlow::paintedOutputOfObjectHasNoEffectRegardlessOfSize() const { 2454 bool LayoutBlockFlow::paintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
2512 // LayoutBlockFlow is in charge of paint invalidation of the first line. 2455 // LayoutBlockFlow is in charge of paint invalidation of the first line.
2513 if (firstLineBox()) 2456 if (firstLineBox())
2514 return false; 2457 return false;
2515 2458
2516 return LayoutBlock::paintedOutputOfObjectHasNoEffectRegardlessOfSize(); 2459 return LayoutBlock::paintedOutputOfObjectHasNoEffectRegardlessOfSize();
2517 } 2460 }
2518 2461
2519 } // namespace blink 2462 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp ('k') | third_party/WebKit/Source/core/layout/LayoutBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698