Move m_floatingObjects to RenderBlockFlow from RenderBlock
[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  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  */
23
24 #include "config.h"
25
26 #include "BidiResolver.h"
27 #include "FloatingObjects.h"
28 #include "Hyphenation.h"
29 #include "InlineIterator.h"
30 #include "InlineTextBox.h"
31 #include "LineInfo.h"
32 #include "LineLayoutState.h"
33 #include "Logging.h"
34 #include "RenderArena.h"
35 #include "RenderBlockFlow.h"
36 #include "RenderCombineText.h"
37 #include "RenderCounter.h"
38 #include "RenderFlowThread.h"
39 #include "RenderInline.h"
40 #include "RenderLayer.h"
41 #include "RenderLineBreak.h"
42 #include "RenderListMarker.h"
43 #include "RenderRegion.h"
44 #include "RenderRubyRun.h"
45 #include "RenderView.h"
46 #include "Settings.h"
47 #include "TrailingFloatsRootInlineBox.h"
48 #include "VerticalPositionCache.h"
49 #include "break_lines.h"
50 #include <wtf/RefCountedLeakCounter.h>
51 #include <wtf/StdLibExtras.h>
52 #include <wtf/Vector.h>
53 #include <wtf/unicode/CharacterNames.h>
54
55 #if ENABLE(CSS_SHAPES)
56 #include "ShapeInsideInfo.h"
57 #endif
58
59 #if ENABLE(SVG)
60 #include "RenderSVGInlineText.h"
61 #include "SVGRootInlineBox.h"
62 #endif
63
64 using namespace std;
65 using namespace WTF;
66 using namespace Unicode;
67
68 namespace WebCore {
69
70 // We don't let our line box tree for a single line get any deeper than this.
71 const unsigned cMaxLineDepth = 200;
72
73 struct RenderTextInfo {
74     // Destruction of m_layout requires TextLayout to be a complete type, so the constructor and destructor are made non-inline to avoid compilation errors.
75     RenderTextInfo();
76     ~RenderTextInfo();
77
78     RenderText* m_text;
79     OwnPtr<TextLayout> m_layout;
80     LazyLineBreakIterator m_lineBreakIterator;
81     const Font* m_font;
82 };
83
84 class LineBreaker {
85 public:
86     LineBreaker(RenderBlockFlow* block)
87         : m_block(block)
88     {
89         reset();
90     }
91
92     InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
93
94     bool lineWasHyphenated() { return m_hyphenated; }
95     const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; }
96     EClear clear() { return m_clear; }
97 private:
98     void reset();
99
100     InlineIterator nextSegmentBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
101     void skipTrailingWhitespace(InlineIterator&, const LineInfo&);
102     void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
103
104     RenderBlockFlow* m_block;
105     bool m_hyphenated;
106     EClear m_clear;
107     Vector<RenderBox*> m_positionedObjects;
108 };
109
110 #if ENABLE(CSS_SHAPES)
111 ShapeInsideInfo* RenderBlock::layoutShapeInsideInfo() const
112 {
113     ShapeInsideInfo* shapeInsideInfo = view().layoutState()->shapeInsideInfo();
114
115     if (!shapeInsideInfo && flowThreadContainingBlock() && allowsShapeInsideInfoSharing()) {
116         LayoutUnit lineHeight = this->lineHeight(false, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
117         // regionAtBlockOffset returns regions like an array first={0,N-1}, second={N,M-1}, ...
118         LayoutUnit offset = logicalHeight() + lineHeight - LayoutUnit(1);
119         RenderRegion* region = regionAtBlockOffset(offset);
120         if (region)
121             shapeInsideInfo = region->shapeInsideInfo();
122     }
123
124     return shapeInsideInfo;
125 }
126 #endif
127
128 static inline LayoutUnit borderPaddingMarginStart(const RenderInline& child)
129 {
130     return child.marginStart() + child.paddingStart() + child.borderStart();
131 }
132
133 static inline LayoutUnit borderPaddingMarginEnd(const RenderInline& child)
134 {
135     return child.marginEnd() + child.paddingEnd() + child.borderEnd();
136 }
137
138 static inline bool shouldAddBorderPaddingMargin(RenderObject* child)
139 {
140     // When deciding whether we're at the edge of an inline, adjacent collapsed whitespace is the same as no sibling at all.
141     return !child || (child->isText() && !toRenderText(child)->textLength());
142 }
143
144 static RenderObject* previousInFlowSibling(RenderObject* child)
145 {
146     child = child->previousSibling();
147     while (child && child->isOutOfFlowPositioned())
148         child = child->previousSibling();
149     return child;
150 }
151
152 static LayoutUnit inlineLogicalWidth(RenderObject* child, bool checkStartEdge = true, bool checkEndEdge = true)
153 {
154     unsigned lineDepth = 1;
155     LayoutUnit extraWidth = 0;
156     RenderElement* parent = child->parent();
157     while (parent->isRenderInline() && lineDepth++ < cMaxLineDepth) {
158         const RenderInline& parentAsRenderInline = toRenderInline(*parent);
159         if (!isEmptyInline(parentAsRenderInline)) {
160             checkStartEdge = checkStartEdge && shouldAddBorderPaddingMargin(previousInFlowSibling(child));
161             if (checkStartEdge)
162                 extraWidth += borderPaddingMarginStart(parentAsRenderInline);
163             checkEndEdge = checkEndEdge && shouldAddBorderPaddingMargin(child->nextSibling());
164             if (checkEndEdge)
165                 extraWidth += borderPaddingMarginEnd(parentAsRenderInline);
166             if (!checkStartEdge && !checkEndEdge)
167                 return extraWidth;
168         }
169         child = parent;
170         parent = child->parent();
171     }
172     return extraWidth;
173 }
174
175 static void determineDirectionality(TextDirection& dir, InlineIterator iter)
176 {
177     while (!iter.atEnd()) {
178         if (iter.atParagraphSeparator())
179             return;
180         if (UChar current = iter.current()) {
181             Direction charDirection = direction(current);
182             if (charDirection == LeftToRight) {
183                 dir = LTR;
184                 return;
185             }
186             if (charDirection == RightToLeft || charDirection == RightToLeftArabic) {
187                 dir = RTL;
188                 return;
189             }
190         }
191         iter.increment();
192     }
193 }
194
195 static void checkMidpoints(LineMidpointState& lineMidpointState, InlineIterator& lBreak)
196 {
197     // Check to see if our last midpoint is a start point beyond the line break.  If so,
198     // shave it off the list, and shave off a trailing space if the previous end point doesn't
199     // preserve whitespace.
200     if (lBreak.m_obj && lineMidpointState.numMidpoints && !(lineMidpointState.numMidpoints % 2)) {
201         InlineIterator* midpoints = lineMidpointState.midpoints.data();
202         InlineIterator& endpoint = midpoints[lineMidpointState.numMidpoints - 2];
203         const InlineIterator& startpoint = midpoints[lineMidpointState.numMidpoints - 1];
204         InlineIterator currpoint = endpoint;
205         while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBreak)
206             currpoint.increment();
207         if (currpoint == lBreak) {
208             // We hit the line break before the start point.  Shave off the start point.
209             lineMidpointState.numMidpoints--;
210             if (endpoint.m_obj->style()->collapseWhiteSpace())
211                 endpoint.m_pos--;
212         }
213     }
214 }
215
216 // Don't call this directly. Use one of the descriptive helper functions below.
217 static void deprecatedAddMidpoint(LineMidpointState& lineMidpointState, const InlineIterator& midpoint)
218 {
219     if (lineMidpointState.midpoints.size() <= lineMidpointState.numMidpoints)
220         lineMidpointState.midpoints.grow(lineMidpointState.numMidpoints + 10);
221
222     InlineIterator* midpoints = lineMidpointState.midpoints.data();
223     midpoints[lineMidpointState.numMidpoints++] = midpoint;
224 }
225
226 static inline void startIgnoringSpaces(LineMidpointState& lineMidpointState, const InlineIterator& midpoint)
227 {
228     ASSERT(!(lineMidpointState.numMidpoints % 2));
229     deprecatedAddMidpoint(lineMidpointState, midpoint);
230 }
231
232 static inline void stopIgnoringSpaces(LineMidpointState& lineMidpointState, const InlineIterator& midpoint)
233 {
234     ASSERT(lineMidpointState.numMidpoints % 2);
235     deprecatedAddMidpoint(lineMidpointState, midpoint);
236 }
237
238 // When ignoring spaces, this needs to be called for objects that need line boxes such as RenderInlines or
239 // hard line breaks to ensure that they're not ignored.
240 static inline void ensureLineBoxInsideIgnoredSpaces(LineMidpointState& lineMidpointState, RenderObject* renderer)
241 {
242     InlineIterator midpoint(0, renderer, 0);
243     stopIgnoringSpaces(lineMidpointState, midpoint);
244     startIgnoringSpaces(lineMidpointState, midpoint);
245 }
246
247 // Adding a pair of midpoints before a character will split it out into a new line box.
248 static inline void ensureCharacterGetsLineBox(LineMidpointState& lineMidpointState, InlineIterator& textParagraphSeparator)
249 {
250     InlineIterator midpoint(0, textParagraphSeparator.m_obj, textParagraphSeparator.m_pos);
251     startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparator.m_obj, textParagraphSeparator.m_pos - 1));
252     stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparator.m_obj, textParagraphSeparator.m_pos));
253 }
254
255 static inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
256 {
257     return new (obj->renderArena()) BidiRun(start, end, obj, resolver.context(), resolver.dir());
258 }
259
260 void RenderBlockFlow::appendRunsForObject(BidiRunList<BidiRun>& runs, int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
261 {
262     if (start > end || shouldSkipCreatingRunsForObject(obj))
263         return;
264
265     LineMidpointState& lineMidpointState = resolver.midpointState();
266     bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointState.numMidpoints);
267     InlineIterator nextMidpoint;
268     if (haveNextMidpoint)
269         nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidpoint];
270     if (lineMidpointState.betweenMidpoints) {
271         if (!(haveNextMidpoint && nextMidpoint.m_obj == obj))
272             return;
273         // This is a new start point. Stop ignoring objects and
274         // adjust our start.
275         lineMidpointState.betweenMidpoints = false;
276         start = nextMidpoint.m_pos;
277         lineMidpointState.currentMidpoint++;
278         if (start < end)
279             return appendRunsForObject(runs, start, end, obj, resolver);
280     } else {
281         if (!haveNextMidpoint || (obj != nextMidpoint.m_obj)) {
282             runs.addRun(createRun(start, end, obj, resolver));
283             return;
284         }
285
286         // An end midpoint has been encountered within our object.  We
287         // need to go ahead and append a run with our endpoint.
288         if (static_cast<int>(nextMidpoint.m_pos + 1) <= end) {
289             lineMidpointState.betweenMidpoints = true;
290             lineMidpointState.currentMidpoint++;
291             if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the object and don't include any of it.
292                 if (static_cast<int>(nextMidpoint.m_pos + 1) > start)
293                     runs.addRun(createRun(start, nextMidpoint.m_pos + 1, obj, resolver));
294                 return appendRunsForObject(runs, nextMidpoint.m_pos + 1, end, obj, resolver);
295             }
296         } else
297            runs.addRun(createRun(start, end, obj, resolver));
298     }
299 }
300
301 static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
302 {
303     if (isRootLineBox)
304         return toRenderBlock(obj)->createAndAppendRootInlineBox();
305
306     if (obj->isText())
307         return toRenderText(obj)->createInlineTextBox();
308
309     if (obj->isBox())
310         return toRenderBox(obj)->createInlineBox();
311
312     if (obj->isLineBreak()) {
313         InlineBox* inlineBox = toRenderLineBreak(obj)->createInlineBox();
314         // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode
315         // (Note the use of strict mode. In "almost strict" mode, we don't treat the box for <br> as text.)
316         inlineBox->setBehavesLikeText(isOnlyRun || obj->document().inNoQuirksMode() || obj->isLineBreakOpportunity());
317         return inlineBox;
318     }
319
320     return toRenderInline(obj)->createAndAppendInlineFlowBox();
321 }
322
323 // FIXME: Don't let counters mark themselves as needing pref width recalcs during layout
324 // so we don't need this hack.
325 static inline void updateCounterIfNeeded(RenderText* o)
326 {
327     if (!o->preferredLogicalWidthsDirty() || !o->isCounter())
328         return;
329     toRenderCounter(o)->updateCounter();
330 }
331
332 static inline void dirtyLineBoxesForRenderer(RenderObject* o, bool fullLayout)
333 {
334     if (o->isText()) {
335         RenderText* renderText = toRenderText(o);
336         updateCounterIfNeeded(renderText);
337         renderText->dirtyLineBoxes(fullLayout);
338     } else if (o->isLineBreak())
339         toRenderLineBreak(o)->dirtyLineBoxes(fullLayout);
340     else
341         toRenderInline(o)->dirtyLineBoxes(fullLayout);
342 }
343
344 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox)
345 {
346     do {
347         if (parentBox->isConstructed() || parentBox->nextOnLine())
348             return true;
349         parentBox = parentBox->parent();
350     } while (parentBox);
351     return false;
352 }
353
354 InlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInfo& lineInfo, InlineBox* childBox, bool startNewSegment)
355 {
356     // See if we have an unconstructed line box for this object that is also
357     // the last item on the line.
358     unsigned lineDepth = 1;
359     InlineFlowBox* parentBox = 0;
360     InlineFlowBox* result = 0;
361     bool hasDefaultLineBoxContain = style()->lineBoxContain() == RenderStyle::initialLineBoxContain();
362     do {
363         ASSERT_WITH_SECURITY_IMPLICATION(obj->isRenderInline() || obj == this);
364
365         RenderInline* inlineFlow = (obj != this) ? toRenderInline(obj) : 0;
366
367         // Get the last box we made for this render object.
368         parentBox = inlineFlow ? inlineFlow->lastLineBox() : toRenderBlock(obj)->lastLineBox();
369
370         // If this box or its ancestor is constructed then it is from a previous line, and we need
371         // to make a new box for our line.  If this box or its ancestor is unconstructed but it has
372         // something following it on the line, then we know we have to make a new box
373         // as well.  In this situation our inline has actually been split in two on
374         // the same line (this can happen with very fancy language mixtures).
375         bool constructedNewBox = false;
376         bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow || inlineFlow->alwaysCreateLineBoxes();
377         bool mustCreateBoxesToRoot = startNewSegment && !(parentBox && parentBox->isRootInlineBox());
378         bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox) && !mustCreateBoxesToRoot;
379         if (allowedToConstructNewBox && !canUseExistingParentBox) {
380             // We need to make a new box for this render object.  Once
381             // made, we need to place it at the end of the current line.
382             InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this);
383             ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox());
384             parentBox = toInlineFlowBox(newBox);
385             parentBox->setIsFirstLine(lineInfo.isFirstLine());
386             parentBox->setIsHorizontal(isHorizontalWritingMode());
387             if (!hasDefaultLineBoxContain)
388                 parentBox->clearDescendantsHaveSameLineHeightAndBaseline();
389             constructedNewBox = true;
390         }
391
392         if (constructedNewBox || canUseExistingParentBox) {
393             if (!result)
394                 result = parentBox;
395
396             // If we have hit the block itself, then |box| represents the root
397             // inline box for the line, and it doesn't have to be appended to any parent
398             // inline.
399             if (childBox)
400                 parentBox->addToLine(childBox);
401
402             if (!constructedNewBox || obj == this)
403                 break;
404
405             childBox = parentBox;
406         }
407
408         // If we've exceeded our line depth, then jump straight to the root and skip all the remaining
409         // intermediate inline flows.
410         obj = (++lineDepth >= cMaxLineDepth) ? this : obj->parent();
411
412     } while (true);
413
414     return result;
415 }
416
417 template <typename CharacterType>
418 static inline bool endsWithASCIISpaces(const CharacterType* characters, unsigned pos, unsigned end)
419 {
420     while (isASCIISpace(characters[pos])) {
421         pos++;
422         if (pos >= end)
423             return true;
424     }
425     return false;
426 }
427
428 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns)
429 {
430     BidiRun* run = bidiRuns.logicallyLastRun();
431     if (!run)
432         return true;
433     unsigned pos = run->stop();
434     RenderObject* r = run->m_object;
435     if (!r->isText())
436         return false;
437     RenderText* renderText = toRenderText(r);
438     unsigned length = renderText->textLength();
439     if (pos >= length)
440         return true;
441
442     if (renderText->is8Bit())
443         return endsWithASCIISpaces(renderText->characters8(), pos, length);
444     return endsWithASCIISpaces(renderText->characters16(), pos, length);
445 }
446
447 RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, const LineInfo& lineInfo)
448 {
449     ASSERT(bidiRuns.firstRun());
450
451     bool rootHasSelectedChildren = false;
452     InlineFlowBox* parentBox = 0;
453     int runCount = bidiRuns.runCount() - lineInfo.runsFromLeadingWhitespace();
454     for (BidiRun* r = bidiRuns.firstRun(); r; r = r->next()) {
455         // Create a box for our object.
456         bool isOnlyRun = (runCount == 1);
457         if (runCount == 2 && !r->m_object->isListMarker())
458             isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun() : bidiRuns.firstRun())->m_object->isListMarker();
459
460         if (lineInfo.isEmpty())
461             continue;
462
463         InlineBox* box = createInlineBoxForRenderer(r->m_object, false, isOnlyRun);
464         r->m_box = box;
465
466         ASSERT(box);
467         if (!box)
468             continue;
469
470         if (!rootHasSelectedChildren && box->renderer().selectionState() != RenderObject::SelectionNone)
471             rootHasSelectedChildren = true;
472
473         // If we have no parent box yet, or if the run is not simply a sibling,
474         // then we need to construct inline boxes as necessary to properly enclose the
475         // run's inline box. Segments can only be siblings at the root level, as
476         // they are positioned separately.
477 #if ENABLE(CSS_SHAPES)
478         bool runStartsSegment = r->m_startsSegment;
479 #else
480         bool runStartsSegment = false;
481 #endif
482         if (!parentBox || &parentBox->renderer() != r->m_object->parent() || runStartsSegment)
483             // Create new inline boxes all the way back to the appropriate insertion point.
484             parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box, runStartsSegment);
485         else {
486             // Append the inline box to this line.
487             parentBox->addToLine(box);
488         }
489
490         bool visuallyOrdered = r->m_object->style()->rtlOrdering() == VisualOrder;
491         box->setBidiLevel(r->level());
492
493         if (box->isInlineTextBox()) {
494             InlineTextBox* text = toInlineTextBox(box);
495             text->setStart(r->m_start);
496             text->setLen(r->m_stop - r->m_start);
497             text->setDirOverride(r->dirOverride(visuallyOrdered));
498             if (r->m_hasHyphen)
499                 text->setHasHyphen(true);
500         }
501     }
502
503     // We should have a root inline box.  It should be unconstructed and
504     // be the last continuation of our line list.
505     ASSERT(lastLineBox() && !lastLineBox()->isConstructed());
506
507     // Set the m_selectedChildren flag on the root inline box if one of the leaf inline box
508     // from the bidi runs walk above has a selection state.
509     if (rootHasSelectedChildren)
510         lastLineBox()->root().setHasSelectedChildren(true);
511
512     // Set bits on our inline flow boxes that indicate which sides should
513     // paint borders/margins/padding.  This knowledge will ultimately be used when
514     // we determine the horizontal positions and widths of all the inline boxes on
515     // the line.
516     bool isLogicallyLastRunWrapped = bidiRuns.logicallyLastRun()->m_object && bidiRuns.logicallyLastRun()->m_object->isText() ? !reachedEndOfTextRenderer(bidiRuns) : true;
517     lastLineBox()->determineSpacingForFlowBoxes(lineInfo.isLastLine(), isLogicallyLastRunWrapped, bidiRuns.logicallyLastRun()->m_object);
518
519     // Now mark the line boxes as being constructed.
520     lastLineBox()->setConstructed();
521
522     // Return the last line.
523     return lastRootBox();
524 }
525
526 ETextAlign RenderBlock::textAlignmentForLine(bool endsWithSoftBreak) const
527 {
528     ETextAlign alignment = style()->textAlign();
529     if (!endsWithSoftBreak && alignment == JUSTIFY)
530         alignment = TASTART;
531
532     return alignment;
533 }
534
535 static void updateLogicalWidthForLeftAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
536 {
537     // The direction of the block should determine what happens with wide lines.
538     // In particular with RTL blocks, wide lines should still spill out to the left.
539     if (isLeftToRightDirection) {
540         if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
541             trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
542         return;
543     }
544
545     if (trailingSpaceRun)
546         trailingSpaceRun->m_box->setLogicalWidth(0);
547     else if (totalLogicalWidth > availableLogicalWidth)
548         logicalLeft -= (totalLogicalWidth - availableLogicalWidth);
549 }
550
551 static void updateLogicalWidthForRightAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
552 {
553     // Wide lines spill out of the block based off direction.
554     // So even if text-align is right, if direction is LTR, wide lines should overflow out of the right
555     // side of the block.
556     if (isLeftToRightDirection) {
557         if (trailingSpaceRun) {
558             totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
559             trailingSpaceRun->m_box->setLogicalWidth(0);
560         }
561         if (totalLogicalWidth < availableLogicalWidth)
562             logicalLeft += availableLogicalWidth - totalLogicalWidth;
563         return;
564     }
565
566     if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) {
567         trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
568         totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
569     } else
570         logicalLeft += availableLogicalWidth - totalLogicalWidth;
571 }
572
573 static void updateLogicalWidthForCenterAlignedBlock(bool isLeftToRightDirection, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float availableLogicalWidth)
574 {
575     float trailingSpaceWidth = 0;
576     if (trailingSpaceRun) {
577         totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
578         trailingSpaceWidth = min(trailingSpaceRun->m_box->logicalWidth(), (availableLogicalWidth - totalLogicalWidth + 1) / 2);
579         trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceWidth));
580     }
581     if (isLeftToRightDirection)
582         logicalLeft += max<float>((availableLogicalWidth - totalLogicalWidth) / 2, 0);
583     else
584         logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLogicalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth;
585 }
586
587 void RenderBlockFlow::setMarginsForRubyRun(BidiRun* run, RenderRubyRun* renderer, RenderObject* previousObject, const LineInfo& lineInfo)
588 {
589     int startOverhang;
590     int endOverhang;
591     RenderObject* nextObject = 0;
592     for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNextObject = runWithNextObject->next()) {
593         if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNextObject->m_box->isLineBreak()) {
594             nextObject = runWithNextObject->m_object;
595             break;
596         }
597     }
598     renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRightDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhang);
599     setMarginStartForChild(renderer, -startOverhang);
600     setMarginEndForChild(renderer, -endOverhang);
601 }
602
603 static inline float measureHyphenWidth(RenderText* renderer, const Font& font, HashSet<const SimpleFontData*>* fallbackFonts = 0)
604 {
605     const RenderStyle& style = *renderer->style();
606     return font.width(RenderBlock::constructTextRun(renderer, font, style.hyphenString().string(), style), fallbackFonts);
607 }
608
609 class WordMeasurement {
610 public:
611     WordMeasurement()
612         : renderer(0)
613         , width(0)
614         , startOffset(0)
615         , endOffset(0)
616     {
617     }
618     
619     RenderText* renderer;
620     float width;
621     int startOffset;
622     int endOffset;
623     HashSet<const SimpleFontData*> fallbackFonts;
624 };
625
626 static inline const RenderStyle& lineStyle(const RenderElement& renderer, const LineInfo& lineInfo)
627 {
628     return lineInfo.isFirstLine() ? *renderer.firstLineStyle() : *renderer.style();
629 }
630
631 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* run, RenderText* renderer, float xPos, const LineInfo& lineInfo,
632     GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements)
633 {
634     HashSet<const SimpleFontData*> fallbackFonts;
635     GlyphOverflow glyphOverflow;
636
637     const Font& font = lineStyle(*renderer->parent(), lineInfo).font();
638     // Always compute glyph overflow if the block's line-box-contain value is "glyphs".
639     if (lineBox->fitsToGlyphs()) {
640         // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization
641         // will keep us from computing glyph bounds in nearly all cases.
642         bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading();
643         int baselineShift = lineBox->verticalPositionForBox(run->m_box, verticalPositionCache);
644         int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0;
645         int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0;
646         int boxAscent = font.fontMetrics().ascent() - baselineShift;
647         int boxDescent = font.fontMetrics().descent() + baselineShift;
648         if (boxAscent > rootDescent ||  boxDescent > rootAscent)
649             glyphOverflow.computeBounds = true; 
650     }
651     
652     LayoutUnit hyphenWidth = 0;
653     if (toInlineTextBox(run->m_box)->hasHyphen())
654         hyphenWidth = measureHyphenWidth(renderer, font, &fallbackFonts);
655
656     float measuredWidth = 0;
657
658     bool kerningIsEnabled = font.typesettingFeatures() & Kerning;
659     bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath();
660     
661     // Since we don't cache glyph overflows, we need to re-measure the run if
662     // the style is linebox-contain: glyph.
663     
664     if (!lineBox->fitsToGlyphs() && canUseSimpleFontCodePath) {
665         int lastEndOffset = run->m_start;
666         for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOffset < run->m_stop; ++i) {
667             WordMeasurement& wordMeasurement = wordMeasurements[i];
668             if (wordMeasurement.width <= 0 || wordMeasurement.startOffset == wordMeasurement.endOffset)
669                 continue;
670             if (wordMeasurement.renderer != renderer || wordMeasurement.startOffset != lastEndOffset || wordMeasurement.endOffset > run->m_stop)
671                 continue;
672
673             lastEndOffset = wordMeasurement.endOffset;
674             if (kerningIsEnabled && lastEndOffset == run->m_stop) {
675                 int wordLength = lastEndOffset - wordMeasurement.startOffset;
676                 GlyphOverflow overflow;
677                 measuredWidth += renderer->width(wordMeasurement.startOffset, wordLength, xPos + measuredWidth, lineInfo.isFirstLine(),
678                     &wordMeasurement.fallbackFonts, &overflow);
679                 UChar c = renderer->characterAt(wordMeasurement.startOffset);
680                 if (i > 0 && wordLength == 1 && (c == ' ' || c == '\t'))
681                     measuredWidth += renderer->style()->wordSpacing();
682             } else
683                 measuredWidth += wordMeasurement.width;
684             if (!wordMeasurement.fallbackFonts.isEmpty()) {
685                 HashSet<const SimpleFontData*>::const_iterator end = wordMeasurement.fallbackFonts.end();
686                 for (HashSet<const SimpleFontData*>::const_iterator it = wordMeasurement.fallbackFonts.begin(); it != end; ++it)
687                     fallbackFonts.add(*it);
688             }
689         }
690         if (measuredWidth && lastEndOffset != run->m_stop) {
691             // If we don't have enough cached data, we'll measure the run again.
692             measuredWidth = 0;
693             fallbackFonts.clear();
694         }
695     }
696
697     if (!measuredWidth)
698         measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow);
699
700     run->m_box->setLogicalWidth(measuredWidth + hyphenWidth);
701     if (!fallbackFonts.isEmpty()) {
702         ASSERT(run->m_box->behavesLikeText());
703         GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator;
704         ASSERT(it->value.first.isEmpty());
705         copyToVector(fallbackFonts, it->value.first);
706         run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline();
707     }
708     if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) {
709         ASSERT(run->m_box->behavesLikeText());
710         GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator;
711         it->value.second = glyphOverflow;
712         run->m_box->clearKnownToHaveNoOverflow();
713     }
714 }
715
716 static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, Vector<unsigned, 16>& expansionOpportunities, unsigned expansionOpportunityCount, float& totalLogicalWidth, float availableLogicalWidth)
717 {
718     if (!expansionOpportunityCount || availableLogicalWidth <= totalLogicalWidth)
719         return;
720
721     size_t i = 0;
722     for (BidiRun* r = firstRun; r; r = r->next()) {
723 #if ENABLE(CSS_SHAPES)
724         // This method is called once per segment, do not move past the current segment.
725         if (r->m_startsSegment)
726             break;
727 #endif
728         if (!r->m_box || r == trailingSpaceRun)
729             continue;
730         
731         if (r->m_object->isText()) {
732             unsigned opportunitiesInRun = expansionOpportunities[i++];
733             
734             ASSERT(opportunitiesInRun <= expansionOpportunityCount);
735             
736             // Only justify text if whitespace is collapsed.
737             if (r->m_object->style()->collapseWhiteSpace()) {
738                 InlineTextBox* textBox = toInlineTextBox(r->m_box);
739                 int expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
740                 textBox->setExpansion(expansion);
741                 totalLogicalWidth += expansion;
742             }
743             expansionOpportunityCount -= opportunitiesInRun;
744             if (!expansionOpportunityCount)
745                 break;
746         }
747     }
748 }
749
750 void RenderBlock::updateLogicalWidthForAlignment(const ETextAlign& textAlign, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount)
751 {
752     // Armed with the total width of the line (without justification),
753     // we now examine our text-align property in order to determine where to position the
754     // objects horizontally. The total width of the line can be increased if we end up
755     // justifying text.
756     switch (textAlign) {
757     case LEFT:
758     case WEBKIT_LEFT:
759         updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
760         break;
761     case RIGHT:
762     case WEBKIT_RIGHT:
763         updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
764         break;
765     case CENTER:
766     case WEBKIT_CENTER:
767         updateLogicalWidthForCenterAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
768         break;
769     case JUSTIFY:
770         adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, availableLogicalWidth);
771         if (expansionOpportunityCount) {
772             if (trailingSpaceRun) {
773                 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
774                 trailingSpaceRun->m_box->setLogicalWidth(0);
775             }
776             break;
777         }
778         // Fall through
779     case TASTART:
780         if (style()->isLeftToRightDirection())
781             updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
782         else
783             updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
784         break;
785     case TAEND:
786         if (style()->isLeftToRightDirection())
787             updateLogicalWidthForRightAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
788         else
789             updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
790         break;
791     }
792 }
793
794 static IndentTextOrNot requiresIndent(bool isFirstLine, bool isAfterHardLineBreak, const RenderStyle& style)
795 {
796     IndentTextOrNot shouldIndentText = DoNotIndentText;
797     if (isFirstLine)
798         shouldIndentText = IndentText;
799 #if ENABLE(CSS3_TEXT)
800     else if (isAfterHardLineBreak && style.textIndentLine() == TextIndentEachLine)
801         shouldIndentText = IndentText;
802
803     if (style.textIndentType() == TextIndentHanging)
804         shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : IndentText;
805 #else
806     UNUSED_PARAM(isAfterHardLineBreak);
807     UNUSED_PARAM(style);
808 #endif
809     return shouldIndentText;
810 }
811
812 static void updateLogicalInlinePositions(RenderBlockFlow* block, float& lineLogicalLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine, IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight)
813 {
814     LayoutUnit lineLogicalHeight = block->minLineHeightForReplacedRenderer(firstLine, boxLogicalHeight);
815     lineLogicalLeft = block->pixelSnappedLogicalLeftOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight);
816     lineLogicalRight = block->pixelSnappedLogicalRightOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight);
817     availableLogicalWidth = lineLogicalRight - lineLogicalLeft;
818 }
819
820 void RenderBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd,
821                                                          GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements)
822 {
823     ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak());
824     
825     // 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 
826     // box is only affected if it is the first child of its parent element."
827     // CSS3 "text-indent", "-webkit-each-line" affects the first line of the block container as well as each line after a forced line break,
828     // but does not affect lines after a soft wrap break.
829     bool isFirstLine = lineInfo.isFirstLine() && !(isAnonymousBlock() && parent()->firstChild() != this);
830     bool isAfterHardLineBreak = lineBox->prevRootBox() && lineBox->prevRootBox()->endsWithBreak();
831     IndentTextOrNot shouldIndentText = requiresIndent(isFirstLine, isAfterHardLineBreak, *style());
832     float lineLogicalLeft;
833     float lineLogicalRight;
834     float availableLogicalWidth;
835     updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, availableLogicalWidth, isFirstLine, shouldIndentText, 0);
836     bool needsWordSpacing;
837 #if ENABLE(CSS_SHAPES)
838     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
839     if (shapeInsideInfo && shapeInsideInfo->hasSegments()) {
840         BidiRun* segmentStart = firstRun;
841         const SegmentList& segments = shapeInsideInfo->segments();
842         float logicalLeft = max<float>(roundToInt(segments[0].logicalLeft), lineLogicalLeft);
843         float logicalRight = min<float>(floorToInt(segments[0].logicalRight), lineLogicalRight);
844         float startLogicalLeft = logicalLeft;
845         float endLogicalRight = logicalLeft;
846         float minLogicalLeft = logicalLeft;
847         float maxLogicalRight = logicalLeft;
848         lineBox->beginPlacingBoxRangesInInlineDirection(logicalLeft);
849         for (size_t i = 0; i < segments.size(); i++) {
850             if (i) {
851                 logicalLeft = max<float>(roundToInt(segments[i].logicalLeft), lineLogicalLeft);
852                 logicalRight = min<float>(floorToInt(segments[i].logicalRight), lineLogicalRight);
853             }
854             availableLogicalWidth = logicalRight - logicalLeft;
855             BidiRun* newSegmentStart = computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, logicalLeft, availableLogicalWidth, segmentStart, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements);
856             needsWordSpacing = false;
857             endLogicalRight = lineBox->placeBoxRangeInInlineDirection(segmentStart->m_box, newSegmentStart ? newSegmentStart->m_box : 0, logicalLeft, minLogicalLeft, maxLogicalRight, needsWordSpacing, textBoxDataMap);
858             if (!newSegmentStart || !newSegmentStart->next())
859                 break;
860             ASSERT(newSegmentStart->m_startsSegment);
861             // Discard the empty segment start marker bidi runs
862             segmentStart = newSegmentStart->next();
863         }
864         lineBox->endPlacingBoxRangesInInlineDirection(startLogicalLeft, endLogicalRight, minLogicalLeft, maxLogicalRight);
865         return;
866     }
867 #endif
868
869     if (firstRun && firstRun->m_object->isReplaced()) {
870         RenderBox* renderBox = toRenderBox(firstRun->m_object);
871         updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, availableLogicalWidth, isFirstLine, shouldIndentText, renderBox->logicalHeight());
872     }
873
874     computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, lineLogicalLeft, availableLogicalWidth, firstRun, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements);
875     // The widths of all runs are now known. We can now place every inline box (and
876     // compute accurate widths for the inline flow boxes).
877     needsWordSpacing = false;
878     lineBox->placeBoxesInInlineDirection(lineLogicalLeft, needsWordSpacing, textBoxDataMap);
879 }
880
881 BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBox* lineBox, const LineInfo& lineInfo, ETextAlign textAlign, float& logicalLeft, 
882     float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache,
883     WordMeasurements& wordMeasurements)
884 {
885     bool needsWordSpacing = false;
886     float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
887     unsigned expansionOpportunityCount = 0;
888     bool isAfterExpansion = true;
889     Vector<unsigned, 16> expansionOpportunities;
890     RenderObject* previousObject = 0;
891
892     BidiRun* r = firstRun;
893     for (; r; r = r->next()) {
894 #if ENABLE(CSS_SHAPES)
895         // Once we have reached the start of the next segment, we have finished
896         // computing the positions for this segment's contents.
897         if (r->m_startsSegment)
898             break;
899 #endif
900         if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLineBreak())
901             continue; // Positioned objects are only participating to figure out their
902                       // correct static x position.  They have no effect on the width.
903                       // Similarly, line break boxes have no effect on the width.
904         if (r->m_object->isText()) {
905             RenderText* rt = toRenderText(r->m_object);
906             if (textAlign == JUSTIFY && r != trailingSpaceRun) {
907                 if (!isAfterExpansion)
908                     toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true);
909                 unsigned opportunitiesInRun;
910                 if (rt->is8Bit())
911                     opportunitiesInRun = Font::expansionOpportunityCount(rt->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
912                 else
913                     opportunitiesInRun = Font::expansionOpportunityCount(rt->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
914                 expansionOpportunities.append(opportunitiesInRun);
915                 expansionOpportunityCount += opportunitiesInRun;
916             }
917
918             if (int length = rt->textLength()) {
919                 if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->characterAt(r->m_start)))
920                     totalLogicalWidth += lineStyle(*rt->parent(), lineInfo).font().wordSpacing();
921                 needsWordSpacing = !isSpaceOrNewline(rt->characterAt(r->m_stop - 1)) && r->m_stop == length;
922             }
923
924             setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache, wordMeasurements);
925         } else {
926             isAfterExpansion = false;
927             if (!r->m_object->isRenderInline()) {
928                 RenderBox* renderBox = toRenderBox(r->m_object);
929                 if (renderBox->isRubyRun())
930                     setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previousObject, lineInfo);
931                 r->m_box->setLogicalWidth(logicalWidthForChild(renderBox));
932                 totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
933             }
934         }
935
936         totalLogicalWidth += r->m_box->logicalWidth();
937         previousObject = r->m_object;
938     }
939
940     if (isAfterExpansion && !expansionOpportunities.isEmpty()) {
941         expansionOpportunities.last()--;
942         expansionOpportunityCount--;
943     }
944
945     updateLogicalWidthForAlignment(textAlign, trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth, expansionOpportunityCount);
946
947     computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpportunities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth);
948
949     return r;
950 }
951
952 void RenderBlockFlow::computeBlockDirectionPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap,
953                                                         VerticalPositionCache& verticalPositionCache)
954 {
955     setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache));
956
957     // Now make sure we place replaced render objects correctly.
958     for (BidiRun* r = firstRun; r; r = r->next()) {
959         ASSERT(r->m_box);
960         if (!r->m_box)
961             continue; // Skip runs with no line boxes.
962
963         // Align positioned boxes with the top of the line box.  This is
964         // a reasonable approximation of an appropriate y position.
965         if (r->m_object->isOutOfFlowPositioned())
966             r->m_box->setLogicalTop(logicalHeight());
967
968         // Position is used to properly position both replaced elements and
969         // to update the static normal flow x/y of positioned elements.
970         if (r->m_object->isText())
971             toRenderText(r->m_object)->positionLineBox(r->m_box);
972         else if (r->m_object->isBox())
973             toRenderBox(r->m_object)->positionLineBox(r->m_box);
974         else if (r->m_object->isLineBreak())
975             toRenderLineBreak(r->m_object)->replaceInlineBoxWrapper(r->m_box);
976     }
977     // Positioned objects and zero-length text nodes destroy their boxes in
978     // position(), which unnecessarily dirties the line.
979     lineBox->markDirty(false);
980 }
981
982 static inline bool isCollapsibleSpace(UChar character, RenderText* renderer)
983 {
984     if (character == ' ' || character == '\t' || character == softHyphen)
985         return true;
986     if (character == '\n')
987         return !renderer->style()->preserveNewline();
988     if (character == noBreakSpace)
989         return renderer->style()->nbspMode() == SPACE;
990     return false;
991 }
992
993
994 static void setStaticPositions(RenderBlockFlow* block, RenderBox* child)
995 {
996     // FIXME: The math here is actually not really right. It's a best-guess approximation that
997     // will work for the common cases
998     RenderElement* containerBlock = child->container();
999     LayoutUnit blockHeight = block->logicalHeight();
1000     if (containerBlock->isRenderInline()) {
1001         // A relative positioned inline encloses us. In this case, we also have to determine our
1002         // position as though we were an inline. Set |staticInlinePosition| and |staticBlockPosition| on the relative positioned
1003         // inline so that we can obtain the value later.
1004         toRenderInline(containerBlock)->layer()->setStaticInlinePosition(block->startAlignedOffsetForLine(blockHeight, false));
1005         toRenderInline(containerBlock)->layer()->setStaticBlockPosition(blockHeight);
1006     }
1007     block->updateStaticInlinePositionForChild(child, blockHeight);
1008     child->layer()->setStaticBlockPosition(blockHeight);
1009 }
1010
1011 template <typename CharacterType>
1012 static inline int findFirstTrailingSpace(RenderText* lastText, const CharacterType* characters, int start, int stop)
1013 {
1014     int firstSpace = stop;
1015     while (firstSpace > start) {
1016         UChar current = characters[firstSpace - 1];
1017         if (!isCollapsibleSpace(current, lastText))
1018             break;
1019         firstSpace--;
1020     }
1021
1022     return firstSpace;
1023 }
1024
1025 inline BidiRun* RenderBlockFlow::handleTrailingSpaces(BidiRunList<BidiRun>& bidiRuns, BidiContext* currentContext)
1026 {
1027     if (!bidiRuns.runCount()
1028         || !bidiRuns.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace()
1029         || !bidiRuns.logicallyLastRun()->m_object->style()->autoWrap())
1030         return 0;
1031
1032     BidiRun* trailingSpaceRun = bidiRuns.logicallyLastRun();
1033     RenderObject* lastObject = trailingSpaceRun->m_object;
1034     if (!lastObject->isText())
1035         return 0;
1036
1037     RenderText* lastText = toRenderText(lastObject);
1038     int firstSpace;
1039     if (lastText->is8Bit())
1040         firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), trailingSpaceRun->start(), trailingSpaceRun->stop());
1041     else
1042         firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(), trailingSpaceRun->start(), trailingSpaceRun->stop());
1043
1044     if (firstSpace == trailingSpaceRun->stop())
1045         return 0;
1046
1047     TextDirection direction = style()->direction();
1048     bool shouldReorder = trailingSpaceRun != (direction == LTR ? bidiRuns.lastRun() : bidiRuns.firstRun());
1049     if (firstSpace != trailingSpaceRun->start()) {
1050         BidiContext* baseContext = currentContext;
1051         while (BidiContext* parent = baseContext->parent())
1052             baseContext = parent;
1053
1054         BidiRun* newTrailingRun = new (renderArena()) BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->m_object, baseContext, OtherNeutral);
1055         trailingSpaceRun->m_stop = firstSpace;
1056         if (direction == LTR)
1057             bidiRuns.addRun(newTrailingRun);
1058         else
1059             bidiRuns.prependRun(newTrailingRun);
1060         trailingSpaceRun = newTrailingRun;
1061         return trailingSpaceRun;
1062     }
1063     if (!shouldReorder)
1064         return trailingSpaceRun;
1065
1066     if (direction == LTR) {
1067         bidiRuns.moveRunToEnd(trailingSpaceRun);
1068         trailingSpaceRun->m_level = 0;
1069     } else {
1070         bidiRuns.moveRunToBeginning(trailingSpaceRun);
1071         trailingSpaceRun->m_level = 1;
1072     }
1073     return trailingSpaceRun;
1074 }
1075
1076 void RenderBlockFlow::appendFloatingObjectToLastLine(FloatingObject* floatingObject)
1077 {
1078     ASSERT(!floatingObject->originatingLine());
1079     floatingObject->setOriginatingLine(lastRootBox());
1080     lastRootBox()->appendFloat(&floatingObject->renderer());
1081 }
1082
1083 // FIXME: This should be a BidiStatus constructor or create method.
1084 static inline BidiStatus statusWithDirection(TextDirection textDirection, bool isOverride)
1085 {
1086     WTF::Unicode::Direction direction = textDirection == LTR ? LeftToRight : RightToLeft;
1087     RefPtr<BidiContext> context = BidiContext::create(textDirection == LTR ? 0 : 1, direction, isOverride, FromStyleOrDOM);
1088
1089     // This copies BidiStatus and may churn the ref on BidiContext. I doubt it matters.
1090     return BidiStatus(direction, direction, direction, context.release());
1091 }
1092
1093 // FIXME: BidiResolver should have this logic.
1094 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirectionOverride override, bool previousLineBrokeCleanly)
1095 {
1096     // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead
1097     // of the resolver owning the runs.
1098     ASSERT(&topResolver.runs() == &bidiRuns);
1099     ASSERT(topResolver.position() != endOfRuns);
1100     RenderObject* currentRoot = topResolver.position().root();
1101     topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeCleanly);
1102
1103     while (!topResolver.isolatedRuns().isEmpty()) {
1104         // It does not matter which order we resolve the runs as long as we resolve them all.
1105         BidiRun* isolatedRun = topResolver.isolatedRuns().last();
1106         topResolver.isolatedRuns().removeLast();
1107
1108         RenderObject* startObj = isolatedRun->object();
1109
1110         // Only inlines make sense with unicode-bidi: isolate (blocks are already isolated).
1111         // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the
1112         // tree to see which parent inline is the isolate. We could change enterIsolate
1113         // to take a RenderObject and do this logic there, but that would be a layering
1114         // violation for BidiResolver (which knows nothing about RenderObject).
1115         RenderInline* isolatedInline = toRenderInline(containingIsolate(startObj, currentRoot));
1116         InlineBidiResolver isolatedResolver;
1117         EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi();
1118         TextDirection direction;
1119         if (unicodeBidi == Plaintext)
1120             determineDirectionality(direction, InlineIterator(isolatedInline, isolatedRun->object(), 0));
1121         else {
1122             ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride);
1123             direction = isolatedInline->style()->direction();
1124         }
1125         isolatedResolver.setStatus(statusWithDirection(direction, isOverride(unicodeBidi)));
1126
1127         // FIXME: The fact that we have to construct an Iterator here
1128         // currently prevents this code from moving into BidiResolver.
1129         if (!bidiFirstSkippingEmptyInlines(isolatedInline, &isolatedResolver))
1130             continue;
1131
1132         // The starting position is the beginning of the first run within the isolate that was identified
1133         // during the earlier call to createBidiRunsForLine. This can be but is not necessarily the
1134         // first run within the isolate.
1135         InlineIterator iter = InlineIterator(isolatedInline, startObj, isolatedRun->m_start);
1136         isolatedResolver.setPositionIgnoringNestedIsolates(iter);
1137
1138         // We stop at the next end of line; we may re-enter this isolate in the next call to constructBidiRuns().
1139         // FIXME: What should end and previousLineBrokeCleanly be?
1140         // rniwa says previousLineBrokeCleanly is just a WinIE hack and could always be false here?
1141         isolatedResolver.createBidiRunsForLine(endOfRuns, NoVisualOverride, previousLineBrokeCleanly);
1142         // Note that we do not delete the runs from the resolver.
1143         // We're not guaranteed to get any BidiRuns in the previous step. If we don't, we allow the placeholder
1144         // itself to be turned into an InlineBox. We can't remove it here without potentially losing track of
1145         // the logically last run.
1146         if (isolatedResolver.runs().runCount())
1147             bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs());
1148
1149         // If we encountered any nested isolate runs, just move them
1150         // to the top resolver's list for later processing.
1151         if (!isolatedResolver.isolatedRuns().isEmpty()) {
1152             topResolver.isolatedRuns().appendVector(isolatedResolver.isolatedRuns());
1153             isolatedResolver.isolatedRuns().clear();
1154             currentRoot = isolatedInline;
1155         }
1156     }
1157 }
1158
1159 static inline void constructBidiRunsForLine(const RenderBlockFlow* block, InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly)
1160 {
1161 #if !ENABLE(CSS_SHAPES)
1162     UNUSED_PARAM(block);
1163     constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly);
1164 #else
1165     ShapeInsideInfo* shapeInsideInfo = block->layoutShapeInsideInfo();
1166     if (!shapeInsideInfo || !shapeInsideInfo->hasSegments()) {
1167         constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly);
1168         return;
1169     }
1170
1171     const SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges();
1172     ASSERT(segmentRanges.size());
1173
1174     for (size_t i = 0; i < segmentRanges.size(); i++) {
1175         LineSegmentIterator iterator = segmentRanges[i].start;
1176         InlineIterator segmentStart(iterator.root, iterator.object, iterator.offset);
1177         iterator = segmentRanges[i].end;
1178         InlineIterator segmentEnd(iterator.root, iterator.object, iterator.offset);
1179         if (i) {
1180             ASSERT(segmentStart.m_obj);
1181             BidiRun* segmentMarker = createRun(segmentStart.m_pos, segmentStart.m_pos, segmentStart.m_obj, topResolver);
1182             segmentMarker->m_startsSegment = true;
1183             bidiRuns.addRun(segmentMarker);
1184             // Do not collapse midpoints between segments
1185             topResolver.midpointState().betweenMidpoints = false;
1186         }
1187         if (segmentStart == segmentEnd)
1188             continue;
1189         topResolver.setPosition(segmentStart, numberOfIsolateAncestors(segmentStart));
1190         constructBidiRunsForSegment(topResolver, bidiRuns, segmentEnd, override, previousLineBrokeCleanly);
1191     }
1192 #endif
1193 }
1194
1195 // This function constructs line boxes for all of the text runs in the resolver and computes their position.
1196 RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements)
1197 {
1198     if (!bidiRuns.runCount())
1199         return 0;
1200
1201     // FIXME: Why is this only done when we had runs?
1202     lineInfo.setLastLine(!end.m_obj);
1203
1204     RootInlineBox* lineBox = constructLine(bidiRuns, lineInfo);
1205     if (!lineBox)
1206         return 0;
1207
1208     lineBox->setEndsWithBreak(lineInfo.previousLineBrokeCleanly());
1209     
1210 #if ENABLE(SVG)
1211     bool isSVGRootInlineBox = lineBox->isSVGRootInlineBox();
1212 #else
1213     bool isSVGRootInlineBox = false;
1214 #endif
1215     
1216     GlyphOverflowAndFallbackFontsMap textBoxDataMap;
1217     
1218     // Now we position all of our text runs horizontally.
1219     if (!isSVGRootInlineBox)
1220         computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache, wordMeasurements);
1221     
1222     // Now position our text runs vertically.
1223     computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), textBoxDataMap, verticalPositionCache);
1224     
1225 #if ENABLE(SVG)
1226     // SVG text layout code computes vertical & horizontal positions on its own.
1227     // Note that we still need to execute computeVerticalPositionsForLine() as
1228     // it calls InlineTextBox::positionLineBox(), which tracks whether the box
1229     // contains reversed text or not. If we wouldn't do that editing and thus
1230     // text selection in RTL boxes would not work as expected.
1231     if (isSVGRootInlineBox) {
1232         ASSERT(isSVGText());
1233         static_cast<SVGRootInlineBox*>(lineBox)->computePerCharacterLayoutInformation();
1234     }
1235 #endif
1236     
1237     // Compute our overflow now.
1238     lineBox->computeOverflow(lineBox->lineTop(), lineBox->lineBottom(), textBoxDataMap);
1239     
1240 #if PLATFORM(MAC)
1241     // Highlight acts as an overflow inflation.
1242     if (style()->highlight() != nullAtom)
1243         lineBox->addHighlightOverflow();
1244 #endif
1245     return lineBox;
1246 }
1247
1248 static void deleteLineRange(LineLayoutState& layoutState, RenderArena& arena, RootInlineBox* startLine, RootInlineBox* stopLine = 0)
1249 {
1250     RootInlineBox* boxToDelete = startLine;
1251     while (boxToDelete && boxToDelete != stopLine) {
1252         layoutState.updateRepaintRangeFromBox(boxToDelete);
1253         // Note: deleteLineRange(renderArena(), firstRootBox()) is not identical to deleteLineBoxTree().
1254         // deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when traversing.
1255         RootInlineBox* next = boxToDelete->nextRootBox();
1256         boxToDelete->deleteLine(arena);
1257         boxToDelete = next;
1258     }
1259 }
1260
1261 void RenderBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState, bool hasInlineChild)
1262 {
1263     // We want to skip ahead to the first dirty line
1264     InlineBidiResolver resolver;
1265     RootInlineBox* startLine = determineStartPosition(layoutState, resolver);
1266
1267     unsigned consecutiveHyphenatedLines = 0;
1268     if (startLine) {
1269         for (RootInlineBox* line = startLine->prevRootBox(); line && line->isHyphenated(); line = line->prevRootBox())
1270             consecutiveHyphenatedLines++;
1271     }
1272
1273     // FIXME: This would make more sense outside of this function, but since
1274     // determineStartPosition can change the fullLayout flag we have to do this here. Failure to call
1275     // determineStartPosition first will break fast/repaint/line-flow-with-floats-9.html.
1276     if (layoutState.isFullLayout() && hasInlineChild && !selfNeedsLayout()) {
1277         setNeedsLayout(MarkOnlyThis); // Mark as needing a full layout to force us to repaint.
1278         if (!view().doingFullRepaint() && hasLayer()) {
1279             // Because we waited until we were already inside layout to discover
1280             // that the block really needed a full layout, we missed our chance to repaint the layer
1281             // before layout started.  Luckily the layer has cached the repaint rect for its original
1282             // position and size, and so we can use that to make a repaint happen now.
1283             repaintUsingContainer(containerForRepaint(), pixelSnappedIntRect(layer()->repaintRect()));
1284         }
1285     }
1286
1287     if (containsFloats())
1288         layoutState.setLastFloat(m_floatingObjects->set().last().get());
1289
1290     // We also find the first clean line and extract these lines.  We will add them back
1291     // if we determine that we're able to synchronize after handling all our dirty lines.
1292     InlineIterator cleanLineStart;
1293     BidiStatus cleanLineBidiStatus;
1294     if (!layoutState.isFullLayout() && startLine)
1295         determineEndPosition(layoutState, startLine, cleanLineStart, cleanLineBidiStatus);
1296
1297     if (startLine) {
1298         if (!layoutState.usesRepaintBounds())
1299             layoutState.setRepaintRange(logicalHeight());
1300         deleteLineRange(layoutState, renderArena(), startLine);
1301     }
1302
1303     if (!layoutState.isFullLayout() && lastRootBox() && lastRootBox()->endsWithBreak()) {
1304         // If the last line before the start line ends with a line break that clear floats,
1305         // adjust the height accordingly.
1306         // A line break can be either the first or the last object on a line, depending on its direction.
1307         if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
1308             RenderObject* lastObject = &lastLeafChild->renderer();
1309             if (!lastObject->isBR())
1310                 lastObject = &lastRootBox()->firstLeafChild()->renderer();
1311             if (lastObject->isBR()) {
1312                 EClear clear = lastObject->style()->clear();
1313                 if (clear != CNONE)
1314                     newLine(clear);
1315             }
1316         }
1317     }
1318
1319     layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineBidiStatus, consecutiveHyphenatedLines);
1320     linkToEndLineIfNeeded(layoutState);
1321     repaintDirtyFloats(layoutState.floats());
1322 }
1323
1324 RenderTextInfo::RenderTextInfo()
1325     : m_text(0)
1326     , m_font(0)
1327 {
1328 }
1329
1330 RenderTextInfo::~RenderTextInfo()
1331 {
1332 }
1333
1334 // Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver.
1335 inline const InlineIterator& RenderBlockFlow::restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver& resolver,  const InlineIterator& oldEnd)
1336 {
1337     removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
1338     setLogicalHeight(newLogicalHeight);
1339     resolver.setPositionIgnoringNestedIsolates(oldEnd);
1340     return oldEnd;
1341 }
1342
1343 #if ENABLE(CSS_SHAPES)
1344 static inline float firstPositiveWidth(const WordMeasurements& wordMeasurements)
1345 {
1346     for (size_t i = 0; i < wordMeasurements.size(); ++i) {
1347         if (wordMeasurements[i].width > 0)
1348             return wordMeasurements[i].width;
1349     }
1350     return 0;
1351 }
1352
1353 static inline LayoutUnit adjustLogicalLineTop(ShapeInsideInfo* shapeInsideInfo, InlineIterator start, InlineIterator end, const WordMeasurements& wordMeasurements)
1354 {
1355     if (!shapeInsideInfo || end != start)
1356         return 0;
1357
1358     float minWidth = firstPositiveWidth(wordMeasurements);
1359     ASSERT(minWidth || wordMeasurements.isEmpty());
1360     if (minWidth > 0 && shapeInsideInfo->adjustLogicalLineTop(minWidth))
1361         return shapeInsideInfo->logicalLineTop();
1362
1363     return shapeInsideInfo->shapeLogicalBottom();
1364 }
1365
1366 static inline void pushShapeContentOverflowBelowTheContentBox(RenderBlockFlow* block, ShapeInsideInfo* shapeInsideInfo, LayoutUnit lineTop, LayoutUnit lineHeight)
1367 {
1368     ASSERT(shapeInsideInfo);
1369
1370     LayoutUnit logicalLineBottom = lineTop + lineHeight;
1371     LayoutUnit shapeLogicalBottom = shapeInsideInfo->shapeLogicalBottom();
1372     LayoutUnit shapeContainingBlockLogicalHeight = shapeInsideInfo->shapeContainingBlockLogicalHeight();
1373
1374     bool isOverflowPositionedAlready = (shapeContainingBlockLogicalHeight - shapeInsideInfo->owner()->borderAndPaddingAfter() + lineHeight) <= lineTop;
1375
1376     // If the last line overlaps with the shape, we don't need the segments anymore
1377     if (lineTop < shapeLogicalBottom && shapeLogicalBottom < logicalLineBottom)
1378         shapeInsideInfo->clearSegments();
1379
1380     if (logicalLineBottom <= shapeLogicalBottom || !shapeContainingBlockLogicalHeight || isOverflowPositionedAlready)
1381         return;
1382
1383     LayoutUnit newLogicalHeight = block->logicalHeight() + (shapeContainingBlockLogicalHeight - (lineTop + shapeInsideInfo->owner()->borderAndPaddingAfter()));
1384     block->setLogicalHeight(newLogicalHeight);
1385 }
1386
1387 void RenderBlockFlow::updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*& shapeInsideInfo, const LayoutSize& logicalOffsetFromShapeContainer, LineLayoutState& layoutState)
1388 {
1389     if (layoutState.flowThread())
1390         return updateShapeAndSegmentsForCurrentLineInFlowThread(shapeInsideInfo, layoutState);
1391
1392     if (!shapeInsideInfo)
1393         return;
1394
1395     LayoutUnit lineTop = logicalHeight() + logicalOffsetFromShapeContainer.height();
1396     LayoutUnit lineLeft = logicalOffsetFromShapeContainer.width();
1397     LayoutUnit lineHeight = this->lineHeight(layoutState.lineInfo().isFirstLine(), isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
1398
1399     // FIXME: Bug 95361: It is possible for a line to grow beyond lineHeight, in which case these segments may be incorrect.
1400     shapeInsideInfo->updateSegmentsForLine(LayoutSize(lineLeft, lineTop), lineHeight);
1401
1402     pushShapeContentOverflowBelowTheContentBox(this, shapeInsideInfo, lineTop, lineHeight);
1403 }
1404
1405 void RenderBlockFlow::updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsideInfo*& shapeInsideInfo, LineLayoutState& layoutState)
1406 {
1407     ASSERT(layoutState.flowThread());
1408
1409     LayoutUnit lineHeight = this->lineHeight(layoutState.lineInfo().isFirstLine(), isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
1410
1411     RenderRegion* currentRegion = regionAtBlockOffset(logicalHeight());
1412     if (!currentRegion)
1413         return;
1414
1415     shapeInsideInfo = currentRegion->shapeInsideInfo();
1416
1417     LayoutUnit logicalLineTopInFlowThread = logicalHeight() + offsetFromLogicalTopOfFirstPage();
1418     LayoutUnit logicalLineBottomInFlowThread = logicalLineTopInFlowThread + lineHeight;
1419     LayoutUnit logicalRegionTopInFlowThread = currentRegion->logicalTopForFlowThreadContent();
1420     LayoutUnit logicalRegionBottomInFlowThread = logicalRegionTopInFlowThread + currentRegion->logicalHeight() - currentRegion->borderAndPaddingBefore() - currentRegion->borderAndPaddingAfter();
1421
1422     // We only want to deal regions with shapes, so we look up for the next region whether it has a shape
1423     if (!shapeInsideInfo && !currentRegion->isLastRegion()) {
1424         LayoutUnit deltaToNextRegion = logicalHeight() + logicalRegionBottomInFlowThread - logicalLineTopInFlowThread;
1425         RenderRegion* lookupForNextRegion = regionAtBlockOffset(logicalHeight() + deltaToNextRegion);
1426         if (!lookupForNextRegion->shapeInsideInfo())
1427             return;
1428     }
1429
1430     LayoutUnit shapeBottomInFlowThread = LayoutUnit::max();
1431     if (shapeInsideInfo)
1432         shapeBottomInFlowThread = shapeInsideInfo->shapeLogicalBottom() + currentRegion->logicalTopForFlowThreadContent();
1433
1434     // If the line is between two shapes/regions we position the line to the top of the next shape/region
1435     RenderRegion* nextRegion = regionAtBlockOffset(logicalHeight() + lineHeight);
1436     if ((currentRegion != nextRegion && (logicalLineBottomInFlowThread > logicalRegionBottomInFlowThread)) || (!currentRegion->isLastRegion() && shapeBottomInFlowThread < logicalLineBottomInFlowThread)) {
1437         LayoutUnit deltaToNextRegion = logicalRegionBottomInFlowThread - logicalLineTopInFlowThread;
1438         nextRegion = regionAtBlockOffset(logicalHeight() + deltaToNextRegion);
1439
1440         ASSERT(currentRegion != nextRegion);
1441
1442         shapeInsideInfo = nextRegion->shapeInsideInfo();
1443         setLogicalHeight(logicalHeight() + deltaToNextRegion);
1444
1445         currentRegion = nextRegion;
1446
1447         logicalLineTopInFlowThread = logicalHeight() + offsetFromLogicalTopOfFirstPage();
1448         logicalLineBottomInFlowThread = logicalLineTopInFlowThread + lineHeight;
1449         logicalRegionTopInFlowThread = currentRegion->logicalTopForFlowThreadContent();
1450         logicalRegionBottomInFlowThread = logicalRegionTopInFlowThread + currentRegion->logicalHeight() - currentRegion->borderAndPaddingBefore() - currentRegion->borderAndPaddingAfter();
1451     }
1452
1453     if (!shapeInsideInfo)
1454         return;
1455
1456     // We position the first line to the top of the shape in the region or to the previously adjusted position in the shape
1457     if (logicalLineBottomInFlowThread <= (logicalRegionTopInFlowThread + lineHeight) || (logicalLineTopInFlowThread - logicalRegionTopInFlowThread) < (layoutState.adjustedLogicalLineTop() - currentRegion->borderAndPaddingBefore())) {
1458         LayoutUnit shapeTopOffset = layoutState.adjustedLogicalLineTop();
1459         if (!shapeTopOffset)
1460             shapeTopOffset = shapeInsideInfo->shapeLogicalTop();
1461
1462         LayoutUnit shapePositionInFlowThread = currentRegion->logicalTopForFlowThreadContent() + shapeTopOffset;
1463         LayoutUnit shapeTopLineTopDelta = shapePositionInFlowThread - logicalLineTopInFlowThread - currentRegion->borderAndPaddingBefore();
1464
1465         setLogicalHeight(logicalHeight() + shapeTopLineTopDelta);
1466         logicalLineTopInFlowThread += shapeTopLineTopDelta;
1467         layoutState.setAdjustedLogicalLineTop(0);
1468     }
1469
1470     LayoutUnit lineTop = logicalLineTopInFlowThread - currentRegion->logicalTopForFlowThreadContent() + currentRegion->borderAndPaddingBefore();
1471
1472     // FIXME: 118571 - Shape inside on a region does not yet take into account its padding for nested flow blocks
1473     shapeInsideInfo->updateSegmentsForLine(LayoutSize(0, lineTop), lineHeight);
1474
1475     if (currentRegion->isLastRegion())
1476         pushShapeContentOverflowBelowTheContentBox(this, shapeInsideInfo, lineTop, lineHeight);
1477 }
1478
1479 bool RenderBlockFlow::adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideInfo* shapeInsideInfo, LayoutUnit absoluteLogicalTop, LineLayoutState& layoutState, InlineBidiResolver& resolver, FloatingObject* lastFloatFromPreviousLine, InlineIterator& end, WordMeasurements& wordMeasurements)
1480 {
1481     LayoutUnit adjustedLogicalLineTop = adjustLogicalLineTop(shapeInsideInfo, resolver.position(), end, wordMeasurements);
1482
1483     if (shapeInsideInfo && !wordMeasurements.size() && containsFloats()) {
1484         lastFloatFromPreviousLine = m_floatingObjects->set().last().get();
1485         LayoutUnit floatLogicalTopOffset = shapeInsideInfo->computeFirstFitPositionForFloat(lastFloatFromPreviousLine->logicalSize(isHorizontalWritingMode()));
1486         if (logicalHeight() < floatLogicalTopOffset)
1487             adjustedLogicalLineTop = floatLogicalTopOffset;
1488     }
1489
1490     if (!adjustedLogicalLineTop)
1491         return false;
1492
1493     LayoutUnit newLogicalHeight = adjustedLogicalLineTop - absoluteLogicalTop;
1494
1495     if (layoutState.flowThread()) {
1496         layoutState.setAdjustedLogicalLineTop(adjustedLogicalLineTop);
1497         newLogicalHeight = logicalHeight();
1498     }
1499
1500     end = restartLayoutRunsAndFloatsInRange(logicalHeight(), newLogicalHeight, lastFloatFromPreviousLine, resolver, end);
1501     return true;
1502 }
1503 #endif
1504
1505 void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, InlineBidiResolver& resolver, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines)
1506 {
1507     RenderStyle* styleToUse = style();
1508     bool paginated = view().layoutState() && view().layoutState()->isPaginated();
1509     LineMidpointState& lineMidpointState = resolver.midpointState();
1510     InlineIterator end = resolver.position();
1511     bool checkForEndLineMatch = layoutState.endLine();
1512     RenderTextInfo renderTextInfo;
1513     VerticalPositionCache verticalPositionCache;
1514
1515     LineBreaker lineBreaker(this);
1516
1517 #if ENABLE(CSS_SHAPES)
1518     LayoutSize logicalOffsetFromShapeContainer;
1519     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
1520     if (shapeInsideInfo) {
1521         ASSERT(shapeInsideInfo->owner() == this || allowsShapeInsideInfoSharing());
1522         if (shapeInsideInfo != this->shapeInsideInfo()) {
1523             // FIXME Bug 100284: If subsequent LayoutStates are pushed, we will have to add
1524             // their offsets from the original shape-inside container.
1525             logicalOffsetFromShapeContainer = logicalOffsetFromShapeAncestorContainer(shapeInsideInfo->owner());
1526         }
1527         // Begin layout at the logical top of our shape inside.
1528         if (logicalHeight() + logicalOffsetFromShapeContainer.height() < shapeInsideInfo->shapeLogicalTop()) {
1529             LayoutUnit logicalHeight = shapeInsideInfo->shapeLogicalTop() - logicalOffsetFromShapeContainer.height();
1530             if (layoutState.flowThread())
1531                 logicalHeight -= shapeInsideInfo->owner()->borderAndPaddingBefore();
1532             setLogicalHeight(logicalHeight);
1533         }
1534     }
1535 #endif
1536
1537     while (!end.atEnd()) {
1538         // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
1539         if (checkForEndLineMatch) {
1540             layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus));
1541             if (layoutState.endLineMatched()) {
1542                 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
1543                 break;
1544             }
1545         }
1546
1547         lineMidpointState.reset();
1548
1549         layoutState.lineInfo().setEmpty(true);
1550         layoutState.lineInfo().resetRunsFromLeadingWhitespace();
1551
1552         const InlineIterator oldEnd = end;
1553         bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly();
1554         FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_floatingObjects->set().last().get() : 0;
1555
1556 #if ENABLE(CSS_SHAPES)
1557         updateShapeAndSegmentsForCurrentLine(shapeInsideInfo, logicalOffsetFromShapeContainer, layoutState);
1558 #endif
1559         WordMeasurements wordMeasurements;
1560         end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
1561         renderTextInfo.m_lineBreakIterator.resetPriorContext();
1562         if (resolver.position().atEnd()) {
1563             // FIXME: We shouldn't be creating any runs in nextLineBreak to begin with!
1564             // Once BidiRunList is separated from BidiResolver this will not be needed.
1565             resolver.runs().deleteRuns();
1566             resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
1567             layoutState.setCheckForFloatsFromLastLine(true);
1568             resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
1569             break;
1570         }
1571
1572 #if ENABLE(CSS_SHAPES)
1573         if (adjustLogicalLineTopAndLogicalHeightIfNeeded(shapeInsideInfo, logicalOffsetFromShapeContainer.height(), layoutState, resolver, lastFloatFromPreviousLine, end, wordMeasurements))
1574             continue;
1575 #endif
1576         ASSERT(end != resolver.position());
1577
1578         // This is a short-cut for empty lines.
1579         if (layoutState.lineInfo().isEmpty()) {
1580             if (lastRootBox())
1581                 lastRootBox()->setLineBreakInfo(end.m_obj, end.m_pos, resolver.status());
1582         } else {
1583             VisualDirectionOverride override = (styleToUse->rtlOrdering() == VisualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualRightToLeftOverride) : NoVisualOverride);
1584
1585             if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && !resolver.context()->parent()) {
1586                 TextDirection direction = styleToUse->direction();
1587                 determineDirectionality(direction, resolver.position());
1588                 resolver.setStatus(BidiStatus(direction, isOverride(styleToUse->unicodeBidi())));
1589             }
1590             // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine.
1591             BidiRunList<BidiRun>& bidiRuns = resolver.runs();
1592             constructBidiRunsForLine(this, resolver, bidiRuns, end, override, layoutState.lineInfo().previousLineBrokeCleanly());
1593             ASSERT(resolver.position() == end);
1594
1595             BidiRun* trailingSpaceRun = !layoutState.lineInfo().previousLineBrokeCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0;
1596
1597             if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) {
1598                 bidiRuns.logicallyLastRun()->m_hasHyphen = true;
1599                 consecutiveHyphenatedLines++;
1600             } else
1601                 consecutiveHyphenatedLines = 0;
1602
1603             // Now that the runs have been ordered, we create the line boxes.
1604             // At the same time we figure out where border/padding/margin should be applied for
1605             // inline flow boxes.
1606
1607             LayoutUnit oldLogicalHeight = logicalHeight();
1608             RootInlineBox* lineBox = createLineBoxesFromBidiRuns(bidiRuns, end, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, wordMeasurements);
1609
1610             bidiRuns.deleteRuns();
1611             resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
1612
1613             if (lineBox) {
1614                 lineBox->setLineBreakInfo(end.m_obj, end.m_pos, resolver.status());
1615                 if (layoutState.usesRepaintBounds())
1616                     layoutState.updateRepaintRangeFromBox(lineBox);
1617
1618                 if (paginated) {
1619                     LayoutUnit adjustment = 0;
1620                     adjustLinePositionForPagination(lineBox, adjustment, layoutState.flowThread());
1621                     if (adjustment) {
1622                         LayoutUnit oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, layoutState.lineInfo().isFirstLine());
1623                         lineBox->adjustBlockDirectionPosition(adjustment);
1624                         if (layoutState.usesRepaintBounds())
1625                             layoutState.updateRepaintRangeFromBox(lineBox);
1626
1627                         if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, layoutState.lineInfo().isFirstLine()) != oldLineWidth) {
1628                             // We have to delete this line, remove all floats that got added, and let line layout re-run.
1629                             lineBox->deleteLine(renderArena());
1630                             end = restartLayoutRunsAndFloatsInRange(oldLogicalHeight, oldLogicalHeight + adjustment, lastFloatFromPreviousLine, resolver, oldEnd);
1631                             continue;
1632                         }
1633
1634                         setLogicalHeight(lineBox->lineBottomWithLeading());
1635                     }
1636
1637                     if (layoutState.flowThread())
1638                         updateRegionForLine(lineBox);
1639                 }
1640             }
1641         }
1642
1643         for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i)
1644             setStaticPositions(this, lineBreaker.positionedObjects()[i]);
1645
1646         if (!layoutState.lineInfo().isEmpty()) {
1647             layoutState.lineInfo().setFirstLine(false);
1648             newLine(lineBreaker.clear());
1649         }
1650
1651         if (m_floatingObjects && lastRootBox()) {
1652             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1653             auto it = floatingObjectSet.begin();
1654             auto end = floatingObjectSet.end();
1655             if (layoutState.lastFloat()) {
1656                 auto lastFloatIterator = floatingObjectSet.find<FloatingObject&, FloatingObjectHashTranslator>(*layoutState.lastFloat());
1657                 ASSERT(lastFloatIterator != end);
1658                 ++lastFloatIterator;
1659                 it = lastFloatIterator;
1660             }
1661             for (; it != end; ++it) {
1662                 FloatingObject* f = it->get();
1663                 appendFloatingObjectToLastLine(f);
1664                 ASSERT(&f->renderer() == layoutState.floats()[layoutState.floatIndex()].object);
1665                 // If a float's geometry has changed, give up on syncing with clean lines.
1666                 if (layoutState.floats()[layoutState.floatIndex()].rect != f->frameRect())
1667                     checkForEndLineMatch = false;
1668                 layoutState.setFloatIndex(layoutState.floatIndex() + 1);
1669             }
1670             layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : nullptr);
1671         }
1672
1673         lineMidpointState.reset();
1674         resolver.setPosition(end, numberOfIsolateAncestors(end));
1675     }
1676
1677     // In case we already adjusted the line positions during this layout to avoid widows
1678     // then we need to ignore the possibility of having a new widows situation.
1679     // Otherwise, we risk leaving empty containers which is against the block fragmentation principles.
1680     if (paginated && !style()->hasAutoWidows() && !didBreakAtLineToAvoidWidow()) {
1681         // Check the line boxes to make sure we didn't create unacceptable widows.
1682         // However, we'll prioritize orphans - so nothing we do here should create
1683         // a new orphan.
1684
1685         RootInlineBox* lineBox = lastRootBox();
1686
1687         // Count from the end of the block backwards, to see how many hanging
1688         // lines we have.
1689         RootInlineBox* firstLineInBlock = firstRootBox();
1690         int numLinesHanging = 1;
1691         while (lineBox && lineBox != firstLineInBlock && !lineBox->isFirstAfterPageBreak()) {
1692             ++numLinesHanging;
1693             lineBox = lineBox->prevRootBox();
1694         }
1695
1696         // If there were no breaks in the block, we didn't create any widows.
1697         if (!lineBox || !lineBox->isFirstAfterPageBreak() || lineBox == firstLineInBlock)
1698             return;
1699
1700         if (numLinesHanging < style()->widows()) {
1701             // We have detected a widow. Now we need to work out how many
1702             // lines there are on the previous page, and how many we need
1703             // to steal.
1704             int numLinesNeeded = style()->widows() - numLinesHanging;
1705             RootInlineBox* currentFirstLineOfNewPage = lineBox;
1706
1707             // Count the number of lines in the previous page.
1708             lineBox = lineBox->prevRootBox();
1709             int numLinesInPreviousPage = 1;
1710             while (lineBox && lineBox != firstLineInBlock && !lineBox->isFirstAfterPageBreak()) {
1711                 ++numLinesInPreviousPage;
1712                 lineBox = lineBox->prevRootBox();
1713             }
1714
1715             // If there was an explicit value for orphans, respect that. If not, we still
1716             // shouldn't create a situation where we make an orphan bigger than the initial value.
1717             // This means that setting widows implies we also care about orphans, but given
1718             // the specification says the initial orphan value is non-zero, this is ok. The
1719             // author is always free to set orphans explicitly as well.
1720             int orphans = style()->hasAutoOrphans() ? style()->initialOrphans() : style()->orphans();
1721             int numLinesAvailable = numLinesInPreviousPage - orphans;
1722             if (numLinesAvailable <= 0)
1723                 return;
1724
1725             int numLinesToTake = min(numLinesAvailable, numLinesNeeded);
1726             // Wind back from our first widowed line.
1727             lineBox = currentFirstLineOfNewPage;
1728             for (int i = 0; i < numLinesToTake; ++i)
1729                 lineBox = lineBox->prevRootBox();
1730
1731             // We now want to break at this line. Remember for next layout and trigger relayout.
1732             setBreakAtLineToAvoidWidow(lineCount(lineBox));
1733             markLinesDirtyInBlockRange(lastRootBox()->lineBottomWithLeading(), lineBox->lineBottomWithLeading(), lineBox);
1734         }
1735     }
1736
1737     clearDidBreakAtLineToAvoidWidow();
1738 }
1739
1740 void RenderBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState)
1741 {
1742     if (layoutState.endLine()) {
1743         if (layoutState.endLineMatched()) {
1744             bool paginated = view().layoutState() && view().layoutState()->isPaginated();
1745             // Attach all the remaining lines, and then adjust their y-positions as needed.
1746             LayoutUnit delta = logicalHeight() - layoutState.endLineLogicalTop();
1747             for (RootInlineBox* line = layoutState.endLine(); line; line = line->nextRootBox()) {
1748                 line->attachLine();
1749                 if (paginated) {
1750                     delta -= line->paginationStrut();
1751                     adjustLinePositionForPagination(line, delta, layoutState.flowThread());
1752                 }
1753                 if (delta) {
1754                     layoutState.updateRepaintRangeFromBox(line, delta);
1755                     line->adjustBlockDirectionPosition(delta);
1756                 }
1757                 if (layoutState.flowThread())
1758                     updateRegionForLine(line);
1759                 if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
1760                     Vector<RenderBox*>::iterator end = cleanLineFloats->end();
1761                     for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
1762                         FloatingObject* floatingObject = insertFloatingObject(*f);
1763                         ASSERT(!floatingObject->originatingLine());
1764                         floatingObject->setOriginatingLine(line);
1765                         setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f) + delta);
1766                         positionNewFloats();
1767                     }
1768                 }
1769             }
1770             setLogicalHeight(lastRootBox()->lineBottomWithLeading());
1771         } else {
1772             // Delete all the remaining lines.
1773             deleteLineRange(layoutState, renderArena(), layoutState.endLine());
1774         }
1775     }
1776     
1777     if (m_floatingObjects && (layoutState.checkForFloatsFromLastLine() || positionNewFloats()) && lastRootBox()) {
1778         // In case we have a float on the last line, it might not be positioned up to now.
1779         // This has to be done before adding in the bottom border/padding, or the float will
1780         // include the padding incorrectly. -dwh
1781         if (layoutState.checkForFloatsFromLastLine()) {
1782             LayoutUnit bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow();
1783             LayoutUnit bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow();
1784             TrailingFloatsRootInlineBox* trailingFloatsLineBox = new (renderArena()) TrailingFloatsRootInlineBox(*this);
1785             m_lineBoxes.appendLineBox(trailingFloatsLineBox);
1786             trailingFloatsLineBox->setConstructed();
1787             GlyphOverflowAndFallbackFontsMap textBoxDataMap;
1788             VerticalPositionCache verticalPositionCache;
1789             LayoutUnit blockLogicalHeight = logicalHeight();
1790             trailingFloatsLineBox->alignBoxesInBlockDirection(blockLogicalHeight, textBoxDataMap, verticalPositionCache);
1791             trailingFloatsLineBox->setLineTopBottomPositions(blockLogicalHeight, blockLogicalHeight, blockLogicalHeight, blockLogicalHeight);
1792             trailingFloatsLineBox->setPaginatedLineWidth(availableLogicalWidthForContent(blockLogicalHeight));
1793             LayoutRect logicalLayoutOverflow(0, blockLogicalHeight, 1, bottomLayoutOverflow - blockLogicalHeight);
1794             LayoutRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight);
1795             trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom());
1796             if (layoutState.flowThread())
1797                 updateRegionForLine(trailingFloatsLineBox);
1798         }
1799
1800         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1801         auto it = floatingObjectSet.begin();
1802         auto end = floatingObjectSet.end();
1803         if (layoutState.lastFloat()) {
1804             auto lastFloatIterator = floatingObjectSet.find<FloatingObject&, FloatingObjectHashTranslator>(*layoutState.lastFloat());
1805             ASSERT(lastFloatIterator != end);
1806             ++lastFloatIterator;
1807             it = lastFloatIterator;
1808         }
1809         for (; it != end; ++it)
1810             appendFloatingObjectToLastLine(it->get());
1811         layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : nullptr);
1812     }
1813 }
1814
1815 void RenderBlockFlow::repaintDirtyFloats(Vector<FloatWithRect>& floats)
1816 {
1817     size_t floatCount = floats.size();
1818     // Floats that did not have layout did not repaint when we laid them out. They would have
1819     // painted by now if they had moved, but if they stayed at (0, 0), they still need to be
1820     // painted.
1821     for (size_t i = 0; i < floatCount; ++i) {
1822         if (!floats[i].everHadLayout) {
1823             RenderBox* f = floats[i].object;
1824             if (!f->x() && !f->y() && f->checkForRepaintDuringLayout())
1825                 f->repaint();
1826         }
1827     }
1828 }
1829
1830 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
1831 {
1832     setLogicalHeight(borderAndPaddingBefore());
1833     
1834     // Lay out our hypothetical grid line as though it occurs at the top of the block.
1835     if (view().layoutState() && view().layoutState()->lineGrid() == this)
1836         layoutLineGridBox();
1837
1838     RenderFlowThread* flowThread = flowThreadContainingBlock();
1839     bool clearLinesForPagination = firstLineBox() && flowThread && !flowThread->hasRegions();
1840
1841     // Figure out if we should clear out our line boxes.
1842     // FIXME: Handle resize eventually!
1843     bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren || clearLinesForPagination;
1844     LineLayoutState layoutState(isFullLayout, repaintLogicalTop, repaintLogicalBottom, flowThread);
1845
1846     if (isFullLayout)
1847         lineBoxes().deleteLineBoxes(renderArena());
1848
1849     // Text truncation kicks in in two cases:
1850     //     1) If your overflow isn't visible and your text-overflow-mode isn't clip.
1851     //     2) If you're an anonymous block with a block parent that satisfies #1.
1852     // FIXME: CSS3 says that descendants that are clipped must also know how to truncate.  This is insanely
1853     // difficult to figure out in general (especially in the middle of doing layout), so we only handle the
1854     // simple case of an anonymous block truncating when it's parent is clipped.
1855     bool hasTextOverflow = (style()->textOverflow() && hasOverflowClip())
1856         || (isAnonymousBlock() && parent() && parent()->isRenderBlock() && parent()->style()->textOverflow() && parent()->hasOverflowClip());
1857
1858     // Walk all the lines and delete our ellipsis line boxes if they exist.
1859     if (hasTextOverflow)
1860          deleteEllipsisLineBoxes();
1861
1862     if (firstChild()) {
1863         // In full layout mode, clear the line boxes of children upfront. Otherwise,
1864         // siblings can run into stale root lineboxes during layout. Then layout
1865         // the replaced elements later. In partial layout mode, line boxes are not
1866         // deleted and only dirtied. In that case, we can layout the replaced
1867         // elements at the same time.
1868         bool hasInlineChild = false;
1869         Vector<RenderBox*> replacedChildren;
1870         for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
1871             RenderObject* o = walker.current();
1872
1873             if (!hasInlineChild && o->isInline())
1874                 hasInlineChild = true;
1875
1876             if (o->isReplaced() || o->isFloating() || o->isOutOfFlowPositioned()) {
1877                 RenderBox* box = toRenderBox(o);
1878
1879                 if (relayoutChildren || box->hasRelativeDimensions())
1880                     box->setChildNeedsLayout(MarkOnlyThis);
1881
1882                 // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
1883                 if (relayoutChildren && box->needsPreferredWidthsRecalculation())
1884                     o->setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
1885
1886                 if (o->isOutOfFlowPositioned())
1887                     o->containingBlock()->insertPositionedObject(box);
1888                 else if (o->isFloating())
1889                     layoutState.floats().append(FloatWithRect(box));
1890                 else if (isFullLayout || o->needsLayout()) {
1891                     // Replaced element.
1892                     box->dirtyLineBoxes(isFullLayout);
1893                     if (isFullLayout)
1894                         replacedChildren.append(box);
1895                     else
1896                         o->layoutIfNeeded();
1897                 }
1898             } else if (o->isTextOrLineBreak() || (o->isRenderInline() && !walker.atEndOfInline())) {
1899                 if (o->isRenderInline())
1900                     toRenderInline(o)->updateAlwaysCreateLineBoxes(layoutState.isFullLayout());
1901                 if (layoutState.isFullLayout() || o->selfNeedsLayout())
1902                     dirtyLineBoxesForRenderer(o, layoutState.isFullLayout());
1903                 o->clearNeedsLayout();
1904             }
1905         }
1906
1907         for (size_t i = 0; i < replacedChildren.size(); i++)
1908              replacedChildren[i]->layoutIfNeeded();
1909
1910         layoutRunsAndFloats(layoutState, hasInlineChild);
1911     }
1912
1913     // Expand the last line to accommodate Ruby and emphasis marks.
1914     int lastLineAnnotationsAdjustment = 0;
1915     if (lastRootBox()) {
1916         LayoutUnit lowestAllowedPosition = max(lastRootBox()->lineBottom(), logicalHeight() + paddingAfter());
1917         if (!style()->isFlippedLinesWritingMode())
1918             lastLineAnnotationsAdjustment = lastRootBox()->computeUnderAnnotationAdjustment(lowestAllowedPosition);
1919         else
1920             lastLineAnnotationsAdjustment = lastRootBox()->computeOverAnnotationAdjustment(lowestAllowedPosition);
1921     }
1922
1923     // Now add in the bottom border/padding.
1924     setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + borderAndPaddingAfter() + scrollbarLogicalHeight());
1925
1926     if (!firstLineBox() && hasLineIfEmpty())
1927         setLogicalHeight(logicalHeight() + lineHeight(true, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
1928
1929     // See if we have any lines that spill out of our block.  If we do, then we will possibly need to
1930     // truncate text.
1931     if (hasTextOverflow)
1932         checkLinesForTextOverflow();
1933 }
1934
1935 void RenderBlockFlow::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWithRect>& floats, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat)
1936 {
1937     Vector<RenderBox*>* cleanLineFloats = line->floatsPtr();
1938     if (!cleanLineFloats)
1939         return;
1940
1941     Vector<RenderBox*>::iterator end = cleanLineFloats->end();
1942     for (Vector<RenderBox*>::iterator it = cleanLineFloats->begin(); it != end; ++it) {
1943         RenderBox* floatingBox = *it;
1944         floatingBox->layoutIfNeeded();
1945         LayoutSize newSize(floatingBox->width() + floatingBox->marginWidth(), floatingBox->height() + floatingBox->marginHeight());
1946         ASSERT_WITH_SECURITY_IMPLICATION(floatIndex < floats.size());
1947         if (floats[floatIndex].object != floatingBox) {
1948             encounteredNewFloat = true;
1949             return;
1950         }
1951
1952         if (floats[floatIndex].rect.size() != newSize) {
1953             LayoutUnit floatTop = isHorizontalWritingMode() ? floats[floatIndex].rect.y() : floats[floatIndex].rect.x();
1954             LayoutUnit floatHeight = isHorizontalWritingMode() ? max(floats[floatIndex].rect.height(), newSize.height())
1955                                                                  : max(floats[floatIndex].rect.width(), newSize.width());
1956             floatHeight = min(floatHeight, LayoutUnit::max() - floatTop);
1957             line->markDirty();
1958             markLinesDirtyInBlockRange(line->lineBottomWithLeading(), floatTop + floatHeight, line);
1959             floats[floatIndex].rect.setSize(newSize);
1960             dirtiedByFloat = true;
1961         }
1962         floatIndex++;
1963     }
1964 }
1965
1966 RootInlineBox* RenderBlockFlow::determineStartPosition(LineLayoutState& layoutState, InlineBidiResolver& resolver)
1967 {
1968     RootInlineBox* curr = 0;
1969     RootInlineBox* last = 0;
1970
1971     // FIXME: This entire float-checking block needs to be broken into a new function.
1972     bool dirtiedByFloat = false;
1973     if (!layoutState.isFullLayout()) {
1974         // Paginate all of the clean lines.
1975         bool paginated = view().layoutState() && view().layoutState()->isPaginated();
1976         LayoutUnit paginationDelta = 0;
1977         size_t floatIndex = 0;
1978         for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
1979             if (paginated) {
1980                 if (lineWidthForPaginatedLineChanged(curr, 0, layoutState.flowThread())) {
1981                     curr->markDirty();
1982                     break;
1983                 }
1984                 paginationDelta -= curr->paginationStrut();
1985                 adjustLinePositionForPagination(curr, paginationDelta, layoutState.flowThread());
1986                 if (paginationDelta) {
1987                     if (containsFloats() || !layoutState.floats().isEmpty()) {
1988                         // FIXME: Do better eventually.  For now if we ever shift because of pagination and floats are present just go to a full layout.
1989                         layoutState.markForFullLayout();
1990                         break;
1991                     }
1992
1993                     layoutState.updateRepaintRangeFromBox(curr, paginationDelta);
1994                     curr->adjustBlockDirectionPosition(paginationDelta);
1995                 }
1996                 if (layoutState.flowThread())
1997                     updateRegionForLine(curr);
1998             }
1999
2000             // If a new float has been inserted before this line or before its last known float, just do a full layout.
2001             bool encounteredNewFloat = false;
2002             checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
2003             if (encounteredNewFloat)
2004                 layoutState.markForFullLayout();
2005
2006             if (dirtiedByFloat || layoutState.isFullLayout())
2007                 break;
2008         }
2009         // Check if a new float has been inserted after the last known float.
2010         if (!curr && floatIndex < layoutState.floats().size())
2011             layoutState.markForFullLayout();
2012     }
2013
2014     if (layoutState.isFullLayout()) {
2015         m_lineBoxes.deleteLineBoxTree(renderArena());
2016         curr = 0;
2017
2018         ASSERT(!firstLineBox() && !lastLineBox());
2019     } else {
2020         if (curr) {
2021             // We have a dirty line.
2022             if (RootInlineBox* prevRootBox = curr->prevRootBox()) {
2023                 // We have a previous line.
2024                 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength())))
2025                     // The previous line didn't break cleanly or broke at a newline
2026                     // that has been deleted, so treat it as dirty too.
2027                     curr = prevRootBox;
2028             }
2029         } else {
2030             // No dirty lines were found.
2031             // If the last line didn't break cleanly, treat it as dirty.
2032             if (lastRootBox() && !lastRootBox()->endsWithBreak())
2033                 curr = lastRootBox();
2034         }
2035
2036         // If we have no dirty lines, then last is just the last root box.
2037         last = curr ? curr->prevRootBox() : lastRootBox();
2038     }
2039
2040     unsigned numCleanFloats = 0;
2041     if (!layoutState.floats().isEmpty()) {
2042         LayoutUnit savedLogicalHeight = logicalHeight();
2043         // Restore floats from clean lines.
2044         RootInlineBox* line = firstRootBox();
2045         while (line != curr) {
2046             if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
2047                 Vector<RenderBox*>::iterator end = cleanLineFloats->end();
2048                 for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
2049                     FloatingObject* floatingObject = insertFloatingObject(*f);
2050                     ASSERT(!floatingObject->originatingLine());
2051                     floatingObject->setOriginatingLine(line);
2052                     setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f));
2053                     positionNewFloats();
2054                     ASSERT(layoutState.floats()[numCleanFloats].object == *f);
2055                     numCleanFloats++;
2056                 }
2057             }
2058             line = line->nextRootBox();
2059         }
2060         setLogicalHeight(savedLogicalHeight);
2061     }
2062     layoutState.setFloatIndex(numCleanFloats);
2063
2064     layoutState.lineInfo().setFirstLine(!last);
2065     layoutState.lineInfo().setPreviousLineBrokeCleanly(!last || last->endsWithBreak());
2066
2067     if (last) {
2068         setLogicalHeight(last->lineBottomWithLeading());
2069         InlineIterator iter = InlineIterator(this, last->lineBreakObj(), last->lineBreakPos());
2070         resolver.setPosition(iter, numberOfIsolateAncestors(iter));
2071         resolver.setStatus(last->lineBreakBidiStatus());
2072     } else {
2073         TextDirection direction = style()->direction();
2074         if (style()->unicodeBidi() == Plaintext)
2075             determineDirectionality(direction, InlineIterator(this, bidiFirstSkippingEmptyInlines(this), 0));
2076         resolver.setStatus(BidiStatus(direction, isOverride(style()->unicodeBidi())));
2077         InlineIterator iter = InlineIterator(this, bidiFirstSkippingEmptyInlines(this, &resolver), 0);
2078         resolver.setPosition(iter, numberOfIsolateAncestors(iter));
2079     }
2080     return curr;
2081 }
2082
2083 void RenderBlockFlow::determineEndPosition(LineLayoutState& layoutState, RootInlineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus)
2084 {
2085     ASSERT(!layoutState.endLine());
2086     size_t floatIndex = layoutState.floatIndex();
2087     RootInlineBox* last = 0;
2088     for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->nextRootBox()) {
2089         if (!curr->isDirty()) {
2090             bool encounteredNewFloat = false;
2091             bool dirtiedByFloat = false;
2092             checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encounteredNewFloat, dirtiedByFloat);
2093             if (encounteredNewFloat)
2094                 return;
2095         }
2096         if (curr->isDirty())
2097             last = 0;
2098         else if (!last)
2099             last = curr;
2100     }
2101
2102     if (!last)
2103         return;
2104
2105     // At this point, |last| is the first line in a run of clean lines that ends with the last line
2106     // in the block.
2107
2108     RootInlineBox* prev = last->prevRootBox();
2109     cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakPos());
2110     cleanLineBidiStatus = prev->lineBreakBidiStatus();
2111     layoutState.setEndLineLogicalTop(prev->lineBottomWithLeading());
2112
2113     for (RootInlineBox* line = last; line; line = line->nextRootBox())
2114         line->extractLine(); // Disconnect all line boxes from their render objects while preserving
2115                              // their connections to one another.
2116
2117     layoutState.setEndLine(last);
2118 }
2119
2120 bool RenderBlockFlow::checkPaginationAndFloatsAtEndLine(LineLayoutState& layoutState)
2121 {
2122     LayoutUnit lineDelta = logicalHeight() - layoutState.endLineLogicalTop();
2123
2124     bool paginated = view().layoutState() && view().layoutState()->isPaginated();
2125     if (paginated && layoutState.flowThread()) {
2126         // Check all lines from here to the end, and see if the hypothetical new position for the lines will result
2127         // in a different available line width.
2128         for (RootInlineBox* lineBox = layoutState.endLine(); lineBox; lineBox = lineBox->nextRootBox()) {
2129             if (paginated) {
2130                 // This isn't the real move we're going to do, so don't update the line box's pagination
2131                 // strut yet.
2132                 LayoutUnit oldPaginationStrut = lineBox->paginationStrut();
2133                 lineDelta -= oldPaginationStrut;
2134                 adjustLinePositionForPagination(lineBox, lineDelta, layoutState.flowThread());
2135                 lineBox->setPaginationStrut(oldPaginationStrut);
2136             }
2137             if (lineWidthForPaginatedLineChanged(lineBox, lineDelta, layoutState.flowThread()))
2138                 return false;
2139         }
2140     }
2141     
2142     if (!lineDelta || !m_floatingObjects)
2143         return true;
2144     
2145     // See if any floats end in the range along which we want to shift the lines vertically.
2146     LayoutUnit logicalTop = min(logicalHeight(), layoutState.endLineLogicalTop());
2147
2148     RootInlineBox* lastLine = layoutState.endLine();
2149     while (RootInlineBox* nextLine = lastLine->nextRootBox())
2150         lastLine = nextLine;
2151
2152     LayoutUnit logicalBottom = lastLine->lineBottomWithLeading() + absoluteValue(lineDelta);
2153
2154     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2155     auto end = floatingObjectSet.end();
2156     for (auto it = floatingObjectSet.begin(); it != end; ++it) {
2157         FloatingObject* f = it->get();
2158         if (f->logicalBottom(isHorizontalWritingMode()) >= logicalTop && f->logicalBottom(isHorizontalWritingMode()) < logicalBottom)
2159             return false;
2160     }
2161
2162     return true;
2163 }
2164
2165 bool RenderBlockFlow::matchedEndLine(LineLayoutState& layoutState, const InlineBidiResolver& resolver, const InlineIterator& endLineStart, const BidiStatus& endLineStatus)
2166 {
2167     if (resolver.position() == endLineStart) {
2168         if (resolver.status() != endLineStatus)
2169             return false;
2170         return checkPaginationAndFloatsAtEndLine(layoutState);
2171     }
2172
2173     // The first clean line doesn't match, but we can check a handful of following lines to try
2174     // to match back up.
2175     static int numLines = 8; // The # of lines we're willing to match against.
2176     RootInlineBox* originalEndLine = layoutState.endLine();
2177     RootInlineBox* line = originalEndLine;
2178     for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) {
2179         if (line->lineBreakObj() == resolver.position().m_obj && line->lineBreakPos() == resolver.position().m_pos) {
2180             // We have a match.
2181             if (line->lineBreakBidiStatus() != resolver.status())
2182                 return false; // ...but the bidi state doesn't match.
2183             
2184             bool matched = false;
2185             RootInlineBox* result = line->nextRootBox();
2186             layoutState.setEndLine(result);
2187             if (result) {
2188                 layoutState.setEndLineLogicalTop(line->lineBottomWithLeading());
2189                 matched = checkPaginationAndFloatsAtEndLine(layoutState);
2190             }
2191
2192             // Now delete the lines that we failed to sync.
2193             deleteLineRange(layoutState, renderArena(), originalEndLine, result);
2194             return matched;
2195         }
2196     }
2197
2198     return false;
2199 }
2200
2201 static inline bool skipNonBreakingSpace(const InlineIterator& it, const LineInfo& lineInfo)
2202 {
2203     if (it.m_obj->style()->nbspMode() != SPACE || it.current() != noBreakSpace)
2204         return false;
2205
2206     // FIXME: This is bad.  It makes nbsp inconsistent with space and won't work correctly
2207     // with m_minWidth/m_maxWidth.
2208     // Do not skip a non-breaking space if it is the first character
2209     // on a line after a clean line break (or on the first line, since previousLineBrokeCleanly starts off
2210     // |true|).
2211     if (lineInfo.isEmpty() && lineInfo.previousLineBrokeCleanly())
2212         return false;
2213
2214     return true;
2215 }
2216
2217 enum WhitespacePosition { LeadingWhitespace, TrailingWhitespace };
2218 static inline bool shouldCollapseWhiteSpace(const RenderStyle* style, const LineInfo& lineInfo, WhitespacePosition whitespacePosition)
2219 {
2220     // CSS2 16.6.1
2221     // If a space (U+0020) at the beginning of a line has 'white-space' set to 'normal', 'nowrap', or 'pre-line', it is removed.
2222     // If a space (U+0020) at the end of a line has 'white-space' set to 'normal', 'nowrap', or 'pre-line', it is also removed.
2223     // If spaces (U+0020) or tabs (U+0009) at the end of a line have 'white-space' set to 'pre-wrap', UAs may visually collapse them.
2224     return style->collapseWhiteSpace()
2225         || (whitespacePosition == TrailingWhitespace && style->whiteSpace() == PRE_WRAP && (!lineInfo.isEmpty() || !lineInfo.previousLineBrokeCleanly()));
2226 }
2227
2228 static bool requiresLineBoxForContent(const RenderInline& flow, const LineInfo& lineInfo)
2229 {
2230     RenderElement* parent = flow.parent();
2231     if (flow.document().inNoQuirksMode()) {
2232         const RenderStyle& flowStyle = lineStyle(flow, lineInfo);
2233         const RenderStyle& parentStyle = lineStyle(*parent, lineInfo);
2234         if (flowStyle.lineHeight() != parentStyle.lineHeight()
2235             || flowStyle.verticalAlign() != parentStyle.verticalAlign()
2236             || !parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(flowStyle.font().fontMetrics()))
2237         return true;
2238     }
2239     return false;
2240 }
2241
2242 static bool hasInlineDirectionBordersPaddingOrMargin(const RenderInline& flow)
2243 {
2244     // Where an empty inline is split across anonymous blocks we should only give lineboxes to the 'sides' of the
2245     // inline that have borders, padding or margin.
2246     bool shouldApplyStartBorderPaddingOrMargin = !flow.parent()->isAnonymousBlock() || !flow.isInlineElementContinuation();
2247     if (shouldApplyStartBorderPaddingOrMargin && (flow.borderStart() || flow.marginStart() || flow.paddingStart()))
2248         return true;
2249
2250     bool shouldApplyEndBorderPaddingOrMargin = !flow.parent()->isAnonymousBlock() || flow.isInlineElementContinuation() || !flow.inlineElementContinuation();
2251     return shouldApplyEndBorderPaddingOrMargin && (flow.borderEnd() || flow.marginEnd() || flow.paddingEnd());
2252 }
2253
2254 static bool alwaysRequiresLineBox(const RenderInline& flow)
2255 {
2256     // FIXME: Right now, we only allow line boxes for inlines that are truly empty.
2257     // We need to fix this, though, because at the very least, inlines containing only
2258     // ignorable whitespace should should also have line boxes.
2259     return isEmptyInline(flow) && hasInlineDirectionBordersPaddingOrMargin(flow);
2260 }
2261
2262 static bool requiresLineBox(const InlineIterator& it, const LineInfo& lineInfo = LineInfo(), WhitespacePosition whitespacePosition = LeadingWhitespace)
2263 {
2264     if (it.m_obj->isFloatingOrOutOfFlowPositioned())
2265         return false;
2266
2267     if (it.m_obj->isBR())
2268         return true;
2269
2270     bool rendererIsEmptyInline = false;
2271     if (it.m_obj->isRenderInline()) {
2272         const RenderInline& inlineRenderer = toRenderInline(*it.m_obj);
2273         if (!alwaysRequiresLineBox(inlineRenderer) && !requiresLineBoxForContent(inlineRenderer, lineInfo))
2274             return false;
2275         rendererIsEmptyInline = isEmptyInline(inlineRenderer);
2276     }
2277
2278     if (!shouldCollapseWhiteSpace(it.m_obj->style(), lineInfo, whitespacePosition))
2279         return true;
2280
2281     UChar current = it.current();
2282     bool notJustWhitespace = current != ' ' && current != '\t' && current != softHyphen && (current != '\n' || it.m_obj->preservesNewline()) && !skipNonBreakingSpace(it, lineInfo);
2283     return notJustWhitespace || rendererIsEmptyInline;
2284 }
2285
2286 bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj)
2287 {
2288     ASSERT(inlineObj->parent() == this);
2289
2290     InlineIterator it(this, inlineObj, 0);
2291     // FIXME: We should pass correct value for WhitespacePosition.
2292     while (!it.atEnd() && !requiresLineBox(it))
2293         it.increment();
2294
2295     return !it.atEnd();
2296 }
2297
2298 // FIXME: The entire concept of the skipTrailingWhitespace function is flawed, since we really need to be building
2299 // line boxes even for containers that may ultimately collapse away. Otherwise we'll never get positioned
2300 // elements quite right. In other words, we need to build this function's work into the normal line
2301 // object iteration process.
2302 // NB. this function will insert any floating elements that would otherwise
2303 // be skipped but it will not position them.
2304 void LineBreaker::skipTrailingWhitespace(InlineIterator& iterator, const LineInfo& lineInfo)
2305 {
2306     while (!iterator.atEnd() && !requiresLineBox(iterator, lineInfo, TrailingWhitespace)) {
2307         RenderObject* object = iterator.m_obj;
2308         if (object->isOutOfFlowPositioned())
2309             setStaticPositions(m_block, toRenderBox(object));
2310         else if (object->isFloating())
2311             m_block->insertFloatingObject(toRenderBox(object));
2312         iterator.increment();
2313     }
2314 }
2315
2316 void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo& lineInfo,
2317                                                      FloatingObject* lastFloatFromPreviousLine, LineWidth& width)
2318 {
2319     while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo, LeadingWhitespace)) {
2320         RenderObject* object = resolver.position().m_obj;
2321         if (object->isOutOfFlowPositioned()) {
2322             setStaticPositions(m_block, toRenderBox(object));
2323             if (object->style()->isOriginalDisplayInlineType()) {
2324                 resolver.runs().addRun(createRun(0, 1, object, resolver));
2325                 lineInfo.incrementRunsFromLeadingWhitespace();
2326             }
2327         } else if (object->isFloating()) {
2328             // The top margin edge of a self-collapsing block that clears a float intrudes up into it by the height of the margin,
2329             // so in order to place this first child float at the top content edge of the self-collapsing block add the margin back in before placement.
2330             LayoutUnit marginOffset = (!object->previousSibling() && m_block->isSelfCollapsingBlock() && m_block->style()->clear() && m_block->getClearDelta(m_block, LayoutUnit())) ? m_block->collapsedMarginBeforeForChild(m_block) : LayoutUnit();
2331             LayoutUnit oldLogicalHeight = m_block->logicalHeight();
2332             m_block->setLogicalHeight(oldLogicalHeight + marginOffset);
2333             m_block->positionNewFloatOnLine(m_block->insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine, lineInfo, width);
2334             m_block->setLogicalHeight(oldLogicalHeight);
2335         } else if (object->isText() && object->style()->hasTextCombine() && object->isCombineText() && !toRenderCombineText(*object).isCombined()) {
2336             toRenderCombineText(*object).combineText();
2337             if (toRenderCombineText(*object).isCombined())
2338                 continue;
2339         }
2340         resolver.increment();
2341     }
2342     resolver.commitExplicitEmbedding();
2343 }
2344
2345 // This is currently just used for list markers and inline flows that have line boxes. Neither should
2346 // have an effect on whitespace at the start of the line.
2347 static bool shouldSkipWhitespaceAfterStartObject(RenderBlockFlow* block, RenderObject* o, LineMidpointState& lineMidpointState)
2348 {
2349     RenderObject* next = bidiNextSkippingEmptyInlines(block, o);
2350     while (next && next->isFloatingOrOutOfFlowPositioned())
2351         next = bidiNextSkippingEmptyInlines(block, next);
2352
2353     if (next && next->isText() && toRenderText(next)->textLength() > 0) {
2354         RenderText* nextText = toRenderText(next);
2355         UChar nextChar = nextText->characterAt(0);
2356         if (nextText->style()->isCollapsibleWhiteSpace(nextChar)) {
2357             startIgnoringSpaces(lineMidpointState, InlineIterator(0, o, 0));
2358             return true;
2359         }
2360     }
2361
2362     return false;
2363 }
2364
2365 static ALWAYS_INLINE float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, HashSet<const SimpleFontData*>& fallbackFonts, TextLayout* layout = 0)
2366 {
2367     const RenderStyle& style = *text->style();
2368
2369     GlyphOverflow glyphOverflow;
2370     if (isFixedPitch || (!from && len == text->textLength()) || style.hasTextCombine())
2371         return text->width(from, len, font, xPos, &fallbackFonts, &glyphOverflow);
2372
2373     if (layout)
2374         return Font::width(*layout, from, len, &fallbackFonts);
2375
2376     TextRun run = RenderBlock::constructTextRun(text, font, text, from, len, style);
2377     run.setCharactersLength(text->textLength() - from);
2378     ASSERT(run.charactersLength() >= run.length());
2379
2380     run.setCharacterScanForCodePath(!text->canUseSimpleFontCodePath());
2381     run.setTabSize(!collapseWhiteSpace, text->style()->tabSize());
2382     run.setXPos(xPos);
2383     return font.width(run, &fallbackFonts, &glyphOverflow);
2384 }
2385
2386 static void tryHyphenating(RenderText* text, const Font& font, const AtomicString& localeIdentifier, unsigned consecutiveHyphenatedLines, int consecutiveHyphenatedLinesLimit, int minimumPrefixLimit, int minimumSuffixLimit, unsigned lastSpace, unsigned pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated)
2387 {
2388     // Map 'hyphenate-limit-{before,after}: auto;' to 2.
2389     unsigned minimumPrefixLength;
2390     unsigned minimumSuffixLength;
2391
2392     if (minimumPrefixLimit < 0)
2393         minimumPrefixLength = 2;
2394     else
2395         minimumPrefixLength = static_cast<unsigned>(minimumPrefixLimit);
2396
2397     if (minimumSuffixLimit < 0)
2398         minimumSuffixLength = 2;
2399     else
2400         minimumSuffixLength = static_cast<unsigned>(minimumSuffixLimit);
2401
2402     if (pos - lastSpace <= minimumSuffixLength)
2403         return;
2404
2405     if (consecutiveHyphenatedLinesLimit >= 0 && consecutiveHyphenatedLines >= static_cast<unsigned>(consecutiveHyphenatedLinesLimit))
2406         return;
2407
2408     int hyphenWidth = measureHyphenWidth(text, font);
2409
2410     float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
2411     // If the maximum width available for the prefix before the hyphen is small, then it is very unlikely
2412     // that an hyphenation opportunity exists, so do not bother to look for it.
2413     if (maxPrefixWidth <= font.pixelSize() * 5 / 4)
2414         return;
2415
2416     const RenderStyle& style = *text->style();
2417     TextRun run = RenderBlock::constructTextRun(text, font, text, lastSpace, pos - lastSpace, style);
2418     run.setCharactersLength(text->textLength() - lastSpace);
2419     ASSERT(run.charactersLength() >= run.length());
2420
2421     run.setTabSize(!collapseWhiteSpace, style.tabSize());
2422     run.setXPos(xPos + lastSpaceWordSpacing);
2423
2424     unsigned prefixLength = font.offsetForPosition(run, maxPrefixWidth, false);
2425     if (prefixLength < minimumPrefixLength)
2426         return;
2427
2428     prefixLength = lastHyphenLocation(text->characters() + lastSpace, pos - lastSpace, min(prefixLength, pos - lastSpace - minimumSuffixLength) + 1, localeIdentifier);
2429     if (!prefixLength || prefixLength < minimumPrefixLength)
2430         return;
2431
2432     // When lastSapce is a space, which it always is except sometimes at the beginning of a line or after collapsed
2433     // space, it should not count towards hyphenate-limit-before.
2434     if (prefixLength == minimumPrefixLength) {
2435         UChar characterAtLastSpace = text->characterAt(lastSpace);
2436         if (characterAtLastSpace == ' ' || characterAtLastSpace == '\n' || characterAtLastSpace == '\t' || characterAtLastSpace == noBreakSpace)
2437             return;
2438     }
2439
2440     ASSERT(pos - lastSpace - prefixLength >= minimumSuffixLength);
2441
2442 #if !ASSERT_DISABLED
2443     HashSet<const SimpleFontData*> fallbackFonts;
2444     float prefixWidth = hyphenWidth + textWidth(text, lastSpace, prefixLength, font, xPos, isFixedPitch, collapseWhiteSpace, fallbackFonts) + lastSpaceWordSpacing;
2445     ASSERT(xPos + prefixWidth <= availableWidth);
2446 #else
2447     UNUSED_PARAM(isFixedPitch);
2448 #endif
2449
2450     lineBreak.moveTo(text, lastSpace + prefixLength, nextBreakable);
2451     hyphenated = true;
2452 }
2453
2454 class TrailingObjects {
2455 public:
2456     TrailingObjects();
2457     void setTrailingWhitespace(RenderText*);
2458     void clear();
2459     void appendBoxIfNeeded(RenderBoxModelObject*);
2460
2461     enum CollapseFirstSpaceOrNot { DoNotCollapseFirstSpace, CollapseFirstSpace };
2462
2463     void updateMidpointsForTrailingBoxes(LineMidpointState&, const InlineIterator& lBreak, CollapseFirstSpaceOrNot);
2464
2465 private:
2466     RenderText* m_whitespace;
2467     Vector<RenderBoxModelObject*, 4> m_boxes;
2468 };
2469
2470 TrailingObjects::TrailingObjects()
2471     : m_whitespace(0)
2472 {
2473 }
2474
2475 inline void TrailingObjects::setTrailingWhitespace(RenderText* whitespace)
2476 {
2477     ASSERT(whitespace);
2478     m_whitespace = whitespace;
2479 }
2480
2481 inline void TrailingObjects::clear()
2482 {
2483     m_whitespace = 0;
2484     m_boxes.shrink(0); // Use shrink(0) instead of clear() to retain our capacity.
2485 }
2486
2487 inline void TrailingObjects::appendBoxIfNeeded(RenderBoxModelObject* box)
2488 {
2489     if (m_whitespace)
2490         m_boxes.append(box);
2491 }
2492
2493 void TrailingObjects::updateMidpointsForTrailingBoxes(LineMidpointState& lineMidpointState, const InlineIterator& lBreak, CollapseFirstSpaceOrNot collapseFirstSpace)
2494 {
2495     if (!m_whitespace)
2496         return;
2497
2498     // This object is either going to be part of the last midpoint, or it is going to be the actual endpoint.
2499     // In both cases we just decrease our pos by 1 level to exclude the space, allowing it to - in effect - collapse into the newline.
2500     if (lineMidpointState.numMidpoints % 2) {
2501         // Find the trailing space object's midpoint.
2502         int trailingSpaceMidpoint = lineMidpointState.numMidpoints - 1;
2503         for ( ; trailingSpaceMidpoint > 0 && lineMidpointState.midpoints[trailingSpaceMidpoint].m_obj != m_whitespace; --trailingSpaceMidpoint) { }
2504         ASSERT(trailingSpaceMidpoint >= 0);
2505         if (collapseFirstSpace == CollapseFirstSpace)
2506             lineMidpointState.midpoints[trailingSpaceMidpoint].m_pos--;
2507
2508         // Now make sure every single trailingPositionedBox following the trailingSpaceMidpoint properly stops and starts
2509         // ignoring spaces.
2510         size_t currentMidpoint = trailingSpaceMidpoint + 1;
2511         for (size_t i = 0; i < m_boxes.size(); ++i) {
2512             if (currentMidpoint >= lineMidpointState.numMidpoints) {
2513                 // We don't have a midpoint for this box yet.
2514                 ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]);
2515             } else {
2516                 ASSERT(lineMidpointState.midpoints[currentMidpoint].m_obj == m_boxes[i]);
2517                 ASSERT(lineMidpointState.midpoints[currentMidpoint + 1].m_obj == m_boxes[i]);
2518             }
2519             currentMidpoint += 2;
2520         }
2521     } else if (!lBreak.m_obj) {
2522         ASSERT(m_whitespace->isText());
2523         ASSERT(collapseFirstSpace == CollapseFirstSpace);
2524         // Add a new end midpoint that stops right at the very end.
2525         unsigned length = m_whitespace->textLength();
2526         unsigned pos = length >= 2 ? length - 2 : UINT_MAX;
2527         InlineIterator endMid(0, m_whitespace, pos);
2528         startIgnoringSpaces(lineMidpointState, endMid);
2529         for (size_t i = 0; i < m_boxes.size(); ++i) {
2530             ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]);
2531         }
2532     }
2533 }
2534
2535 void LineBreaker::reset()
2536 {
2537     m_positionedObjects.clear();
2538     m_hyphenated = false;
2539     m_clear = CNONE;
2540 }
2541
2542 InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements)
2543 {
2544 #if !ENABLE(CSS_SHAPES)
2545     return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
2546 #else
2547     ShapeInsideInfo* shapeInsideInfo = m_block->layoutShapeInsideInfo();
2548
2549     if (!shapeInsideInfo || !shapeInsideInfo->lineOverlapsShapeBounds())
2550         return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
2551
2552     InlineIterator end = resolver.position();
2553     InlineIterator oldEnd = end;
2554
2555     if (!shapeInsideInfo->hasSegments()) {
2556         end = nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
2557         resolver.setPositionIgnoringNestedIsolates(oldEnd);
2558         return oldEnd;
2559     }
2560
2561     const SegmentList& segments = shapeInsideInfo->segments();
2562     SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges();
2563
2564     for (unsigned i = 0; i < segments.size() && !end.atEnd(); i++) {
2565         InlineIterator segmentStart = resolver.position();
2566         end = nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
2567
2568         ASSERT(segmentRanges.size() == i);
2569         if (resolver.position().atEnd()) {
2570             segmentRanges.append(LineSegmentRange(segmentStart, end));
2571             break;
2572         }
2573         if (resolver.position() == end) {
2574             // Nothing fit this segment
2575             end = segmentStart;
2576             segmentRanges.append(LineSegmentRange(segmentStart, segmentStart));
2577             resolver.setPositionIgnoringNestedIsolates(segmentStart);
2578         } else {
2579             // Note that resolver.position is already skipping some of the white space at the beginning of the line,
2580             // so that's why segmentStart might be different than resolver.position().
2581             LineSegmentRange range(resolver.position(), end);
2582             segmentRanges.append(range);
2583             resolver.setPosition(end, numberOfIsolateAncestors(end));
2584
2585             if (lineInfo.previousLineBrokeCleanly()) {
2586                 // If we hit a new line break, just stop adding anything to this line.
2587                 break;
2588             }
2589         }
2590     }
2591     resolver.setPositionIgnoringNestedIsolates(oldEnd);
2592     return end;
2593 #endif
2594 }
2595
2596 static inline bool iteratorIsBeyondEndOfRenderCombineText(const InlineIterator& iter, RenderCombineText& renderer)
2597 {
2598     return iter.m_obj == &renderer && iter.m_pos >= renderer.textLength();
2599 }
2600
2601 static inline void commitLineBreakAtCurrentWidth(LineWidth& width, InlineIterator& lBreak, RenderObject* object, unsigned offset = 0, int nextBreak = -1)
2602 {
2603     width.commit();
2604     lBreak.moveTo(object, offset, nextBreak);
2605 }
2606
2607 static bool textBeginsWithBreakablePosition(RenderObject* next)
2608 {
2609     ASSERT(next->isText());
2610     RenderText* nextText = toRenderText(next);
2611     if (!nextText->textLength())
2612         return false;
2613     UChar c = nextText->characterAt(0);
2614     return c == ' ' || c == '\t' || (c == '\n' && !nextText->preservesNewline());
2615 }
2616
2617 static bool canBreakAtThisPosition(bool autoWrap, LineWidth& width, InlineIterator& lBreak, RenderObject* next, const InlineIterator& current, EWhiteSpace currWS, bool currentCharacterIsSpace, bool autoWrapWasEverTrueOnLine)
2618 {
2619     // If we are no-wrap and have found a line-breaking opportunity already then we should take it.
2620     if (width.committedWidth() && !width.fitsOnLine(currentCharacterIsSpace) && currWS == NOWRAP)
2621         return true;
2622
2623     // Avoid breaking before empty inlines.
2624     if (next && next->isRenderInline() && isEmptyInline(toRenderInline(*next)))
2625         return false;
2626
2627     // Return early if we autowrap and the current character is a space as we will always want to break at such a position.
2628     if (autoWrap && currentCharacterIsSpace)
2629         return true;
2630
2631     if (next && next->isLineBreakOpportunity())
2632         return autoWrap;
2633
2634     bool nextIsAutoWrappingText = (next && next->isText() && (autoWrap || next->style()->autoWrap()));
2635     if (!nextIsAutoWrappingText)
2636         return autoWrap;
2637     bool currentIsTextOrEmptyInline = current.m_obj->isText() || (current.m_obj->isRenderInline() && isEmptyInline(toRenderInline(*current.m_obj)));
2638     if (!currentIsTextOrEmptyInline)
2639         return autoWrap;
2640
2641     bool canBreakHere = !currentCharacterIsSpace && textBeginsWithBreakablePosition(next);
2642
2643     // See if attempting to fit below floats creates more available width on the line.
2644     if (!width.fitsOnLine() && !width.committedWidth())
2645         width.fitBelowFloats();
2646
2647     bool canPlaceOnLine = width.fitsOnLine() || !autoWrapWasEverTrueOnLine;
2648
2649     if (canPlaceOnLine && canBreakHere)
2650         commitLineBreakAtCurrentWidth(width, lBreak, next);
2651
2652     return canBreakHere;
2653 }
2654
2655 #if ENABLE(CSS_SHAPES)
2656 static void updateSegmentsForShapes(RenderBlockFlow* block, const FloatingObject* lastFloatFromPreviousLine, const WordMeasurements& wordMeasurements, LineWidth& width, bool isFirstLine)
2657 {
2658     ASSERT(lastFloatFromPreviousLine);
2659
2660     ShapeInsideInfo* shapeInsideInfo = block->layoutShapeInsideInfo();
2661     if (!lastFloatFromPreviousLine->isPlaced() || !shapeInsideInfo)
2662         return;
2663
2664     bool isHorizontalWritingMode = block->isHorizontalWritingMode();
2665     LayoutUnit logicalOffsetFromShapeContainer = block->logicalOffsetFromShapeAncestorContainer(shapeInsideInfo->owner()).height();
2666
2667     LayoutUnit lineLogicalTop = block->logicalHeight() + logicalOffsetFromShapeContainer;
2668     LayoutUnit lineLogicalHeight = block->lineHeight(isFirstLine, isHorizontalWritingMode ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
2669     LayoutUnit lineLogicalBottom = lineLogicalTop + lineLogicalHeight;
2670
2671     LayoutUnit floatLogicalTop = lastFloatFromPreviousLine->logicalTop(isHorizontalWritingMode);
2672     LayoutUnit floatLogicalBottom = lastFloatFromPreviousLine->logicalBottom(isHorizontalWritingMode);
2673
2674     bool lineOverlapsWithFloat = (floatLogicalTop < lineLogicalBottom) && (lineLogicalTop < floatLogicalBottom);
2675     if (!lineOverlapsWithFloat)
2676         return;
2677
2678     float minSegmentWidth = firstPositiveWidth(wordMeasurements);
2679
2680     LayoutUnit floatLogicalWidth = lastFloatFromPreviousLine->logicalWidth(isHorizontalWritingMode);
2681     LayoutUnit availableLogicalWidth = block->logicalWidth() - lastFloatFromPreviousLine->logicalRight(isHorizontalWritingMode);
2682     if (availableLogicalWidth < minSegmentWidth)
2683         block->setLogicalHeight(floatLogicalBottom);
2684
2685     if (block->logicalHeight() < floatLogicalTop) {
2686         shapeInsideInfo->adjustLogicalLineTop(minSegmentWidth + floatLogicalWidth);
2687         block->setLogicalHeight(shapeInsideInfo->logicalLineTop() - logicalOffsetFromShapeContainer);
2688     }
2689
2690     lineLogicalTop = block->logicalHeight() + logicalOffsetFromShapeContainer;
2691
2692     shapeInsideInfo->updateSegmentsForLine(lineLogicalTop, lineLogicalHeight);
2693     width.updateCurrentShapeSegment();
2694     width.updateAvailableWidth();
2695 }
2696 #endif
2697
2698 InlineIterator LineBreaker::nextSegmentBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements)
2699 {
2700     reset();
2701
2702     ASSERT(resolver.position().root() == m_block);
2703
2704     bool appliedStartWidth = resolver.position().m_pos > 0;
2705     bool includeEndWidth = true;
2706     LineMidpointState& lineMidpointState = resolver.midpointState();
2707
2708     LineWidth width(*m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.isFirstLine(), lineInfo.previousLineBrokeCleanly(), *m_block->style()));
2709
2710     skipLeadingWhitespace(resolver, lineInfo, lastFloatFromPreviousLine, width);
2711
2712     if (resolver.position().atEnd())
2713         return resolver.position();
2714
2715     // This variable is used only if whitespace isn't set to PRE, and it tells us whether
2716     // or not we are currently ignoring whitespace.
2717     bool ignoringSpaces = false;
2718     InlineIterator ignoreStart;
2719
2720     // This variable tracks whether the very last character we saw was a space.  We use
2721     // this to detect when we encounter a second space so we know we have to terminate
2722     // a run.
2723     bool currentCharacterIsSpace = false;
2724     bool currentCharacterIsWS = false;
2725     TrailingObjects trailingObjects;
2726
2727     InlineIterator lBreak = resolver.position();
2728
2729     // FIXME: It is error-prone to split the position object out like this.
2730     // Teach this code to work with objects instead of this split tuple.
2731     InlineIterator current = resolver.position();
2732     RenderObject* last = current.m_obj;
2733     bool atStart = true;
2734
2735     bool startingNewParagraph = lineInfo.previousLineBrokeCleanly();
2736     lineInfo.setPreviousLineBrokeCleanly(false);
2737
2738     bool autoWrapWasEverTrueOnLine = false;
2739     bool floatsFitOnLine = true;
2740
2741     // Firefox and Opera will allow a table cell to grow to fit an image inside it under
2742     // very specific circumstances (in order to match common WinIE renderings).
2743     // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
2744     const RenderStyle& blockStyle = *m_block->style();
2745     bool allowImagesToBreak = !m_block->document().inQuirksMode() || !m_block->isTableCell() || !blockStyle.logicalWidth().isIntrinsicOrAuto();
2746
2747     EWhiteSpace currWS = blockStyle.whiteSpace();
2748     EWhiteSpace lastWS = currWS;
2749     while (current.m_obj) {
2750         const RenderStyle& currentStyle = *current.m_obj->style();
2751         RenderObject* next = bidiNextSkippingEmptyInlines(m_block, current.m_obj);
2752         if (next && next->parent() && !next->parent()->isDescendantOf(current.m_obj->parent()))
2753             includeEndWidth = true;
2754
2755         currWS = current.m_obj->isReplaced() ? current.m_obj->parent()->style()->whiteSpace() : currentStyle.whiteSpace();
2756         lastWS = last->isReplaced() ? last->parent()->style()->whiteSpace() : last->style()->whiteSpace();
2757
2758         bool autoWrap = RenderStyle::autoWrap(currWS);
2759         autoWrapWasEverTrueOnLine = autoWrapWasEverTrueOnLine || autoWrap;
2760
2761 #if ENABLE(SVG)
2762         bool preserveNewline = current.m_obj->isSVGInlineText() ? false : RenderStyle::preserveNewline(currWS);
2763 #else
2764         bool preserveNewline = RenderStyle::preserveNewline(currWS);
2765 #endif
2766
2767         bool collapseWhiteSpace = RenderStyle::collapseWhiteSpace(currWS);
2768
2769         if (current.m_obj->isBR()) {
2770             if (width.fitsOnLine()) {
2771                 lBreak.moveToStartOf(current.m_obj);
2772                 lBreak.increment();
2773
2774                 // A <br> always breaks a line, so don't let the line be collapsed
2775                 // away. Also, the space at the end of a line with a <br> does not
2776                 // get collapsed away.  It only does this if the previous line broke
2777                 // cleanly.  Otherwise the <br> has no effect on whether the line is
2778                 // empty or not.
2779                 if (startingNewParagraph)
2780                     lineInfo.setEmpty(false, m_block, &width);
2781                 trailingObjects.clear();
2782                 lineInfo.setPreviousLineBrokeCleanly(true);
2783
2784                 // A <br> with clearance always needs a linebox in case the lines below it get dirtied later and 
2785                 // need to check for floats to clear - so if we're ignoring spaces, stop ignoring them and add a
2786                 // run for this object.
2787                 if (ignoringSpaces && currentStyle.clear() != CNONE)
2788                     ensureLineBoxInsideIgnoredSpaces(lineMidpointState, current.m_obj);
2789                 // If we were preceded by collapsing space and are in a right-aligned container we need to ensure the space gets
2790                 // collapsed away so that it doesn't push the text out from the container's right-hand edge.
2791                 // FIXME: Do this regardless of the container's alignment - will require rebaselining a lot of test results.
2792                 else if (ignoringSpaces && (blockStyle.textAlign() == RIGHT || blockStyle.textAlign() == WEBKIT_RIGHT))
2793                     stopIgnoringSpaces(lineMidpointState, InlineIterator(0, current.m_obj, current.m_pos));
2794
2795                 if (!lineInfo.isEmpty())
2796                     m_clear = currentStyle.clear();
2797             }
2798             goto end;
2799         }
2800
2801         if (current.m_obj->isOutOfFlowPositioned()) {
2802             // If our original display wasn't an inline type, then we can
2803             // go ahead and determine our static inline position now.
2804             RenderBox* box = toRenderBox(current.m_obj);
2805             bool isInlineType = box->style()->isOriginalDisplayInlineType();
2806             if (!isInlineType)
2807                 m_block->setStaticInlinePositionForChild(box, m_block->logicalHeight(), m_block->startOffsetForContent(m_block->logicalHeight()));
2808             else  {
2809                 // If our original display was an INLINE type, then we can go ahead
2810                 // and determine our static y position now.
2811                 box->layer()->setStaticBlockPosition(m_block->logicalHeight());
2812             }
2813
2814             // If we're ignoring spaces, we have to stop and include this object and
2815             // then start ignoring spaces again.
2816             if (isInlineType || current.m_obj->container()->isRenderInline()) {
2817                 if (ignoringSpaces)
2818                     ensureLineBoxInsideIgnoredSpaces(lineMidpointState, current.m_obj);
2819                 trailingObjects.appendBoxIfNeeded(box);
2820             } else
2821                 m_positionedObjects.append(box);
2822             width.addUncommittedWidth(inlineLogicalWidth(current.m_obj));
2823             // Reset prior line break context characters.
2824             renderTextInfo.m_lineBreakIterator.resetPriorContext();
2825         } else if (current.m_obj->isFloating()) {
2826             RenderBox* floatBox = toRenderBox(current.m_obj);
2827             FloatingObject* f = m_block->insertFloatingObject(floatBox);
2828             // check if it fits in the current line.
2829             // If it does, position it now, otherwise, position
2830             // it after moving to next line (in newLine() func)
2831             // FIXME: Bug 110372: Properly position multiple stacked floats with non-rectangular shape outside.
2832             if (floatsFitOnLine && width.fitsOnLineExcludingTrailingWhitespace(f->logicalWidth(m_block->isHorizontalWritingMode()))) {
2833                 m_block->positionNewFloatOnLine(f, lastFloatFromPreviousLine, lineInfo, width);
2834                 if (lBreak.m_obj == current.m_obj) {
2835                     ASSERT(!lBreak.m_pos);
2836                     lBreak.increment();
2837                 }
2838             } else
2839                 floatsFitOnLine = false;
2840             // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for floating element.
2841             renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter);
2842         } else if (current.m_obj->isRenderInline()) {
2843             RenderInline& flowBox = toRenderInline(*current.m_obj);
2844             // Right now, we should only encounter empty inlines here.
2845             ASSERT(isEmptyInline(flowBox));
2846             // Now that some inline flows have line boxes, if we are already ignoring spaces, we need
2847             // to make sure that we stop to include this object and then start ignoring spaces again.
2848             // If this object is at the start of the line, we need to behave like list markers and
2849             // start ignoring spaces.
2850             bool requiresLineBox = alwaysRequiresLineBox(flowBox);
2851             if (requiresLineBox || requiresLineBoxForContent(flowBox, lineInfo)) {
2852                 // An empty inline that only has line-height, vertical-align or font-metrics will only get a
2853                 // line box to affect the height of the line if the rest of the line is not empty.
2854                 if (requiresLineBox)
2855                     lineInfo.setEmpty(false, m_block, &width);
2856                 if (ignoringSpaces) {
2857                     trailingObjects.clear();
2858                     ensureLineBoxInsideIgnoredSpaces(lineMidpointState, current.m_obj);
2859                 } else if (blockStyle.collapseWhiteSpace() && resolver.position().m_obj == current.m_obj
2860                     && shouldSkipWhitespaceAfterStartObject(m_block, current.m_obj, lineMidpointState)) {
2861                     // Like with list markers, we start ignoring spaces to make sure that any
2862                     // additional spaces we see will be discarded.
2863                     currentCharacterIsSpace = true;
2864                     currentCharacterIsWS = true;
2865                     ignoringSpaces = true;
2866                 } else {
2867                     trailingObjects.appendBoxIfNeeded(&flowBox);
2868                 }
2869             }
2870
2871             width.addUncommittedWidth(inlineLogicalWidth(current.m_obj) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox));
2872         } else if (current.m_obj->isReplaced()) {
2873             RenderBox* replacedBox = toRenderBox(current.m_obj);
2874
2875             if (atStart)
2876                 width.updateAvailableWidth(replacedBox->logicalHeight());
2877
2878             // Break on replaced elements if either has normal white-space.
2879             if ((autoWrap || RenderStyle::autoWrap(lastWS)) && (!current.m_obj->isImage() || allowImagesToBreak))
2880                 commitLineBreakAtCurrentWidth(width, lBreak, current.m_obj);
2881
2882             if (ignoringSpaces)
2883                 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, current.m_obj, 0));
2884
2885             lineInfo.setEmpty(false, m_block, &width);
2886             ignoringSpaces = false;
2887             currentCharacterIsSpace = false;
2888             currentCharacterIsWS = false;
2889             trailingObjects.clear();
2890
2891             // Optimize for a common case. If we can't find whitespace after the list
2892             // item, then this is all moot.
2893             LayoutUnit replacedLogicalWidth = m_block->logicalWidthForChild(replacedBox) + m_block->marginStartForChild(replacedBox) + m_block->marginEndForChild(replacedBox) + inlineLogicalWidth(current.m_obj);
2894             if (current.m_obj->isListMarker()) {
2895                 if (blockStyle.collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(m_block, current.m_obj, lineMidpointState)) {
2896                     // Like with inline flows, we start ignoring spaces to make sure that any
2897                     // additional spaces we see will be discarded.
2898                     currentCharacterIsSpace = true;
2899                     currentCharacterIsWS = true;
2900                     ignoringSpaces = true;
2901                 }
2902                 if (toRenderListMarker(*current.m_obj).isInside())
2903                     width.addUncommittedWidth(replacedLogicalWidth);
2904             } else
2905                 width.addUncommittedWidth(replacedLogicalWidth);
2906             if (current.m_obj->isRubyRun())
2907                 width.applyOverhang(toRenderRubyRun(current.m_obj), last, next);
2908             // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for replaced element.
2909             renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter);
2910         } else if (current.m_obj->isText()) {
2911             if (!current.m_pos)
2912                 appliedStartWidth = false;
2913
2914             RenderText* t = toRenderText(current.m_obj);
2915
2916 #if ENABLE(SVG)
2917             bool isSVGText = t->isSVGInlineText();
2918 #endif
2919
2920             // If we have left a no-wrap inline and entered an autowrap inline while ignoring spaces
2921             // then we need to mark the start of the autowrap inline as a potential linebreak now. 
2922             if (autoWrap && !RenderStyle::autoWrap(lastWS) && ignoringSpaces)
2923                 commitLineBreakAtCurrentWidth(width, lBreak, current.m_obj);
2924
2925             if (t->style()->hasTextCombine() && current.m_obj->isCombineText() && !toRenderCombineText(*current.m_obj).isCombined()) {
2926                 RenderCombineText& combineRenderer = toRenderCombineText(*current.m_obj);
2927                 combineRenderer.combineText();
2928                 // The length of the renderer's text may have changed. Increment stale iterator positions
2929                 if (iteratorIsBeyondEndOfRenderCombineText(lBreak, combineRenderer)) {
2930                     ASSERT(iteratorIsBeyondEndOfRenderCombineText(resolver.position(), combineRenderer));
2931                     lBreak.increment();
2932                     resolver.increment();
2933                 }
2934             }
2935
2936             const RenderStyle& style = lineStyle(*t->parent(), lineInfo);
2937             const Font& f = style.font();
2938             bool isFixedPitch = f.isFixedPitch();
2939             bool canHyphenate = style.hyphens() == HyphensAuto && WebCore::canHyphenate(style.locale());
2940
2941             unsigned lastSpace = current.m_pos;
2942             float wordSpacing = currentStyle.wordSpacing();
2943             float lastSpaceWordSpacing = 0;
2944             float wordSpacingForWordMeasurement = 0;
2945
2946             float wrapW = width.uncommittedWidth() + inlineLogicalWidth(current.m_obj, !appliedStartWidth, true);
2947             float charWidth = 0;
2948             bool breakNBSP = autoWrap && currentStyle.nbspMode() == SPACE;
2949             // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word,
2950             // which is only possible if the word is the first thing on the line, that is, if |w| is zero.
2951             bool breakWords = currentStyle.breakWords() && ((autoWrap && !width.committedWidth()) || currWS == PRE);
2952             bool midWordBreak = false;
2953             bool breakAll = currentStyle.wordBreak() == BreakAllWordBreak && autoWrap;
2954             float hyphenWidth = 0;
2955 #if ENABLE(SVG)
2956             if (isSVGText) {
2957                 breakWords = false;
2958                 breakAll = false;
2959             }
2960 #endif
2961
2962             if (renderTextInfo.m_text != t) {
2963                 updateCounterIfNeeded(t);
2964                 renderTextInfo.m_text = t;
2965                 renderTextInfo.m_font = &f;
2966                 renderTextInfo.m_layout = f.createLayout(t, width.currentWidth(), collapseWhiteSpace);
2967                 renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(t->text(), style.locale());
2968             } else if (renderTextInfo.m_layout && renderTextInfo.m_font != &f) {
2969                 renderTextInfo.m_font = &f;
2970                 renderTextInfo.m_layout = f.createLayout(t, width.currentWidth(), collapseWhiteSpace);
2971             }
2972
2973             TextLayout* textLayout = renderTextInfo.m_layout.get();
2974
2975             // Non-zero only when kerning is enabled and TextLayout isn't used, in which case we measure
2976             // words with their trailing space, then subtract its width.
2977             HashSet<const SimpleFontData*> fallbackFonts;
2978             float wordTrailingSpaceWidth = (f.typesettingFeatures() & Kerning) && !textLayout ? f.width(RenderBlock::constructTextRun(t, f, &space, 1, style), &fallbackFonts) + wordSpacing : 0;
2979
2980             UChar lastCharacter = renderTextInfo.m_lineBreakIterator.lastCharacter();
2981             UChar secondToLastCharacter = renderTextInfo.m_lineBreakIterator.secondToLastCharacter();
2982             for (; current.m_pos < t->textLength(); current.fastIncrementInTextNode()) {
2983                 bool previousCharacterIsSpace = currentCharacterIsSpace;
2984                 bool previousCharacterIsWS = currentCharacterIsWS;
2985                 UChar c = current.current();
2986                 currentCharacterIsSpace = c == ' ' || c == '\t' || (!preserveNewline && (c == '\n'));
2987
2988                 if (!collapseWhiteSpace || !currentCharacterIsSpace)
2989                     lineInfo.setEmpty(false, m_block, &width);
2990
2991                 if (c == softHyphen && autoWrap && !hyphenWidth && style.hyphens() != HyphensNone) {
2992                     hyphenWidth = measureHyphenWidth(t, f, &fallbackFonts);
2993                     width.addUncommittedWidth(hyphenWidth);
2994                 }
2995
2996                 bool applyWordSpacing = false;
2997
2998                 currentCharacterIsWS = currentCharacterIsSpace || (breakNBSP && c == noBreakSpace);
2999
3000                 if ((breakAll || breakWords) && !midWordBreak) {
3001                     wrapW += charWidth;
3002                     bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && current.m_pos + 1 < t->textLength() && U16_IS_TRAIL(t->characters()[current.m_pos + 1]);
3003                     charWidth = textWidth(t, current.m_pos, midWordBreakIsBeforeSurrogatePair ? 2 : 1, f, width.committedWidth() + wrapW, isFixedPitch, collapseWhiteSpace, fallbackFonts, textLayout);
3004                     midWordBreak = width.committedWidth() + wrapW + charWidth > width.availableWidth();
3005                 }
3006
3007                 bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(renderTextInfo.m_lineBreakIterator, current.m_pos, current.m_nextBreakablePosition, breakNBSP)
3008                     && (style.hyphens() != HyphensNone || (current.previousInSameNode() != softHyphen)));
3009
3010                 if (betweenWords || midWordBreak) {
3011                     bool stoppedIgnoringSpaces = false;
3012                     if (ignoringSpaces) {
3013                         lastSpaceWordSpacing = 0;
3014                         if (!currentCharacterIsSpace) {
3015                             // Stop ignoring spaces and begin at this
3016                             // new point.
3017                             ignoringSpaces = false;
3018                             wordSpacingForWordMeasurement = 0;
3019                             lastSpace = current.m_pos; // e.g., "Foo    goo", don't add in any of the ignored spaces.
3020                             stopIgnoringSpaces(lineMidpointState, InlineIterator(0, current.m_obj, current.m_pos));
3021                             stoppedIgnoringSpaces = true;
3022                         } else {
3023                             // Just keep ignoring these spaces.
3024                             goto nextCharacter;
3025                         }
3026                     }
3027
3028                     wordMeasurements.grow(wordMeasurements.size() + 1);
3029                     WordMeasurement& wordMeasurement = wordMeasurements.last();
3030                     
3031                     wordMeasurement.renderer = t;
3032                     wordMeasurement.endOffset = current.m_pos;
3033                     wordMeasurement.startOffset = lastSpace;
3034
3035                     float additionalTempWidth;
3036                     if (wordTrailingSpaceWidth && c == ' ')
3037                         additionalTempWidth = textWidth(t, lastSpace, current.m_pos + 1 - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth;
3038                     else
3039                         additionalTempWidth = textWidth(t, lastSpace, current.m_pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout);
3040
3041                     if (wordMeasurement.fallbackFonts.isEmpty() && !fallbackFonts.isEmpty())
3042                         wordMeasurement.fallbackFonts.swap(fallbackFonts);
3043                     fallbackFonts.clear();
3044
3045                     wordMeasurement.width = additionalTempWidth + wordSpacingForWordMeasurement;
3046                     additionalTempWidth += lastSpaceWordSpacing;
3047                     width.addUncommittedWidth(additionalTempWidth);
3048
3049                     if (collapseWhiteSpace && previousCharacterIsSpace && currentCharacterIsSpace && additionalTempWidth)
3050                         width.setTrailingWhitespaceWidth(additionalTempWidth);
3051
3052                     if (!appliedStartWidth) {
3053                         width.addUncommittedWidth(inlineLogicalWidth(current.m_obj, true, false));
3054                         appliedStartWidth = true;
3055                     }
3056
3057 #if ENABLE(CSS_SHAPES)
3058                     if (lastFloatFromPreviousLine)