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