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

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

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