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