2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2007 David Smith (catfish.man@gmail.com)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
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.
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.
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.
26 #include "ColumnInfo.h"
28 #include "PODIntervalTree.h"
29 #include "RenderBox.h"
30 #include "RenderLineBoxList.h"
31 #include "RootInlineBox.h"
32 #include "TextBreakIterator.h"
34 #include <wtf/OwnPtr.h>
35 #include <wtf/ListHashSet.h>
37 #if ENABLE(CSS_SHAPES)
38 #include "ShapeInsideInfo.h"
39 #include "ShapeValue.h"
46 class LayoutStateMaintainer;
47 class LineLayoutState;
49 class LogicalSelectionOffsetCaches;
57 #if ENABLE(CSS_SHAPES)
61 class WordMeasurement;
63 template <class Iterator, class Run> class BidiResolver;
64 template <class Run> class BidiRunList;
65 template <class Iterator> struct MidpointState;
66 typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver;
67 typedef MidpointState<InlineIterator> LineMidpointState;
68 typedef WTF::ListHashSet<RenderBox*, 16> TrackedRendererListHashSet;
69 typedef WTF::HashMap<const RenderBlock*, OwnPtr<TrackedRendererListHashSet> > TrackedDescendantsMap;
70 typedef WTF::HashMap<const RenderBox*, OwnPtr<HashSet<RenderBlock*> > > TrackedContainerMap;
71 typedef Vector<WordMeasurement, 64> WordMeasurements;
73 enum CaretType { CursorCaret, DragCaret };
74 enum ContainingBlockState { NewContainingBlock, SameContainingBlock };
77 DefaultTextRunFlags = 0,
78 RespectDirection = 1 << 0,
79 RespectDirectionOverride = 1 << 1
82 typedef unsigned TextRunFlags;
84 class RenderBlock : public RenderBox {
86 friend class LineLayoutState;
88 // Used by the PODIntervalTree for debugging the FloatingObject.
89 template <class> friend struct ValueToString;
92 explicit RenderBlock(ContainerNode*);
93 virtual ~RenderBlock();
95 static RenderBlock* createAnonymous(Document*);
97 RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
98 RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
100 const RenderObjectChildList* children() const { return &m_children; }
101 RenderObjectChildList* children() { return &m_children; }
103 bool beingDestroyed() const { return m_beingDestroyed; }
105 // These two functions are overridden for inline-block.
106 virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE FINAL;
107 virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
109 RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
110 const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
112 InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); }
113 InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); }
115 void deleteLineBoxTree();
117 virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
118 virtual void removeChild(RenderObject*);
120 virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0);
122 void insertPositionedObject(RenderBox*);
123 static void removePositionedObject(RenderBox*);
124 void removePositionedObjects(RenderBlock*, ContainingBlockState = SameContainingBlock);
126 void removeFloatingObjects();
128 TrackedRendererListHashSet* positionedObjects() const;
129 bool hasPositionedObjects() const
131 TrackedRendererListHashSet* objects = positionedObjects();
132 return objects && !objects->isEmpty();
135 void addPercentHeightDescendant(RenderBox*);
136 static void removePercentHeightDescendant(RenderBox*);
137 TrackedRendererListHashSet* percentHeightDescendants() const;
138 static bool hasPercentHeightContainerMap();
139 static bool hasPercentHeightDescendant(RenderBox*);
140 static void clearPercentHeightDescendantsFrom(RenderBox*);
141 static void removePercentHeightDescendantIfNeeded(RenderBox*);
143 void setHasMarkupTruncation(bool b) { m_hasMarkupTruncation = b; }
144 bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }
146 void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; }
147 void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; }
149 bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
150 bool hasMarginAfterQuirk() const { return m_hasMarginAfterQuirk; }
152 bool hasMarginBeforeQuirk(const RenderBox* child) const;
153 bool hasMarginAfterQuirk(const RenderBox* child) const;
155 RootInlineBox* createAndAppendRootInlineBox();
157 bool generatesLineBoxesForInlineChild(RenderObject*);
159 void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
160 void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = 0);
161 void markPositionedObjectsForLayout();
162 virtual void markForPaginationRelayoutIfNeeded() OVERRIDE FINAL;
164 bool containsFloats() const { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
165 bool containsFloat(RenderBox*) const;
167 // Versions that can compute line offsets with the region and page offset passed in. Used for speed to avoid having to
168 // compute the region all over again when you already know it.
169 LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
171 return max<LayoutUnit>(0, logicalRightOffsetForLine(position, shouldIndentText, region, logicalHeight)
172 - logicalLeftOffsetForLine(position, shouldIndentText, region, logicalHeight));
174 LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
176 return logicalRightOffsetForLine(position, logicalRightOffsetForContent(region), shouldIndentText, 0, logicalHeight);
178 LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
180 return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(region), shouldIndentText, 0, logicalHeight);
182 LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
184 return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, region, logicalHeight)
185 : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, region, logicalHeight);
187 LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
189 return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, region, logicalHeight)
190 : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, region, logicalHeight);
193 LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
195 return availableLogicalWidthForLine(position, shouldIndentText, regionAtBlockOffset(position), logicalHeight);
197 LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
199 return logicalRightOffsetForLine(position, logicalRightOffsetForContent(position), shouldIndentText, 0, logicalHeight);
201 LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
203 return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(position), shouldIndentText, 0, logicalHeight);
205 LayoutUnit pixelSnappedLogicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
207 return roundToInt(logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight));
209 LayoutUnit pixelSnappedLogicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
211 // FIXME: Multicolumn layouts break carrying over subpixel values to the logical right offset because the lines may be shifted
212 // by a subpixel value for all but the first column. This can lead to the actual pixel snapped width of the column being off
213 // by one pixel when rendered versus layed out, which can result in the line being clipped. For now, we have to floor.
214 // https://bugs.webkit.org/show_bug.cgi?id=105461
215 return floorToInt(logicalRightOffsetForLine(position, shouldIndentText, logicalHeight));
217 LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
219 return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
220 : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
222 LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
224 return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
225 : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
228 LayoutUnit startAlignedOffsetForLine(LayoutUnit position, bool shouldIndentText);
229 LayoutUnit textIndentOffset() const;
231 virtual VisiblePosition positionForPoint(const LayoutPoint&);
233 // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
234 virtual LayoutUnit availableLogicalWidth() const OVERRIDE FINAL;
236 LayoutPoint flipForWritingModeIncludingColumns(const LayoutPoint&) const;
237 void adjustStartEdgeForWritingModeIncludingColumns(LayoutRect&) const;
239 RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); }
240 RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
242 bool containsNonZeroBidiLevel() const;
244 GapRects selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer);
245 LayoutRect logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
246 RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
247 LayoutRect logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
248 RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
249 void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
250 RenderBlock* blockBeforeWithinSelectionRoot(LayoutSize& offset) const;
252 LayoutRect logicalRectToPhysicalRect(const LayoutPoint& physicalPosition, const LayoutRect& logicalRect);
254 // Helper methods for computing line counts and heights for line counts.
255 RootInlineBox* lineAtIndex(int) const;
256 int lineCount(const RootInlineBox* = 0, bool* = 0) const;
257 int heightForLineCount(int);
258 void clearTruncation();
260 void adjustRectForColumns(LayoutRect&) const;
261 virtual void adjustForColumns(LayoutSize&, const LayoutPoint&) const OVERRIDE FINAL;
262 void adjustForColumnRect(LayoutSize& offset, const LayoutPoint& locationInContainer) const;
264 void addContinuationWithOutline(RenderInline*);
265 bool paintsContinuationOutline(RenderInline*);
267 virtual RenderBoxModelObject* virtualContinuation() const OVERRIDE FINAL { return continuation(); }
268 bool isAnonymousBlockContinuation() const { return continuation() && isAnonymousBlock(); }
269 RenderInline* inlineElementContinuation() const;
270 RenderBlock* blockElementContinuation() const;
272 using RenderBoxModelObject::continuation;
273 using RenderBoxModelObject::setContinuation;
275 static RenderBlock* createAnonymousWithParentRendererAndDisplay(const RenderObject*, EDisplay = BLOCK);
276 static RenderBlock* createAnonymousColumnsWithParentRenderer(const RenderObject*);
277 static RenderBlock* createAnonymousColumnSpanWithParentRenderer(const RenderObject*);
278 RenderBlock* createAnonymousBlock(EDisplay display = BLOCK) const { return createAnonymousWithParentRendererAndDisplay(this, display); }
279 RenderBlock* createAnonymousColumnsBlock() const { return createAnonymousColumnsWithParentRenderer(this); }
280 RenderBlock* createAnonymousColumnSpanBlock() const { return createAnonymousColumnSpanWithParentRenderer(this); }
281 static void collapseAnonymousBoxChild(RenderBlock* parent, RenderObject* child);
283 virtual RenderBox* createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const OVERRIDE;
285 static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
287 return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline());
290 static void appendRunsForObject(BidiRunList<BidiRun>&, int start, int end, RenderObject*, InlineBidiResolver&);
292 static TextRun constructTextRun(RenderObject* context, const Font& font, const String& string, RenderStyle* style,
293 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
295 static TextRun constructTextRun(RenderObject* context, const Font& font, const RenderText* text, RenderStyle* style,
296 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
298 static TextRun constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, unsigned length, RenderStyle* style,
299 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
301 static TextRun constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, RenderStyle* style,
302 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
304 #if ENABLE(8BIT_TEXTRUN)
305 static TextRun constructTextRun(RenderObject* context, const Font& font, const LChar* characters, int length, RenderStyle* style,
306 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
309 static TextRun constructTextRun(RenderObject* context, const Font& font, const UChar* characters, int length, RenderStyle* style,
310 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
312 ColumnInfo* columnInfo() const;
313 int columnGap() const;
315 void updateColumnInfoFromStyle(RenderStyle*);
317 LayoutUnit initialBlockOffsetForPainting() const;
318 LayoutUnit blockDeltaForPaintingNextColumn() const;
320 // These two functions take the ColumnInfo* to avoid repeated lookups of the info in the global HashMap.
321 unsigned columnCount(ColumnInfo*) const;
322 LayoutRect columnRectAt(ColumnInfo*, unsigned) const;
324 LayoutUnit paginationStrut() const { return m_rareData ? m_rareData->m_paginationStrut : LayoutUnit(); }
325 void setPaginationStrut(LayoutUnit);
327 bool shouldBreakAtLineToAvoidWidow() const { return m_rareData && m_rareData->m_shouldBreakAtLineToAvoidWidow; }
328 void clearShouldBreakAtLineToAvoidWidow() const;
329 int lineBreakToAvoidWidow() const { return m_rareData ? m_rareData->m_lineBreakToAvoidWidow : -1; }
330 void setBreakAtLineToAvoidWidow(int);
332 // The page logical offset is the object's offset from the top of the page in the page progression
333 // direction (so an x-offset in vertical text and a y-offset for horizontal text).
334 LayoutUnit pageLogicalOffset() const { return m_rareData ? m_rareData->m_pageLogicalOffset : LayoutUnit(); }
335 void setPageLogicalOffset(LayoutUnit);
337 RootInlineBox* lineGridBox() const { return m_rareData ? m_rareData->m_lineGridBox : 0; }
338 void setLineGridBox(RootInlineBox* box)
341 m_rareData = adoptPtr(new RenderBlockRareData(this));
342 if (m_rareData->m_lineGridBox)
343 m_rareData->m_lineGridBox->destroy(renderArena());
344 m_rareData->m_lineGridBox = box;
346 void layoutLineGridBox();
348 // Accessors for logical width/height and margins in the containing block's block-flow direction.
349 enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
350 LayoutUnit logicalWidthForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->width() : child->height(); }
351 LayoutUnit logicalHeightForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->height() : child->width(); }
352 LayoutUnit logicalTopForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->y() : child->x(); }
353 void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
354 void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
355 LayoutUnit marginBeforeForChild(const RenderBoxModelObject* child) const { return child->marginBefore(style()); }
356 LayoutUnit marginAfterForChild(const RenderBoxModelObject* child) const { return child->marginAfter(style()); }
357 LayoutUnit marginStartForChild(const RenderBoxModelObject* child) const { return child->marginStart(style()); }
358 LayoutUnit marginEndForChild(const RenderBoxModelObject* child) const { return child->marginEnd(style()); }
359 void setMarginStartForChild(RenderBox* child, LayoutUnit value) const { child->setMarginStart(value, style()); }
360 void setMarginEndForChild(RenderBox* child, LayoutUnit value) const { child->setMarginEnd(value, style()); }
361 void setMarginBeforeForChild(RenderBox* child, LayoutUnit value) const { child->setMarginBefore(value, style()); }
362 void setMarginAfterForChild(RenderBox* child, LayoutUnit value) const { child->setMarginAfter(value, style()); }
363 LayoutUnit collapsedMarginBeforeForChild(const RenderBox* child) const;
364 LayoutUnit collapsedMarginAfterForChild(const RenderBox* child) const;
366 void updateLogicalWidthForAlignment(const ETextAlign&, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount);
368 virtual void updateFirstLetter();
372 MarginValues(LayoutUnit beforePos, LayoutUnit beforeNeg, LayoutUnit afterPos, LayoutUnit afterNeg)
373 : m_positiveMarginBefore(beforePos)
374 , m_negativeMarginBefore(beforeNeg)
375 , m_positiveMarginAfter(afterPos)
376 , m_negativeMarginAfter(afterNeg)
379 LayoutUnit positiveMarginBefore() const { return m_positiveMarginBefore; }
380 LayoutUnit negativeMarginBefore() const { return m_negativeMarginBefore; }
381 LayoutUnit positiveMarginAfter() const { return m_positiveMarginAfter; }
382 LayoutUnit negativeMarginAfter() const { return m_negativeMarginAfter; }
384 void setPositiveMarginBefore(LayoutUnit pos) { m_positiveMarginBefore = pos; }
385 void setNegativeMarginBefore(LayoutUnit neg) { m_negativeMarginBefore = neg; }
386 void setPositiveMarginAfter(LayoutUnit pos) { m_positiveMarginAfter = pos; }
387 void setNegativeMarginAfter(LayoutUnit neg) { m_negativeMarginAfter = neg; }
390 LayoutUnit m_positiveMarginBefore;
391 LayoutUnit m_negativeMarginBefore;
392 LayoutUnit m_positiveMarginAfter;
393 LayoutUnit m_negativeMarginAfter;
395 MarginValues marginValuesForChild(RenderBox* child) const;
397 virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { };
399 LayoutUnit logicalLeftOffsetForContent(RenderRegion*) const;
400 LayoutUnit logicalRightOffsetForContent(RenderRegion*) const;
401 LayoutUnit availableLogicalWidthForContent(RenderRegion* region) const
403 return max<LayoutUnit>(0, logicalRightOffsetForContent(region) - logicalLeftOffsetForContent(region)); }
404 LayoutUnit startOffsetForContent(RenderRegion* region) const
406 return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region) : logicalWidth() - logicalRightOffsetForContent(region);
408 LayoutUnit endOffsetForContent(RenderRegion* region) const
410 return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region) : logicalWidth() - logicalRightOffsetForContent(region);
412 LayoutUnit logicalLeftOffsetForContent(LayoutUnit blockOffset) const
414 return logicalLeftOffsetForContent(regionAtBlockOffset(blockOffset));
416 LayoutUnit logicalRightOffsetForContent(LayoutUnit blockOffset) const
418 return logicalRightOffsetForContent(regionAtBlockOffset(blockOffset));
420 LayoutUnit availableLogicalWidthForContent(LayoutUnit blockOffset) const
422 return availableLogicalWidthForContent(regionAtBlockOffset(blockOffset));
424 LayoutUnit startOffsetForContent(LayoutUnit blockOffset) const
426 return startOffsetForContent(regionAtBlockOffset(blockOffset));
428 LayoutUnit endOffsetForContent(LayoutUnit blockOffset) const
430 return endOffsetForContent(regionAtBlockOffset(blockOffset));
432 LayoutUnit logicalLeftOffsetForContent() const { return isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
433 LayoutUnit logicalRightOffsetForContent() const { return logicalLeftOffsetForContent() + availableLogicalWidth(); }
434 LayoutUnit startOffsetForContent() const { return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
435 LayoutUnit endOffsetForContent() const { return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
437 void setStaticInlinePositionForChild(RenderBox*, LayoutUnit blockOffset, LayoutUnit inlinePosition);
438 void updateStaticInlinePositionForChild(RenderBox*, LayoutUnit logicalTop);
440 LayoutUnit computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart, RenderRegion* = 0);
442 void placeRunInIfNeeded(RenderObject* newChild);
443 bool runInIsPlacedIntoSiblingBlock(RenderObject* runIn);
446 void checkPositionedObjectsNeedLayout();
447 void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0) const;
450 #if ENABLE(CSS_SHAPES)
451 ShapeInsideInfo* ensureShapeInsideInfo()
453 if (!m_rareData || !m_rareData->m_shapeInsideInfo)
454 setShapeInsideInfo(ShapeInsideInfo::createInfo(this));
455 return m_rareData->m_shapeInsideInfo.get();
458 ShapeInsideInfo* shapeInsideInfo() const
460 if (!m_rareData || !m_rareData->m_shapeInsideInfo)
462 return ShapeInsideInfo::isEnabledFor(this) ? m_rareData->m_shapeInsideInfo.get() : 0;
464 void setShapeInsideInfo(PassOwnPtr<ShapeInsideInfo> value)
467 m_rareData = adoptPtr(new RenderBlockRareData(this));
468 m_rareData->m_shapeInsideInfo = value;
470 void markShapeInsideDescendantsForLayout();
471 ShapeInsideInfo* layoutShapeInsideInfo() const;
472 bool allowsShapeInsideInfoSharing() const { return !isInline() && !isFloating(); }
476 virtual void willBeDestroyed();
478 LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockRareData::positiveMarginBeforeDefault(this); }
479 LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockRareData::negativeMarginBeforeDefault(this); }
480 LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockRareData::positiveMarginAfterDefault(this); }
481 LayoutUnit maxNegativeMarginAfter() const { return m_rareData ? m_rareData->m_margins.negativeMarginAfter() : RenderBlockRareData::negativeMarginAfterDefault(this); }
483 void setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg);
484 void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
486 void setMustDiscardMarginBefore(bool = true);
487 void setMustDiscardMarginAfter(bool = true);
489 bool mustDiscardMarginBefore() const;
490 bool mustDiscardMarginAfter() const;
492 bool mustDiscardMarginBeforeForChild(const RenderBox*) const;
493 bool mustDiscardMarginAfterForChild(const RenderBox*) const;
495 bool mustSeparateMarginBeforeForChild(const RenderBox*) const;
496 bool mustSeparateMarginAfterForChild(const RenderBox*) const;
498 void initMaxMarginValues()
501 m_rareData->m_margins = MarginValues(RenderBlockRareData::positiveMarginBeforeDefault(this) , RenderBlockRareData::negativeMarginBeforeDefault(this),
502 RenderBlockRareData::positiveMarginAfterDefault(this), RenderBlockRareData::negativeMarginAfterDefault(this));
503 m_rareData->m_paginationStrut = 0;
505 m_rareData->m_discardMarginBefore = false;
506 m_rareData->m_discardMarginAfter = false;
510 virtual void layout();
512 void layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly = false);
513 void markFixedPositionObjectForLayoutIfNeeded(RenderObject* child);
515 virtual void paint(PaintInfo&, const LayoutPoint&);
516 virtual void paintObject(PaintInfo&, const LayoutPoint&);
517 virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect);
518 bool paintChild(RenderBox*, PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect);
520 LayoutUnit logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining = 0, LayoutUnit logicalHeight = 0) const
522 return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, heightRemaining, logicalHeight, ShapeOutsideFloatShapeOffset), applyTextIndent);
524 LayoutUnit logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining = 0, LayoutUnit logicalHeight = 0) const
526 return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, heightRemaining, logicalHeight, ShapeOutsideFloatShapeOffset), applyTextIndent);
528 LayoutUnit logicalRightOffsetForLineIgnoringShapeOutside(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining = 0, LayoutUnit logicalHeight = 0) const
530 return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, heightRemaining, logicalHeight, ShapeOutsideFloatMarginBoxOffset), applyTextIndent);
532 LayoutUnit logicalLeftOffsetForLineIgnoringShapeOutside(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining = 0, LayoutUnit logicalHeight = 0) const
534 return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, heightRemaining, logicalHeight, ShapeOutsideFloatMarginBoxOffset), applyTextIndent);
537 virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
538 virtual void adjustInlineDirectionLineBounds(int /* expansionOpportunityCount */, float& /* logicalLeft */, float& /* logicalWidth */) const { }
540 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
542 virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
543 virtual void computePreferredLogicalWidths() OVERRIDE;
545 virtual int firstLineBoxBaseline() const;
546 virtual int inlineBlockBaseline(LineDirectionMode) const OVERRIDE;
547 int lastLineBoxBaseline(LineDirectionMode) const;
549 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&);
551 // Delay update scrollbar until finishDelayRepaint() will be
552 // called. This function is used when a flexbox is laying out its
553 // descendant. If multiple calls are made to startDelayRepaint(),
554 // finishDelayRepaint() will do nothing until finishDelayRepaint()
555 // is called the same number of times.
556 static void startDelayUpdateScrollInfo();
557 static void finishDelayUpdateScrollInfo();
559 void updateScrollInfoAfterLayout();
561 virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
562 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
564 virtual bool hasLineIfEmpty() const;
566 bool simplifiedLayout();
567 virtual void simplifiedNormalFlowLayout();
569 void setDesiredColumnCountAndWidth(int, LayoutUnit);
572 void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false);
573 void clearLayoutOverflow();
575 virtual void addOverflowFromChildren();
576 void addOverflowFromFloats();
577 void addOverflowFromPositionedObjects();
578 void addOverflowFromBlockChildren();
579 void addOverflowFromInlineChildren();
580 void addVisualOverflowFromTheme();
582 virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
585 // Only used by RenderSVGText, which explicitely overrides RenderBlock::layoutBlock(), do NOT use for anything else.
586 void forceLayoutInlineChildren()
588 LayoutUnit repaintLogicalTop = 0;
589 LayoutUnit repaintLogicalBottom = 0;
591 layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom);
595 bool updateShapesBeforeBlockLayout();
596 void updateShapesAfterBlockLayout(bool heightChanged = false);
597 void computeRegionRangeForBoxChild(const RenderBox*) const;
599 void estimateRegionRangeForBoxChild(const RenderBox*) const;
600 bool updateRegionRangeForBoxChild(const RenderBox*) const;
602 void updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox*);
604 virtual void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
607 enum ShapeOutsideFloatOffsetMode { ShapeOutsideFloatShapeOffset, ShapeOutsideFloatMarginBoxOffset };
609 LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode) const;
610 LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode) const;
611 LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
612 LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
614 #if ENABLE(CSS_SHAPES)
615 void computeShapeSize();
616 void updateShapeInsideInfoAfterStyleChange(const ShapeValue*, const ShapeValue* oldShape);
618 virtual RenderObjectChildList* virtualChildren() { return children(); }
619 virtual const RenderObjectChildList* virtualChildren() const { return children(); }
621 virtual const char* renderName() const;
623 virtual bool isRenderBlock() const OVERRIDE FINAL { return true; }
624 virtual bool isBlockFlow() const OVERRIDE FINAL { return (!isInline() || isReplaced()) && !isTable(); }
625 virtual bool isInlineBlockOrInlineTable() const OVERRIDE FINAL { return isInline() && isReplaced(); }
627 void makeChildrenNonInline(RenderObject* insertionPoint = 0);
628 virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
630 void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert);
632 virtual void dirtyLinesFromChangedChild(RenderObject* child) OVERRIDE FINAL { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
634 void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
635 void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild);
636 void addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild);
638 void addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild = 0);
640 virtual bool isSelfCollapsingBlock() const OVERRIDE FINAL;
642 virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
643 virtual LayoutUnit collapsedMarginAfter() const OVERRIDE FINAL { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
645 virtual void repaintOverhangingFloats(bool paintAllDescendants) OVERRIDE FINAL;
647 void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom);
648 void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
649 BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*);
651 void insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
652 static void removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
654 virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby.
656 // Called to lay out the legend for a fieldset or the ruby text of a ruby run.
657 virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/) { return 0; }
659 bool relayoutToAvoidWidows(LayoutStateMaintainer&);
661 void createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild);
662 void updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer);
664 Node* nodeForHitTest() const;
666 struct FloatWithRect {
667 FloatWithRect(RenderBox* f)
669 , rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight()))
670 , everHadLayout(f->everHadLayout())
679 struct FloatingObject {
680 WTF_MAKE_NONCOPYABLE(FloatingObject); WTF_MAKE_FAST_ALLOCATED;
682 // Note that Type uses bits so you can use FloatLeftRight as a mask to query for both left and right.
683 enum Type { FloatLeft = 1, FloatRight = 2, FloatLeftRight = 3 };
685 FloatingObject(EFloat type)
687 , m_originatingLine(0)
688 , m_paginationStrut(0)
689 , m_shouldPaint(true)
690 , m_isDescendant(false)
693 , m_isInPlacedTree(false)
696 ASSERT(type != NoFloat);
697 if (type == LeftFloat)
699 else if (type == RightFloat)
703 FloatingObject(Type type, const LayoutRect& frameRect)
705 , m_originatingLine(0)
706 , m_frameRect(frameRect)
707 , m_paginationStrut(0)
709 , m_shouldPaint(true)
710 , m_isDescendant(false)
713 , m_isInPlacedTree(false)
718 FloatingObject* clone() const
720 FloatingObject* cloneObject = new FloatingObject(type(), m_frameRect);
721 cloneObject->m_renderer = m_renderer;
722 cloneObject->m_originatingLine = m_originatingLine;
723 cloneObject->m_paginationStrut = m_paginationStrut;
724 cloneObject->m_shouldPaint = m_shouldPaint;
725 cloneObject->m_isDescendant = m_isDescendant;
726 cloneObject->m_isPlaced = m_isPlaced;
730 Type type() const { return static_cast<Type>(m_type); }
731 RenderBox* renderer() const { return m_renderer; }
733 bool isPlaced() const { return m_isPlaced; }
734 void setIsPlaced(bool placed = true) { m_isPlaced = placed; }
736 inline LayoutUnit x() const { ASSERT(isPlaced()); return m_frameRect.x(); }
737 inline LayoutUnit maxX() const { ASSERT(isPlaced()); return m_frameRect.maxX(); }
738 inline LayoutUnit y() const { ASSERT(isPlaced()); return m_frameRect.y(); }
739 inline LayoutUnit maxY() const { ASSERT(isPlaced()); return m_frameRect.maxY(); }
740 inline LayoutUnit width() const { return m_frameRect.width(); }
741 inline LayoutUnit height() const { return m_frameRect.height(); }
743 void setX(LayoutUnit x) { ASSERT(!isInPlacedTree()); m_frameRect.setX(x); }
744 void setY(LayoutUnit y) { ASSERT(!isInPlacedTree()); m_frameRect.setY(y); }
745 void setWidth(LayoutUnit width) { ASSERT(!isInPlacedTree()); m_frameRect.setWidth(width); }
746 void setHeight(LayoutUnit height) { ASSERT(!isInPlacedTree()); m_frameRect.setHeight(height); }
748 const LayoutRect& frameRect() const { ASSERT(isPlaced()); return m_frameRect; }
749 void setFrameRect(const LayoutRect& frameRect) { ASSERT(!isInPlacedTree()); m_frameRect = frameRect; }
752 bool isInPlacedTree() const { return m_isInPlacedTree; }
753 void setIsInPlacedTree(bool value) { m_isInPlacedTree = value; }
756 bool shouldPaint() const { return m_shouldPaint; }
757 void setShouldPaint(bool shouldPaint) { m_shouldPaint = shouldPaint; }
758 bool isDescendant() const { return m_isDescendant; }
759 void setIsDescendant(bool isDescendant) { m_isDescendant = isDescendant; }
761 RenderBox* m_renderer;
762 RootInlineBox* m_originatingLine;
763 LayoutRect m_frameRect;
764 int m_paginationStrut;
767 unsigned m_type : 2; // Type (left or right aligned)
768 unsigned m_shouldPaint : 1;
769 unsigned m_isDescendant : 1;
770 unsigned m_isPlaced : 1;
772 unsigned m_isInPlacedTree : 1;
776 LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
778 LayoutUnit logicalTopForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->y() : child->x(); }
779 LayoutUnit logicalBottomForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->maxY() : child->maxX(); }
780 LayoutUnit logicalLeftForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->x() : child->y(); }
781 LayoutUnit logicalRightForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->maxX() : child->maxY(); }
782 LayoutUnit logicalWidthForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->width() : child->height(); }
784 int pixelSnappedLogicalTopForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedY() : child->frameRect().pixelSnappedX(); }
785 int pixelSnappedLogicalBottomForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedMaxY() : child->frameRect().pixelSnappedMaxX(); }
786 int pixelSnappedLogicalLeftForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedX() : child->frameRect().pixelSnappedY(); }
787 int pixelSnappedLogicalRightForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedMaxX() : child->frameRect().pixelSnappedMaxY(); }
789 void setLogicalTopForFloat(FloatingObject* child, LayoutUnit logicalTop)
791 if (isHorizontalWritingMode())
792 child->setY(logicalTop);
794 child->setX(logicalTop);
796 void setLogicalLeftForFloat(FloatingObject* child, LayoutUnit logicalLeft)
798 if (isHorizontalWritingMode())
799 child->setX(logicalLeft);
801 child->setY(logicalLeft);
803 void setLogicalHeightForFloat(FloatingObject* child, LayoutUnit logicalHeight)
805 if (isHorizontalWritingMode())
806 child->setHeight(logicalHeight);
808 child->setWidth(logicalHeight);
810 void setLogicalWidthForFloat(FloatingObject* child, LayoutUnit logicalWidth)
812 if (isHorizontalWritingMode())
813 child->setWidth(logicalWidth);
815 child->setHeight(logicalWidth);
818 LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
820 if (isHorizontalWritingMode())
821 return child->x() + child->renderer()->marginLeft();
823 return child->x() + marginBeforeForChild(child->renderer());
826 LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const
828 if (isHorizontalWritingMode())
829 return child->y() + marginBeforeForChild(child->renderer());
831 return child->y() + child->renderer()->marginTop();
834 LayoutPoint computeLogicalLocationForFloat(const FloatingObject*, LayoutUnit logicalTopOffset) const;
836 // The following functions' implementations are in RenderBlockLineLayout.cpp.
837 struct RenderTextInfo {
838 // Destruction of m_layout requires TextLayout to be a complete type, so the constructor and destructor are made non-inline to avoid compilation errors.
843 OwnPtr<TextLayout> m_layout;
844 LazyLineBreakIterator m_lineBreakIterator;
850 LineBreaker(RenderBlock* block)
856 InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
858 bool lineWasHyphenated() { return m_hyphenated; }
859 const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; }
860 EClear clear() { return m_clear; }
864 InlineIterator nextSegmentBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
865 void skipTrailingWhitespace(InlineIterator&, const LineInfo&);
866 void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
868 RenderBlock* m_block;
871 Vector<RenderBox*> m_positionedObjects;
874 void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
875 RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&);
876 void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
877 bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus);
878 bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
880 RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
881 InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment);
883 void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
885 BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
886 float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&);
887 void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
888 void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
889 void deleteEllipsisLineBoxes();
890 void checkLinesForTextOverflow();
892 // Positions new floats and also adjust all floats encountered on the line if any of them
893 // have to move to the next page/column.
894 bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
895 void appendFloatingObjectToLastLine(FloatingObject*);
897 // End of functions defined in RenderBlockLineLayout.cpp.
899 void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false);
900 void paintContents(PaintInfo&, const LayoutPoint&);
901 void paintColumnContents(PaintInfo&, const LayoutPoint&, bool paintFloats = false);
902 void paintColumnRules(PaintInfo&, const LayoutPoint&);
903 void paintSelection(PaintInfo&, const LayoutPoint&);
904 void paintCaret(PaintInfo&, const LayoutPoint&, CaretType);
906 FloatingObject* insertFloatingObject(RenderBox*);
907 void removeFloatingObject(RenderBox*);
908 void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
910 // Called from lineWidth, to position the floats added in the last line.
911 // Returns true if and only if it has positioned any floats.
912 bool positionNewFloats();
916 LayoutUnit getClearDelta(RenderBox* child, LayoutUnit yPos);
918 virtual bool avoidsFloats() const;
920 bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
921 bool hasOverhangingFloat(RenderBox*);
922 void addIntrudingFloats(RenderBlock* prev, LayoutUnit xoffset, LayoutUnit yoffset);
923 LayoutUnit addOverhangingFloats(RenderBlock* child, bool makeChildPaintOtherFloats);
925 LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const;
926 LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit) const;
928 bool hitTestColumns(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
929 virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
930 bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset);
932 virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset);
934 // FIXME: Make this method const so we can remove the const_cast in computeIntrinsicLogicalWidths.
935 void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
936 void computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
938 // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
940 virtual RenderBlock* firstLineBlock() const OVERRIDE;
942 virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const OVERRIDE FINAL;
943 virtual RenderStyle* outlineStyleForRepaint() const OVERRIDE FINAL;
945 virtual RenderObject* hoverAncestor() const OVERRIDE FINAL;
946 virtual void updateDragState(bool dragOn) OVERRIDE FINAL;
947 virtual void childBecameNonInline(RenderObject* child) OVERRIDE FINAL;
949 virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool /*clipToVisibleContent*/) OVERRIDE FINAL
951 return selectionGapRectsForRepaint(repaintContainer);
953 virtual bool shouldPaintSelectionGaps() const OVERRIDE FINAL;
954 bool isSelectionRoot() const;
955 GapRects selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
956 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo* = 0);
957 GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
958 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
959 GapRects blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
960 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
961 LayoutRect blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
962 LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const LogicalSelectionOffsetCaches&, const PaintInfo*);
963 LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
964 LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
966 friend class LogicalSelectionOffsetCaches;
968 virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
969 virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
971 LayoutUnit desiredColumnWidth() const;
972 unsigned desiredColumnCount() const;
974 void paintContinuationOutlines(PaintInfo&, const LayoutPoint&);
976 virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) OVERRIDE FINAL;
978 void adjustPointToColumnContents(LayoutPoint&) const;
980 void fitBorderToLinesIfNeeded(); // Shrink the box in which the border paints if border-fit is set.
981 void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const; // Helper function for borderFitAdjust
983 void markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest = 0);
985 void newLine(EClear);
987 Position positionForBox(InlineBox*, bool start = true) const;
988 VisiblePosition positionForPointWithInlineChildren(const LayoutPoint&);
990 virtual void calcColumnWidth();
991 void makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild);
993 bool expandsToEncloseOverhangingFloats() const;
995 void splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
996 RenderObject* beforeChild, RenderBoxModelObject* oldCont);
997 void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
998 RenderObject* newChild, RenderBoxModelObject* oldCont);
999 RenderBlock* clone() const;
1000 RenderBlock* continuationBefore(RenderObject* beforeChild);
1001 RenderBlock* containingColumnsBlock(bool allowAnonymousColumnBlock = true);
1002 RenderBlock* columnsBlockForSpanningElement(RenderObject* newChild);
1005 // Collapsing flags for whether we can collapse our margins with our children's margins.
1006 bool m_canCollapseWithChildren : 1;
1007 bool m_canCollapseMarginBeforeWithChildren : 1;
1008 bool m_canCollapseMarginAfterWithChildren : 1;
1010 // Whether or not we are a quirky container, i.e., do we collapse away top and bottom
1011 // margins in our container. Table cells and the body are the common examples. We
1012 // also have a custom style property for Safari RSS to deal with TypePad blog articles.
1013 bool m_quirkContainer : 1;
1015 // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block.
1016 // They may or may not collapse with the top margin of the block (|m_canCollapseTopWithChildren| tells us that), but they will
1017 // always be collapsing with one another. This variable can remain set to true through multiple iterations
1018 // as long as we keep encountering self-collapsing blocks.
1019 bool m_atBeforeSideOfBlock : 1;
1021 // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block.
1022 bool m_atAfterSideOfBlock : 1;
1024 // These variables are used to detect quirky margins that we need to collapse away (in table cells
1025 // and in the body element).
1026 bool m_hasMarginBeforeQuirk : 1;
1027 bool m_hasMarginAfterQuirk : 1;
1028 bool m_determinedMarginBeforeQuirk : 1;
1030 bool m_discardMargin : 1;
1032 // These flags track the previous maximal positive and negative margins.
1033 LayoutUnit m_positiveMargin;
1034 LayoutUnit m_negativeMargin;
1037 MarginInfo(RenderBlock*, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding);
1039 void setAtBeforeSideOfBlock(bool b) { m_atBeforeSideOfBlock = b; }
1040 void setAtAfterSideOfBlock(bool b) { m_atAfterSideOfBlock = b; }
1043 m_positiveMargin = 0;
1044 m_negativeMargin = 0;
1046 void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; }
1047 void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; }
1048 void setDeterminedMarginBeforeQuirk(bool b) { m_determinedMarginBeforeQuirk = b; }
1049 void setPositiveMargin(LayoutUnit p) { ASSERT(!m_discardMargin); m_positiveMargin = p; }
1050 void setNegativeMargin(LayoutUnit n) { ASSERT(!m_discardMargin); m_negativeMargin = n; }
1051 void setPositiveMarginIfLarger(LayoutUnit p)
1053 ASSERT(!m_discardMargin);
1054 if (p > m_positiveMargin)
1055 m_positiveMargin = p;
1057 void setNegativeMarginIfLarger(LayoutUnit n)
1059 ASSERT(!m_discardMargin);
1060 if (n > m_negativeMargin)
1061 m_negativeMargin = n;
1064 void setMargin(LayoutUnit p, LayoutUnit n) { ASSERT(!m_discardMargin); m_positiveMargin = p; m_negativeMargin = n; }
1065 void setCanCollapseMarginAfterWithChildren(bool collapse) { m_canCollapseMarginAfterWithChildren = collapse; }
1066 void setDiscardMargin(bool value) { m_discardMargin = value; }
1068 bool atBeforeSideOfBlock() const { return m_atBeforeSideOfBlock; }
1069 bool canCollapseWithMarginBefore() const { return m_atBeforeSideOfBlock && m_canCollapseMarginBeforeWithChildren; }
1070 bool canCollapseWithMarginAfter() const { return m_atAfterSideOfBlock && m_canCollapseMarginAfterWithChildren; }
1071 bool canCollapseMarginBeforeWithChildren() const { return m_canCollapseMarginBeforeWithChildren; }
1072 bool canCollapseMarginAfterWithChildren() const { return m_canCollapseMarginAfterWithChildren; }
1073 bool quirkContainer() const { return m_quirkContainer; }
1074 bool determinedMarginBeforeQuirk() const { return m_determinedMarginBeforeQuirk; }
1075 bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
1076 bool hasMarginAfterQuirk() const { return m_hasMarginAfterQuirk; }
1077 LayoutUnit positiveMargin() const { return m_positiveMargin; }
1078 LayoutUnit negativeMargin() const { return m_negativeMargin; }
1079 bool discardMargin() const { return m_discardMargin; }
1080 LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; }
1083 void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom);
1084 void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
1085 void adjustFloatingBlock(const MarginInfo&);
1087 RenderBoxModelObject* createReplacementRunIn(RenderBoxModelObject* runIn);
1088 void moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn);
1089 void moveRunInToOriginalPosition(RenderObject* runIn);
1091 LayoutUnit collapseMargins(RenderBox* child, MarginInfo&);
1092 LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos);
1093 LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
1094 void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const;
1095 void handleAfterSideOfBlock(LayoutUnit top, LayoutUnit bottom, MarginInfo&);
1096 void setCollapsedBottomMargin(const MarginInfo&);
1097 // End helper functions and structs used by layoutBlockChildren.
1099 // Helper function for layoutInlineChildren()
1100 RootInlineBox* createLineBoxesFromBidiRuns(BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
1101 void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild);
1102 void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
1103 #if ENABLE(CSS_SHAPES)
1104 void updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*&, LayoutUnit&, LineLayoutState&);
1105 void updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsideInfo*&, LineLayoutState&);
1106 bool adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideInfo*, LayoutUnit, LineLayoutState&, InlineBidiResolver&, FloatingObject*, InlineIterator&, WordMeasurements&);
1108 const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&, const InlineIterator&);
1109 void linkToEndLineIfNeeded(LineLayoutState&);
1110 static void repaintDirtyFloats(Vector<FloatWithRect>& floats);
1113 void dirtyForLayoutFromPercentageHeightDescendants();
1115 void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
1117 // Pagination routines.
1118 virtual bool relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer&);
1120 // Returns the logicalOffset at the top of the next page. If the offset passed in is already at the top of the current page,
1121 // then nextPageLogicalTop with ExcludePageBoundary will still move to the top of the next page. nextPageLogicalTop with
1122 // IncludePageBoundary set will not.
1124 // 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.
1125 enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary };
1126 LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
1127 bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
1129 virtual ColumnInfo::PaginationUnit paginationUnit() const;
1131 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.
1132 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.
1135 LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
1136 LayoutUnit pageLogicalHeightForOffset(LayoutUnit offset) const;
1137 LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule = IncludePageBoundary) const;
1140 bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
1142 // A page break is required at some offset due to space shortage in the current fragmentainer.
1143 void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage);
1145 // Update minimum page height required to avoid fragmentation where it shouldn't occur (inside
1146 // unbreakable content, between orphans and widows, etc.). This will be used as a hint to the
1147 // column balancer to help set a good minimum column height.
1148 void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight);
1150 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.
1151 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.
1152 LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock);
1154 // Adjust from painting offsets to the local coords of this renderer
1155 void offsetForContents(LayoutPoint&) const;
1157 // 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
1158 // region/page/column that has a different available line width than the old one. Used to know when you have to dirty a
1159 // line, i.e., that it can't be re-used.
1160 bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const;
1162 bool logicalWidthChangedInRegions(RenderFlowThread*) const;
1164 virtual bool requiresColumns(int desiredColumnCount) const;
1166 virtual bool updateLogicalWidthAndColumnWidth();
1168 virtual bool canCollapseAnonymousBlockChild() const { return true; }
1171 virtual LayoutUnit offsetFromLogicalTopOfFirstPage() const;
1172 RenderRegion* regionAtBlockOffset(LayoutUnit) const;
1175 struct FloatingObjectHashFunctions {
1176 static unsigned hash(FloatingObject* key) { return DefaultHash<RenderBox*>::Hash::hash(key->m_renderer); }
1177 static bool equal(FloatingObject* a, FloatingObject* b) { return a->m_renderer == b->m_renderer; }
1178 static const bool safeToCompareToEmptyOrDeleted = true;
1180 struct FloatingObjectHashTranslator {
1181 static unsigned hash(RenderBox* key) { return DefaultHash<RenderBox*>::Hash::hash(key); }
1182 static bool equal(FloatingObject* a, RenderBox* b) { return a->m_renderer == b; }
1184 typedef ListHashSet<FloatingObject*, 4, FloatingObjectHashFunctions> FloatingObjectSet;
1185 typedef FloatingObjectSet::const_iterator FloatingObjectSetIterator;
1186 typedef PODInterval<int, FloatingObject*> FloatingObjectInterval;
1187 typedef PODIntervalTree<int, FloatingObject*> FloatingObjectTree;
1188 typedef PODFreeListArena<PODRedBlackTree<FloatingObjectInterval>::Node> IntervalArena;
1190 template <FloatingObject::Type FloatTypeValue>
1191 class FloatIntervalSearchAdapter {
1193 typedef FloatingObjectInterval IntervalType;
1195 FloatIntervalSearchAdapter(const RenderBlock* renderer, int lowValue, int highValue, LayoutUnit& offset, LayoutUnit* heightRemaining)
1196 : m_renderer(renderer)
1197 , m_lowValue(lowValue)
1198 , m_highValue(highValue)
1200 , m_heightRemaining(heightRemaining)
1201 #if ENABLE(CSS_SHAPES)
1207 inline int lowValue() const { return m_lowValue; }
1208 inline int highValue() const { return m_highValue; }
1209 void collectIfNeeded(const IntervalType&) const;
1211 #if ENABLE(CSS_SHAPES)
1212 // When computing the offset caused by the floats on a given line, if
1213 // the outermost float on that line has a shape-outside, the inline
1214 // content that butts up against that float must be positioned using
1215 // the contours of the shape, not the margin box of the float.
1216 // We save the last float encountered so that the offset can be
1217 // computed correctly by the code using this adapter.
1218 const FloatingObject* lastFloat() const { return m_last; }
1222 const RenderBlock* m_renderer;
1225 LayoutUnit& m_offset;
1226 LayoutUnit* m_heightRemaining;
1227 #if ENABLE(CSS_SHAPES)
1228 // This member variable is mutable because the collectIfNeeded method
1229 // is declared as const, even though it doesn't actually respect that
1230 // contract. It modifies other member variables via loopholes in the
1231 // const behavior. Instead of using loopholes, I decided it was better
1232 // to make the fact that this is modified in a const method explicit.
1233 mutable const FloatingObject* m_last;
1237 void createFloatingObjects();
1241 class FloatingObjects {
1242 WTF_MAKE_NONCOPYABLE(FloatingObjects); WTF_MAKE_FAST_ALLOCATED;
1245 void add(FloatingObject*);
1246 void remove(FloatingObject*);
1247 void addPlacedObject(FloatingObject*);
1248 void removePlacedObject(FloatingObject*);
1249 void setHorizontalWritingMode(bool b = true) { m_horizontalWritingMode = b; }
1251 bool hasLeftObjects() const { return m_leftObjectsCount > 0; }
1252 bool hasRightObjects() const { return m_rightObjectsCount > 0; }
1253 const FloatingObjectSet& set() const { return m_set; }
1254 const FloatingObjectTree& placedFloatsTree()
1256 computePlacedFloatsTreeIfNeeded();
1257 return m_placedFloatsTree;
1260 FloatingObjects(const RenderBlock*, bool horizontalWritingMode);
1261 void computePlacedFloatsTree();
1262 inline void computePlacedFloatsTreeIfNeeded()
1264 if (!m_placedFloatsTree.isInitialized())
1265 computePlacedFloatsTree();
1267 void increaseObjectsCount(FloatingObject::Type);
1268 void decreaseObjectsCount(FloatingObject::Type);
1269 FloatingObjectInterval intervalForFloatingObject(FloatingObject*);
1271 FloatingObjectSet m_set;
1272 FloatingObjectTree m_placedFloatsTree;
1273 unsigned m_leftObjectsCount;
1274 unsigned m_rightObjectsCount;
1275 bool m_horizontalWritingMode;
1276 const RenderBlock* m_renderer;
1278 friend void RenderBlock::createFloatingObjects();
1281 // Allocated only when some of these fields have non-default values
1282 struct RenderBlockRareData {
1283 WTF_MAKE_NONCOPYABLE(RenderBlockRareData); WTF_MAKE_FAST_ALLOCATED;
1285 RenderBlockRareData(const RenderBlock* block)
1286 : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
1287 , m_paginationStrut(0)
1288 , m_pageLogicalOffset(0)
1290 , m_lineBreakToAvoidWidow(-1)
1291 , m_shouldBreakAtLineToAvoidWidow(false)
1292 , m_discardMarginBefore(false)
1293 , m_discardMarginAfter(false)
1297 static LayoutUnit positiveMarginBeforeDefault(const RenderBlock* block)
1299 return std::max<LayoutUnit>(block->marginBefore(), 0);
1301 static LayoutUnit negativeMarginBeforeDefault(const RenderBlock* block)
1303 return std::max<LayoutUnit>(-block->marginBefore(), 0);
1305 static LayoutUnit positiveMarginAfterDefault(const RenderBlock* block)
1307 return std::max<LayoutUnit>(block->marginAfter(), 0);
1309 static LayoutUnit negativeMarginAfterDefault(const RenderBlock* block)
1311 return std::max<LayoutUnit>(-block->marginAfter(), 0);
1314 MarginValues m_margins;
1315 LayoutUnit m_paginationStrut;
1316 LayoutUnit m_pageLogicalOffset;
1318 RootInlineBox* m_lineGridBox;
1320 int m_lineBreakToAvoidWidow;
1321 #if ENABLE(CSS_SHAPES)
1322 OwnPtr<ShapeInsideInfo> m_shapeInsideInfo;
1324 bool m_shouldBreakAtLineToAvoidWidow : 1;
1325 bool m_discardMarginBefore : 1;
1326 bool m_discardMarginAfter : 1;
1331 OwnPtr<FloatingObjects> m_floatingObjects;
1332 OwnPtr<RenderBlockRareData> m_rareData;
1334 RenderObjectChildList m_children;
1335 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>.
1337 mutable signed m_lineHeight : 27;
1338 unsigned m_hasMarginBeforeQuirk : 1; // Note these quirk values can't be put in RenderBlockRareData since they are set too frequently.
1339 unsigned m_hasMarginAfterQuirk : 1;
1340 unsigned m_beingDestroyed : 1;
1341 unsigned m_hasMarkupTruncation : 1;
1342 unsigned m_hasBorderOrPaddingLogicalWidthChanged : 1;
1344 // RenderRubyBase objects need to be able to split and merge, moving their children around
1345 // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
1346 friend class RenderRubyBase;
1347 friend class LineWidth; // Needs to know FloatingObject
1350 // Used to store state between styleWillChange and styleDidChange
1351 static bool s_canPropagateFloatIntoSibling;
1354 inline RenderBlock* toRenderBlock(RenderObject* object)
1356 ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderBlock());
1357 return static_cast<RenderBlock*>(object);
1360 inline const RenderBlock* toRenderBlock(const RenderObject* object)
1362 ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderBlock());
1363 return static_cast<const RenderBlock*>(object);
1366 // This will catch anyone doing an unnecessary cast.
1367 void toRenderBlock(const RenderBlock*);
1370 // These structures are used by PODIntervalTree for debugging purposes.
1371 template <> struct ValueToString<int> {
1372 static String string(const int value);
1374 template<> struct ValueToString<RenderBlock::FloatingObject*> {
1375 static String string(const RenderBlock::FloatingObject*);
1379 } // namespace WebCore
1381 #endif // RenderBlock_h