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, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Library General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Library General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Library General Public License
     18  * along with this library; see the file COPYING.LIB.  If not, write to
     19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     20  * Boston, MA 02110-1301, USA.
     21  */
     22 
     23 #ifndef RenderBlock_h
     24 #define RenderBlock_h
     25 
     26 #include "core/platform/PODIntervalTree.h"
     27 #include "core/platform/graphics/TextRun.h"
     28 #include "core/platform/text/TextBreakIterator.h"
     29 #include "core/rendering/ColumnInfo.h"
     30 #include "core/rendering/GapRects.h"
     31 #include "core/rendering/RenderBox.h"
     32 #include "core/rendering/RenderLineBoxList.h"
     33 #include "core/rendering/RootInlineBox.h"
     34 #include "core/rendering/shapes/ShapeInsideInfo.h"
     35 #include "core/rendering/style/ShapeValue.h"
     36 #include "wtf/ListHashSet.h"
     37 #include "wtf/OwnPtr.h"
     38 
     39 namespace WebCore {
     40 
     41 class BasicShape;
     42 class BidiContext;
     43 class InlineIterator;
     44 class LayoutStateMaintainer;
     45 class LineLayoutState;
     46 class LineWidth;
     47 class RenderInline;
     48 class RenderText;
     49 
     50 struct BidiRun;
     51 struct PaintInfo;
     52 class LineInfo;
     53 class RenderRubyRun;
     54 class TextLayout;
     55 class WordMeasurement;
     56 
     57 template <class Iterator, class Run> class BidiResolver;
     58 template <class Run> class BidiRunList;
     59 template <class Iterator> struct MidpointState;
     60 typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver;
     61 typedef MidpointState<InlineIterator> LineMidpointState;
     62 typedef WTF::ListHashSet<RenderBox*, 16> TrackedRendererListHashSet;
     63 typedef WTF::HashMap<const RenderBlock*, OwnPtr<TrackedRendererListHashSet> > TrackedDescendantsMap;
     64 typedef WTF::HashMap<const RenderBox*, OwnPtr<HashSet<RenderBlock*> > > TrackedContainerMap;
     65 typedef Vector<WordMeasurement, 64> WordMeasurements;
     66 
     67 enum CaretType { CursorCaret, DragCaret };
     68 enum ContainingBlockState { NewContainingBlock, SameContainingBlock };
     69 
     70 enum TextRunFlag {
     71     DefaultTextRunFlags = 0,
     72     RespectDirection = 1 << 0,
     73     RespectDirectionOverride = 1 << 1
     74 };
     75 
     76 typedef unsigned TextRunFlags;
     77 
     78 class RenderBlock : public RenderBox {
     79 public:
     80     friend class LineLayoutState;
     81 #ifndef NDEBUG
     82     // Used by the PODIntervalTree for debugging the FloatingObject.
     83     template <class> friend struct ValueToString;
     84 #endif
     85 
     86     explicit RenderBlock(ContainerNode*);
     87     virtual ~RenderBlock();
     88 
     89     static RenderBlock* createAnonymous(Document*);
     90 
     91     RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
     92     RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
     93 
     94     const RenderObjectChildList* children() const { return &m_children; }
     95     RenderObjectChildList* children() { return &m_children; }
     96 
     97     bool beingDestroyed() const { return m_beingDestroyed; }
     98 
     99     // These two functions are overridden for inline-block.
    100     virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE FINAL;
    101     virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
    102 
    103     RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
    104     const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
    105 
    106     InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); }
    107     InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); }
    108 
    109     void deleteLineBoxTree();
    110 
    111     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
    112     virtual void removeChild(RenderObject*);
    113 
    114     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0);
    115 
    116     void insertPositionedObject(RenderBox*);
    117     static void removePositionedObject(RenderBox*);
    118     void removePositionedObjects(RenderBlock*, ContainingBlockState = SameContainingBlock);
    119 
    120     void removeFloatingObjects();
    121 
    122     TrackedRendererListHashSet* positionedObjects() const;
    123     bool hasPositionedObjects() const
    124     {
    125         TrackedRendererListHashSet* objects = positionedObjects();
    126         return objects && !objects->isEmpty();
    127     }
    128 
    129     void addPercentHeightDescendant(RenderBox*);
    130     static void removePercentHeightDescendant(RenderBox*);
    131     TrackedRendererListHashSet* percentHeightDescendants() const;
    132     static bool hasPercentHeightContainerMap();
    133     static bool hasPercentHeightDescendant(RenderBox*);
    134     static void clearPercentHeightDescendantsFrom(RenderBox*);
    135     static void removePercentHeightDescendantIfNeeded(RenderBox*);
    136 
    137     void setHasMarkupTruncation(bool b) { m_hasMarkupTruncation = b; }
    138     bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }
    139 
    140     void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; }
    141     void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; }
    142 
    143     bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
    144     bool hasMarginAfterQuirk() const { return m_hasMarginAfterQuirk; }
    145 
    146     bool hasMarginBeforeQuirk(const RenderBox* child) const;
    147     bool hasMarginAfterQuirk(const RenderBox* child) const;
    148 
    149     RootInlineBox* createAndAppendRootInlineBox();
    150 
    151     bool generatesLineBoxesForInlineChild(RenderObject*);
    152 
    153     void markShapeInsideDescendantsForLayout();
    154     void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
    155     void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = 0);
    156     void markPositionedObjectsForLayout();
    157     virtual void markForPaginationRelayoutIfNeeded() OVERRIDE FINAL;
    158 
    159     bool containsFloats() const { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
    160     bool containsFloat(RenderBox*) const;
    161 
    162     // Versions that can compute line offsets with the region and page offset passed in. Used for speed to avoid having to
    163     // compute the region all over again when you already know it.
    164     LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const
    165     {
    166         return max<LayoutUnit>(0, logicalRightOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight)
    167             - logicalLeftOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight));
    168     }
    169     LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const
    170     {
    171         return logicalRightOffsetForLine(position, logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage), shouldIndentText, 0, logicalHeight);
    172     }
    173     LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const
    174     {
    175         return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage), shouldIndentText, 0, logicalHeight);
    176     }
    177     LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const
    178     {
    179         return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight)
    180             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight);
    181     }
    182     LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const
    183     {
    184         return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight)
    185             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight);
    186     }
    187 
    188     LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
    189     {
    190         return availableLogicalWidthForLine(position, shouldIndentText, regionAtBlockOffset(position), offsetFromLogicalTopOfFirstPage(), logicalHeight);
    191     }
    192     LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
    193     {
    194         return logicalRightOffsetForLine(position, logicalRightOffsetForContent(position), shouldIndentText, 0, logicalHeight);
    195     }
    196     LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
    197     {
    198         return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(position), shouldIndentText, 0, logicalHeight);
    199     }
    200     LayoutUnit pixelSnappedLogicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
    201     {
    202         return roundToInt(logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight));
    203     }
    204     LayoutUnit pixelSnappedLogicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
    205     {
    206         // FIXME: Multicolumn layouts break carrying over subpixel values to the logical right offset because the lines may be shifted
    207         // by a subpixel value for all but the first column. This can lead to the actual pixel snapped width of the column being off
    208         // by one pixel when rendered versus layed out, which can result in the line being clipped. For now, we have to floor.
    209         // https://bugs.webkit.org/show_bug.cgi?id=105461
    210         return floorToInt(logicalRightOffsetForLine(position, shouldIndentText, logicalHeight));
    211     }
    212     LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
    213     {
    214         return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
    215             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
    216     }
    217     LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
    218     {
    219         return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
    220             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
    221     }
    222 
    223     LayoutUnit startAlignedOffsetForLine(LayoutUnit position, bool shouldIndentText);
    224     LayoutUnit textIndentOffset() const;
    225 
    226     virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
    227 
    228     // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
    229     virtual LayoutUnit availableLogicalWidth() const OVERRIDE FINAL;
    230 
    231     LayoutPoint flipForWritingModeIncludingColumns(const LayoutPoint&) const;
    232     void adjustStartEdgeForWritingModeIncludingColumns(LayoutRect&) const;
    233 
    234     RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); }
    235     RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
    236 
    237     GapRects selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer);
    238     LayoutRect logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
    239                                        RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo*);
    240     LayoutRect logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
    241                                         RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo*);
    242     void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
    243     RenderBlock* blockBeforeWithinSelectionRoot(LayoutSize& offset) const;
    244 
    245     LayoutRect logicalRectToPhysicalRect(const LayoutPoint& physicalPosition, const LayoutRect& logicalRect);
    246 
    247     // Helper methods for computing line counts and heights for line counts.
    248     RootInlineBox* lineAtIndex(int) const;
    249     int lineCount(const RootInlineBox* = 0, bool* = 0) const;
    250     int heightForLineCount(int);
    251     void clearTruncation();
    252 
    253     void adjustRectForColumns(LayoutRect&) const;
    254     virtual void adjustForColumns(LayoutSize&, const LayoutPoint&) const OVERRIDE FINAL;
    255     void adjustForColumnRect(LayoutSize& offset, const LayoutPoint& locationInContainer) const;
    256 
    257     void addContinuationWithOutline(RenderInline*);
    258     bool paintsContinuationOutline(RenderInline*);
    259 
    260     virtual RenderBoxModelObject* virtualContinuation() const OVERRIDE FINAL { return continuation(); }
    261     bool isAnonymousBlockContinuation() const { return continuation() && isAnonymousBlock(); }
    262     RenderInline* inlineElementContinuation() const;
    263     RenderBlock* blockElementContinuation() const;
    264 
    265     using RenderBoxModelObject::continuation;
    266     using RenderBoxModelObject::setContinuation;
    267 
    268     static RenderBlock* createAnonymousWithParentRendererAndDisplay(const RenderObject*, EDisplay = BLOCK);
    269     static RenderBlock* createAnonymousColumnsWithParentRenderer(const RenderObject*);
    270     static RenderBlock* createAnonymousColumnSpanWithParentRenderer(const RenderObject*);
    271     RenderBlock* createAnonymousBlock(EDisplay display = BLOCK) const { return createAnonymousWithParentRendererAndDisplay(this, display); }
    272     RenderBlock* createAnonymousColumnsBlock() const { return createAnonymousColumnsWithParentRenderer(this); }
    273     RenderBlock* createAnonymousColumnSpanBlock() const { return createAnonymousColumnSpanWithParentRenderer(this); }
    274 
    275     virtual RenderBox* createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const OVERRIDE;
    276 
    277     static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
    278     {
    279         return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline());
    280     }
    281 
    282     static void appendRunsForObject(BidiRunList<BidiRun>&, int start, int end, RenderObject*, InlineBidiResolver&);
    283 
    284     static TextRun constructTextRun(RenderObject* context, const Font& font, const String& string, RenderStyle* style,
    285         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
    286 
    287     static TextRun constructTextRun(RenderObject* context, const Font& font, const RenderText* text, RenderStyle* style,
    288         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    289 
    290     static TextRun constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, unsigned length, RenderStyle* style,
    291         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    292 
    293     static TextRun constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, RenderStyle* style,
    294         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    295 
    296     static TextRun constructTextRun(RenderObject* context, const Font& font, const LChar* characters, int length, RenderStyle* style,
    297         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    298 
    299     static TextRun constructTextRun(RenderObject* context, const Font& font, const UChar* characters, int length, RenderStyle* style,
    300         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
    301 
    302     ColumnInfo* columnInfo() const;
    303     int columnGap() const;
    304 
    305     void updateColumnInfoFromStyle(RenderStyle*);
    306 
    307     // These two functions take the ColumnInfo* to avoid repeated lookups of the info in the global HashMap.
    308     unsigned columnCount(ColumnInfo*) const;
    309     LayoutRect columnRectAt(ColumnInfo*, unsigned) const;
    310 
    311     LayoutUnit paginationStrut() const { return m_rareData ? m_rareData->m_paginationStrut : LayoutUnit(); }
    312     void setPaginationStrut(LayoutUnit);
    313 
    314     bool shouldBreakAtLineToAvoidWidow() const { return m_rareData && m_rareData->m_shouldBreakAtLineToAvoidWidow; }
    315     void clearShouldBreakAtLineToAvoidWidow() const;
    316     RootInlineBox* lineBreakToAvoidWidow() const { return m_rareData ? m_rareData->m_lineBreakToAvoidWidow : 0; }
    317     void setBreakAtLineToAvoidWidow(RootInlineBox*);
    318 
    319     // The page logical offset is the object's offset from the top of the page in the page progression
    320     // direction (so an x-offset in vertical text and a y-offset for horizontal text).
    321     LayoutUnit pageLogicalOffset() const { return m_rareData ? m_rareData->m_pageLogicalOffset : LayoutUnit(); }
    322     void setPageLogicalOffset(LayoutUnit);
    323 
    324     RootInlineBox* lineGridBox() const { return m_rareData ? m_rareData->m_lineGridBox : 0; }
    325     void setLineGridBox(RootInlineBox* box)
    326     {
    327         if (!m_rareData)
    328             m_rareData = adoptPtr(new RenderBlockRareData(this));
    329         if (m_rareData->m_lineGridBox)
    330             m_rareData->m_lineGridBox->destroy();
    331         m_rareData->m_lineGridBox = box;
    332     }
    333     void layoutLineGridBox();
    334 
    335     // Accessors for logical width/height and margins in the containing block's block-flow direction.
    336     enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
    337     LayoutUnit logicalWidthForChild(const RenderBox* child) { return isHorizontalWritingMode() ? child->width() : child->height(); }
    338     LayoutUnit logicalHeightForChild(const RenderBox* child) { return isHorizontalWritingMode() ? child->height() : child->width(); }
    339     LayoutUnit logicalTopForChild(const RenderBox* child) { return isHorizontalWritingMode() ? child->y() : child->x(); }
    340     void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
    341     void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
    342     LayoutUnit marginBeforeForChild(const RenderBoxModelObject* child) const { return child->marginBefore(style()); }
    343     LayoutUnit marginAfterForChild(const RenderBoxModelObject* child) const { return child->marginAfter(style()); }
    344     LayoutUnit marginStartForChild(const RenderBoxModelObject* child) const { return child->marginStart(style()); }
    345     LayoutUnit marginEndForChild(const RenderBoxModelObject* child) const { return child->marginEnd(style()); }
    346     void setMarginStartForChild(RenderBox* child, LayoutUnit value) const { child->setMarginStart(value, style()); }
    347     void setMarginEndForChild(RenderBox* child, LayoutUnit value) const { child->setMarginEnd(value, style()); }
    348     void setMarginBeforeForChild(RenderBox* child, LayoutUnit value) const { child->setMarginBefore(value, style()); }
    349     void setMarginAfterForChild(RenderBox* child, LayoutUnit value) const { child->setMarginAfter(value, style()); }
    350     LayoutUnit collapsedMarginBeforeForChild(const RenderBox* child) const;
    351     LayoutUnit collapsedMarginAfterForChild(const RenderBox* child) const;
    352 
    353     void updateLogicalWidthForAlignment(const ETextAlign&, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount);
    354 
    355     virtual void updateFirstLetter();
    356 
    357     class MarginValues {
    358     public:
    359         MarginValues(LayoutUnit beforePos, LayoutUnit beforeNeg, LayoutUnit afterPos, LayoutUnit afterNeg)
    360             : m_positiveMarginBefore(beforePos)
    361             , m_negativeMarginBefore(beforeNeg)
    362             , m_positiveMarginAfter(afterPos)
    363             , m_negativeMarginAfter(afterNeg)
    364         { }
    365 
    366         LayoutUnit positiveMarginBefore() const { return m_positiveMarginBefore; }
    367         LayoutUnit negativeMarginBefore() const { return m_negativeMarginBefore; }
    368         LayoutUnit positiveMarginAfter() const { return m_positiveMarginAfter; }
    369         LayoutUnit negativeMarginAfter() const { return m_negativeMarginAfter; }
    370 
    371         void setPositiveMarginBefore(LayoutUnit pos) { m_positiveMarginBefore = pos; }
    372         void setNegativeMarginBefore(LayoutUnit neg) { m_negativeMarginBefore = neg; }
    373         void setPositiveMarginAfter(LayoutUnit pos) { m_positiveMarginAfter = pos; }
    374         void setNegativeMarginAfter(LayoutUnit neg) { m_negativeMarginAfter = neg; }
    375 
    376     private:
    377         LayoutUnit m_positiveMarginBefore;
    378         LayoutUnit m_negativeMarginBefore;
    379         LayoutUnit m_positiveMarginAfter;
    380         LayoutUnit m_negativeMarginAfter;
    381     };
    382     MarginValues marginValuesForChild(RenderBox* child) const;
    383 
    384     virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { };
    385 
    386     LayoutUnit logicalLeftOffsetForContent(RenderRegion*, LayoutUnit offsetFromLogicalTopOfFirstPage) const;
    387     LayoutUnit logicalRightOffsetForContent(RenderRegion*, LayoutUnit offsetFromLogicalTopOfFirstPage) const;
    388     LayoutUnit availableLogicalWidthForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
    389     {
    390         return max<LayoutUnit>(0, logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage) -
    391             logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage)); }
    392     LayoutUnit startOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
    393     {
    394         return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage)
    395             : logicalWidth() - logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage);
    396     }
    397     LayoutUnit endOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
    398     {
    399         return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage)
    400             : logicalWidth() - logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage);
    401     }
    402     LayoutUnit logicalLeftOffsetForContent(LayoutUnit blockOffset) const
    403     {
    404         return logicalLeftOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
    405     }
    406     LayoutUnit logicalRightOffsetForContent(LayoutUnit blockOffset) const
    407     {
    408         return logicalRightOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
    409     }
    410     LayoutUnit availableLogicalWidthForContent(LayoutUnit blockOffset) const
    411     {
    412         return availableLogicalWidthForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
    413     }
    414     LayoutUnit startOffsetForContent(LayoutUnit blockOffset) const
    415     {
    416         return startOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
    417     }
    418     LayoutUnit endOffsetForContent(LayoutUnit blockOffset) const
    419     {
    420         return endOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
    421     }
    422     LayoutUnit logicalLeftOffsetForContent() const { return isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
    423     LayoutUnit logicalRightOffsetForContent() const { return logicalLeftOffsetForContent() + availableLogicalWidth(); }
    424     LayoutUnit startOffsetForContent() const { return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
    425     LayoutUnit endOffsetForContent() const { return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
    426 
    427     void setStaticInlinePositionForChild(RenderBox*, LayoutUnit blockOffset, LayoutUnit inlinePosition);
    428     void updateStaticInlinePositionForChild(RenderBox*, LayoutUnit logicalTop);
    429 
    430     LayoutUnit computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart, RenderRegion* = 0, LayoutUnit offsetFromLogicalTopOfFirstPage = 0);
    431 
    432     void placeRunInIfNeeded(RenderObject* newChild);
    433     bool runInIsPlacedIntoSiblingBlock(RenderObject* runIn);
    434 
    435 #ifndef NDEBUG
    436     void checkPositionedObjectsNeedLayout();
    437     void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0) const;
    438 #endif
    439 
    440     ShapeInsideInfo* ensureShapeInsideInfo()
    441     {
    442         if (!m_rareData || !m_rareData->m_shapeInsideInfo)
    443             setShapeInsideInfo(ShapeInsideInfo::createInfo(this));
    444         return m_rareData->m_shapeInsideInfo.get();
    445     }
    446     ShapeInsideInfo* shapeInsideInfo() const
    447     {
    448         return m_rareData && m_rareData->m_shapeInsideInfo && ShapeInsideInfo::isEnabledFor(this) ? m_rareData->m_shapeInsideInfo.get() : 0;
    449     }
    450     void setShapeInsideInfo(PassOwnPtr<ShapeInsideInfo> value)
    451     {
    452         if (!m_rareData)
    453             m_rareData = adoptPtr(new RenderBlockRareData(this));
    454         m_rareData->m_shapeInsideInfo = value;
    455     }
    456     ShapeInsideInfo* layoutShapeInsideInfo() const;
    457     bool allowsShapeInsideInfoSharing() const { return !isInline() && !isFloating(); }
    458 
    459 protected:
    460     virtual void willBeDestroyed();
    461 
    462     LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockRareData::positiveMarginBeforeDefault(this); }
    463     LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockRareData::negativeMarginBeforeDefault(this); }
    464     LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockRareData::positiveMarginAfterDefault(this); }
    465     LayoutUnit maxNegativeMarginAfter() const { return m_rareData ? m_rareData->m_margins.negativeMarginAfter() : RenderBlockRareData::negativeMarginAfterDefault(this); }
    466 
    467     void setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg);
    468     void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
    469 
    470     void setMustDiscardMarginBefore(bool = true);
    471     void setMustDiscardMarginAfter(bool = true);
    472 
    473     bool mustDiscardMarginBefore() const;
    474     bool mustDiscardMarginAfter() const;
    475 
    476     bool mustDiscardMarginBeforeForChild(const RenderBox*) const;
    477     bool mustDiscardMarginAfterForChild(const RenderBox*) const;
    478 
    479     bool mustSeparateMarginBeforeForChild(const RenderBox*) const;
    480     bool mustSeparateMarginAfterForChild(const RenderBox*) const;
    481 
    482     void initMaxMarginValues()
    483     {
    484         if (m_rareData) {
    485             m_rareData->m_margins = MarginValues(RenderBlockRareData::positiveMarginBeforeDefault(this) , RenderBlockRareData::negativeMarginBeforeDefault(this),
    486                                                  RenderBlockRareData::positiveMarginAfterDefault(this), RenderBlockRareData::negativeMarginAfterDefault(this));
    487             m_rareData->m_paginationStrut = 0;
    488 
    489             m_rareData->m_discardMarginBefore = false;
    490             m_rareData->m_discardMarginAfter = false;
    491         }
    492     }
    493 
    494     virtual void layout();
    495 
    496     void layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly = false);
    497     void markFixedPositionObjectForLayoutIfNeeded(RenderObject* child);
    498 
    499     virtual void paint(PaintInfo&, const LayoutPoint&);
    500     virtual void paintObject(PaintInfo&, const LayoutPoint&);
    501     virtual void paintChildren(PaintInfo&, const LayoutPoint&);
    502     void paintChild(RenderBox*, PaintInfo&, const LayoutPoint&);
    503 
    504     LayoutUnit logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining = 0, LayoutUnit logicalHeight = 0) const
    505     {
    506         return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, heightRemaining, logicalHeight, ShapeOutsideFloatShapeOffset), applyTextIndent);
    507     }
    508     LayoutUnit logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining = 0, LayoutUnit logicalHeight = 0) const
    509     {
    510         return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, heightRemaining, logicalHeight, ShapeOutsideFloatShapeOffset), applyTextIndent);
    511     }
    512     LayoutUnit logicalRightOffsetForLineIgnoringShapeOutside(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining = 0, LayoutUnit logicalHeight = 0) const
    513     {
    514         return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, heightRemaining, logicalHeight, ShapeOutsideFloatMarginBoxOffset), applyTextIndent);
    515     }
    516     LayoutUnit logicalLeftOffsetForLineIgnoringShapeOutside(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining = 0, LayoutUnit logicalHeight = 0) const
    517     {
    518         return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, heightRemaining, logicalHeight, ShapeOutsideFloatMarginBoxOffset), applyTextIndent);
    519     }
    520 
    521     virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
    522     virtual void adjustInlineDirectionLineBounds(int /* expansionOpportunityCount */, float& /* logicalLeft */, float& /* logicalWidth */) const { }
    523 
    524     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
    525 
    526     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
    527     virtual void computePreferredLogicalWidths() OVERRIDE;
    528 
    529     virtual int firstLineBoxBaseline() const;
    530     virtual int inlineBlockBaseline(LineDirectionMode) const OVERRIDE;
    531     int lastLineBoxBaseline(LineDirectionMode) const;
    532 
    533     virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&);
    534 
    535     // Delay update scrollbar until finishDelayRepaint() will be
    536     // called. This function is used when a flexbox is laying out its
    537     // descendant. If multiple calls are made to startDelayRepaint(),
    538     // finishDelayRepaint() will do nothing until finishDelayRepaint()
    539     // is called the same number of times.
    540     static void startDelayUpdateScrollInfo();
    541     static void finishDelayUpdateScrollInfo();
    542 
    543     void updateScrollInfoAfterLayout();
    544 
    545     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
    546     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    547 
    548     virtual bool hasLineIfEmpty() const;
    549 
    550     bool simplifiedLayout();
    551     virtual void simplifiedNormalFlowLayout();
    552 
    553     void setDesiredColumnCountAndWidth(int, LayoutUnit);
    554 
    555 public:
    556     void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false);
    557 protected:
    558     virtual void addOverflowFromChildren();
    559     void addOverflowFromFloats();
    560     void addOverflowFromPositionedObjects();
    561     void addOverflowFromBlockChildren();
    562     void addOverflowFromInlineChildren();
    563     void addVisualOverflowFromTheme();
    564 
    565     virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
    566 
    567     virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const OVERRIDE;
    568 
    569     // Only used by RenderSVGText, which explicitly overrides RenderBlock::layoutBlock(), do NOT use for anything else.
    570     void forceLayoutInlineChildren()
    571     {
    572         LayoutUnit repaintLogicalTop = 0;
    573         LayoutUnit repaintLogicalBottom = 0;
    574         clearFloats();
    575         layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom);
    576     }
    577 
    578     bool updateRegionsAndShapesLogicalSize(RenderFlowThread*);
    579     void computeRegionRangeForBlock(RenderFlowThread*);
    580 
    581     void updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox*);
    582 
    583     virtual void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
    584 
    585 private:
    586     enum ShapeOutsideFloatOffsetMode { ShapeOutsideFloatShapeOffset, ShapeOutsideFloatMarginBoxOffset };
    587 
    588     LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode) const;
    589     LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode) const;
    590     LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
    591     LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
    592 
    593     void computeShapeSize();
    594     void updateRegionsAndShapesAfterChildLayout(RenderFlowThread*, bool);
    595     void updateShapeInsideInfoAfterStyleChange(const ShapeValue*, const ShapeValue* oldShape);
    596 
    597     virtual RenderObjectChildList* virtualChildren() OVERRIDE FINAL { return children(); }
    598     virtual const RenderObjectChildList* virtualChildren() const OVERRIDE FINAL { return children(); }
    599 
    600     virtual const char* renderName() const;
    601 
    602     virtual bool isRenderBlock() const OVERRIDE FINAL { return true; }
    603     virtual bool isBlockFlow() const OVERRIDE FINAL { return (!isInline() || isReplaced()) && !isTable(); }
    604     virtual bool isInlineBlockOrInlineTable() const OVERRIDE FINAL { return isInline() && isReplaced(); }
    605 
    606     void makeChildrenNonInline(RenderObject* insertionPoint = 0);
    607     virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
    608 
    609     static void collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock* child);
    610     void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert);
    611 
    612     virtual void dirtyLinesFromChangedChild(RenderObject* child) OVERRIDE FINAL { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
    613 
    614     void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
    615     void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild);
    616     void addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild);
    617 
    618     void addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild = 0);
    619 
    620     virtual bool isSelfCollapsingBlock() const OVERRIDE FINAL;
    621 
    622     virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
    623     virtual LayoutUnit collapsedMarginAfter() const OVERRIDE FINAL { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
    624 
    625     virtual void repaintOverhangingFloats(bool paintAllDescendants) OVERRIDE FINAL;
    626 
    627     void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom);
    628     void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
    629     BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*);
    630 
    631     void insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
    632     static void removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
    633 
    634     virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby.
    635 
    636     // Called to lay out the legend for a fieldset or the ruby text of a ruby run.
    637     virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/) { return 0; }
    638 
    639     void createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild);
    640     void updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer);
    641 
    642     Node* nodeForHitTest() const;
    643 
    644     struct FloatWithRect {
    645         FloatWithRect(RenderBox* f)
    646             : object(f)
    647             , rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight()))
    648             , everHadLayout(f->everHadLayout())
    649         {
    650         }
    651 
    652         RenderBox* object;
    653         LayoutRect rect;
    654         bool everHadLayout;
    655     };
    656 
    657     struct FloatingObject {
    658         WTF_MAKE_NONCOPYABLE(FloatingObject); WTF_MAKE_FAST_ALLOCATED;
    659     public:
    660         // Note that Type uses bits so you can use FloatLeftRight as a mask to query for both left and right.
    661         enum Type { FloatLeft = 1, FloatRight = 2, FloatLeftRight = 3 };
    662 
    663         FloatingObject(EFloat type)
    664             : m_renderer(0)
    665             , m_originatingLine(0)
    666             , m_paginationStrut(0)
    667             , m_shouldPaint(true)
    668             , m_isDescendant(false)
    669             , m_isPlaced(false)
    670 #ifndef NDEBUG
    671             , m_isInPlacedTree(false)
    672 #endif
    673         {
    674             ASSERT(type != NoFloat);
    675             if (type == LeftFloat)
    676                 m_type = FloatLeft;
    677             else if (type == RightFloat)
    678                 m_type = FloatRight;
    679         }
    680 
    681         FloatingObject(Type type, const LayoutRect& frameRect)
    682             : m_renderer(0)
    683             , m_originatingLine(0)
    684             , m_frameRect(frameRect)
    685             , m_paginationStrut(0)
    686             , m_type(type)
    687             , m_shouldPaint(true)
    688             , m_isDescendant(false)
    689             , m_isPlaced(true)
    690 #ifndef NDEBUG
    691             , m_isInPlacedTree(false)
    692 #endif
    693         {
    694         }
    695 
    696         FloatingObject* clone() const
    697         {
    698             FloatingObject* cloneObject = new FloatingObject(type(), m_frameRect);
    699             cloneObject->m_renderer = m_renderer;
    700             cloneObject->m_originatingLine = m_originatingLine;
    701             cloneObject->m_paginationStrut = m_paginationStrut;
    702             cloneObject->m_shouldPaint = m_shouldPaint;
    703             cloneObject->m_isDescendant = m_isDescendant;
    704             cloneObject->m_isPlaced = m_isPlaced;
    705             return cloneObject;
    706         }
    707 
    708         Type type() const { return static_cast<Type>(m_type); }
    709         RenderBox* renderer() const { return m_renderer; }
    710 
    711         bool isPlaced() const { return m_isPlaced; }
    712         void setIsPlaced(bool placed = true) { m_isPlaced = placed; }
    713 
    714         inline LayoutUnit x() const { ASSERT(isPlaced()); return m_frameRect.x(); }
    715         inline LayoutUnit maxX() const { ASSERT(isPlaced()); return m_frameRect.maxX(); }
    716         inline LayoutUnit y() const { ASSERT(isPlaced()); return m_frameRect.y(); }
    717         inline LayoutUnit maxY() const { ASSERT(isPlaced()); return m_frameRect.maxY(); }
    718         inline LayoutUnit width() const { return m_frameRect.width(); }
    719         inline LayoutUnit height() const { return m_frameRect.height(); }
    720 
    721         void setX(LayoutUnit x) { ASSERT(!isInPlacedTree()); m_frameRect.setX(x); }
    722         void setY(LayoutUnit y) { ASSERT(!isInPlacedTree()); m_frameRect.setY(y); }
    723         void setWidth(LayoutUnit width) { ASSERT(!isInPlacedTree()); m_frameRect.setWidth(width); }
    724         void setHeight(LayoutUnit height) { ASSERT(!isInPlacedTree()); m_frameRect.setHeight(height); }
    725 
    726         const LayoutRect& frameRect() const { ASSERT(isPlaced()); return m_frameRect; }
    727         void setFrameRect(const LayoutRect& frameRect) { ASSERT(!isInPlacedTree()); m_frameRect = frameRect; }
    728 
    729 #ifndef NDEBUG
    730         bool isInPlacedTree() const { return m_isInPlacedTree; }
    731         void setIsInPlacedTree(bool value) { m_isInPlacedTree = value; }
    732 #endif
    733 
    734         bool shouldPaint() const { return m_shouldPaint; }
    735         void setShouldPaint(bool shouldPaint) { m_shouldPaint = shouldPaint; }
    736         bool isDescendant() const { return m_isDescendant; }
    737         void setIsDescendant(bool isDescendant) { m_isDescendant = isDescendant; }
    738 
    739         RenderBox* m_renderer;
    740         RootInlineBox* m_originatingLine;
    741         LayoutRect m_frameRect;
    742         int m_paginationStrut;
    743 
    744     private:
    745         unsigned m_type : 2; // Type (left or right aligned)
    746         unsigned m_shouldPaint : 1;
    747         unsigned m_isDescendant : 1;
    748         unsigned m_isPlaced : 1;
    749 #ifndef NDEBUG
    750         unsigned m_isInPlacedTree : 1;
    751 #endif
    752     };
    753 
    754     LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
    755 
    756     LayoutUnit logicalTopForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->y() : child->x(); }
    757     LayoutUnit logicalBottomForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->maxY() : child->maxX(); }
    758     LayoutUnit logicalLeftForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->x() : child->y(); }
    759     LayoutUnit logicalRightForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->maxX() : child->maxY(); }
    760     LayoutUnit logicalWidthForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->width() : child->height(); }
    761 
    762     int pixelSnappedLogicalTopForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedY() : child->frameRect().pixelSnappedX(); }
    763     int pixelSnappedLogicalBottomForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedMaxY() : child->frameRect().pixelSnappedMaxX(); }
    764     int pixelSnappedLogicalLeftForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedX() : child->frameRect().pixelSnappedY(); }
    765     int pixelSnappedLogicalRightForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedMaxX() : child->frameRect().pixelSnappedMaxY(); }
    766 
    767     void setLogicalTopForFloat(FloatingObject* child, LayoutUnit logicalTop)
    768     {
    769         if (isHorizontalWritingMode())
    770             child->setY(logicalTop);
    771         else
    772             child->setX(logicalTop);
    773     }
    774     void setLogicalLeftForFloat(FloatingObject* child, LayoutUnit logicalLeft)
    775     {
    776         if (isHorizontalWritingMode())
    777             child->setX(logicalLeft);
    778         else
    779             child->setY(logicalLeft);
    780     }
    781     void setLogicalHeightForFloat(FloatingObject* child, LayoutUnit logicalHeight)
    782     {
    783         if (isHorizontalWritingMode())
    784             child->setHeight(logicalHeight);
    785         else
    786             child->setWidth(logicalHeight);
    787     }
    788     void setLogicalWidthForFloat(FloatingObject* child, LayoutUnit logicalWidth)
    789     {
    790         if (isHorizontalWritingMode())
    791             child->setWidth(logicalWidth);
    792         else
    793             child->setHeight(logicalWidth);
    794     }
    795 
    796     LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
    797     {
    798         if (isHorizontalWritingMode())
    799             return child->x() + child->renderer()->marginLeft();
    800         else
    801             return child->x() + marginBeforeForChild(child->renderer());
    802     }
    803 
    804     LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const
    805     {
    806         if (isHorizontalWritingMode())
    807             return child->y() + marginBeforeForChild(child->renderer());
    808         else
    809             return child->y() + child->renderer()->marginTop();
    810     }
    811 
    812     LayoutPoint computeLogicalLocationForFloat(const FloatingObject*, LayoutUnit logicalTopOffset) const;
    813 
    814     // The following functions' implementations are in RenderBlockLineLayout.cpp.
    815     struct RenderTextInfo {
    816         // Destruction of m_layout requires TextLayout to be a complete type, so the constructor and destructor are made non-inline to avoid compilation errors.
    817         RenderTextInfo();
    818         ~RenderTextInfo();
    819 
    820         RenderText* m_text;
    821         OwnPtr<TextLayout> m_layout;
    822         LazyLineBreakIterator m_lineBreakIterator;
    823         const Font* m_font;
    824     };
    825 
    826     class LineBreaker {
    827     public:
    828         LineBreaker(RenderBlock* block)
    829             : m_block(block)
    830         {
    831             reset();
    832         }
    833 
    834         InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
    835 
    836         bool lineWasHyphenated() { return m_hyphenated; }
    837         const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; }
    838         EClear clear() { return m_clear; }
    839     private:
    840         void reset();
    841 
    842         InlineIterator nextSegmentBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
    843         void skipTrailingWhitespace(InlineIterator&, const LineInfo&);
    844         void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
    845 
    846         RenderBlock* m_block;
    847         bool m_hyphenated;
    848         EClear m_clear;
    849         Vector<RenderBox*> m_positionedObjects;
    850     };
    851 
    852     void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
    853     RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&);
    854     void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
    855     bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus);
    856     bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
    857 
    858     RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
    859     InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment);
    860 
    861     void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
    862 
    863     BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
    864         float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&);
    865     void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
    866     void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
    867     void deleteEllipsisLineBoxes();
    868     void checkLinesForTextOverflow();
    869 
    870     // Positions new floats and also adjust all floats encountered on the line if any of them
    871     // have to move to the next page/column.
    872     bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
    873     void appendFloatingObjectToLastLine(FloatingObject*);
    874 
    875     // End of functions defined in RenderBlockLineLayout.cpp.
    876 
    877     void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false);
    878     void paintContents(PaintInfo&, const LayoutPoint&);
    879     void paintColumnContents(PaintInfo&, const LayoutPoint&, bool paintFloats = false);
    880     void paintColumnRules(PaintInfo&, const LayoutPoint&);
    881     void paintSelection(PaintInfo&, const LayoutPoint&);
    882     void paintCaret(PaintInfo&, const LayoutPoint&, CaretType);
    883 
    884     bool hasCaret() const { return hasCaret(CursorCaret) || hasCaret(DragCaret); }
    885     bool hasCaret(CaretType) const;
    886 
    887     FloatingObject* insertFloatingObject(RenderBox*);
    888     void removeFloatingObject(RenderBox*);
    889     void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
    890 
    891     // Called from lineWidth, to position the floats added in the last line.
    892     // Returns true if and only if it has positioned any floats.
    893     bool positionNewFloats();
    894 
    895     void clearFloats();
    896 
    897     LayoutUnit getClearDelta(RenderBox* child, LayoutUnit yPos);
    898 
    899     virtual bool avoidsFloats() const;
    900 
    901     bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
    902     bool hasOverhangingFloat(RenderBox*);
    903     void addIntrudingFloats(RenderBlock* prev, LayoutUnit xoffset, LayoutUnit yoffset);
    904     LayoutUnit addOverhangingFloats(RenderBlock* child, bool makeChildPaintOtherFloats);
    905 
    906     LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const;
    907     LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit) const;
    908 
    909     bool hitTestColumns(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
    910     bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
    911     bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset);
    912 
    913     virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset);
    914 
    915     // FIXME: Make this method const so we can remove the const_cast in computeIntrinsicLogicalWidths.
    916     void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
    917     void computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
    918 
    919     // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
    920     // children.
    921     virtual RenderBlock* firstLineBlock() const;
    922 
    923     virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const OVERRIDE FINAL;
    924     virtual RenderStyle* outlineStyleForRepaint() const OVERRIDE FINAL;
    925 
    926     virtual RenderObject* hoverAncestor() const OVERRIDE FINAL;
    927     virtual void updateDragState(bool dragOn) OVERRIDE FINAL;
    928     virtual void childBecameNonInline(RenderObject* child) OVERRIDE FINAL;
    929 
    930     virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool /*clipToVisibleContent*/) OVERRIDE FINAL
    931     {
    932         return selectionGapRectsForRepaint(repaintContainer);
    933     }
    934     virtual bool shouldPaintSelectionGaps() const OVERRIDE FINAL;
    935     bool isSelectionRoot() const;
    936     GapRects selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
    937                            LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* = 0);
    938     GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
    939                                  LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
    940     GapRects blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
    941                                 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
    942     LayoutRect blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
    943                                  LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo*);
    944     LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
    945     LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
    946 
    947     virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
    948     virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
    949 
    950     LayoutUnit desiredColumnWidth() const;
    951     unsigned desiredColumnCount() const;
    952 
    953     void paintContinuationOutlines(PaintInfo&, const LayoutPoint&);
    954 
    955     virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) OVERRIDE FINAL;
    956 
    957     void adjustPointToColumnContents(LayoutPoint&) const;
    958 
    959     void fitBorderToLinesIfNeeded(); // Shrink the box in which the border paints if border-fit is set.
    960     void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const; // Helper function for borderFitAdjust
    961 
    962     void markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest = 0);
    963 
    964     void newLine(EClear);
    965 
    966     Position positionForBox(InlineBox*, bool start = true) const;
    967     PositionWithAffinity positionForPointWithInlineChildren(const LayoutPoint&);
    968 
    969     virtual void calcColumnWidth();
    970     void makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild);
    971 
    972     bool expandsToEncloseOverhangingFloats() const;
    973 
    974     void splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
    975                      RenderObject* beforeChild, RenderBoxModelObject* oldCont);
    976     void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
    977                    RenderObject* newChild, RenderBoxModelObject* oldCont);
    978     RenderBlock* clone() const;
    979     RenderBlock* continuationBefore(RenderObject* beforeChild);
    980     RenderBlock* containingColumnsBlock(bool allowAnonymousColumnBlock = true);
    981     RenderBlock* columnsBlockForSpanningElement(RenderObject* newChild);
    982 
    983     class MarginInfo {
    984         // Collapsing flags for whether we can collapse our margins with our children's margins.
    985         bool m_canCollapseWithChildren : 1;
    986         bool m_canCollapseMarginBeforeWithChildren : 1;
    987         bool m_canCollapseMarginAfterWithChildren : 1;
    988 
    989         // Whether or not we are a quirky container, i.e., do we collapse away top and bottom
    990         // margins in our container.  Table cells and the body are the common examples. We
    991         // also have a custom style property for Safari RSS to deal with TypePad blog articles.
    992         bool m_quirkContainer : 1;
    993 
    994         // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block.
    995         // They may or may not collapse with the top margin of the block (|m_canCollapseTopWithChildren| tells us that), but they will
    996         // always be collapsing with one another.  This variable can remain set to true through multiple iterations
    997         // as long as we keep encountering self-collapsing blocks.
    998         bool m_atBeforeSideOfBlock : 1;
    999 
   1000         // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block.
   1001         bool m_atAfterSideOfBlock : 1;
   1002 
   1003         // These variables are used to detect quirky margins that we need to collapse away (in table cells
   1004         // and in the body element).
   1005         bool m_hasMarginBeforeQuirk : 1;
   1006         bool m_hasMarginAfterQuirk : 1;
   1007         bool m_determinedMarginBeforeQuirk : 1;
   1008 
   1009         bool m_discardMargin : 1;
   1010 
   1011         // These flags track the previous maximal positive and negative margins.
   1012         LayoutUnit m_positiveMargin;
   1013         LayoutUnit m_negativeMargin;
   1014 
   1015     public:
   1016         MarginInfo(RenderBlock*, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding);
   1017 
   1018         void setAtBeforeSideOfBlock(bool b) { m_atBeforeSideOfBlock = b; }
   1019         void setAtAfterSideOfBlock(bool b) { m_atAfterSideOfBlock = b; }
   1020         void clearMargin()
   1021         {
   1022             m_positiveMargin = 0;
   1023             m_negativeMargin = 0;
   1024         }
   1025         void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; }
   1026         void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; }
   1027         void setDeterminedMarginBeforeQuirk(bool b) { m_determinedMarginBeforeQuirk = b; }
   1028         void setPositiveMargin(LayoutUnit p) { ASSERT(!m_discardMargin); m_positiveMargin = p; }
   1029         void setNegativeMargin(LayoutUnit n) { ASSERT(!m_discardMargin); m_negativeMargin = n; }
   1030         void setPositiveMarginIfLarger(LayoutUnit p)
   1031         {
   1032             ASSERT(!m_discardMargin);
   1033             if (p > m_positiveMargin)
   1034                 m_positiveMargin = p;
   1035         }
   1036         void setNegativeMarginIfLarger(LayoutUnit n)
   1037         {
   1038             ASSERT(!m_discardMargin);
   1039             if (n > m_negativeMargin)
   1040                 m_negativeMargin = n;
   1041         }
   1042 
   1043         void setMargin(LayoutUnit p, LayoutUnit n) { ASSERT(!m_discardMargin); m_positiveMargin = p; m_negativeMargin = n; }
   1044         void setCanCollapseMarginAfterWithChildren(bool collapse) { m_canCollapseMarginAfterWithChildren = collapse; }
   1045         void setDiscardMargin(bool value) { m_discardMargin = value; }
   1046 
   1047         bool atBeforeSideOfBlock() const { return m_atBeforeSideOfBlock; }
   1048         bool canCollapseWithMarginBefore() const { return m_atBeforeSideOfBlock && m_canCollapseMarginBeforeWithChildren; }
   1049         bool canCollapseWithMarginAfter() const { return m_atAfterSideOfBlock && m_canCollapseMarginAfterWithChildren; }
   1050         bool canCollapseMarginBeforeWithChildren() const { return m_canCollapseMarginBeforeWithChildren; }
   1051         bool canCollapseMarginAfterWithChildren() const { return m_canCollapseMarginAfterWithChildren; }
   1052         bool quirkContainer() const { return m_quirkContainer; }
   1053         bool determinedMarginBeforeQuirk() const { return m_determinedMarginBeforeQuirk; }
   1054         bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
   1055         bool hasMarginAfterQuirk() const { return m_hasMarginAfterQuirk; }
   1056         LayoutUnit positiveMargin() const { return m_positiveMargin; }
   1057         LayoutUnit negativeMargin() const { return m_negativeMargin; }
   1058         bool discardMargin() const { return m_discardMargin; }
   1059         LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; }
   1060     };
   1061 
   1062     void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom);
   1063     void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
   1064     void adjustFloatingBlock(const MarginInfo&);
   1065 
   1066     RenderBoxModelObject* createReplacementRunIn(RenderBoxModelObject* runIn);
   1067     void moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn);
   1068     void moveRunInToOriginalPosition(RenderObject* runIn);
   1069 
   1070     LayoutUnit collapseMargins(RenderBox* child, MarginInfo&);
   1071     LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos);
   1072     LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
   1073     void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const;
   1074     void handleAfterSideOfBlock(LayoutUnit top, LayoutUnit bottom, MarginInfo&);
   1075     void setCollapsedBottomMargin(const MarginInfo&);
   1076     // End helper functions and structs used by layoutBlockChildren.
   1077 
   1078     // Helper function for layoutInlineChildren()
   1079     RootInlineBox* createLineBoxesFromBidiRuns(BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
   1080     void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild);
   1081     void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
   1082     void updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*&, LayoutUnit&, LineLayoutState&);
   1083     void updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsideInfo*&, LineLayoutState&);
   1084     bool adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideInfo*, LayoutUnit, LineLayoutState&, InlineBidiResolver&, FloatingObject*, InlineIterator&, WordMeasurements&);
   1085     const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&,  const InlineIterator&);
   1086     void linkToEndLineIfNeeded(LineLayoutState&);
   1087     static void repaintDirtyFloats(Vector<FloatWithRect>& floats);
   1088 
   1089 protected:
   1090     void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
   1091 
   1092     // Pagination routines.
   1093     virtual bool relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer&);
   1094 
   1095     // Returns the logicalOffset at the top of the next page. If the offset passed in is already at the top of the current page,
   1096     // then nextPageLogicalTop with ExcludePageBoundary will still move to the top of the next page. nextPageLogicalTop with
   1097     // IncludePageBoundary set will not.
   1098     //
   1099     // For a page height of 800px, the first rule will return 800 if the value passed in is 0. The second rule will simply return 0.
   1100     enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary };
   1101     LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
   1102     bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
   1103 
   1104     virtual ColumnInfo::PaginationUnit paginationUnit() const;
   1105 
   1106     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.
   1107     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.
   1108 
   1109 public:
   1110     LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
   1111     LayoutUnit pageLogicalHeightForOffset(LayoutUnit offset) const;
   1112     LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule = IncludePageBoundary) const;
   1113 
   1114 protected:
   1115     bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
   1116 
   1117     // A page break is required at some offset due to space shortage in the current fragmentainer.
   1118     void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage);
   1119 
   1120     // Update minimum page height required to avoid fragmentation where it shouldn't occur (inside
   1121     // unbreakable content, between orphans and widows, etc.). This will be used as a hint to the
   1122     // column balancer to help set a good minimum column height.
   1123     void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight);
   1124 
   1125     LayoutUnit adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins = false); // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
   1126     void adjustLinePositionForPagination(RootInlineBox*, LayoutUnit& deltaOffset, RenderFlowThread*); // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
   1127     LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock);
   1128 
   1129     // Adjust from painting offsets to the local coords of this renderer
   1130     void offsetForContents(LayoutPoint&) const;
   1131 
   1132     // This function is called to test a line box that has moved in the block direction to see if it has ended up in a new
   1133     // region/page/column that has a different available line width than the old one. Used to know when you have to dirty a
   1134     // line, i.e., that it can't be re-used.
   1135     bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const;
   1136 
   1137     bool logicalWidthChangedInRegions(RenderFlowThread*) const;
   1138 
   1139     virtual bool requiresColumns(int desiredColumnCount) const;
   1140 
   1141     virtual bool updateLogicalWidthAndColumnWidth();
   1142 
   1143     virtual bool canCollapseAnonymousBlockChild() const { return true; }
   1144 
   1145 public:
   1146     LayoutUnit offsetFromLogicalTopOfFirstPage() const;
   1147     RenderRegion* regionAtBlockOffset(LayoutUnit) const;
   1148     RenderRegion* clampToStartAndEndRegions(RenderRegion*) const;
   1149 
   1150 protected:
   1151     struct FloatingObjectHashFunctions {
   1152         static unsigned hash(FloatingObject* key) { return DefaultHash<RenderBox*>::Hash::hash(key->m_renderer); }
   1153         static bool equal(FloatingObject* a, FloatingObject* b) { return a->m_renderer == b->m_renderer; }
   1154         static const bool safeToCompareToEmptyOrDeleted = true;
   1155     };
   1156     struct FloatingObjectHashTranslator {
   1157         static unsigned hash(RenderBox* key) { return DefaultHash<RenderBox*>::Hash::hash(key); }
   1158         static bool equal(FloatingObject* a, RenderBox* b) { return a->m_renderer == b; }
   1159     };
   1160     typedef ListHashSet<FloatingObject*, 4, FloatingObjectHashFunctions> FloatingObjectSet;
   1161     typedef FloatingObjectSet::const_iterator FloatingObjectSetIterator;
   1162     typedef PODInterval<int, FloatingObject*> FloatingObjectInterval;
   1163     typedef PODIntervalTree<int, FloatingObject*> FloatingObjectTree;
   1164     typedef PODFreeListArena<PODRedBlackTree<FloatingObjectInterval>::Node> IntervalArena;
   1165 
   1166     template <FloatingObject::Type FloatTypeValue>
   1167     class FloatIntervalSearchAdapter {
   1168     public:
   1169         typedef FloatingObjectInterval IntervalType;
   1170 
   1171         FloatIntervalSearchAdapter(const RenderBlock* renderer, int lowValue, int highValue, LayoutUnit& offset, LayoutUnit* heightRemaining)
   1172             : m_renderer(renderer)
   1173             , m_lowValue(lowValue)
   1174             , m_highValue(highValue)
   1175             , m_offset(offset)
   1176             , m_heightRemaining(heightRemaining)
   1177             , m_last(0)
   1178         {
   1179         }
   1180 
   1181         inline int lowValue() const { return m_lowValue; }
   1182         inline int highValue() const { return m_highValue; }
   1183         void collectIfNeeded(const IntervalType&) const;
   1184 
   1185         // When computing the offset caused by the floats on a given line, if
   1186         // the outermost float on that line has a shape-outside, the inline
   1187         // content that butts up against that float must be positioned using
   1188         // the contours of the shape, not the margin box of the float.
   1189         // We save the last float encountered so that the offset can be
   1190         // computed correctly by the code using this adapter.
   1191         const FloatingObject* lastFloat() const { return m_last; }
   1192 
   1193     private:
   1194         bool updateOffsetIfNeeded(const FloatingObject*) const;
   1195 
   1196         const RenderBlock* m_renderer;
   1197         int m_lowValue;
   1198         int m_highValue;
   1199         LayoutUnit& m_offset;
   1200         LayoutUnit* m_heightRemaining;
   1201         // This member variable is mutable because the collectIfNeeded method
   1202         // is declared as const, even though it doesn't actually respect that
   1203         // contract. It modifies other member variables via loopholes in the
   1204         // const behavior. Instead of using loopholes, I decided it was better
   1205         // to make the fact that this is modified in a const method explicit.
   1206         mutable const FloatingObject* m_last;
   1207     };
   1208 
   1209     void createFloatingObjects();
   1210 
   1211 public:
   1212 
   1213     class FloatingObjects {
   1214         WTF_MAKE_NONCOPYABLE(FloatingObjects); WTF_MAKE_FAST_ALLOCATED;
   1215     public:
   1216         void clear();
   1217         void add(FloatingObject*);
   1218         void remove(FloatingObject*);
   1219         void addPlacedObject(FloatingObject*);
   1220         void removePlacedObject(FloatingObject*);
   1221         void setHorizontalWritingMode(bool b = true) { m_horizontalWritingMode = b; }
   1222 
   1223         bool hasLeftObjects() const { return m_leftObjectsCount > 0; }
   1224         bool hasRightObjects() const { return m_rightObjectsCount > 0; }
   1225         const FloatingObjectSet& set() const { return m_set; }
   1226         const FloatingObjectTree& placedFloatsTree()
   1227         {
   1228             computePlacedFloatsTreeIfNeeded();
   1229             return m_placedFloatsTree;
   1230         }
   1231     private:
   1232         FloatingObjects(const RenderBlock*, bool horizontalWritingMode);
   1233         void computePlacedFloatsTree();
   1234         inline void computePlacedFloatsTreeIfNeeded()
   1235         {
   1236             if (!m_placedFloatsTree.isInitialized())
   1237                 computePlacedFloatsTree();
   1238         }
   1239         void increaseObjectsCount(FloatingObject::Type);
   1240         void decreaseObjectsCount(FloatingObject::Type);
   1241         FloatingObjectInterval intervalForFloatingObject(FloatingObject*);
   1242 
   1243         FloatingObjectSet m_set;
   1244         FloatingObjectTree m_placedFloatsTree;
   1245         unsigned m_leftObjectsCount;
   1246         unsigned m_rightObjectsCount;
   1247         bool m_horizontalWritingMode;
   1248         const RenderBlock* m_renderer;
   1249 
   1250         friend void RenderBlock::createFloatingObjects();
   1251     };
   1252 
   1253     // Allocated only when some of these fields have non-default values
   1254     struct RenderBlockRareData {
   1255         WTF_MAKE_NONCOPYABLE(RenderBlockRareData); WTF_MAKE_FAST_ALLOCATED;
   1256     public:
   1257         RenderBlockRareData(const RenderBlock* block)
   1258             : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
   1259             , m_paginationStrut(0)
   1260             , m_pageLogicalOffset(0)
   1261             , m_lineGridBox(0)
   1262             , m_lineBreakToAvoidWidow(0)
   1263             , m_shouldBreakAtLineToAvoidWidow(false)
   1264             , m_discardMarginBefore(false)
   1265             , m_discardMarginAfter(false)
   1266         {
   1267         }
   1268 
   1269         static LayoutUnit positiveMarginBeforeDefault(const RenderBlock* block)
   1270         {
   1271             return std::max<LayoutUnit>(block->marginBefore(), 0);
   1272         }
   1273         static LayoutUnit negativeMarginBeforeDefault(const RenderBlock* block)
   1274         {
   1275             return std::max<LayoutUnit>(-block->marginBefore(), 0);
   1276         }
   1277         static LayoutUnit positiveMarginAfterDefault(const RenderBlock* block)
   1278         {
   1279             return std::max<LayoutUnit>(block->marginAfter(), 0);
   1280         }
   1281         static LayoutUnit negativeMarginAfterDefault(const RenderBlock* block)
   1282         {
   1283             return std::max<LayoutUnit>(-block->marginAfter(), 0);
   1284         }
   1285 
   1286         MarginValues m_margins;
   1287         LayoutUnit m_paginationStrut;
   1288         LayoutUnit m_pageLogicalOffset;
   1289 
   1290         RootInlineBox* m_lineGridBox;
   1291 
   1292         RootInlineBox* m_lineBreakToAvoidWidow;
   1293         OwnPtr<ShapeInsideInfo> m_shapeInsideInfo;
   1294         bool m_shouldBreakAtLineToAvoidWidow : 1;
   1295         bool m_discardMarginBefore : 1;
   1296         bool m_discardMarginAfter : 1;
   1297      };
   1298 
   1299 protected:
   1300 
   1301     OwnPtr<FloatingObjects> m_floatingObjects;
   1302     OwnPtr<RenderBlockRareData> m_rareData;
   1303 
   1304     RenderObjectChildList m_children;
   1305     RenderLineBoxList m_lineBoxes;   // All of the root line boxes created for this block flow.  For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
   1306 
   1307     mutable signed m_lineHeight : 27;
   1308     unsigned m_hasMarginBeforeQuirk : 1; // Note these quirk values can't be put in RenderBlockRareData since they are set too frequently.
   1309     unsigned m_hasMarginAfterQuirk : 1;
   1310     unsigned m_beingDestroyed : 1;
   1311     unsigned m_hasMarkupTruncation : 1;
   1312     unsigned m_hasBorderOrPaddingLogicalWidthChanged : 1;
   1313 
   1314     // RenderRubyBase objects need to be able to split and merge, moving their children around
   1315     // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
   1316     friend class RenderRubyBase;
   1317     friend class LineWidth; // Needs to know FloatingObject
   1318 
   1319 private:
   1320     // Used to store state between styleWillChange and styleDidChange
   1321     static bool s_canPropagateFloatIntoSibling;
   1322 };
   1323 
   1324 inline RenderBlock* toRenderBlock(RenderObject* object)
   1325 {
   1326     ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderBlock());
   1327     return static_cast<RenderBlock*>(object);
   1328 }
   1329 
   1330 inline const RenderBlock* toRenderBlock(const RenderObject* object)
   1331 {
   1332     ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderBlock());
   1333     return static_cast<const RenderBlock*>(object);
   1334 }
   1335 
   1336 // This will catch anyone doing an unnecessary cast.
   1337 void toRenderBlock(const RenderBlock*);
   1338 
   1339 #ifndef NDEBUG
   1340 // These structures are used by PODIntervalTree for debugging purposes.
   1341 template <> struct ValueToString<int> {
   1342     static String string(const int value);
   1343 };
   1344 template<> struct ValueToString<RenderBlock::FloatingObject*> {
   1345     static String string(const RenderBlock::FloatingObject*);
   1346 };
   1347 #endif
   1348 
   1349 } // namespace WebCore
   1350 
   1351 #endif // RenderBlock_h
   1352