1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4 *           (C) 2007 David Smith (catfish.man@gmail.com)
5 * Copyright (C) 2003-2013 Apple Inc. All rights reserved.
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7 * Copyright (C) 2013 Google Inc. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
11 * met:
12 *
13 *     * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *     * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following disclaimer
17 * in the documentation and/or other materials provided with the
18 * distribution.
19 *     * Neither the name of Google Inc. nor the names of its
20 * contributors may be used to endorse or promote products derived from
21 * this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#ifndef RenderBlockFlow_h
37#define RenderBlockFlow_h
38
39#include "core/rendering/FloatingObjects.h"
40#include "core/rendering/RenderBlock.h"
41#include "core/rendering/style/RenderStyleConstants.h"
42
43namespace WebCore {
44
45class MarginInfo;
46class LineBreaker;
47class LineWidth;
48class RenderNamedFlowFragment;
49
50class RenderBlockFlow : public RenderBlock {
51public:
52    explicit RenderBlockFlow(ContainerNode*);
53    virtual ~RenderBlockFlow();
54
55    static RenderBlockFlow* createAnonymous(Document*);
56    RenderBlockFlow* createAnonymousBlockFlow() const;
57
58    virtual bool isRenderBlockFlow() const OVERRIDE FINAL { return true; }
59
60    virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
61
62    virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false) OVERRIDE;
63    virtual void deleteLineBoxTree() OVERRIDE FINAL;
64
65    void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
66    void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = 0);
67
68    virtual bool containsFloats() const OVERRIDE FINAL { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
69    bool containsFloat(RenderBox*) const;
70
71    void removeFloatingObjects();
72
73    bool generatesLineBoxesForInlineChild(RenderObject*);
74
75    LayoutUnit logicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->y() : floatingObject->x(); }
76    LayoutUnit logicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxY() : floatingObject->maxX(); }
77    LayoutUnit logicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->x() : floatingObject->y(); }
78    LayoutUnit logicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxX() : floatingObject->maxY(); }
79    LayoutUnit logicalWidthForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->width() : floatingObject->height(); }
80    LayoutUnit logicalHeightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->height() : floatingObject->width(); }
81    LayoutSize logicalSizeForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? LayoutSize(floatingObject->width(), floatingObject->height()) : LayoutSize(floatingObject->height(), floatingObject->width()); }
82
83    int pixelSnappedLogicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedY() : floatingObject->frameRect().pixelSnappedX(); }
84    int pixelSnappedLogicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxY() : floatingObject->frameRect().pixelSnappedMaxX(); }
85    int pixelSnappedLogicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedX() : floatingObject->frameRect().pixelSnappedY(); }
86    int pixelSnappedLogicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxX() : floatingObject->frameRect().pixelSnappedMaxY(); }
87
88    void setLogicalTopForFloat(FloatingObject* floatingObject, LayoutUnit logicalTop)
89    {
90        if (isHorizontalWritingMode())
91            floatingObject->setY(logicalTop);
92        else
93            floatingObject->setX(logicalTop);
94    }
95    void setLogicalLeftForFloat(FloatingObject* floatingObject, LayoutUnit logicalLeft)
96    {
97        if (isHorizontalWritingMode())
98            floatingObject->setX(logicalLeft);
99        else
100            floatingObject->setY(logicalLeft);
101    }
102    void setLogicalHeightForFloat(FloatingObject* floatingObject, LayoutUnit logicalHeight)
103    {
104        if (isHorizontalWritingMode())
105            floatingObject->setHeight(logicalHeight);
106        else
107            floatingObject->setWidth(logicalHeight);
108    }
109    void setLogicalWidthForFloat(FloatingObject* floatingObject, LayoutUnit logicalWidth)
110    {
111        if (isHorizontalWritingMode())
112            floatingObject->setWidth(logicalWidth);
113        else
114            floatingObject->setHeight(logicalWidth);
115    }
116
117    LayoutUnit startAlignedOffsetForLine(LayoutUnit position, bool shouldIndentText);
118
119    void setStaticInlinePositionForChild(RenderBox*, LayoutUnit blockOffset, LayoutUnit inlinePosition);
120    void updateStaticInlinePositionForChild(RenderBox*, LayoutUnit logicalTop);
121
122    static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
123    {
124        return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline());
125    }
126
127    static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*,
128        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
129
130    static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, RenderStyle*,
131        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
132
133    static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*,
134        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
135
136    static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, RenderStyle*,
137        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
138
139    static TextRun constructTextRun(RenderObject* context, const Font&, const LChar* characters, int length, RenderStyle*,
140        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
141
142    static TextRun constructTextRun(RenderObject* context, const Font&, const UChar* characters, int length, RenderStyle*,
143        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
144
145    RootInlineBox* lineGridBox() const { return m_rareData ? m_rareData->m_lineGridBox : 0; }
146    void setLineGridBox(RootInlineBox* box)
147    {
148        RenderBlockFlow::RenderBlockFlowRareData& rareData = ensureRareData();
149        if (rareData.m_lineGridBox)
150            rareData.m_lineGridBox->destroy();
151        rareData.m_lineGridBox = box;
152    }
153    void layoutLineGridBox();
154
155    void addOverflowFromInlineChildren();
156
157    GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
158        LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
159protected:
160    // Only used by RenderSVGText, which explicitly overrides RenderBlock::layoutBlock(), do NOT use for anything else.
161    void forceLayoutInlineChildren()
162    {
163        LayoutUnit repaintLogicalTop = 0;
164        LayoutUnit repaintLogicalBottom = 0;
165        rebuildFloatsFromIntruding();
166        layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom);
167    }
168
169    void createFloatingObjects();
170
171    virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE;
172    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
173
174    void addOverflowFromFloats();
175
176    virtual void insertedIntoTree() OVERRIDE;
177    virtual void willBeDestroyed() OVERRIDE;
178private:
179    void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom, SubtreeLayoutScope&);
180    void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
181
182    void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom);
183    void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
184    void adjustFloatingBlock(const MarginInfo&);
185
186    void rebuildFloatsFromIntruding();
187
188    LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
189
190    LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
191    {
192        if (isHorizontalWritingMode())
193            return child->x() + child->renderer()->marginLeft();
194
195        return child->x() + marginBeforeForChild(child->renderer());
196    }
197
198    LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const
199    {
200        if (isHorizontalWritingMode())
201            return child->y() + marginBeforeForChild(child->renderer());
202
203        return child->y() + child->renderer()->marginTop();
204    }
205
206    LayoutPoint computeLogicalLocationForFloat(const FloatingObject*, LayoutUnit logicalTopOffset) const;
207
208    FloatingObject* insertFloatingObject(RenderBox*);
209    void removeFloatingObject(RenderBox*);
210    void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
211
212    // Called from lineWidth, to position the floats added in the last line.
213    // Returns true if and only if it has positioned any floats.
214    bool positionNewFloats();
215
216    LayoutUnit getClearDelta(RenderBox* child, LayoutUnit yPos);
217
218    bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
219    bool hasOverhangingFloat(RenderBox*);
220    void addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit xoffset, LayoutUnit yoffset);
221    LayoutUnit addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats);
222
223    LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const;
224    LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatMarginBoxOffset) const;
225
226    virtual bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) OVERRIDE FINAL;
227
228    virtual void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert) OVERRIDE;
229    virtual void repaintOverhangingFloats(bool paintAllDescendants) OVERRIDE FINAL;
230    virtual void repaintOverflow() OVERRIDE;
231    virtual void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false) OVERRIDE FINAL;
232    virtual void clipOutFloatingObjects(RenderBlock*, const PaintInfo*, const LayoutPoint&, const LayoutSize&) OVERRIDE;
233    void clearFloats(EClear);
234
235    virtual LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const OVERRIDE;
236    virtual LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const OVERRIDE;
237
238    LayoutUnit logicalRightOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
239    LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
240
241    virtual void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const OVERRIDE; // Helper function for borderFitAdjust
242
243    virtual RootInlineBox* createRootInlineBox() OVERRIDE;
244
245    void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount);
246    virtual bool relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer&);
247public:
248    struct FloatWithRect {
249        FloatWithRect(RenderBox* f)
250            : object(f)
251            , rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight()))
252            , everHadLayout(f->everHadLayout())
253        {
254        }
255
256        RenderBox* object;
257        LayoutRect rect;
258        bool everHadLayout;
259    };
260
261    class MarginValues {
262    public:
263        MarginValues(LayoutUnit beforePos, LayoutUnit beforeNeg, LayoutUnit afterPos, LayoutUnit afterNeg)
264            : m_positiveMarginBefore(beforePos)
265            , m_negativeMarginBefore(beforeNeg)
266            , m_positiveMarginAfter(afterPos)
267            , m_negativeMarginAfter(afterNeg)
268        { }
269
270        LayoutUnit positiveMarginBefore() const { return m_positiveMarginBefore; }
271        LayoutUnit negativeMarginBefore() const { return m_negativeMarginBefore; }
272        LayoutUnit positiveMarginAfter() const { return m_positiveMarginAfter; }
273        LayoutUnit negativeMarginAfter() const { return m_negativeMarginAfter; }
274
275        void setPositiveMarginBefore(LayoutUnit pos) { m_positiveMarginBefore = pos; }
276        void setNegativeMarginBefore(LayoutUnit neg) { m_negativeMarginBefore = neg; }
277        void setPositiveMarginAfter(LayoutUnit pos) { m_positiveMarginAfter = pos; }
278        void setNegativeMarginAfter(LayoutUnit neg) { m_negativeMarginAfter = neg; }
279
280    private:
281        LayoutUnit m_positiveMarginBefore;
282        LayoutUnit m_negativeMarginBefore;
283        LayoutUnit m_positiveMarginAfter;
284        LayoutUnit m_negativeMarginAfter;
285    };
286    MarginValues marginValuesForChild(RenderBox* child) const;
287
288    virtual void updateLogicalHeight() OVERRIDE;
289
290    // Allocated only when some of these fields have non-default values
291    struct RenderBlockFlowRareData {
292        WTF_MAKE_NONCOPYABLE(RenderBlockFlowRareData); WTF_MAKE_FAST_ALLOCATED;
293    public:
294        RenderBlockFlowRareData(const RenderBlockFlow* block)
295            : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
296            , m_lineGridBox(0)
297            , m_discardMarginBefore(false)
298            , m_discardMarginAfter(false)
299            , m_renderNamedFlowFragment(0)
300        {
301        }
302
303        static LayoutUnit positiveMarginBeforeDefault(const RenderBlockFlow* block)
304        {
305            return std::max<LayoutUnit>(block->marginBefore(), 0);
306        }
307        static LayoutUnit negativeMarginBeforeDefault(const RenderBlockFlow* block)
308        {
309            return std::max<LayoutUnit>(-block->marginBefore(), 0);
310        }
311        static LayoutUnit positiveMarginAfterDefault(const RenderBlockFlow* block)
312        {
313            return std::max<LayoutUnit>(block->marginAfter(), 0);
314        }
315        static LayoutUnit negativeMarginAfterDefault(const RenderBlockFlow* block)
316        {
317            return std::max<LayoutUnit>(-block->marginAfter(), 0);
318        }
319
320        MarginValues m_margins;
321
322        RootInlineBox* m_lineGridBox;
323
324        bool m_discardMarginBefore : 1;
325        bool m_discardMarginAfter : 1;
326        RenderNamedFlowFragment* m_renderNamedFlowFragment;
327    };
328    LayoutUnit marginOffsetForSelfCollapsingBlock();
329
330    RenderNamedFlowFragment* renderNamedFlowFragment() const { return m_rareData ? m_rareData->m_renderNamedFlowFragment : 0; }
331    void setRenderNamedFlowFragment(RenderNamedFlowFragment*);
332
333protected:
334    LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockFlowRareData::positiveMarginBeforeDefault(this); }
335    LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockFlowRareData::negativeMarginBeforeDefault(this); }
336    LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockFlowRareData::positiveMarginAfterDefault(this); }
337    LayoutUnit maxNegativeMarginAfter() const { return m_rareData ? m_rareData->m_margins.negativeMarginAfter() : RenderBlockFlowRareData::negativeMarginAfterDefault(this); }
338
339    void setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg);
340    void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
341
342    void setMustDiscardMarginBefore(bool = true);
343    void setMustDiscardMarginAfter(bool = true);
344
345    bool mustDiscardMarginBefore() const;
346    bool mustDiscardMarginAfter() const;
347
348    bool mustDiscardMarginBeforeForChild(const RenderBox*) const;
349    bool mustDiscardMarginAfterForChild(const RenderBox*) const;
350
351    bool mustSeparateMarginBeforeForChild(const RenderBox*) const;
352    bool mustSeparateMarginAfterForChild(const RenderBox*) const;
353
354    void initMaxMarginValues()
355    {
356        if (m_rareData) {
357            m_rareData->m_margins = MarginValues(RenderBlockFlowRareData::positiveMarginBeforeDefault(this) , RenderBlockFlowRareData::negativeMarginBeforeDefault(this),
358                RenderBlockFlowRareData::positiveMarginAfterDefault(this), RenderBlockFlowRareData::negativeMarginAfterDefault(this));
359
360            m_rareData->m_discardMarginBefore = false;
361            m_rareData->m_discardMarginAfter = false;
362        }
363    }
364
365    virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
366private:
367    virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
368    virtual LayoutUnit collapsedMarginAfter() const OVERRIDE FINAL { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
369
370    LayoutUnit collapseMargins(RenderBox* child, MarginInfo&);
371    LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos);
372    LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
373    void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const;
374    void handleAfterSideOfBlock(LayoutUnit top, LayoutUnit bottom, MarginInfo&);
375    void setCollapsedBottomMargin(const MarginInfo&);
376
377    LayoutUnit applyBeforeBreak(RenderBox* child, LayoutUnit logicalOffset); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
378    LayoutUnit applyAfterBreak(RenderBox* child, LayoutUnit logicalOffset, MarginInfo&); // If the child has an after break, then return a new offset that shifts to the top of the next page/column.
379
380    LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock);
381
382    // Used to store state between styleWillChange and styleDidChange
383    static bool s_canPropagateFloatIntoSibling;
384
385    virtual bool canHaveChildren() const OVERRIDE;
386    virtual bool canHaveGeneratedChildren() const OVERRIDE;
387
388    void createRenderNamedFlowFragmentIfNeeded();
389
390    RenderBlockFlowRareData& ensureRareData();
391
392    LayoutUnit m_repaintLogicalTop;
393    LayoutUnit m_repaintLogicalBottom;
394
395protected:
396    OwnPtr<RenderBlockFlowRareData> m_rareData;
397    OwnPtr<FloatingObjects> m_floatingObjects;
398
399    friend class BreakingContext; // FIXME: It uses insertFloatingObject and positionNewFloatOnLine, if we move those out from the private scope/add a helper to LineBreaker, we can remove this friend
400    friend class MarginInfo;
401    friend class LineBreaker;
402    friend class LineWidth; // needs to know FloatingObject
403
404// FIXME-BLOCKFLOW: These methods have implementations in
405// RenderBlockLineLayout. They should be moved to the proper header once the
406// line layout code is separated from RenderBlock and RenderBlockFlow.
407// START METHODS DEFINED IN RenderBlockLineLayout
408private:
409    InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment);
410    RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
411    void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
412    void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
413    BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
414        float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&);
415    void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
416    BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*);
417    void appendFloatingObjectToLastLine(FloatingObject*);
418    // Helper function for layoutInlineChildren()
419    RootInlineBox* createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
420    void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild);
421    const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&,  const InlineIterator&);
422    void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
423    void updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*&, const LayoutSize&, LineLayoutState&);
424    void updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsideInfo*&, LineLayoutState&);
425    bool adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideInfo*, LayoutUnit, LineLayoutState&, InlineBidiResolver&, FloatingObject*, InlineIterator&, WordMeasurements&);
426    void linkToEndLineIfNeeded(LineLayoutState&);
427    static void repaintDirtyFloats(Vector<FloatWithRect>& floats);
428    void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
429    RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&);
430    void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
431    bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
432    bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus);
433    void deleteEllipsisLineBoxes();
434    void checkLinesForTextOverflow();
435    // Positions new floats and also adjust all floats encountered on the line if any of them
436    // have to move to the next page/column.
437    bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
438
439
440// END METHODS DEFINED IN RenderBlockLineLayout
441
442};
443
444DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBlockFlow, isRenderBlockFlow());
445
446} // namespace WebCore
447
448#endif // RenderBlockFlow_h
449