Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2007 David Smith (catfish.man (at) 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/line/TrailingObjects.h"
     42 #include "core/rendering/style/RenderStyleConstants.h"
     43 
     44 namespace WebCore {
     45 
     46 class MarginInfo;
     47 class LineBreaker;
     48 class LineWidth;
     49 class RenderMultiColumnFlowThread;
     50 
     51 class RenderBlockFlow : public RenderBlock {
     52 public:
     53     explicit RenderBlockFlow(ContainerNode*);
     54     virtual ~RenderBlockFlow();
     55 
     56     static RenderBlockFlow* createAnonymous(Document*);
     57 
     58     virtual bool isRenderBlockFlow() const OVERRIDE FINAL { return true; }
     59 
     60     virtual void layoutBlock(bool relayoutChildren) OVERRIDE;
     61 
     62     virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false) OVERRIDE;
     63     virtual void deleteLineBoxTree() OVERRIDE FINAL;
     64 
     65     LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
     66     {
     67         return max<LayoutUnit>(0, logicalRightOffsetForLine(position, shouldIndentText, logicalHeight) - logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight));
     68     }
     69     LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
     70     {
     71         return logicalRightOffsetForLine(position, logicalRightOffsetForContent(), shouldIndentText, logicalHeight);
     72     }
     73     LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
     74     {
     75         return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(), shouldIndentText, logicalHeight);
     76     }
     77     LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
     78     {
     79         return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
     80             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
     81     }
     82     LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
     83     {
     84         return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
     85             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
     86     }
     87 
     88     virtual LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) OVERRIDE;
     89     virtual LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) OVERRIDE;
     90 
     91     LayoutUnit computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart);
     92 
     93     RootInlineBox* createAndAppendRootInlineBox();
     94 
     95     void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
     96     void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = 0);
     97 
     98     virtual bool containsFloats() const OVERRIDE FINAL { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
     99     bool containsFloat(RenderBox*) const;
    100 
    101     void removeFloatingObjects();
    102 
    103     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
    104 
    105     void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert);
    106 
    107     bool generatesLineBoxesForInlineChild(RenderObject*);
    108 
    109     LayoutUnit logicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->y() : floatingObject->x(); }
    110     LayoutUnit logicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxY() : floatingObject->maxX(); }
    111     LayoutUnit logicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->x() : floatingObject->y(); }
    112     LayoutUnit logicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxX() : floatingObject->maxY(); }
    113     LayoutUnit logicalWidthForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->width() : floatingObject->height(); }
    114     LayoutUnit logicalHeightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->height() : floatingObject->width(); }
    115     LayoutSize logicalSizeForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? LayoutSize(floatingObject->width(), floatingObject->height()) : LayoutSize(floatingObject->height(), floatingObject->width()); }
    116 
    117     int pixelSnappedLogicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedY() : floatingObject->frameRect().pixelSnappedX(); }
    118     int pixelSnappedLogicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxY() : floatingObject->frameRect().pixelSnappedMaxX(); }
    119     int pixelSnappedLogicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedX() : floatingObject->frameRect().pixelSnappedY(); }
    120     int pixelSnappedLogicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxX() : floatingObject->frameRect().pixelSnappedMaxY(); }
    121 
    122     void setLogicalTopForFloat(FloatingObject* floatingObject, LayoutUnit logicalTop)
    123     {
    124         if (isHorizontalWritingMode())
    125             floatingObject->setY(logicalTop);
    126         else
    127             floatingObject->setX(logicalTop);
    128     }
    129     void setLogicalLeftForFloat(FloatingObject* floatingObject, LayoutUnit logicalLeft)
    130     {
    131         if (isHorizontalWritingMode())
    132             floatingObject->setX(logicalLeft);
    133         else
    134             floatingObject->setY(logicalLeft);
    135     }
    136     void setLogicalHeightForFloat(FloatingObject* floatingObject, LayoutUnit logicalHeight)
    137     {
    138         if (isHorizontalWritingMode())
    139             floatingObject->setHeight(logicalHeight);
    140         else
    141             floatingObject->setWidth(logicalHeight);
    142     }
    143     void setLogicalWidthForFloat(FloatingObject* floatingObject, LayoutUnit logicalWidth)
    144     {
    145         if (isHorizontalWritingMode())
    146             floatingObject->setWidth(logicalWidth);
    147         else
    148             floatingObject->setHeight(logicalWidth);
    149     }
    150 
    151     LayoutUnit startAlignedOffsetForLine(LayoutUnit position, bool shouldIndentText);
    152 
    153     void setStaticInlinePositionForChild(RenderBox*, LayoutUnit blockOffset, LayoutUnit inlinePosition);
    154     void updateStaticInlinePositionForChild(RenderBox*, LayoutUnit logicalTop);
    155 
    156     static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
    157     {
    158         return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline());
    159     }
    160 
    161     // Direction resolved from string value.
    162     static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*,
    163         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
    164     static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*,
    165         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    166 
    167     // Explicit direction.
    168     static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*, TextDirection,
    169         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
    170 
    171     static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, RenderStyle*, TextDirection,
    172         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    173 
    174     static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*, TextDirection,
    175         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    176 
    177     static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, RenderStyle*,
    178         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    179 
    180     static TextRun constructTextRun(RenderObject* context, const Font&, const LChar* characters, int length, RenderStyle*, TextDirection,
    181         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    182 
    183     static TextRun constructTextRun(RenderObject* context, const Font&, const UChar* characters, int length, RenderStyle*, TextDirection,
    184         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    185 
    186     RenderMultiColumnFlowThread* multiColumnFlowThread() const { return m_rareData ? m_rareData->m_multiColumnFlowThread : 0; }
    187     void resetMultiColumnFlowThread()
    188     {
    189         if (m_rareData)
    190             m_rareData->m_multiColumnFlowThread = 0;
    191     }
    192 
    193     void addOverflowFromInlineChildren();
    194 
    195     // FIXME: This should be const to avoid a const_cast, but can modify child dirty bits and RenderCombineText
    196     void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
    197 
    198     GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
    199         LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
    200 protected:
    201     void rebuildFloatsFromIntruding();
    202     void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, LayoutUnit afterEdge);
    203 
    204     void createFloatingObjects();
    205 
    206     virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
    207     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
    208 
    209     void addOverflowFromFloats();
    210 
    211     LayoutUnit logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
    212     {
    213         return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
    214     }
    215     LayoutUnit logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
    216     {
    217         return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
    218     }
    219 
    220     virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/, SubtreeLayoutScope&);
    221     virtual bool updateLogicalWidthAndColumnWidth() OVERRIDE;
    222 
    223     // These functions optionally update LayoutState's layoutDelta, which is used to ensure they're repainted correctly when moved
    224     enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
    225     void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
    226     void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
    227     void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
    228 
    229 private:
    230     bool layoutBlockFlow(bool relayoutChildren, LayoutUnit& pageLogicalHeight, SubtreeLayoutScope&);
    231     void layoutBlockChildren(bool relayoutChildren, SubtreeLayoutScope&, LayoutUnit beforeEdge, LayoutUnit afterEdge);
    232 
    233     void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom);
    234     void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
    235     void adjustFloatingBlock(const MarginInfo&);
    236 
    237     LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
    238 
    239     LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
    240     {
    241         if (isHorizontalWritingMode())
    242             return child->x() + child->renderer()->marginLeft();
    243 
    244         return child->x() + marginBeforeForChild(child->renderer());
    245     }
    246 
    247     LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const
    248     {
    249         if (isHorizontalWritingMode())
    250             return child->y() + marginBeforeForChild(child->renderer());
    251 
    252         return child->y() + child->renderer()->marginTop();
    253     }
    254 
    255     LayoutPoint computeLogicalLocationForFloat(const FloatingObject*, LayoutUnit logicalTopOffset) const;
    256 
    257     FloatingObject* insertFloatingObject(RenderBox*);
    258     void removeFloatingObject(RenderBox*);
    259     void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
    260 
    261     // Called from lineWidth, to position the floats added in the last line.
    262     // Returns true if and only if it has positioned any floats.
    263     bool positionNewFloats();
    264 
    265     LayoutUnit getClearDelta(RenderBox* child, LayoutUnit yPos);
    266 
    267     bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
    268     bool hasOverhangingFloat(RenderBox*);
    269     void addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit xoffset, LayoutUnit yoffset);
    270     void addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats);
    271 
    272     LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const;
    273     LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatMarginBoxOffset) const;
    274 
    275     virtual bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) OVERRIDE FINAL;
    276 
    277     virtual void repaintOverhangingFloats(bool paintAllDescendants) OVERRIDE FINAL;
    278     virtual void invalidatePaintForOverflow() OVERRIDE FINAL;
    279     virtual void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false) OVERRIDE FINAL;
    280     virtual void clipOutFloatingObjects(RenderBlock*, const PaintInfo*, const LayoutPoint&, const LayoutSize&) OVERRIDE;
    281     void clearFloats(EClear);
    282 
    283     LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const;
    284     LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const;
    285 
    286     LayoutUnit logicalRightOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
    287     LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
    288 
    289     LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
    290     LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
    291 
    292     virtual void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const OVERRIDE; // Helper function for borderFitAdjust
    293 
    294     virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG
    295 
    296     void createOrDestroyMultiColumnFlowThreadIfNeeded();
    297 
    298     void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount);
    299     void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
    300     bool shouldRelayoutForPagination(LayoutUnit& pageLogicalHeight, LayoutUnit layoutOverflowLogicalBottom) const;
    301     void setColumnCountAndHeight(unsigned count, LayoutUnit pageLogicalHeight);
    302 
    303 public:
    304     struct FloatWithRect {
    305         FloatWithRect(RenderBox* f)
    306             : object(f)
    307             , rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight()))
    308             , everHadLayout(f->everHadLayout())
    309         {
    310         }
    311 
    312         RenderBox* object;
    313         LayoutRect rect;
    314         bool everHadLayout;
    315     };
    316 
    317     class MarginValues {
    318     public:
    319         MarginValues(LayoutUnit beforePos, LayoutUnit beforeNeg, LayoutUnit afterPos, LayoutUnit afterNeg)
    320             : m_positiveMarginBefore(beforePos)
    321             , m_negativeMarginBefore(beforeNeg)
    322             , m_positiveMarginAfter(afterPos)
    323             , m_negativeMarginAfter(afterNeg)
    324         { }
    325 
    326         LayoutUnit positiveMarginBefore() const { return m_positiveMarginBefore; }
    327         LayoutUnit negativeMarginBefore() const { return m_negativeMarginBefore; }
    328         LayoutUnit positiveMarginAfter() const { return m_positiveMarginAfter; }
    329         LayoutUnit negativeMarginAfter() const { return m_negativeMarginAfter; }
    330 
    331         void setPositiveMarginBefore(LayoutUnit pos) { m_positiveMarginBefore = pos; }
    332         void setNegativeMarginBefore(LayoutUnit neg) { m_negativeMarginBefore = neg; }
    333         void setPositiveMarginAfter(LayoutUnit pos) { m_positiveMarginAfter = pos; }
    334         void setNegativeMarginAfter(LayoutUnit neg) { m_negativeMarginAfter = neg; }
    335 
    336     private:
    337         LayoutUnit m_positiveMarginBefore;
    338         LayoutUnit m_negativeMarginBefore;
    339         LayoutUnit m_positiveMarginAfter;
    340         LayoutUnit m_negativeMarginAfter;
    341     };
    342     MarginValues marginValuesForChild(RenderBox* child) const;
    343 
    344     // Allocated only when some of these fields have non-default values
    345     struct RenderBlockFlowRareData {
    346         WTF_MAKE_NONCOPYABLE(RenderBlockFlowRareData); WTF_MAKE_FAST_ALLOCATED;
    347     public:
    348         RenderBlockFlowRareData(const RenderBlockFlow* block)
    349             : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
    350             , m_multiColumnFlowThread(0)
    351             , m_discardMarginBefore(false)
    352             , m_discardMarginAfter(false)
    353         {
    354         }
    355 
    356         static LayoutUnit positiveMarginBeforeDefault(const RenderBlockFlow* block)
    357         {
    358             return std::max<LayoutUnit>(block->marginBefore(), 0);
    359         }
    360         static LayoutUnit negativeMarginBeforeDefault(const RenderBlockFlow* block)
    361         {
    362             return std::max<LayoutUnit>(-block->marginBefore(), 0);
    363         }
    364         static LayoutUnit positiveMarginAfterDefault(const RenderBlockFlow* block)
    365         {
    366             return std::max<LayoutUnit>(block->marginAfter(), 0);
    367         }
    368         static LayoutUnit negativeMarginAfterDefault(const RenderBlockFlow* block)
    369         {
    370             return std::max<LayoutUnit>(-block->marginAfter(), 0);
    371         }
    372 
    373         MarginValues m_margins;
    374 
    375         RenderMultiColumnFlowThread* m_multiColumnFlowThread;
    376 
    377         bool m_discardMarginBefore : 1;
    378         bool m_discardMarginAfter : 1;
    379     };
    380     LayoutUnit marginOffsetForSelfCollapsingBlock();
    381 
    382 protected:
    383     LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockFlowRareData::positiveMarginBeforeDefault(this); }
    384     LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockFlowRareData::negativeMarginBeforeDefault(this); }
    385     LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockFlowRareData::positiveMarginAfterDefault(this); }
    386     LayoutUnit maxNegativeMarginAfter() const { return m_rareData ? m_rareData->m_margins.negativeMarginAfter() : RenderBlockFlowRareData::negativeMarginAfterDefault(this); }
    387 
    388     void setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg);
    389     void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
    390 
    391     void setMustDiscardMarginBefore(bool = true);
    392     void setMustDiscardMarginAfter(bool = true);
    393 
    394     bool mustDiscardMarginBefore() const;
    395     bool mustDiscardMarginAfter() const;
    396 
    397     bool mustDiscardMarginBeforeForChild(const RenderBox*) const;
    398     bool mustDiscardMarginAfterForChild(const RenderBox*) const;
    399 
    400     bool mustSeparateMarginBeforeForChild(const RenderBox*) const;
    401     bool mustSeparateMarginAfterForChild(const RenderBox*) const;
    402 
    403     void initMaxMarginValues()
    404     {
    405         if (m_rareData) {
    406             m_rareData->m_margins = MarginValues(RenderBlockFlowRareData::positiveMarginBeforeDefault(this) , RenderBlockFlowRareData::negativeMarginBeforeDefault(this),
    407                 RenderBlockFlowRareData::positiveMarginAfterDefault(this), RenderBlockFlowRareData::negativeMarginAfterDefault(this));
    408 
    409             m_rareData->m_discardMarginBefore = false;
    410             m_rareData->m_discardMarginAfter = false;
    411         }
    412     }
    413 
    414     virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
    415 private:
    416     virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
    417     virtual LayoutUnit collapsedMarginAfter() const OVERRIDE FINAL { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
    418 
    419     LayoutUnit collapseMargins(RenderBox* child, MarginInfo&, bool childIsSelfCollapsing);
    420     LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos, bool childIsSelfCollapsing);
    421     LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
    422     void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const;
    423     void handleAfterSideOfBlock(RenderBox* lastChild, LayoutUnit top, LayoutUnit bottom, MarginInfo&);
    424     void setCollapsedBottomMargin(const MarginInfo&);
    425 
    426     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.
    427     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.
    428 
    429     LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock);
    430 
    431     // Used to store state between styleWillChange and styleDidChange
    432     static bool s_canPropagateFloatIntoSibling;
    433 
    434     RenderBlockFlowRareData& ensureRareData();
    435 
    436     LayoutUnit m_repaintLogicalTop;
    437     LayoutUnit m_repaintLogicalBottom;
    438 
    439     virtual bool isSelfCollapsingBlock() const OVERRIDE;
    440 protected:
    441     OwnPtr<RenderBlockFlowRareData> m_rareData;
    442     OwnPtr<FloatingObjects> m_floatingObjects;
    443 
    444     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
    445     friend class MarginInfo;
    446     friend class LineBreaker;
    447     friend class LineWidth; // needs to know FloatingObject
    448 
    449 // FIXME-BLOCKFLOW: These methods have implementations in
    450 // RenderBlockLineLayout. They should be moved to the proper header once the
    451 // line layout code is separated from RenderBlock and RenderBlockFlow.
    452 // START METHODS DEFINED IN RenderBlockLineLayout
    453 private:
    454     InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox);
    455     RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
    456     void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
    457     void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
    458     BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
    459         float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&);
    460     void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
    461     BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*);
    462     void appendFloatingObjectToLastLine(FloatingObject*);
    463     // Helper function for layoutInlineChildren()
    464     RootInlineBox* createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
    465     void layoutRunsAndFloats(LineLayoutState&);
    466     const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&,  const InlineIterator&);
    467     void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
    468     void linkToEndLineIfNeeded(LineLayoutState&);
    469     static void repaintDirtyFloats(Vector<FloatWithRect>& floats);
    470     void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
    471     RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&);
    472     void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
    473     bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
    474     bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus);
    475     void deleteEllipsisLineBoxes();
    476     void checkLinesForTextOverflow();
    477     // Positions new floats and also adjust all floats encountered on the line if any of them
    478     // have to move to the next page/column.
    479     bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
    480 
    481 
    482 // END METHODS DEFINED IN RenderBlockLineLayout
    483 
    484 };
    485 
    486 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBlockFlow, isRenderBlockFlow());
    487 
    488 } // namespace WebCore
    489 
    490 #endif // RenderBlockFlow_h
    491