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