[iOS] Don't build DumpRenderTree, gtest, or TestWebKitAPI
[WebKit-https.git] / Source / WebCore / rendering / RenderBlockLineLayout.cpp
1 /*
2  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
4  * Copyright (C) 2010 Google Inc. All rights reserved.
5  * Copyright (C) 2013 ChangSeok Oh <shivamidow@gmail.com>
6  * Copyright (C) 2013 Adobe Systems Inc. All right reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #include "config.h"
26
27 #include "AXObjectCache.h"
28 #include "BidiResolver.h"
29 #include "BreakingContextInlineHeaders.h"
30 #include "FloatingObjects.h"
31 #include "InlineElementBox.h"
32 #include "InlineIterator.h"
33 #include "InlineTextBox.h"
34 #include "LineLayoutState.h"
35 #include "Logging.h"
36 #include "RenderBlockFlow.h"
37 #include "RenderFlowThread.h"
38 #include "RenderLineBreak.h"
39 #include "RenderRegion.h"
40 #include "RenderView.h"
41 #include "Settings.h"
42 #include "SimpleLineLayoutFunctions.h"
43 #include "TrailingFloatsRootInlineBox.h"
44 #include "VerticalPositionCache.h"
45 #include <wtf/RefCountedLeakCounter.h>
46 #include <wtf/StdLibExtras.h>
47
48 #if ENABLE(SVG)
49 #include "SVGRootInlineBox.h"
50 #endif
51
52 namespace WebCore {
53
54 static void determineDirectionality(TextDirection& dir, InlineIterator iter)
55 {
56     while (!iter.atEnd()) {
57         if (iter.atParagraphSeparator())
58             return;
59         if (UChar current = iter.current()) {
60             UCharDirection charDirection = u_charDirection(current);
61             if (charDirection == U_LEFT_TO_RIGHT) {
62                 dir = LTR;
63                 return;
64             }
65             if (charDirection == U_RIGHT_TO_LEFT || charDirection == U_RIGHT_TO_LEFT_ARABIC) {
66                 dir = RTL;
67                 return;
68             }
69         }
70         iter.increment();
71     }
72 }
73
74 inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
75 {
76     ASSERT(obj);
77     return new BidiRun(start, end, *obj, resolver.context(), resolver.dir());
78 }
79
80 void RenderBlockFlow::appendRunsForObject(BidiRunList<BidiRun>& runs, int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
81 {
82     if (start > end || shouldSkipCreatingRunsForObject(obj))
83         return;
84
85     LineMidpointState& lineMidpointState = resolver.midpointState();
86     bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointState.numMidpoints);
87     InlineIterator nextMidpoint;
88     if (haveNextMidpoint)
89         nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidpoint];
90     if (lineMidpointState.betweenMidpoints) {
91         if (!(haveNextMidpoint && nextMidpoint.renderer() == obj))
92             return;
93         // This is a new start point. Stop ignoring objects and
94         // adjust our start.
95         lineMidpointState.betweenMidpoints = false;
96         start = nextMidpoint.offset();
97         lineMidpointState.currentMidpoint++;
98         if (start < end)
99             return appendRunsForObject(runs, start, end, obj, resolver);
100     } else {
101         if (!haveNextMidpoint || (obj != nextMidpoint.renderer())) {
102             runs.addRun(createRun(start, end, obj, resolver));
103             return;
104         }
105
106         // An end midpoint has been encountered within our object.  We
107         // need to go ahead and append a run with our endpoint.
108         if (static_cast<int>(nextMidpoint.offset() + 1) <= end) {
109             lineMidpointState.betweenMidpoints = true;
110             lineMidpointState.currentMidpoint++;
111             if (nextMidpoint.offset() != UINT_MAX) { // UINT_MAX means stop at the object and don't include any of it.
112                 if (static_cast<int>(nextMidpoint.offset() + 1) > start)
113                     runs.addRun(createRun(start, nextMidpoint.offset() + 1, obj, resolver));
114                 return appendRunsForObject(runs, nextMidpoint.offset() + 1, end, obj, resolver);
115             }
116         } else
117            runs.addRun(createRun(start, end, obj, resolver));
118     }
119 }
120
121 std::unique_ptr<RootInlineBox> RenderBlockFlow::createRootInlineBox()
122 {
123     return std::make_unique<RootInlineBox>(*this);
124 }
125
126 RootInlineBox* RenderBlockFlow::createAndAppendRootInlineBox()
127 {
128     auto newRootBox = createRootInlineBox();
129     RootInlineBox* rootBox = newRootBox.get();
130     m_lineBoxes.appendLineBox(std::move(newRootBox));
131
132     if (UNLIKELY(AXObjectCache::accessibilityEnabled()) && firstRootBox() == rootBox) {
133         if (AXObjectCache* cache = document().existingAXObjectCache())
134             cache->recomputeIsIgnored(this);
135     }
136
137     return rootBox;
138 }
139
140 static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
141 {
142     if (isRootLineBox)
143         return toRenderBlockFlow(obj)->createAndAppendRootInlineBox();
144
145     if (obj->isText())
146         return toRenderText(obj)->createInlineTextBox();
147
148     if (obj->isBox()) {
149         // FIXME: This is terrible. This branch returns an *owned* pointer!
150         return toRenderBox(obj)->createInlineBox().release();
151     }
152
153     if (obj->isLineBreak()) {
154         // FIXME: This is terrible. This branch returns an *owned* pointer!
155         auto inlineBox = toRenderLineBreak(obj)->createInlineBox().release();
156         // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode
157         // (Note the use of strict mode. In "almost strict" mode, we don't treat the box for <br> as text.)
158         inlineBox->setBehavesLikeText(isOnlyRun || obj->document().inNoQuirksMode() || obj->isLineBreakOpportunity());
159         return inlineBox;
160     }
161
162     return toRenderInline(obj)->createAndAppendInlineFlowBox();
163 }
164
165 static inline void dirtyLineBoxesForRenderer(RenderObject& renderer, bool fullLayout)
166 {
167     if (renderer.isText()) {
168         RenderText& renderText = toRenderText(renderer);
169         updateCounterIfNeeded(renderText);
170         renderText.dirtyLineBoxes(fullLayout);
171     } else if (renderer.isLineBreak())
172         toRenderLineBreak(renderer).dirtyLineBoxes(fullLayout);
173     else
174         toRenderInline(renderer).dirtyLineBoxes(fullLayout);
175 }
176
177 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox)
178 {
179     do {
180         if (parentBox->isConstructed() || parentBox->nextOnLine())
181             return true;
182         parentBox = parentBox->parent();
183     } while (parentBox);
184     return false;
185 }
186
187 InlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInfo& lineInfo, InlineBox* childBox, bool startNewSegment)
188 {
189     // See if we have an unconstructed line box for this object that is also
190     // the last item on the line.
191     unsigned lineDepth = 1;
192     InlineFlowBox* parentBox = 0;
193     InlineFlowBox* result = 0;
194     bool hasDefaultLineBoxContain = style().lineBoxContain() == RenderStyle::initialLineBoxContain();
195     do {
196         ASSERT_WITH_SECURITY_IMPLICATION(obj->isRenderInline() || obj == this);
197
198         RenderInline* inlineFlow = (obj != this) ? toRenderInline(obj) : 0;
199
200         // Get the last box we made for this render object.
201         parentBox = inlineFlow ? inlineFlow->lastLineBox() : toRenderBlockFlow(obj)->lastRootBox();
202
203         // If this box or its ancestor is constructed then it is from a previous line, and we need
204         // to make a new box for our line.  If this box or its ancestor is unconstructed but it has
205         // something following it on the line, then we know we have to make a new box
206         // as well.  In this situation our inline has actually been split in two on
207         // the same line (this can happen with very fancy language mixtures).
208         bool constructedNewBox = false;
209         bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow || inlineFlow->alwaysCreateLineBoxes();
210         bool mustCreateBoxesToRoot = startNewSegment && !(parentBox && parentBox->isRootInlineBox());
211         bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox) && !mustCreateBoxesToRoot;
212         if (allowedToConstructNewBox && !canUseExistingParentBox) {
213             // We need to make a new box for this render object.  Once
214             // made, we need to place it at the end of the current line.
215             InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this);
216             ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox());
217             parentBox = toInlineFlowBox(newBox);
218             parentBox->setIsFirstLine(lineInfo.isFirstLine());
219             parentBox->setIsHorizontal(isHorizontalWritingMode());
220             if (!hasDefaultLineBoxContain)
221                 parentBox->clearDescendantsHaveSameLineHeightAndBaseline();
222             constructedNewBox = true;
223         }
224
225         if (constructedNewBox || canUseExistingParentBox) {
226             if (!result)
227                 result = parentBox;
228
229             // If we have hit the block itself, then |box| represents the root
230             // inline box for the line, and it doesn't have to be appended to any parent
231             // inline.
232             if (childBox)
233                 parentBox->addToLine(childBox);
234
235             if (!constructedNewBox || obj == this)
236                 break;
237
238             childBox = parentBox;
239         }
240
241         // If we've exceeded our line depth, then jump straight to the root and skip all the remaining
242         // intermediate inline flows.
243         obj = (++lineDepth >= cMaxLineDepth) ? this : obj->parent();
244
245     } while (true);
246
247     return result;
248 }
249
250 template <typename CharacterType>
251 static inline bool endsWithASCIISpaces(const CharacterType* characters, unsigned pos, unsigned end)
252 {
253     while (isASCIISpace(characters[pos])) {
254         pos++;
255         if (pos >= end)
256             return true;
257     }
258     return false;
259 }
260
261 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns)
262 {
263     BidiRun* run = bidiRuns.logicallyLastRun();
264     if (!run)
265         return true;
266     unsigned pos = run->stop();
267     const RenderObject& r = run->renderer();
268     if (!r.isText())
269         return false;
270     const RenderText& renderText = toRenderText(r);
271     unsigned length = renderText.textLength();
272     if (pos >= length)
273         return true;
274
275     if (renderText.is8Bit())
276         return endsWithASCIISpaces(renderText.characters8(), pos, length);
277     return endsWithASCIISpaces(renderText.characters16(), pos, length);
278 }
279
280 RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, const LineInfo& lineInfo)
281 {
282     ASSERT(bidiRuns.firstRun());
283
284     bool rootHasSelectedChildren = false;
285     InlineFlowBox* parentBox = 0;
286     int runCount = bidiRuns.runCount() - lineInfo.runsFromLeadingWhitespace();
287     for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) {
288         // Create a box for our object.
289         bool isOnlyRun = (runCount == 1);
290         if (runCount == 2 && !r->renderer().isListMarker())
291             isOnlyRun = (!style().isLeftToRightDirection() ? bidiRuns.lastRun() : bidiRuns.firstRun())->renderer().isListMarker();
292
293         if (lineInfo.isEmpty())
294             continue;
295
296         InlineBox* box = createInlineBoxForRenderer(&r->renderer(), false, isOnlyRun);
297         r->setBox(*box);
298
299         if (!rootHasSelectedChildren && box->renderer().selectionState() != RenderObject::SelectionNone)
300             rootHasSelectedChildren = true;
301
302         // If we have no parent box yet, or if the run is not simply a sibling,
303         // then we need to construct inline boxes as necessary to properly enclose the
304         // run's inline box. Segments can only be siblings at the root level, as
305         // they are positioned separately.
306 #if ENABLE(CSS_SHAPES)
307         bool runStartsSegment = r->m_startsSegment;
308 #else
309         bool runStartsSegment = false;
310 #endif
311         if (!parentBox || &parentBox->renderer() != r->renderer().parent() || runStartsSegment)
312             // Create new inline boxes all the way back to the appropriate insertion point.
313             parentBox = createLineBoxes(r->renderer().parent(), lineInfo, box, runStartsSegment);
314         else {
315             // Append the inline box to this line.
316             parentBox->addToLine(box);
317         }
318
319         bool visuallyOrdered = r->renderer().style().rtlOrdering() == VisualOrder;
320         box->setBidiLevel(r->level());
321
322         if (box->isInlineTextBox()) {
323             InlineTextBox* text = toInlineTextBox(box);
324             text->setStart(r->m_start);
325             text->setLen(r->m_stop - r->m_start);
326             text->setDirOverride(r->dirOverride(visuallyOrdered));
327             if (r->m_hasHyphen)
328                 text->setHasHyphen(true);
329         }
330     }
331
332     // We should have a root inline box.  It should be unconstructed and
333     // be the last continuation of our line list.
334     ASSERT(lastRootBox() && !lastRootBox()->isConstructed());
335
336     // Set the m_selectedChildren flag on the root inline box if one of the leaf inline box
337     // from the bidi runs walk above has a selection state.
338     if (rootHasSelectedChildren)
339         lastRootBox()->root().setHasSelectedChildren(true);
340
341     // Set bits on our inline flow boxes that indicate which sides should
342     // paint borders/margins/padding.  This knowledge will ultimately be used when
343     // we determine the horizontal positions and widths of all the inline boxes on
344     // the line.
345     bool isLogicallyLastRunWrapped = bidiRuns.logicallyLastRun()->renderer().isText() ? !reachedEndOfTextRenderer(bidiRuns) : true;
346     lastRootBox()->determineSpacingForFlowBoxes(lineInfo.isLastLine(), isLogicallyLastRunWrapped, &bidiRuns.logicallyLastRun()->renderer());
347
348     // Now mark the line boxes as being constructed.
349     lastRootBox()->setConstructed();
350
351     // Return the last line.
352     return lastRootBox();
353 }
354
355 ETextAlign RenderBlockFlow::textAlignmentForLine(bool endsWithSoftBreak) const
356 {
357     ETextAlign alignment = style().textAlign();
358     if (endsWithSoftBreak)
359         return alignment;
360
361 #if !ENABLE(CSS3_TEXT)
362     return (alignment == JUSTIFY) ? TASTART : alignment;
363 #else
364     if (alignment != JUSTIFY)
365         return alignment;
366
367     TextAlignLast alignmentLast = style().textAlignLast();
368     switch (alignmentLast) {
369     case TextAlignLastStart:
370         return TASTART;
371     case TextAlignLastEnd:
372         return TAEND;
373     case TextAlignLastLeft:
374         return LEFT;
375     case TextAlignLastRight:
376         return RIGHT;
377     case TextAlignLastCenter:
378         return CENTER;
379     case TextAlignLastJustify:
380         return JUSTIFY;
381     case TextAlignLastAuto:
382         if (style().textJustify() == TextJustifyDistribute)
383             return JUSTIFY;
384         return TASTART;
385     }
386     return alignment;
387 #endif
388 }
389
390 static void updateLogicalWidthForLeftAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
391 {
392     // 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 left.
394     if (isLeftToRightDirection) {
395         if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
396             trailingSpaceRun->box()->setLogicalWidth(std::max<float>(0, trailingSpaceRun->box()->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
397         return;
398     }
399
400     if (trailingSpaceRun)
401         trailingSpaceRun->box()->setLogicalWidth(0);
402     else if (totalLogicalWidth > availableLogicalWidth)
403         logicalLeft -= (totalLogicalWidth - availableLogicalWidth);
404 }
405
406 static void updateLogicalWidthForRightAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
407 {
408     // Wide lines spill out of the block based off direction.
409     // So even if text-align is right, if direction is LTR, wide lines should overflow out of the right
410     // side of the block.
411     if (isLeftToRightDirection) {
412         if (trailingSpaceRun) {
413             totalLogicalWidth -= trailingSpaceRun->box()->logicalWidth();
414             trailingSpaceRun->box()->setLogicalWidth(0);
415         }
416         if (totalLogicalWidth < availableLogicalWidth)
417             logicalLeft += availableLogicalWidth - totalLogicalWidth;
418         return;
419     }
420
421     if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) {
422         trailingSpaceRun->box()->setLogicalWidth(std::max<float>(0, trailingSpaceRun->box()->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
423         totalLogicalWidth -= trailingSpaceRun->box()->logicalWidth();
424     } else
425         logicalLeft += availableLogicalWidth - totalLogicalWidth;
426 }
427
428 static void updateLogicalWidthForCenterAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
429 {
430     float trailingSpaceWidth = 0;
431     if (trailingSpaceRun) {
432         totalLogicalWidth -= trailingSpaceRun->box()->logicalWidth();
433         trailingSpaceWidth = std::min(trailingSpaceRun->box()->logicalWidth(), (availableLogicalWidth - totalLogicalWidth + 1) / 2);
434         trailingSpaceRun->box()->setLogicalWidth(std::max<float>(0, trailingSpaceWidth));
435     }
436     if (isLeftToRightDirection)
437         logicalLeft += std::max<float>((availableLogicalWidth - totalLogicalWidth) / 2, 0);
438     else
439         logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLogicalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth;
440 }
441
442 void RenderBlockFlow::setMarginsForRubyRun(BidiRun* run, RenderRubyRun& renderer, RenderObject* previousObject, const LineInfo& lineInfo)
443 {
444     int startOverhang;
445     int endOverhang;
446     RenderObject* nextObject = 0;
447     for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNextObject = runWithNextObject->next()) {
448         if (!runWithNextObject->renderer().isOutOfFlowPositioned() && !runWithNextObject->box()->isLineBreak()) {
449             nextObject = &runWithNextObject->renderer();
450             break;
451         }
452     }
453     renderer.getOverhang(lineInfo.isFirstLine(), renderer.style().isLeftToRightDirection() ? previousObject : nextObject, renderer.style().isLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhang);
454     setMarginStartForChild(renderer, -startOverhang);
455     setMarginEndForChild(renderer, -endOverhang);
456 }
457
458 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* run, RenderText* renderer, float xPos, const LineInfo& lineInfo,
459     GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements)
460 {
461     HashSet<const SimpleFontData*> fallbackFonts;
462     GlyphOverflow glyphOverflow;
463
464     const Font& font = lineStyle(*renderer->parent(), lineInfo).font();
465     // Always compute glyph overflow if the block's line-box-contain value is "glyphs".
466     if (lineBox->fitsToGlyphs()) {
467         // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization
468         // will keep us from computing glyph bounds in nearly all cases.
469         bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading();
470         int baselineShift = lineBox->verticalPositionForBox(run->box(), verticalPositionCache);
471         int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0;
472         int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0;
473         int boxAscent = font.fontMetrics().ascent() - baselineShift;
474         int boxDescent = font.fontMetrics().descent() + baselineShift;
475         if (boxAscent > rootDescent ||  boxDescent > rootAscent)
476             glyphOverflow.computeBounds = true; 
477     }
478     
479     LayoutUnit hyphenWidth = 0;
480     if (toInlineTextBox(run->box())->hasHyphen())
481         hyphenWidth = measureHyphenWidth(renderer, font, &fallbackFonts);
482
483     float measuredWidth = 0;
484
485     bool kerningIsEnabled = font.typesettingFeatures() & Kerning;
486     bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath();
487     
488     // Since we don't cache glyph overflows, we need to re-measure the run if
489     // the style is linebox-contain: glyph.
490     
491     if (!lineBox->fitsToGlyphs() && canUseSimpleFontCodePath) {
492         int lastEndOffset = run->m_start;
493         for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOffset < run->m_stop; ++i) {
494             WordMeasurement& wordMeasurement = wordMeasurements[i];
495             if (wordMeasurement.width <= 0 || wordMeasurement.startOffset == wordMeasurement.endOffset)
496                 continue;
497             if (wordMeasurement.renderer != renderer || wordMeasurement.startOffset != lastEndOffset || wordMeasurement.endOffset > run->m_stop)
498                 continue;
499
500             lastEndOffset = wordMeasurement.endOffset;
501             if (kerningIsEnabled && lastEndOffset == run->m_stop) {
502                 int wordLength = lastEndOffset - wordMeasurement.startOffset;
503                 GlyphOverflow overflow;
504                 measuredWidth += renderer->width(wordMeasurement.startOffset, wordLength, xPos + measuredWidth, lineInfo.isFirstLine(),
505                     &wordMeasurement.fallbackFonts, &overflow);
506                 UChar c = renderer->characterAt(wordMeasurement.startOffset);
507                 if (i > 0 && wordLength == 1 && (c == ' ' || c == '\t'))
508                     measuredWidth += renderer->style().font().wordSpacing();
509             } else
510                 measuredWidth += wordMeasurement.width;
511             if (!wordMeasurement.fallbackFonts.isEmpty()) {
512                 HashSet<const SimpleFontData*>::const_iterator end = wordMeasurement.fallbackFonts.end();
513                 for (HashSet<const SimpleFontData*>::const_iterator it = wordMeasurement.fallbackFonts.begin(); it != end; ++it)
514                     fallbackFonts.add(*it);
515             }
516         }
517         if (measuredWidth && lastEndOffset != run->m_stop) {
518             // If we don't have enough cached data, we'll measure the run again.
519             measuredWidth = 0;
520             fallbackFonts.clear();
521         }
522     }
523
524     if (!measuredWidth)
525         measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow);
526
527     run->box()->setLogicalWidth(measuredWidth + hyphenWidth);
528     if (!fallbackFonts.isEmpty()) {
529         ASSERT(run->box()->behavesLikeText());
530         GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->box()), std::make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator;
531         ASSERT(it->value.first.isEmpty());
532         copyToVector(fallbackFonts, it->value.first);
533         run->box()->parent()->clearDescendantsHaveSameLineHeightAndBaseline();
534     }
535     if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) {
536         ASSERT(run->box()->behavesLikeText());
537         GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->box()), std::make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator;
538         it->value.second = glyphOverflow;
539         run->box()->clearKnownToHaveNoOverflow();
540     }
541 }
542
543 static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, Vector<unsigned, 16>& expansionOpportunities, unsigned expansionOpportunityCount, float& totalLogicalWidth, float availableLogicalWidth)
544 {
545     if (!expansionOpportunityCount || availableLogicalWidth <= totalLogicalWidth)
546         return;
547
548     size_t i = 0;
549     for (BidiRun* r = firstRun; r; r = r->next()) {
550 #if ENABLE(CSS_SHAPES)
551         // This method is called once per segment, do not move past the current segment.
552         if (r->m_startsSegment)
553             break;
554 #endif
555         if (!r->box() || r == trailingSpaceRun)
556             continue;
557         
558         if (r->renderer().isText()) {
559             unsigned opportunitiesInRun = expansionOpportunities[i++];
560             
561             ASSERT(opportunitiesInRun <= expansionOpportunityCount);
562             
563             // Only justify text if whitespace is collapsed.
564             if (r->renderer().style().collapseWhiteSpace()) {
565                 InlineTextBox* textBox = toInlineTextBox(r->box());
566                 int expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
567                 textBox->setExpansion(expansion);
568                 totalLogicalWidth += expansion;
569             }
570             expansionOpportunityCount -= opportunitiesInRun;
571             if (!expansionOpportunityCount)
572                 break;
573         }
574     }
575 }
576
577 void RenderBlockFlow::updateLogicalWidthForAlignment(const ETextAlign& textAlign, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount)
578 {
579     // Armed with the total width of the line (without justification),
580     // we now examine our text-align property in order to determine where to position the
581     // objects horizontally. The total width of the line can be increased if we end up
582     // justifying text.
583     switch (textAlign) {
584     case LEFT:
585     case WEBKIT_LEFT:
586         updateLogicalWidthForLeftAlignedBlock(style().isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
587         break;
588     case RIGHT:
589     case WEBKIT_RIGHT:
590         updateLogicalWidthForRightAlignedBlock(style().isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
591         break;
592     case CENTER:
593     case WEBKIT_CENTER:
594         updateLogicalWidthForCenterAlignedBlock(style().isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
595         break;
596     case JUSTIFY:
597         adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, availableLogicalWidth);
598         if (expansionOpportunityCount) {
599             if (trailingSpaceRun) {
600                 totalLogicalWidth -= trailingSpaceRun->box()->logicalWidth();
601                 trailingSpaceRun->box()->setLogicalWidth(0);
602             }
603             break;
604         }
605         // Fall through
606     case TASTART:
607         if (style().isLeftToRightDirection())
608             updateLogicalWidthForLeftAlignedBlock(style().isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
609         else
610             updateLogicalWidthForRightAlignedBlock(style().isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
611         break;
612     case TAEND:
613         if (style().isLeftToRightDirection())
614             updateLogicalWidthForRightAlignedBlock(style().isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
615         else
616             updateLogicalWidthForLeftAlignedBlock(style().isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
617         break;
618     }
619 }
620
621 static void updateLogicalInlinePositions(RenderBlockFlow& block, float& lineLogicalLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine, IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight)
622 {
623     LayoutUnit lineLogicalHeight = block.minLineHeightForReplacedRenderer(firstLine, boxLogicalHeight);
624     lineLogicalLeft = block.pixelSnappedLogicalLeftOffsetForLine(block.logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight);
625     lineLogicalRight = block.pixelSnappedLogicalRightOffsetForLine(block.logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight);
626     availableLogicalWidth = lineLogicalRight - lineLogicalLeft;
627 }
628
629 void RenderBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements)
630 {
631     ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak());
632     
633     // CSS 2.1: "'Text-indent' only affects a line if it is the first formatted line of an element. For example, the first line of an anonymous block 
634     // box is only affected if it is the first child of its parent element."
635     // CSS3 "text-indent", "-webkit-each-line" affects the first line of the block container as well as each line after a forced line break,
636     // but does not affect lines after a soft wrap break.
637     bool isFirstLine = lineInfo.isFirstLine() && !(isAnonymousBlock() && parent()->firstChild() != this);
638     bool isAfterHardLineBreak = lineBox->prevRootBox() && lineBox->prevRootBox()->endsWithBreak();
639     IndentTextOrNot shouldIndentText = requiresIndent(isFirstLine, isAfterHardLineBreak, style());
640     float lineLogicalLeft;
641     float lineLogicalRight;
642     float availableLogicalWidth;
643     updateLogicalInlinePositions(*this, lineLogicalLeft, lineLogicalRight, availableLogicalWidth, isFirstLine, shouldIndentText, 0);
644     bool needsWordSpacing;
645 #if ENABLE(CSS_SHAPES)
646     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
647     if (shapeInsideInfo && shapeInsideInfo->hasSegments()) {
648         BidiRun* segmentStart = firstRun;
649         const SegmentList& segments = shapeInsideInfo->segments();
650         float logicalLeft = std::max<float>(roundToInt(segments[0].logicalLeft), lineLogicalLeft);
651         float logicalRight = std::min<float>(floorToInt(segments[0].logicalRight), lineLogicalRight);
652         float startLogicalLeft = logicalLeft;
653         float endLogicalRight = logicalLeft;
654         float minLogicalLeft = logicalLeft;
655         float maxLogicalRight = logicalLeft;
656         lineBox->beginPlacingBoxRangesInInlineDirection(logicalLeft);
657         for (size_t i = 0; i < segments.size(); i++) {
658             if (i) {
659                 logicalLeft = std::max<float>(roundToInt(segments[i].logicalLeft), lineLogicalLeft);
660                 logicalRight = std::min<float>(floorToInt(segments[i].logicalRight), lineLogicalRight);
661             }
662             availableLogicalWidth = logicalRight - logicalLeft;
663             BidiRun* newSegmentStart = computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, logicalLeft, availableLogicalWidth, segmentStart, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements);
664             needsWordSpacing = false;
665             endLogicalRight = lineBox->placeBoxRangeInInlineDirection(segmentStart->box(), newSegmentStart ? newSegmentStart->box() : 0, logicalLeft, minLogicalLeft, maxLogicalRight, needsWordSpacing, textBoxDataMap);
666             if (!newSegmentStart || !newSegmentStart->next())
667                 break;
668             ASSERT(newSegmentStart->m_startsSegment);
669             // Discard the empty segment start marker bidi runs
670             segmentStart = newSegmentStart->next();
671         }
672         lineBox->endPlacingBoxRangesInInlineDirection(startLogicalLeft, endLogicalRight, minLogicalLeft, maxLogicalRight);
673         return;
674     }
675 #endif
676
677     if (firstRun && firstRun->renderer().isReplaced()) {
678         RenderBox& renderBox = toRenderBox(firstRun->renderer());
679         updateLogicalInlinePositions(*this, lineLogicalLeft, lineLogicalRight, availableLogicalWidth, isFirstLine, shouldIndentText, renderBox.logicalHeight());
680     }
681
682     computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, lineLogicalLeft, availableLogicalWidth, firstRun, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements);
683     // The widths of all runs are now known. We can now place every inline box (and
684     // compute accurate widths for the inline flow boxes).
685     needsWordSpacing = false;
686     lineBox->placeBoxesInInlineDirection(lineLogicalLeft, needsWordSpacing, textBoxDataMap);
687 }
688
689 BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBox* lineBox, const LineInfo& lineInfo, ETextAlign textAlign, float& logicalLeft, 
690     float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache,
691     WordMeasurements& wordMeasurements)
692 {
693     bool needsWordSpacing = false;
694     float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
695     unsigned expansionOpportunityCount = 0;
696     bool isAfterExpansion = true;
697     Vector<unsigned, 16> expansionOpportunities;
698     RenderObject* previousObject = 0;
699
700     BidiRun* r = firstRun;
701     for (; r; r = r->next()) {
702 #if ENABLE(CSS_SHAPES)
703         // Once we have reached the start of the next segment, we have finished
704         // computing the positions for this segment's contents.
705         if (r->m_startsSegment)
706             break;
707 #endif
708         if (!r->box() || r->renderer().isOutOfFlowPositioned() || r->box()->isLineBreak())
709             continue; // Positioned objects are only participating to figure out their
710                       // correct static x position.  They have no effect on the width.
711                       // Similarly, line break boxes have no effect on the width.
712         if (r->renderer().isText()) {
713             RenderText& rt = toRenderText(r->renderer());
714             if (textAlign == JUSTIFY && r != trailingSpaceRun) {
715                 if (!isAfterExpansion)
716                     toInlineTextBox(r->box())->setCanHaveLeadingExpansion(true);
717                 unsigned opportunitiesInRun;
718                 if (rt.is8Bit())
719                     opportunitiesInRun = Font::expansionOpportunityCount(rt.characters8() + r->m_start, r->m_stop - r->m_start, r->box()->direction(), isAfterExpansion);
720                 else
721                     opportunitiesInRun = Font::expansionOpportunityCount(rt.characters16() + r->m_start, r->m_stop - r->m_start, r->box()->direction(), isAfterExpansion);
722                 expansionOpportunities.append(opportunitiesInRun);
723                 expansionOpportunityCount += opportunitiesInRun;
724             }
725
726             if (int length = rt.textLength()) {
727                 if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt.characterAt(r->m_start)))
728                     totalLogicalWidth += lineStyle(*rt.parent(), lineInfo).font().wordSpacing();
729                 needsWordSpacing = !isSpaceOrNewline(rt.characterAt(r->m_stop - 1)) && r->m_stop == length;
730             }
731
732             setLogicalWidthForTextRun(lineBox, r, &rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache, wordMeasurements);
733         } else {
734             isAfterExpansion = false;
735             if (!r->renderer().isRenderInline()) {
736                 RenderBox& renderBox = toRenderBox(r->renderer());
737                 if (renderBox.isRubyRun())
738                     setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previousObject, lineInfo);
739                 r->box()->setLogicalWidth(logicalWidthForChild(renderBox));
740                 totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
741             }
742         }
743
744         totalLogicalWidth += r->box()->logicalWidth();
745         previousObject = &r->renderer();
746     }
747
748     if (isAfterExpansion && !expansionOpportunities.isEmpty()) {
749         expansionOpportunities.last()--;
750         expansionOpportunityCount--;
751     }
752
753     updateLogicalWidthForAlignment(textAlign, trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth, expansionOpportunityCount);
754
755     computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpportunities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth);
756
757     return r;
758 }
759
760 void RenderBlockFlow::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
761                                                         VerticalPositionCache& verticalPositionCache)
762 {
763     setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache));
764
765     // Now make sure we place replaced render objects correctly.
766     for (BidiRun* r = firstRun; r; r = r->next()) {
767         ASSERT(r->box());
768         if (!r->box())
769             continue; // Skip runs with no line boxes.
770
771         InlineBox& box = *r->box();
772
773         // Align positioned boxes with the top of the line box.  This is
774         // a reasonable approximation of an appropriate y position.
775         if (r->renderer().isOutOfFlowPositioned())
776             box.setLogicalTop(logicalHeight());
777
778         // Position is used to properly position both replaced elements and
779         // to update the static normal flow x/y of positioned elements.
780         if (r->renderer().isText())
781             toRenderText(r->renderer()).positionLineBox(toInlineTextBox(box));
782         else if (r->renderer().isBox())
783             toRenderBox(r->renderer()).positionLineBox(toInlineElementBox(box));
784         else if (r->renderer().isLineBreak())
785             toRenderLineBreak(r->renderer()).replaceInlineBoxWrapper(toInlineElementBox(box));
786     }
787     // Positioned objects and zero-length text nodes destroy their boxes in
788     // position(), which unnecessarily dirties the line.
789     lineBox->markDirty(false);
790 }
791
792 static inline bool isCollapsibleSpace(UChar character, const RenderText& renderer)
793 {
794     if (character == ' ' || character == '\t' || character == softHyphen)
795         return true;
796     if (character == '\n')
797         return !renderer.style().preserveNewline();
798     if (character == noBreakSpace)
799         return renderer.style().nbspMode() == SPACE;
800     return false;
801 }
802
803 template <typename CharacterType>
804 static inline int findFirstTrailingSpace(const RenderText& lastText, const CharacterType* characters, int start, int stop)
805 {
806     int firstSpace = stop;
807     while (firstSpace > start) {
808         UChar current = characters[firstSpace - 1];
809         if (!isCollapsibleSpace(current, lastText))
810             break;
811         firstSpace--;
812     }
813
814     return firstSpace;
815 }
816
817 inline BidiRun* RenderBlockFlow::handleTrailingSpaces(BidiRunList<BidiRun>& bidiRuns, BidiContext* currentContext)
818 {
819     if (!bidiRuns.runCount()
820         || !bidiRuns.logicallyLastRun()->renderer().style().breakOnlyAfterWhiteSpace()
821         || !bidiRuns.logicallyLastRun()->renderer().style().autoWrap())
822         return 0;
823
824     BidiRun* trailingSpaceRun = bidiRuns.logicallyLastRun();
825     const RenderObject& lastObject = trailingSpaceRun->renderer();
826     if (!lastObject.isText())
827         return 0;
828
829     const RenderText& lastText = toRenderText(lastObject);
830     int firstSpace;
831     if (lastText.is8Bit())
832         firstSpace = findFirstTrailingSpace(lastText, lastText.characters8(), trailingSpaceRun->start(), trailingSpaceRun->stop());
833     else
834         firstSpace = findFirstTrailingSpace(lastText, lastText.characters16(), trailingSpaceRun->start(), trailingSpaceRun->stop());
835
836     if (firstSpace == trailingSpaceRun->stop())
837         return 0;
838
839     TextDirection direction = style().direction();
840     bool shouldReorder = trailingSpaceRun != (direction == LTR ? bidiRuns.lastRun() : bidiRuns.firstRun());
841     if (firstSpace != trailingSpaceRun->start()) {
842         BidiContext* baseContext = currentContext;
843         while (BidiContext* parent = baseContext->parent())
844             baseContext = parent;
845
846         BidiRun* newTrailingRun = new BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->renderer(), baseContext, U_OTHER_NEUTRAL);
847         trailingSpaceRun->m_stop = firstSpace;
848         if (direction == LTR)
849             bidiRuns.addRun(newTrailingRun);
850         else
851             bidiRuns.prependRun(newTrailingRun);
852         trailingSpaceRun = newTrailingRun;
853         return trailingSpaceRun;
854     }
855     if (!shouldReorder)
856         return trailingSpaceRun;
857
858     if (direction == LTR) {
859         bidiRuns.moveRunToEnd(trailingSpaceRun);
860         trailingSpaceRun->m_level = 0;
861     } else {
862         bidiRuns.moveRunToBeginning(trailingSpaceRun);
863         trailingSpaceRun->m_level = 1;
864     }
865     return trailingSpaceRun;
866 }
867
868 void RenderBlockFlow::appendFloatingObjectToLastLine(FloatingObject* floatingObject)
869 {
870     ASSERT(!floatingObject->originatingLine());
871     floatingObject->setOriginatingLine(lastRootBox());
872     lastRootBox()->appendFloat(floatingObject->renderer());
873 }
874
875 // FIXME: BidiResolver should have this logic.
876 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirectionOverride override, bool previousLineBrokeCleanly)
877 {
878     // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead
879     // of the resolver owning the runs.
880     ASSERT(&topResolver.runs() == &bidiRuns);
881     ASSERT(topResolver.position() != endOfRuns);
882     RenderObject* currentRoot = topResolver.position().root();
883     topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeCleanly);
884
885     while (!topResolver.isolatedRuns().isEmpty()) {
886         // It does not matter which order we resolve the runs as long as we resolve them all.
887         BidiRun* isolatedRun = topResolver.isolatedRuns().last();
888         topResolver.isolatedRuns().removeLast();
889
890         RenderObject& startObj = isolatedRun->renderer();
891
892         // Only inlines make sense with unicode-bidi: isolate (blocks are already isolated).
893         // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the
894         // tree to see which parent inline is the isolate. We could change enterIsolate
895         // to take a RenderObject and do this logic there, but that would be a layering
896         // violation for BidiResolver (which knows nothing about RenderObject).
897         RenderInline* isolatedInline = toRenderInline(containingIsolate(&startObj, currentRoot));
898         InlineBidiResolver isolatedResolver;
899         EUnicodeBidi unicodeBidi = isolatedInline->style().unicodeBidi();
900         TextDirection direction;
901         if (unicodeBidi == Plaintext)
902             determineDirectionality(direction, InlineIterator(isolatedInline, &isolatedRun->renderer(), 0));
903         else {
904             ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride);
905             direction = isolatedInline->style().direction();
906         }
907         isolatedResolver.setStatus(BidiStatus(direction, isOverride(unicodeBidi)));
908
909         // FIXME: The fact that we have to construct an Iterator here
910         // currently prevents this code from moving into BidiResolver.
911         if (!bidiFirstSkippingEmptyInlines(*isolatedInline, &isolatedResolver))
912             continue;
913
914         // The starting position is the beginning of the first run within the isolate that was identified
915         // during the earlier call to createBidiRunsForLine. This can be but is not necessarily the
916         // first run within the isolate.
917         InlineIterator iter = InlineIterator(isolatedInline, &startObj, isolatedRun->m_start);
918         isolatedResolver.setPositionIgnoringNestedIsolates(iter);
919
920         // We stop at the next end of line; we may re-enter this isolate in the next call to constructBidiRuns().
921         // FIXME: What should end and previousLineBrokeCleanly be?
922         // rniwa says previousLineBrokeCleanly is just a WinIE hack and could always be false here?
923         isolatedResolver.createBidiRunsForLine(endOfRuns, NoVisualOverride, previousLineBrokeCleanly);
924         // Note that we do not delete the runs from the resolver.
925         // We're not guaranteed to get any BidiRuns in the previous step. If we don't, we allow the placeholder
926         // itself to be turned into an InlineBox. We can't remove it here without potentially losing track of
927         // the logically last run.
928         if (isolatedResolver.runs().runCount())
929             bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs());
930
931         // If we encountered any nested isolate runs, just move them
932         // to the top resolver's list for later processing.
933         if (!isolatedResolver.isolatedRuns().isEmpty()) {
934             topResolver.isolatedRuns().appendVector(isolatedResolver.isolatedRuns());
935             isolatedResolver.isolatedRuns().clear();
936             currentRoot = isolatedInline;
937         }
938     }
939 }
940
941 static inline void constructBidiRunsForLine(const RenderBlockFlow* block, InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly)
942 {
943 #if !ENABLE(CSS_SHAPES)
944     UNUSED_PARAM(block);
945     constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly);
946 #else
947     ShapeInsideInfo* shapeInsideInfo = block->layoutShapeInsideInfo();
948     if (!shapeInsideInfo || !shapeInsideInfo->hasSegments()) {
949         constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly);
950         return;
951     }
952
953     const SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges();
954     ASSERT(segmentRanges.size());
955
956     for (size_t i = 0; i < segmentRanges.size(); i++) {
957         LineSegmentIterator iterator = segmentRanges[i].start;
958         InlineIterator segmentStart(iterator.root, iterator.object, iterator.offset);
959         iterator = segmentRanges[i].end;
960         InlineIterator segmentEnd(iterator.root, iterator.object, iterator.offset);
961         if (i) {
962             ASSERT(segmentStart.renderer());
963             BidiRun* segmentMarker = createRun(segmentStart.offset(), segmentStart.offset(), segmentStart.renderer(), topResolver);
964             segmentMarker->m_startsSegment = true;
965             bidiRuns.addRun(segmentMarker);
966             // Do not collapse midpoints between segments
967             topResolver.midpointState().betweenMidpoints = false;
968         }
969         if (segmentStart == segmentEnd)
970             continue;
971         topResolver.setPosition(segmentStart, numberOfIsolateAncestors(segmentStart));
972         constructBidiRunsForSegment(topResolver, bidiRuns, segmentEnd, override, previousLineBrokeCleanly);
973     }
974 #endif
975 }
976
977 // This function constructs line boxes for all of the text runs in the resolver and computes their position.
978 RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements)
979 {
980     if (!bidiRuns.runCount())
981         return 0;
982
983     // FIXME: Why is this only done when we had runs?
984     lineInfo.setLastLine(!end.renderer());
985
986     RootInlineBox* lineBox = constructLine(bidiRuns, lineInfo);
987     if (!lineBox)
988         return 0;
989
990     lineBox->setEndsWithBreak(lineInfo.previousLineBrokeCleanly());
991     
992 #if ENABLE(SVG)
993     bool isSVGRootInlineBox = lineBox->isSVGRootInlineBox();
994 #else
995     bool isSVGRootInlineBox = false;
996 #endif
997     
998     GlyphOverflowAndFallbackFontsMap textBoxDataMap;
999     
1000     // Now we position all of our text runs horizontally.
1001     if (!isSVGRootInlineBox)
1002         computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache, wordMeasurements);
1003     
1004     // Now position our text runs vertically.
1005     computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), textBoxDataMap, verticalPositionCache);
1006     
1007 #if ENABLE(SVG)
1008     // SVG text layout code computes vertical & horizontal positions on its own.
1009     // Note that we still need to execute computeVerticalPositionsForLine() as
1010     // it calls InlineTextBox::positionLineBox(), which tracks whether the box
1011     // contains reversed text or not. If we wouldn't do that editing and thus
1012     // text selection in RTL boxes would not work as expected.
1013     if (isSVGRootInlineBox) {
1014         ASSERT_WITH_SECURITY_IMPLICATION(isSVGText());
1015         toSVGRootInlineBox(lineBox)->computePerCharacterLayoutInformation();
1016     }
1017 #endif
1018     
1019     // Compute our overflow now.
1020     lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), textBoxDataMap);
1021     
1022 #if PLATFORM(MAC)
1023     // Highlight acts as an overflow inflation.
1024     if (style().highlight() != nullAtom)
1025         lineBox->addHighlightOverflow();
1026 #endif
1027     return lineBox;
1028 }
1029
1030 static void deleteLineRange(LineLayoutState& layoutState, RootInlineBox* startLine, RootInlineBox* stopLine = 0)
1031 {
1032     RootInlineBox* boxToDelete = startLine;
1033     while (boxToDelete && boxToDelete != stopLine) {
1034         layoutState.updateRepaintRangeFromBox(boxToDelete);
1035         // Note: deleteLineRange(firstRootBox()) is not identical to deleteLineBoxTree().
1036         // deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when traversing.
1037         RootInlineBox* next = boxToDelete->nextRootBox();
1038         boxToDelete->deleteLine();
1039         boxToDelete = next;
1040     }
1041 }
1042
1043 void RenderBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState, bool hasInlineChild)
1044 {
1045     // We want to skip ahead to the first dirty line
1046     InlineBidiResolver resolver;
1047     RootInlineBox* startLine = determineStartPosition(layoutState, resolver);
1048
1049     unsigned consecutiveHyphenatedLines = 0;
1050     if (startLine) {
1051         for (RootInlineBox* line = startLine->prevRootBox(); line && line->isHyphenated(); line = line->prevRootBox())
1052             consecutiveHyphenatedLines++;
1053     }
1054
1055     // FIXME: This would make more sense outside of this function, but since
1056     // determineStartPosition can change the fullLayout flag we have to do this here. Failure to call
1057     // determineStartPosition first will break fast/repaint/line-flow-with-floats-9.html.
1058     if (layoutState.isFullLayout() && hasInlineChild && !selfNeedsLayout()) {
1059         setNeedsLayout(MarkOnlyThis); // Mark as needing a full layout to force us to repaint.
1060         if (!view().doingFullRepaint() && hasLayer()) {
1061             // Because we waited until we were already inside layout to discover
1062             // that the block really needed a full layout, we missed our chance to repaint the layer
1063             // before layout started.  Luckily the layer has cached the repaint rect for its original
1064             // position and size, and so we can use that to make a repaint happen now.
1065             repaintUsingContainer(containerForRepaint(), pixelSnappedIntRect(layer()->repaintRect()));
1066         }
1067     }
1068
1069     if (containsFloats())
1070         layoutState.setLastFloat(m_floatingObjects->set().last().get());
1071
1072     // We also find the first clean line and extract these lines.  We will add them back
1073     // if we determine that we're able to synchronize after handling all our dirty lines.
1074     InlineIterator cleanLineStart;
1075     BidiStatus cleanLineBidiStatus;
1076     if (!layoutState.isFullLayout() && startLine)
1077         determineEndPosition(layoutState, startLine, cleanLineStart, cleanLineBidiStatus);
1078
1079     if (startLine) {
1080         if (!layoutState.usesRepaintBounds())
1081             layoutState.setRepaintRange(logicalHeight());
1082         deleteLineRange(layoutState, startLine);
1083     }
1084
1085     if (!layoutState.isFullLayout() && lastRootBox() && lastRootBox()->endsWithBreak()) {
1086         // If the last line before the start line ends with a line break that clear floats,
1087         // adjust the height accordingly.
1088         // A line break can be either the first or the last object on a line, depending on its direction.
1089         if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
1090             RenderObject* lastObject = &lastLeafChild->renderer();
1091             if (!lastObject->isBR())
1092                 lastObject = &lastRootBox()->firstLeafChild()->renderer();
1093             if (lastObject->isBR()) {
1094                 EClear clear = lastObject->style().clear();
1095                 if (clear != CNONE)
1096                     newLine(clear);
1097             }
1098         }
1099     }
1100
1101     layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineBidiStatus, consecutiveHyphenatedLines);
1102     linkToEndLineIfNeeded(layoutState);
1103     repaintDirtyFloats(layoutState.floats());
1104 }
1105
1106 RenderTextInfo::RenderTextInfo()
1107     : m_text(0)
1108     , m_font(0)
1109 {
1110 }
1111
1112 RenderTextInfo::~RenderTextInfo()
1113 {
1114 }
1115
1116 // Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver.
1117 inline const InlineIterator& RenderBlockFlow::restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver& resolver,  const InlineIterator& oldEnd)
1118 {
1119     removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
1120     setLogicalHeight(newLogicalHeight);
1121     resolver.setPositionIgnoringNestedIsolates(oldEnd);
1122     return oldEnd;
1123 }
1124
1125 #if ENABLE(CSS_SHAPES)
1126 static inline void pushShapeContentOverflowBelowTheContentBox(RenderBlockFlow* block, ShapeInsideInfo* shapeInsideInfo, LayoutUnit lineTop, LayoutUnit lineHeight)
1127 {
1128     ASSERT(shapeInsideInfo);
1129
1130     LayoutUnit logicalLineBottom = lineTop + lineHeight;
1131     LayoutUnit shapeLogicalBottom = shapeInsideInfo->shapeLogicalBottom();
1132     LayoutUnit shapeContainingBlockLogicalHeight = shapeInsideInfo->shapeContainingBlockLogicalHeight();
1133
1134     bool isOverflowPositionedAlready = (shapeContainingBlockLogicalHeight - shapeInsideInfo->owner().borderAndPaddingAfter() + lineHeight) <= lineTop;
1135
1136     // If the last line overlaps with the shape, we don't need the segments anymore
1137     if (lineTop < shapeLogicalBottom && shapeLogicalBottom < logicalLineBottom)
1138         shapeInsideInfo->clearSegments();
1139
1140     if (logicalLineBottom <= shapeLogicalBottom || !shapeContainingBlockLogicalHeight || isOverflowPositionedAlready)
1141         return;
1142
1143     LayoutUnit newLogicalHeight = block->logicalHeight() + (shapeContainingBlockLogicalHeight - (lineTop + shapeInsideInfo->owner().borderAndPaddingAfter()));
1144     block->setLogicalHeight(newLogicalHeight);
1145 }
1146
1147 void RenderBlockFlow::updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*& shapeInsideInfo, const LayoutSize& logicalOffsetFromShapeContainer, LineLayoutState& layoutState)
1148 {
1149     if (layoutState.flowThread())
1150         return updateShapeAndSegmentsForCurrentLineInFlowThread(shapeInsideInfo, layoutState);
1151
1152     if (!shapeInsideInfo)
1153         return;
1154
1155     LayoutUnit lineTop = logicalHeight() + logicalOffsetFromShapeContainer.height();
1156     LayoutUnit lineLeft = logicalOffsetFromShapeContainer.width();
1157     LayoutUnit lineHeight = this->lineHeight(layoutState.lineInfo().isFirstLine(), isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
1158
1159     // FIXME: Bug 95361: It is possible for a line to grow beyond lineHeight, in which case these segments may be incorrect.
1160     shapeInsideInfo->updateSegmentsForLine(LayoutSize(lineLeft, lineTop), lineHeight);
1161
1162     pushShapeContentOverflowBelowTheContentBox(this, shapeInsideInfo, lineTop, lineHeight);
1163 }
1164
1165 void RenderBlockFlow::updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsideInfo*& shapeInsideInfo, LineLayoutState& layoutState)
1166 {
1167     ASSERT(layoutState.flowThread());
1168
1169     RenderRegion* currentRegion = regionAtBlockOffset(logicalHeight());
1170     if (!currentRegion || !currentRegion->logicalHeight())
1171         return;
1172
1173     shapeInsideInfo = currentRegion->shapeInsideInfo();
1174
1175     RenderRegion* nextRegion = 0;
1176     if (!currentRegion->isLastRegion()) {
1177         RenderRegionList regionList = layoutState.flowThread()->renderRegionList();
1178         auto it = regionList.find(currentRegion);
1179         nextRegion = *(++it);
1180     }
1181
1182     // We only want to deal regions with shapes, so we check if the next region has a shape
1183     if (!shapeInsideInfo && nextRegion && !nextRegion->shapeInsideInfo())
1184         return;
1185
1186     LayoutUnit lineHeight = this->lineHeight(layoutState.lineInfo().isFirstLine(), isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
1187     LayoutUnit logicalLineTopInFlowThread = logicalHeight() + offsetFromLogicalTopOfFirstPage();
1188     LayoutUnit logicalLineBottomInFlowThread = logicalLineTopInFlowThread + lineHeight;
1189     LayoutUnit logicalRegionTopInFlowThread = currentRegion->logicalTopForFlowThreadContent();
1190     LayoutUnit logicalRegionBottomInFlowThread = logicalRegionTopInFlowThread + currentRegion->logicalHeight() - currentRegion->borderAndPaddingBefore() - currentRegion->borderAndPaddingAfter();
1191
1192     LayoutUnit shapeBottomInFlowThread = LayoutUnit::max();
1193     if (shapeInsideInfo)
1194         shapeBottomInFlowThread = shapeInsideInfo->shapeLogicalBottom() + currentRegion->logicalTopForFlowThreadContent();
1195
1196     bool lineOverLapsWithShapeBottom = shapeBottomInFlowThread < logicalLineBottomInFlowThread;
1197     bool lineTopAdjustedIntoNextRegion = layoutState.adjustedLogicalLineTop() >= currentRegion->logicalHeight();
1198     bool lineOverLapsWithRegionBottom = logicalLineBottomInFlowThread > logicalRegionBottomInFlowThread || lineTopAdjustedIntoNextRegion;
1199     bool overFlowsToNextRegion = nextRegion && (lineOverLapsWithShapeBottom || lineOverLapsWithRegionBottom);
1200
1201     // If the line is between two shapes/regions we position the line to the top of the next shape/region
1202     if (overFlowsToNextRegion) {
1203         ASSERT(currentRegion != nextRegion);
1204         LayoutUnit deltaToNextRegion = logicalRegionBottomInFlowThread - logicalLineTopInFlowThread;
1205         setLogicalHeight(logicalHeight() + deltaToNextRegion);
1206
1207         currentRegion = nextRegion;
1208         shapeInsideInfo = currentRegion->shapeInsideInfo();
1209
1210         logicalLineTopInFlowThread = logicalHeight() + offsetFromLogicalTopOfFirstPage();
1211         logicalLineBottomInFlowThread = logicalLineTopInFlowThread + lineHeight;
1212         logicalRegionTopInFlowThread = currentRegion->logicalTopForFlowThreadContent();
1213         logicalRegionBottomInFlowThread = logicalRegionTopInFlowThread + currentRegion->logicalHeight() - currentRegion->borderAndPaddingBefore() - currentRegion->borderAndPaddingAfter();
1214
1215         if (lineTopAdjustedIntoNextRegion)
1216             layoutState.setAdjustedLogicalLineTop(0);
1217     }
1218
1219     if (!shapeInsideInfo)
1220         return;
1221
1222     bool isFirstLineInRegion = logicalLineBottomInFlowThread <= (logicalRegionTopInFlowThread + lineHeight);
1223     bool isFirstLineAdjusted = (logicalLineTopInFlowThread - logicalRegionTopInFlowThread) < (layoutState.adjustedLogicalLineTop() - currentRegion->borderAndPaddingBefore());
1224     // We position the first line to the top of the shape in the region or to the previously adjusted position in the shape
1225     if (isFirstLineInRegion || isFirstLineAdjusted) {
1226         LayoutUnit shapeTopOffset = layoutState.adjustedLogicalLineTop();
1227
1228         if (!shapeTopOffset && (shapeInsideInfo->shapeLogicalTop() > 0))
1229             shapeTopOffset = shapeInsideInfo->shapeLogicalTop();
1230
1231         LayoutUnit shapePositionInFlowThread = currentRegion->logicalTopForFlowThreadContent() + shapeTopOffset;
1232         LayoutUnit shapeTopLineTopDelta = shapePositionInFlowThread - logicalLineTopInFlowThread - currentRegion->borderAndPaddingBefore();
1233
1234         setLogicalHeight(logicalHeight() + shapeTopLineTopDelta);
1235         logicalLineTopInFlowThread += shapeTopLineTopDelta;
1236         layoutState.setAdjustedLogicalLineTop(0);
1237     }
1238
1239     LayoutUnit lineTop = logicalLineTopInFlowThread - currentRegion->logicalTopForFlowThreadContent() + currentRegion->borderAndPaddingBefore();
1240
1241     // FIXME: 118571 - Shape inside on a region does not yet take into account its padding for nested flow blocks
1242     shapeInsideInfo->updateSegmentsForLine(LayoutSize(0, lineTop), lineHeight);
1243
1244     if (currentRegion->isLastRegion())
1245         pushShapeContentOverflowBelowTheContentBox(this, shapeInsideInfo, lineTop, lineHeight);
1246 }
1247
1248 static inline LayoutUnit adjustLogicalLineTop(ShapeInsideInfo* shapeInsideInfo, InlineIterator start, InlineIterator end, const WordMeasurements& wordMeasurements)
1249 {
1250     if (!shapeInsideInfo || end != start)
1251         return 0;
1252
1253     float minWidth = firstPositiveWidth(wordMeasurements);
1254     ASSERT(minWidth || wordMeasurements.isEmpty());
1255     if (minWidth > 0 && shapeInsideInfo->adjustLogicalLineTop(minWidth))
1256         return shapeInsideInfo->logicalLineTop();
1257
1258     return shapeInsideInfo->shapeLogicalBottom();
1259 }
1260
1261 bool RenderBlockFlow::adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideInfo* shapeInsideInfo, LayoutUnit absoluteLogicalTop, LineLayoutState& layoutState, InlineBidiResolver& resolver, FloatingObject* lastFloatFromPreviousLine, InlineIterator& end, WordMeasurements& wordMeasurements)
1262 {
1263     LayoutUnit adjustedLogicalLineTop = adjustLogicalLineTop(shapeInsideInfo, resolver.position(), end, wordMeasurements);
1264
1265     if (shapeInsideInfo && containsFloats()) {
1266         lastFloatFromPreviousLine = m_floatingObjects->set().last().get();
1267         if (!wordMeasurements.size()) {
1268             LayoutUnit floatLogicalTopOffset = shapeInsideInfo->computeFirstFitPositionForFloat(logicalSizeForFloat(lastFloatFromPreviousLine));
1269             if (logicalHeight() < floatLogicalTopOffset)
1270                 adjustedLogicalLineTop = floatLogicalTopOffset;
1271         }
1272     }
1273
1274     if (!adjustedLogicalLineTop)
1275         return false;
1276
1277     LayoutUnit newLogicalHeight = adjustedLogicalLineTop - absoluteLogicalTop;
1278
1279     if (layoutState.flowThread()) {
1280         layoutState.setAdjustedLogicalLineTop(adjustedLogicalLineTop);
1281         newLogicalHeight = logicalHeight();
1282     }
1283
1284     end = restartLayoutRunsAndFloatsInRange(logicalHeight(), newLogicalHeight, lastFloatFromPreviousLine, resolver, end);
1285     return true;
1286 }
1287 #endif
1288
1289 void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, InlineBidiResolver& resolver, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines)
1290 {
1291     const RenderStyle& styleToUse = style();
1292     bool paginated = view().layoutState() && view().layoutState()->isPaginated();
1293     LineMidpointState& lineMidpointState = resolver.midpointState();
1294     InlineIterator end = resolver.position();
1295     bool checkForEndLineMatch = layoutState.endLine();
1296     RenderTextInfo renderTextInfo;
1297     VerticalPositionCache verticalPositionCache;
1298
1299     LineBreaker lineBreaker(*this);
1300
1301 #if ENABLE(CSS_SHAPES)
1302     LayoutSize logicalOffsetFromShapeContainer;
1303     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
1304     if (shapeInsideInfo) {
1305         ASSERT(&shapeInsideInfo->owner() == this || allowsShapeInsideInfoSharing());
1306         if (shapeInsideInfo != this->shapeInsideInfo()) {
1307             // FIXME Bug 100284: If subsequent LayoutStates are pushed, we will have to add
1308             // their offsets from the original shape-inside container.
1309             logicalOffsetFromShapeContainer = logicalOffsetFromShapeAncestorContainer(&shapeInsideInfo->owner());
1310         }
1311         // Begin layout at the logical top of our shape inside.
1312         if (logicalHeight() + logicalOffsetFromShapeContainer.height() < shapeInsideInfo->shapeLogicalTop()) {
1313             LayoutUnit logicalHeight = shapeInsideInfo->shapeLogicalTop() - logicalOffsetFromShapeContainer.height();
1314             if (layoutState.flowThread())
1315                 logicalHeight -= shapeInsideInfo->owner().borderAndPaddingBefore();
1316             setLogicalHeight(logicalHeight);
1317         }
1318     }
1319 #endif
1320
1321     while (!end.atEnd()) {
1322         // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
1323         if (checkForEndLineMatch) {
1324             layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus));
1325             if (layoutState.endLineMatched()) {
1326                 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
1327                 break;
1328             }
1329         }
1330
1331         lineMidpointState.reset();
1332
1333         layoutState.lineInfo().setEmpty(true);
1334         layoutState.lineInfo().resetRunsFromLeadingWhitespace();
1335
1336         const InlineIterator oldEnd = end;
1337         bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly();
1338         FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_floatingObjects->set().last().get() : 0;
1339
1340 #if ENABLE(CSS_SHAPES)
1341         updateShapeAndSegmentsForCurrentLine(shapeInsideInfo, logicalOffsetFromShapeContainer, layoutState);
1342 #endif
1343         WordMeasurements wordMeasurements;
1344         end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
1345         renderTextInfo.m_lineBreakIterator.resetPriorContext();
1346         if (resolver.position().atEnd()) {
1347             // FIXME: We shouldn't be creating any runs in nextLineBreak to begin with!
1348             // Once BidiRunList is separated from BidiResolver this will not be needed.
1349             resolver.runs().deleteRuns();
1350             resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
1351             layoutState.setCheckForFloatsFromLastLine(true);
1352             resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
1353             break;
1354         }
1355
1356 #if ENABLE(CSS_SHAPES)
1357         if (adjustLogicalLineTopAndLogicalHeightIfNeeded(shapeInsideInfo, logicalOffsetFromShapeContainer.height(), layoutState, resolver, lastFloatFromPreviousLine, end, wordMeasurements))
1358             continue;
1359 #endif
1360         ASSERT(end != resolver.position());
1361
1362         // This is a short-cut for empty lines.
1363         if (layoutState.lineInfo().isEmpty()) {
1364             if (lastRootBox())
1365                 lastRootBox()->setLineBreakInfo(end.renderer(), end.offset(), resolver.status());
1366         } else {
1367             VisualDirectionOverride override = (styleToUse.rtlOrdering() == VisualOrder ? (styleToUse.direction() == LTR ? VisualLeftToRightOverride : VisualRightToLeftOverride) : NoVisualOverride);
1368
1369             if (isNewUBAParagraph && styleToUse.unicodeBidi() == Plaintext && !resolver.context()->parent()) {
1370                 TextDirection direction = styleToUse.direction();
1371                 determineDirectionality(direction, resolver.position());
1372                 resolver.setStatus(BidiStatus(direction, isOverride(styleToUse.unicodeBidi())));
1373             }
1374             // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine.
1375             BidiRunList<BidiRun>& bidiRuns = resolver.runs();
1376             constructBidiRunsForLine(this, resolver, bidiRuns, end, override, layoutState.lineInfo().previousLineBrokeCleanly());
1377             ASSERT(resolver.position() == end);
1378
1379             BidiRun* trailingSpaceRun = !layoutState.lineInfo().previousLineBrokeCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0;
1380
1381             if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) {
1382                 bidiRuns.logicallyLastRun()->m_hasHyphen = true;
1383                 consecutiveHyphenatedLines++;
1384             } else
1385                 consecutiveHyphenatedLines = 0;
1386
1387             // Now that the runs have been ordered, we create the line boxes.
1388             // At the same time we figure out where border/padding/margin should be applied for
1389             // inline flow boxes.
1390
1391             LayoutUnit oldLogicalHeight = logicalHeight();
1392             RootInlineBox* lineBox = createLineBoxesFromBidiRuns(bidiRuns, end, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, wordMeasurements);
1393
1394             bidiRuns.deleteRuns();
1395             resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
1396
1397             if (lineBox) {
1398                 lineBox->setLineBreakInfo(end.renderer(), end.offset(), resolver.status());
1399                 if (layoutState.usesRepaintBounds())
1400                     layoutState.updateRepaintRangeFromBox(lineBox);
1401
1402                 if (paginated) {
1403                     LayoutUnit adjustment = 0;
1404                     adjustLinePositionForPagination(lineBox, adjustment, layoutState.flowThread());
1405                     if (adjustment) {
1406                         LayoutUnit oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, layoutState.lineInfo().isFirstLine());
1407                         lineBox->adjustBlockDirectionPosition(adjustment);
1408                         if (layoutState.usesRepaintBounds())
1409                             layoutState.updateRepaintRangeFromBox(lineBox);
1410
1411                         if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, layoutState.lineInfo().isFirstLine()) != oldLineWidth) {
1412                             // We have to delete this line, remove all floats that got added, and let line layout re-run.
1413                             lineBox->deleteLine();
1414                             end = restartLayoutRunsAndFloatsInRange(oldLogicalHeight, oldLogicalHeight + adjustment, lastFloatFromPreviousLine, resolver, oldEnd);
1415                             continue;
1416                         }
1417
1418                         setLogicalHeight(lineBox->lineBottomWithLeading());
1419                     }
1420
1421                     if (layoutState.flowThread())
1422                         updateRegionForLine(lineBox);
1423                 }
1424             }
1425         }
1426
1427         for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i)
1428             setStaticPositions(*this, *lineBreaker.positionedObjects()[i]);
1429
1430         if (!layoutState.lineInfo().isEmpty()) {
1431             layoutState.lineInfo().setFirstLine(false);
1432             newLine(lineBreaker.clear());
1433         }
1434
1435         if (m_floatingObjects && lastRootBox()) {
1436             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1437             auto it = floatingObjectSet.begin();
1438             auto end = floatingObjectSet.end();
1439             if (layoutState.lastFloat()) {
1440                 auto lastFloatIterator = floatingObjectSet.find<FloatingObject&, FloatingObjectHashTranslator>(*layoutState.lastFloat());
1441                 ASSERT(lastFloatIterator != end);
1442                 ++lastFloatIterator;
1443                 it = lastFloatIterator;
1444             }
1445             for (; it != end; ++it) {
1446                 FloatingObject* f = it->get();
1447                 appendFloatingObjectToLastLine(f);
1448                 ASSERT(&f->renderer() == &layoutState.floats()[layoutState.floatIndex()].object);
1449                 // If a float's geometry has changed, give up on syncing with clean lines.
1450                 if (layoutState.floats()[layoutState.floatIndex()].rect != f->frameRect())
1451                     checkForEndLineMatch = false;
1452                 layoutState.setFloatIndex(layoutState.floatIndex() + 1);
1453             }
1454             layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : nullptr);
1455         }
1456
1457         lineMidpointState.reset();
1458         resolver.setPosition(end, numberOfIsolateAncestors(end));
1459     }
1460
1461     // In case we already adjusted the line positions during this layout to avoid widows
1462     // then we need to ignore the possibility of having a new widows situation.
1463     // Otherwise, we risk leaving empty containers which is against the block fragmentation principles.
1464     if (paginated && !style().hasAutoWidows() && !didBreakAtLineToAvoidWidow()) {
1465         // Check the line boxes to make sure we didn't create unacceptable widows.
1466         // However, we'll prioritize orphans - so nothing we do here should create
1467         // a new orphan.
1468
1469         RootInlineBox* lineBox = lastRootBox();
1470
1471         // Count from the end of the block backwards, to see how many hanging
1472         // lines we have.
1473         RootInlineBox* firstLineInBlock = firstRootBox();
1474         int numLinesHanging = 1;
1475         while (lineBox && lineBox != firstLineInBlock && !lineBox->isFirstAfterPageBreak()) {
1476             ++numLinesHanging;
1477             lineBox = lineBox->prevRootBox();
1478         }
1479
1480         // If there were no breaks in the block, we didn't create any widows.
1481         if (!lineBox || !lineBox->isFirstAfterPageBreak() || lineBox == firstLineInBlock)
1482             return;
1483
1484         if (numLinesHanging < style().widows()) {
1485             // We have detected a widow. Now we need to work out how many
1486             // lines there are on the previous page, and how many we need
1487             // to steal.
1488             int numLinesNeeded = style().widows() - numLinesHanging;
1489             RootInlineBox* currentFirstLineOfNewPage = lineBox;
1490
1491             // Count the number of lines in the previous page.
1492             lineBox = lineBox->prevRootBox();
1493             int numLinesInPreviousPage = 1;
1494             while (lineBox && lineBox != firstLineInBlock && !lineBox->isFirstAfterPageBreak()) {
1495                 ++numLinesInPreviousPage;
1496                 lineBox = lineBox->prevRootBox();
1497             }
1498
1499             // If there was an explicit value for orphans, respect that. If not, we still
1500             // shouldn't create a situation where we make an orphan bigger than the initial value.
1501             // This means that setting widows implies we also care about orphans, but given
1502             // the specification says the initial orphan value is non-zero, this is ok. The
1503             // author is always free to set orphans explicitly as well.
1504             int orphans = style().hasAutoOrphans() ? style().initialOrphans() : style().orphans();
1505             int numLinesAvailable = numLinesInPreviousPage - orphans;
1506             if (numLinesAvailable <= 0)
1507                 return;
1508
1509             int numLinesToTake = std::min(numLinesAvailable, numLinesNeeded);
1510             // Wind back from our first widowed line.
1511             lineBox = currentFirstLineOfNewPage;
1512             for (int i = 0; i < numLinesToTake; ++i)
1513                 lineBox = lineBox->prevRootBox();
1514
1515             // We now want to break at this line. Remember for next layout and trigger relayout.
1516             setBreakAtLineToAvoidWidow(lineCount(lineBox));
1517             markLinesDirtyInBlockRange(lastRootBox()->lineBottomWithLeading(), lineBox->lineBottomWithLeading(), lineBox);
1518         }
1519     }
1520
1521     clearDidBreakAtLineToAvoidWidow();
1522 }
1523
1524 void RenderBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState)
1525 {
1526     if (layoutState.endLine()) {
1527         if (layoutState.endLineMatched()) {
1528             bool paginated = view().layoutState() && view().layoutState()->isPaginated();
1529             // Attach all the remaining lines, and then adjust their y-positions as needed.
1530             LayoutUnit delta = logicalHeight() - layoutState.endLineLogicalTop();
1531             for (RootInlineBox* line = layoutState.endLine(); line; line = line->nextRootBox()) {
1532                 line->attachLine();
1533                 if (paginated) {
1534                     delta -= line->paginationStrut();
1535                     adjustLinePositionForPagination(line, delta, layoutState.flowThread());
1536                 }
1537                 if (delta) {
1538                     layoutState.updateRepaintRangeFromBox(line, delta);
1539                     line->adjustBlockDirectionPosition(delta);
1540                 }
1541                 if (layoutState.flowThread())
1542                     updateRegionForLine(line);
1543                 if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
1544                     for (auto it = cleanLineFloats->begin(), end = cleanLineFloats->end(); it != end; ++it) {
1545                         RenderBox* floatingBox = *it;
1546                         FloatingObject* floatingObject = insertFloatingObject(*floatingBox);
1547                         ASSERT(!floatingObject->originatingLine());
1548                         floatingObject->setOriginatingLine(line);
1549                         setLogicalHeight(logicalTopForChild(*floatingBox) - marginBeforeForChild(*floatingBox) + delta);
1550                         positionNewFloats();
1551                     }
1552                 }
1553             }
1554             setLogicalHeight(lastRootBox()->lineBottomWithLeading());
1555         } else {
1556             // Delete all the remaining lines.
1557             deleteLineRange(layoutState, layoutState.endLine());
1558         }
1559     }
1560     
1561     if (m_floatingObjects && (layoutState.checkForFloatsFromLastLine() || positionNewFloats()) && lastRootBox()) {
1562         // In case we have a float on the last line, it might not be positioned up to now.
1563         // This has to be done before adding in the bottom border/padding, or the float will
1564         // include the padding incorrectly. -dwh
1565         if (layoutState.checkForFloatsFromLastLine()) {
1566             LayoutUnit bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow();
1567             LayoutUnit bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow();
1568             auto newLineBox = std::make_unique<TrailingFloatsRootInlineBox>(*this);
1569             auto trailingFloatsLineBox = newLineBox.get();
1570             m_lineBoxes.appendLineBox(std::move(newLineBox));
1571             trailingFloatsLineBox->setConstructed();
1572             GlyphOverflowAndFallbackFontsMap textBoxDataMap;
1573             VerticalPositionCache verticalPositionCache;
1574             LayoutUnit blockLogicalHeight = logicalHeight();
1575             trailingFloatsLineBox->alignBoxesInBlockDirection(blockLogicalHeight, textBoxDataMap, verticalPositionCache);
1576             trailingFloatsLineBox->setLineTopBottomPositions(blockLogicalHeight, blockLogicalHeight, blockLogicalHeight, blockLogicalHeight);
1577             trailingFloatsLineBox->setPaginatedLineWidth(availableLogicalWidthForContent(blockLogicalHeight));
1578             LayoutRect logicalLayoutOverflow(0, blockLogicalHeight, 1, bottomLayoutOverflow - blockLogicalHeight);
1579             LayoutRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight);
1580             trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom());
1581             if (layoutState.flowThread())
1582                 updateRegionForLine(trailingFloatsLineBox);
1583         }
1584
1585         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1586         auto it = floatingObjectSet.begin();
1587         auto end = floatingObjectSet.end();
1588         if (layoutState.lastFloat()) {
1589             auto lastFloatIterator = floatingObjectSet.find<FloatingObject&, FloatingObjectHashTranslator>(*layoutState.lastFloat());
1590             ASSERT(lastFloatIterator != end);
1591             ++lastFloatIterator;
1592             it = lastFloatIterator;
1593         }
1594         for (; it != end; ++it)
1595             appendFloatingObjectToLastLine(it->get());
1596         layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : nullptr);
1597     }
1598 }
1599
1600 void RenderBlockFlow::repaintDirtyFloats(Vector<FloatWithRect>& floats)
1601 {
1602     size_t floatCount = floats.size();
1603     // Floats that did not have layout did not repaint when we laid them out. They would have
1604     // painted by now if they had moved, but if they stayed at (0, 0), they still need to be
1605     // painted.
1606     for (size_t i = 0; i < floatCount; ++i) {
1607         if (!floats[i].everHadLayout) {
1608             RenderBox& box = floats[i].object;
1609             if (!box.x() && !box.y() && box.checkForRepaintDuringLayout())
1610                 box.repaint();
1611         }
1612     }
1613 }
1614
1615 void RenderBlockFlow::layoutLineBoxes(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
1616 {
1617     ASSERT(!m_simpleLineLayout);
1618
1619     setLogicalHeight(borderAndPaddingBefore());
1620     
1621     // Lay out our hypothetical grid line as though it occurs at the top of the block.
1622     if (view().layoutState() && view().layoutState()->lineGrid() == this)
1623         layoutLineGridBox();
1624
1625     RenderFlowThread* flowThread = flowThreadContainingBlock();
1626     bool clearLinesForPagination = firstRootBox() && flowThread && !flowThread->hasRegions();
1627
1628     // Figure out if we should clear out our line boxes.
1629     // FIXME: Handle resize eventually!
1630     bool isFullLayout = !firstRootBox() || selfNeedsLayout() || relayoutChildren || clearLinesForPagination;
1631     LineLayoutState layoutState(isFullLayout, repaintLogicalTop, repaintLogicalBottom, flowThread);
1632
1633     if (isFullLayout)
1634         lineBoxes().deleteLineBoxes();
1635
1636     // Text truncation kicks in in two cases:
1637     //     1) If your overflow isn't visible and your text-overflow-mode isn't clip.
1638     //     2) If you're an anonymous block with a block parent that satisfies #1.
1639     // FIXME: CSS3 says that descendants that are clipped must also know how to truncate.  This is insanely
1640     // difficult to figure out in general (especially in the middle of doing layout), so we only handle the
1641     // simple case of an anonymous block truncating when it's parent is clipped.
1642     bool hasTextOverflow = (style().textOverflow() && hasOverflowClip())
1643         || (isAnonymousBlock() && parent() && parent()->isRenderBlock() && parent()->style().textOverflow() && parent()->hasOverflowClip());
1644
1645     // Walk all the lines and delete our ellipsis line boxes if they exist.
1646     if (hasTextOverflow)
1647          deleteEllipsisLineBoxes();
1648
1649     if (firstChild()) {
1650         // In full layout mode, clear the line boxes of children upfront. Otherwise,
1651         // siblings can run into stale root lineboxes during layout. Then layout
1652         // the replaced elements later. In partial layout mode, line boxes are not
1653         // deleted and only dirtied. In that case, we can layout the replaced
1654         // elements at the same time.
1655         bool hasInlineChild = false;
1656         Vector<RenderBox*> replacedChildren;
1657         for (InlineWalker walker(*this); !walker.atEnd(); walker.advance()) {
1658             RenderObject& o = *walker.current();
1659
1660             if (!hasInlineChild && o.isInline())
1661                 hasInlineChild = true;
1662
1663             if (o.isReplaced() || o.isFloating() || o.isOutOfFlowPositioned()) {
1664                 RenderBox& box = toRenderBox(o);
1665
1666                 if (relayoutChildren || box.hasRelativeDimensions())
1667                     box.setChildNeedsLayout(MarkOnlyThis);
1668
1669                 // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
1670                 if (relayoutChildren && box.needsPreferredWidthsRecalculation())
1671                     box.setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
1672
1673                 if (box.isOutOfFlowPositioned())
1674                     box.containingBlock()->insertPositionedObject(box);
1675                 else if (box.isFloating())
1676                     layoutState.floats().append(FloatWithRect(box));
1677                 else if (isFullLayout || box.needsLayout()) {
1678                     // Replaced element.
1679                     box.dirtyLineBoxes(isFullLayout);
1680                     if (isFullLayout)
1681                         replacedChildren.append(&box);
1682                     else
1683                         box.layoutIfNeeded();
1684                 }
1685             } else if (o.isTextOrLineBreak() || (o.isRenderInline() && !walker.atEndOfInline())) {
1686                 if (o.isRenderInline())
1687                     toRenderInline(o).updateAlwaysCreateLineBoxes(layoutState.isFullLayout());
1688                 if (layoutState.isFullLayout() || o.selfNeedsLayout())
1689                     dirtyLineBoxesForRenderer(o, layoutState.isFullLayout());
1690                 o.clearNeedsLayout();
1691             }
1692         }
1693
1694         for (size_t i = 0; i < replacedChildren.size(); i++)
1695              replacedChildren[i]->layoutIfNeeded();
1696
1697         layoutRunsAndFloats(layoutState, hasInlineChild);
1698     }
1699
1700     // Expand the last line to accommodate Ruby and emphasis marks.
1701     int lastLineAnnotationsAdjustment = 0;
1702     if (lastRootBox()) {
1703         LayoutUnit lowestAllowedPosition = std::max(lastRootBox()->lineBottom(), logicalHeight() + paddingAfter());
1704         if (!style().isFlippedLinesWritingMode())
1705             lastLineAnnotationsAdjustment = lastRootBox()->computeUnderAnnotationAdjustment(lowestAllowedPosition);
1706         else
1707             lastLineAnnotationsAdjustment = lastRootBox()->computeOverAnnotationAdjustment(lowestAllowedPosition);
1708     }
1709
1710     // Now add in the bottom border/padding.
1711     setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + borderAndPaddingAfter() + scrollbarLogicalHeight());
1712
1713     if (!firstRootBox() && hasLineIfEmpty())
1714         setLogicalHeight(logicalHeight() + lineHeight(true, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
1715
1716     // See if we have any lines that spill out of our block.  If we do, then we will possibly need to
1717     // truncate text.
1718     if (hasTextOverflow)
1719         checkLinesForTextOverflow();
1720 }
1721
1722 void RenderBlockFlow::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWithRect>& floats, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat)
1723 {
1724     Vector<RenderBox*>* cleanLineFloats = line->floatsPtr();
1725     if (!cleanLineFloats)
1726         return;
1727
1728     for (auto it = cleanLineFloats->begin(), end = cleanLineFloats->end(); it != end; ++it) {
1729         RenderBox* floatingBox = *it;
1730         floatingBox->layoutIfNeeded();
1731         LayoutSize newSize(floatingBox->width() + floatingBox->marginWidth(), floatingBox->height() + floatingBox->marginHeight());
1732         ASSERT_WITH_SECURITY_IMPLICATION(floatIndex < floats.size());
1733         if (&floats[floatIndex].object != floatingBox) {
1734             encounteredNewFloat = true;
1735             return;
1736         }
1737
1738         if (floats[floatIndex].rect.size() != newSize) {
1739             LayoutUnit floatTop = isHorizontalWritingMode() ? floats[floatIndex].rect.y() : floats[floatIndex].rect.x();
1740             LayoutUnit floatHeight = isHorizontalWritingMode() ? std::max(floats[floatIndex].rect.height(), newSize.height()) : std::max(floats[floatIndex].rect.width(), newSize.width());
1741             floatHeight = std::min(floatHeight, LayoutUnit::max() - floatTop);
1742             line->markDirty();
1743             markLinesDirtyInBlockRange(line->lineBottomWithLeading(), floatTop + floatHeight, line);
1744             floats[floatIndex].rect.setSize(newSize);
1745             dirtiedByFloat = true;
1746         }
1747         floatIndex++;
1748     }
1749 }
1750
1751 RootInlineBox* RenderBlockFlow::determineStartPosition(LineLayoutState& layoutState, InlineBidiResolver& resolver)
1752 {
1753     RootInlineBox* curr = 0;
1754     RootInlineBox* last = 0;
1755
1756     // FIXME: This entire float-checking block needs to be broken into a new function.
1757     bool dirtiedByFloat = false;
1758     if (!layoutState.isFullLayout()) {
1759         // Paginate all of the clean lines.
1760         bool paginated = view().layoutState() && view().layoutState()->isPaginated();
1761         LayoutUnit paginationDelta = 0;
1762         size_t floatIndex = 0;
1763         for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
1764             if (paginated) {
1765                 if (lineWidthForPaginatedLineChanged(curr, 0, layoutState.flowThread())) {
1766                     curr->markDirty();
1767                     break;
1768                 }
1769                 paginationDelta -= curr->paginationStrut();
1770                 adjustLinePositionForPagination(curr, paginationDelta, layoutState.flowThread());
1771                 if (paginationDelta) {
1772                     if (containsFloats() || !layoutState.floats().isEmpty()) {
1773                         // FIXME: Do better eventually.  For now if we ever shift because of pagination and floats are present just go to a full layout.
1774                         layoutState.markForFullLayout();
1775                         break;
1776                     }
1777
1778                     layoutState.updateRepaintRangeFromBox(curr, paginationDelta);
1779                     curr->adjustBlockDirectionPosition(paginationDelta);
1780                 }
1781                 if (layoutState.flowThread())
1782                     updateRegionForLine(curr);
1783             }
1784
1785             // If a new float has been inserted before this line or before its last known float, just do a full layout.
1786             bool encounteredNewFloat = false;
1787             checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
1788             if (encounteredNewFloat)
1789                 layoutState.markForFullLayout();
1790
1791             if (dirtiedByFloat || layoutState.isFullLayout())
1792                 break;
1793         }
1794         // Check if a new float has been inserted after the last known float.
1795         if (!curr && floatIndex < layoutState.floats().size())
1796             layoutState.markForFullLayout();
1797     }
1798
1799     if (layoutState.isFullLayout()) {
1800         m_lineBoxes.deleteLineBoxTree();
1801         curr = 0;
1802
1803         ASSERT(!firstRootBox() && !lastRootBox());
1804     } else {
1805         if (curr) {
1806             // We have a dirty line.
1807             if (RootInlineBox* prevRootBox = curr->prevRootBox()) {
1808                 // We have a previous line.
1809                 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength())))
1810                     // The previous line didn't break cleanly or broke at a newline
1811                     // that has been deleted, so treat it as dirty too.
1812                     curr = prevRootBox;
1813             }
1814         } else {
1815             // No dirty lines were found.
1816             // If the last line didn't break cleanly, treat it as dirty.
1817             if (lastRootBox() && !lastRootBox()->endsWithBreak())
1818                 curr = lastRootBox();
1819         }
1820
1821         // If we have no dirty lines, then last is just the last root box.
1822         last = curr ? curr->prevRootBox() : lastRootBox();
1823     }
1824
1825     unsigned numCleanFloats = 0;
1826     if (!layoutState.floats().isEmpty()) {
1827         LayoutUnit savedLogicalHeight = logicalHeight();
1828         // Restore floats from clean lines.
1829         RootInlineBox* line = firstRootBox();
1830         while (line != curr) {
1831             if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
1832                 for (auto it = cleanLineFloats->begin(), end = cleanLineFloats->end(); it != end; ++it) {
1833                     RenderBox* floatingBox = *it;
1834                     FloatingObject* floatingObject = insertFloatingObject(*floatingBox);
1835                     ASSERT(!floatingObject->originatingLine());
1836                     floatingObject->setOriginatingLine(line);
1837                     setLogicalHeight(logicalTopForChild(*floatingBox) - marginBeforeForChild(*floatingBox));
1838                     positionNewFloats();
1839                     ASSERT(&layoutState.floats()[numCleanFloats].object == floatingBox);
1840                     numCleanFloats++;
1841                 }
1842             }
1843             line = line->nextRootBox();
1844         }
1845         setLogicalHeight(savedLogicalHeight);
1846     }
1847     layoutState.setFloatIndex(numCleanFloats);
1848
1849     layoutState.lineInfo().setFirstLine(!last);
1850     layoutState.lineInfo().setPreviousLineBrokeCleanly(!last || last->endsWithBreak());
1851
1852     if (last) {
1853         setLogicalHeight(last->lineBottomWithLeading());
1854         InlineIterator iter = InlineIterator(this, last->lineBreakObj(), last->lineBreakPos());
1855         resolver.setPosition(iter, numberOfIsolateAncestors(iter));
1856         resolver.setStatus(last->lineBreakBidiStatus());
1857     } else {
1858         TextDirection direction = style().direction();
1859         if (style().unicodeBidi() == Plaintext)
1860             determineDirectionality(direction, InlineIterator(this, bidiFirstSkippingEmptyInlines(*this), 0));
1861         resolver.setStatus(BidiStatus(direction, isOverride(style().unicodeBidi())));
1862         InlineIterator iter = InlineIterator(this, bidiFirstSkippingEmptyInlines(*this, &resolver), 0);
1863         resolver.setPosition(iter, numberOfIsolateAncestors(iter));
1864     }
1865     return curr;
1866 }
1867
1868 void RenderBlockFlow::determineEndPosition(LineLayoutState& layoutState, RootInlineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus)
1869 {
1870     ASSERT(!layoutState.endLine());
1871     size_t floatIndex = layoutState.floatIndex();
1872     RootInlineBox* last = 0;
1873     for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->nextRootBox()) {
1874         if (!curr->isDirty()) {
1875             bool encounteredNewFloat = false;
1876             bool dirtiedByFloat = false;
1877             checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
1878             if (encounteredNewFloat)
1879                 return;
1880         }
1881         if (curr->isDirty())
1882             last = 0;
1883         else if (!last)
1884             last = curr;
1885     }
1886
1887     if (!last)
1888         return;
1889
1890     // At this point, |last| is the first line in a run of clean lines that ends with the last line
1891     // in the block.
1892
1893     RootInlineBox* prev = last->prevRootBox();
1894     cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakPos());
1895     cleanLineBidiStatus = prev->lineBreakBidiStatus();
1896     layoutState.setEndLineLogicalTop(prev->lineBottomWithLeading());
1897
1898     for (RootInlineBox* line = last; line; line = line->nextRootBox())
1899         line->extractLine(); // Disconnect all line boxes from their render objects while preserving
1900                              // their connections to one another.
1901
1902     layoutState.setEndLine(last);
1903 }
1904
1905 bool RenderBlockFlow::checkPaginationAndFloatsAtEndLine(LineLayoutState& layoutState)
1906 {
1907     LayoutUnit lineDelta = logicalHeight() - layoutState.endLineLogicalTop();
1908
1909     bool paginated = view().layoutState() && view().layoutState()->isPaginated();
1910     if (paginated && layoutState.flowThread()) {
1911         // Check all lines from here to the end, and see if the hypothetical new position for the lines will result
1912         // in a different available line width.
1913         for (RootInlineBox* lineBox = layoutState.endLine(); lineBox; lineBox = lineBox->nextRootBox()) {
1914             if (paginated) {
1915                 // This isn't the real move we're going to do, so don't update the line box's pagination
1916                 // strut yet.
1917                 LayoutUnit oldPaginationStrut = lineBox->paginationStrut();
1918                 lineDelta -= oldPaginationStrut;
1919                 adjustLinePositionForPagination(lineBox, lineDelta, layoutState.flowThread());
1920                 lineBox->setPaginationStrut(oldPaginationStrut);
1921             }
1922             if (lineWidthForPaginatedLineChanged(lineBox, lineDelta, layoutState.flowThread()))
1923                 return false;
1924         }
1925     }
1926     
1927     if (!lineDelta || !m_floatingObjects)
1928         return true;
1929     
1930     // See if any floats end in the range along which we want to shift the lines vertically.
1931     LayoutUnit logicalTop = std::min(logicalHeight(), layoutState.endLineLogicalTop());
1932
1933     RootInlineBox* lastLine = layoutState.endLine();
1934     while (RootInlineBox* nextLine = lastLine->nextRootBox())
1935         lastLine = nextLine;
1936
1937     LayoutUnit logicalBottom = lastLine->lineBottomWithLeading() + absoluteValue(lineDelta);
1938
1939     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1940     auto end = floatingObjectSet.end();
1941     for (auto it = floatingObjectSet.begin(); it != end; ++it) {
1942         FloatingObject* floatingObject = it->get();
1943         if (logicalBottomForFloat(floatingObject) >= logicalTop && logicalBottomForFloat(floatingObject) < logicalBottom)
1944             return false;
1945     }
1946
1947     return true;
1948 }
1949
1950 bool RenderBlockFlow::lineWidthForPaginatedLineChanged(RootInlineBox* rootBox, LayoutUnit lineDelta, RenderFlowThread* flowThread) const
1951 {
1952     if (!flowThread)
1953         return false;
1954
1955     RenderRegion* currentRegion = regionAtBlockOffset(rootBox->lineTopWithLeading() + lineDelta);
1956     // Just bail if the region didn't change.
1957     if (rootBox->containingRegion() == currentRegion)
1958         return false;
1959     return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(currentRegion);
1960 }
1961
1962 bool RenderBlockFlow::matchedEndLine(LineLayoutState& layoutState, const InlineBidiResolver& resolver, const InlineIterator& endLineStart, const BidiStatus& endLineStatus)
1963 {
1964     if (resolver.position() == endLineStart) {
1965         if (resolver.status() != endLineStatus)
1966             return false;
1967         return checkPaginationAndFloatsAtEndLine(layoutState);
1968     }
1969
1970     // The first clean line doesn't match, but we can check a handful of following lines to try
1971     // to match back up.
1972     static int numLines = 8; // The # of lines we're willing to match against.
1973     RootInlineBox* originalEndLine = layoutState.endLine();
1974     RootInlineBox* line = originalEndLine;
1975     for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) {
1976         if (line->lineBreakObj() == resolver.position().renderer() && line->lineBreakPos() == resolver.position().offset()) {
1977             // We have a match.
1978             if (line->lineBreakBidiStatus() != resolver.status())
1979                 return false; // ...but the bidi state doesn't match.
1980             
1981             bool matched = false;
1982             RootInlineBox* result = line->nextRootBox();
1983             layoutState.setEndLine(result);
1984             if (result) {
1985                 layoutState.setEndLineLogicalTop(line->lineBottomWithLeading());
1986                 matched = checkPaginationAndFloatsAtEndLine(layoutState);
1987             }
1988
1989             // Now delete the lines that we failed to sync.
1990             deleteLineRange(layoutState, originalEndLine, result);
1991             return matched;
1992         }
1993     }
1994
1995     return false;
1996 }
1997
1998 bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj)
1999 {
2000     ASSERT(inlineObj->parent() == this);
2001
2002     InlineIterator it(this, inlineObj, 0);
2003     // FIXME: We should pass correct value for WhitespacePosition.
2004     while (!it.atEnd() && !requiresLineBox(it))
2005         it.increment();
2006
2007     return !it.atEnd();
2008 }
2009
2010 void RenderBlockFlow::addOverflowFromInlineChildren()
2011 {
2012     if (auto layout = simpleLineLayout()) {
2013         ASSERT(!hasOverflowClip());
2014         SimpleLineLayout::collectFlowOverflow(*this, *layout);
2015         return;
2016     }
2017     LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit();
2018     // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
2019     if (hasOverflowClip() && !endPadding && element() && element()->isRootEditableElement() && style().isLeftToRightDirection())
2020         endPadding = 1;
2021     for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
2022         addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding));
2023         RenderRegion* region = curr->containingRegion();
2024         if (region)
2025             region->addLayoutOverflowForBox(this, curr->paddedLayoutOverflowRect(endPadding));
2026         if (!hasOverflowClip()) {
2027             addVisualOverflow(curr->visualOverflowRect(curr->lineTop(), curr->lineBottom()));
2028             if (region)
2029                 region->addVisualOverflowForBox(this, curr->visualOverflowRect(curr->lineTop(), curr->lineBottom()));
2030         }
2031     }
2032 }
2033
2034 void RenderBlockFlow::deleteEllipsisLineBoxes()
2035 {
2036     ETextAlign textAlign = style().textAlign();
2037     bool ltr = style().isLeftToRightDirection();
2038     bool firstLine = true;
2039     for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
2040         if (curr->hasEllipsisBox()) {
2041             curr->clearTruncation();
2042
2043             // Shift the line back where it belongs if we cannot accomodate an ellipsis.
2044             float logicalLeft = pixelSnappedLogicalLeftOffsetForLine(curr->lineTop(), firstLine);
2045             float availableLogicalWidth = logicalRightOffsetForLine(curr->lineTop(), false) - logicalLeft;
2046             float totalLogicalWidth = curr->logicalWidth();
2047             updateLogicalWidthForAlignment(textAlign, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
2048
2049             if (ltr)
2050                 curr->adjustLogicalPosition((logicalLeft - curr->logicalLeft()), 0);
2051             else
2052                 curr->adjustLogicalPosition(-(curr->logicalLeft() - logicalLeft), 0);
2053         }
2054         firstLine = false;
2055     }
2056 }
2057
2058 void RenderBlockFlow::checkLinesForTextOverflow()
2059 {
2060     // Determine the width of the ellipsis using the current font.
2061     // FIXME: CSS3 says this is configurable, also need to use 0x002E (FULL STOP) if horizontal ellipsis is "not renderable"
2062     const Font& font = style().font();
2063     DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1));
2064     const Font& firstLineFont = firstLineStyle().font();
2065     int firstLineEllipsisWidth = firstLineFont.width(constructTextRun(this, firstLineFont, &horizontalEllipsis, 1, firstLineStyle()));
2066     int ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(constructTextRun(this, font, &horizontalEllipsis, 1, style()));
2067
2068     // For LTR text truncation, we want to get the right edge of our padding box, and then we want to see
2069     // if the right edge of a line box exceeds that.  For RTL, we use the left edge of the padding box and
2070     // check the left edge of the line box to see if it is less
2071     // Include the scrollbar for overflow blocks, which means we want to use "contentWidth()"
2072     bool ltr = style().isLeftToRightDirection();
2073     ETextAlign textAlign = style().textAlign();
2074     bool firstLine = true;
2075     for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
2076         // FIXME: Use pixelSnappedLogicalRightOffsetForLine instead of snapping it ourselves once the column workaround in said method has been fixed.
2077         // https://bugs.webkit.org/show_bug.cgi?id=105461
2078         int blockRightEdge = snapSizeToPixel(logicalRightOffsetForLine(curr->lineTop(), firstLine), curr->x());
2079         int blockLeftEdge = pixelSnappedLogicalLeftOffsetForLine(curr->lineTop(), firstLine);
2080         int lineBoxEdge = ltr ? snapSizeToPixel(curr->x() + curr->logicalWidth(), curr->x()) : snapSizeToPixel(curr->x(), 0);
2081         if ((ltr && lineBoxEdge > blockRightEdge) || (!ltr && lineBoxEdge < blockLeftEdge)) {
2082             // This line spills out of our box in the appropriate direction.  Now we need to see if the line
2083             // can be truncated.  In order for truncation to be possible, the line must have sufficient space to
2084             // accommodate our truncation string, and no replaced elements (images, tables) can overlap the ellipsis
2085             // space.
2086
2087             LayoutUnit width = firstLine ? firstLineEllipsisWidth : ellipsisWidth;
2088             LayoutUnit blockEdge = ltr ? blockRightEdge : blockLeftEdge;
2089             if (curr->lineCanAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width)) {
2090                 float totalLogicalWidth = curr->placeEllipsis(ellipsisStr, ltr, blockLeftEdge, blockRightEdge, width);
2091
2092                 float logicalLeft = 0; // We are only interested in the delta from the base position.
2093                 float truncatedWidth = pixelSnappedLogicalRightOffsetForLine(curr->lineTop(), firstLine);
2094                 updateLogicalWidthForAlignment(textAlign, 0, logicalLeft, totalLogicalWidth, truncatedWidth, 0);
2095                 if (ltr)
2096                     curr->adjustLogicalPosition(logicalLeft, 0);
2097                 else
2098                     curr->adjustLogicalPosition(-(truncatedWidth - (logicalLeft + totalLogicalWidth)), 0);
2099             }
2100         }
2101         firstLine = false;
2102     }
2103 }
2104
2105 bool RenderBlockFlow::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo& lineInfo, LineWidth& width)
2106 {
2107     if (!positionNewFloats())
2108         return false;
2109
2110     width.shrinkAvailableWidthForNewFloatIfNeeded(newFloat);
2111
2112     // We only connect floats to lines for pagination purposes if the floats occur at the start of
2113     // the line and the previous line had a hard break (so this line is either the first in the block
2114     // or follows a <br>).
2115     if (!newFloat->paginationStrut() || !lineInfo.previousLineBrokeCleanly() || !lineInfo.isEmpty())
2116         return true;
2117
2118     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2119     ASSERT(floatingObjectSet.last().get() == newFloat);
2120
2121     LayoutUnit floatLogicalTop = logicalTopForFloat(newFloat);
2122     int paginationStrut = newFloat->paginationStrut();
2123
2124     if (floatLogicalTop - paginationStrut != logicalHeight() + lineInfo.floatPaginationStrut())
2125         return true;
2126
2127     auto it = floatingObjectSet.end();
2128     --it; // Last float is newFloat, skip that one.
2129     auto begin = floatingObjectSet.begin();
2130     while (it != begin) {
2131         --it;
2132         FloatingObject* floatingObject = it->get();
2133         if (floatingObject == lastFloatFromPreviousLine)
2134             break;
2135         if (logicalTopForFloat(floatingObject) == logicalHeight() + lineInfo.floatPaginationStrut()) {
2136             floatingObject->setPaginationStrut(paginationStrut + floatingObject->paginationStrut());
2137             RenderBox& floatBox = floatingObject->renderer();
2138             setLogicalTopForChild(floatBox, logicalTopForChild(floatBox) + marginBeforeForChild(floatBox) + paginationStrut);
2139
2140             if (updateRegionRangeForBoxChild(floatingObject->renderer()))
2141                 floatBox.setNeedsLayout(MarkOnlyThis);
2142             else if (floatBox.isRenderBlock())
2143                 toRenderBlock(floatBox).setChildNeedsLayout(MarkOnlyThis);
2144             floatBox.layoutIfNeeded();
2145
2146             // Save the old logical top before calling removePlacedObject which will set
2147             // isPlaced to false. Otherwise it will trigger an assert in logicalTopForFloat.
2148             LayoutUnit oldLogicalTop = logicalTopForFloat(floatingObject);
2149             m_floatingObjects->removePlacedObject(floatingObject);
2150             setLogicalTopForFloat(floatingObject, oldLogicalTop + paginationStrut);
2151             m_floatingObjects->addPlacedObject(floatingObject);
2152         }
2153     }
2154
2155     // Just update the line info's pagination strut without altering our logical height yet. If the line ends up containing
2156     // no content, then we don't want to improperly grow the height of the block.
2157     lineInfo.setFloatPaginationStrut(lineInfo.floatPaginationStrut() + paginationStrut);
2158     return true;
2159 }
2160
2161 LayoutUnit RenderBlockFlow::startAlignedOffsetForLine(LayoutUnit position, bool firstLine)
2162 {
2163     ETextAlign textAlign = style().textAlign();
2164
2165     // <rdar://problem/15427571>
2166     // https://bugs.webkit.org/show_bug.cgi?id=124522
2167     // This quirk is for legacy content that doesn't work properly with the center positioning scheme
2168     // being honored (e.g., epubs).
2169     if (textAlign == TASTART || document().settings()->useLegacyTextAlignPositionedElementBehavior()) // FIXME: Handle TAEND here
2170         return startOffsetForLine(position, firstLine);
2171
2172     // updateLogicalWidthForAlignment() handles the direction of the block so no need to consider it here
2173     float totalLogicalWidth = 0;
2174     float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false);
2175     float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), false) - logicalLeft;
2176     updateLogicalWidthForAlignment(textAlign, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
2177
2178     if (!style().isLeftToRightDirection())
2179         return logicalWidth() - logicalLeft;
2180     return logicalLeft;
2181 }
2182
2183 void RenderBlockFlow::updateRegionForLine(RootInlineBox* lineBox) const
2184 {
2185     ASSERT(lineBox);
2186
2187     if (auto containingRegion = regionAtBlockOffset(lineBox->lineTopWithLeading()))
2188         lineBox->setContainingRegion(*containingRegion);
2189     else
2190         lineBox->clearContainingRegion();
2191
2192     RootInlineBox* prevLineBox = lineBox->prevRootBox();
2193     if (!prevLineBox)
2194         return;
2195
2196     // This check is more accurate than the one in |adjustLinePositionForPagination| because it takes into
2197     // account just the container changes between lines. The before mentioned function doesn't set the flag
2198     // correctly if the line is positioned at the top of the last fragment container.
2199     if (lineBox->containingRegion() != prevLineBox->containingRegion())
2200         lineBox->setIsFirstAfterPageBreak(true);
2201 }
2202
2203 }