1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4 *           (C) 2007 David Smith (catfish.man@gmail.com)
5 * Copyright (C) 2003, 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 "GapRects.h"
27#include "RenderBox.h"
28#include "TextRun.h"
29#include <memory>
30#include <wtf/ListHashSet.h>
31
32namespace WebCore {
33
34class LayoutState;
35class LineLayoutState;
36class LogicalSelectionOffsetCaches;
37class RenderInline;
38class RenderText;
39
40struct BidiRun;
41struct PaintInfo;
42
43typedef WTF::ListHashSet<RenderBox*, 16> TrackedRendererListHashSet;
44typedef WTF::HashMap<const RenderBlock*, std::unique_ptr<TrackedRendererListHashSet>> TrackedDescendantsMap;
45typedef WTF::HashMap<const RenderBox*, std::unique_ptr<HashSet<RenderBlock*>>> TrackedContainerMap;
46
47enum CaretType { CursorCaret, DragCaret };
48enum ContainingBlockState { NewContainingBlock, SameContainingBlock };
49
50enum TextRunFlag {
51    DefaultTextRunFlags = 0,
52    RespectDirection = 1 << 0,
53    RespectDirectionOverride = 1 << 1
54};
55
56typedef unsigned TextRunFlags;
57
58class RenderBlock : public RenderBox {
59public:
60    friend class LineLayoutState;
61
62protected:
63    RenderBlock(Element&, PassRef<RenderStyle>, unsigned baseTypeFlags);
64    RenderBlock(Document&, PassRef<RenderStyle>, unsigned baseTypeFlags);
65    virtual ~RenderBlock();
66
67public:
68    bool beingDestroyed() const { return m_beingDestroyed; }
69
70    // These two functions are overridden for inline-block.
71    virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override final;
72    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
73
74    LayoutUnit minLineHeightForReplacedRenderer(bool isFirstLine, LayoutUnit replacedHeight) const;
75
76    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
77    virtual void deleteLines();
78
79    virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override;
80    virtual RenderObject* removeChild(RenderObject&) override;
81
82    virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0);
83
84    virtual void invalidateLineLayoutPath() { }
85
86    void insertPositionedObject(RenderBox&);
87    static void removePositionedObject(RenderBox&);
88    void removePositionedObjects(RenderBlock*, ContainingBlockState = SameContainingBlock);
89
90    TrackedRendererListHashSet* positionedObjects() const;
91    bool hasPositionedObjects() const
92    {
93        TrackedRendererListHashSet* objects = positionedObjects();
94        return objects && !objects->isEmpty();
95    }
96
97    void addPercentHeightDescendant(RenderBox&);
98    static void removePercentHeightDescendant(RenderBox&);
99    TrackedRendererListHashSet* percentHeightDescendants() const;
100    static bool hasPercentHeightContainerMap();
101    static bool hasPercentHeightDescendant(RenderBox&);
102    static void clearPercentHeightDescendantsFrom(RenderBox&);
103    static void removePercentHeightDescendantIfNeeded(RenderBox&);
104
105    void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; }
106    void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; }
107
108    bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
109    bool hasMarginAfterQuirk() const { return m_hasMarginAfterQuirk; }
110
111    bool hasMarginBeforeQuirk(const RenderBox& child) const;
112    bool hasMarginAfterQuirk(const RenderBox& child) const;
113
114    bool generatesLineBoxesForInlineChild(RenderObject*);
115
116    void markPositionedObjectsForLayout();
117    virtual void markForPaginationRelayoutIfNeeded() override final;
118
119    // FIXME-BLOCKFLOW: Remove virtualizaion when all of the line layout code has been moved out of RenderBlock
120    virtual bool containsFloats() const { return false; }
121
122    // Versions that can compute line offsets with the region and page offset passed in. Used for speed to avoid having to
123    // compute the region all over again when you already know it.
124    LayoutUnit availableLogicalWidthForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
125    {
126        return std::max<LayoutUnit>(0, logicalRightOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight)
127            - logicalLeftOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight));
128    }
129    LayoutUnit logicalRightOffsetForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
130    {
131        return logicalRightOffsetForLine(position, logicalRightOffsetForContent(region), shouldIndentText, logicalHeight);
132    }
133    LayoutUnit logicalLeftOffsetForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
134    {
135        return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(region), shouldIndentText, logicalHeight);
136    }
137    LayoutUnit startOffsetForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
138    {
139        return style().isLeftToRightDirection() ? logicalLeftOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight)
140            : logicalWidth() - logicalRightOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight);
141    }
142    LayoutUnit endOffsetForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
143    {
144        return !style().isLeftToRightDirection() ? logicalLeftOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight)
145            : logicalWidth() - logicalRightOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight);
146    }
147
148    LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
149    {
150        return availableLogicalWidthForLineInRegion(position, shouldIndentText, regionAtBlockOffset(position), logicalHeight);
151    }
152    LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
153    {
154        return logicalRightOffsetForLine(position, logicalRightOffsetForContent(position), shouldIndentText, logicalHeight);
155    }
156    LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
157    {
158        return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(position), shouldIndentText, logicalHeight);
159    }
160    LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
161    {
162        return style().isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
163            : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
164    }
165    LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
166    {
167        return !style().isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
168            : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
169    }
170
171    LayoutUnit textIndentOffset() const;
172
173    virtual VisiblePosition positionForPoint(const LayoutPoint&, const RenderRegion*) override;
174
175    GapRects selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer);
176    LayoutRect logicalLeftSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
177        RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
178    LayoutRect logicalRightSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
179        RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
180    void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
181    RenderBlock* blockBeforeWithinSelectionRoot(LayoutSize& offset) const;
182
183    LayoutRect logicalRectToPhysicalRect(const LayoutPoint& physicalPosition, const LayoutRect& logicalRect);
184
185    void addContinuationWithOutline(RenderInline*);
186    bool paintsContinuationOutline(RenderInline*);
187
188    virtual RenderBoxModelObject* virtualContinuation() const override final { return continuation(); }
189    bool isAnonymousBlockContinuation() const { return isAnonymousBlock() && continuation(); }
190    RenderInline* inlineElementContinuation() const;
191    RenderBlock* blockElementContinuation() const;
192
193    using RenderBoxModelObject::continuation;
194    using RenderBoxModelObject::setContinuation;
195
196    static RenderBlock* createAnonymousWithParentRendererAndDisplay(const RenderObject*, EDisplay = BLOCK);
197    RenderBlock* createAnonymousBlock(EDisplay display = BLOCK) const { return createAnonymousWithParentRendererAndDisplay(this, display); }
198    static void collapseAnonymousBoxChild(RenderBlock* parent, RenderBlock* child);
199
200    virtual RenderBox* createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const override;
201
202    static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
203    {
204        return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style().isOriginalDisplayInlineType() && !obj->container()->isRenderInline());
205    }
206
207    static TextRun constructTextRun(RenderObject* context, const Font&, const String&, const RenderStyle&,
208        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
209
210    static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, const RenderStyle&,
211        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
212
213    static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, const RenderStyle&,
214        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
215
216    static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, const RenderStyle&,
217        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
218
219    static TextRun constructTextRun(RenderObject* context, const Font&, const LChar* characters, int length, const RenderStyle&,
220        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
221
222    static TextRun constructTextRun(RenderObject* context, const Font&, const UChar* characters, int length, const RenderStyle&,
223        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
224
225    LayoutUnit paginationStrut() const;
226    void setPaginationStrut(LayoutUnit);
227
228    // The page logical offset is the object's offset from the top of the page in the page progression
229    // direction (so an x-offset in vertical text and a y-offset for horizontal text).
230    LayoutUnit pageLogicalOffset() const;
231    void setPageLogicalOffset(LayoutUnit);
232
233    // Accessors for logical width/height and margins in the containing block's block-flow direction.
234    enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
235    LayoutUnit logicalWidthForChild(const RenderBox& child) const { return isHorizontalWritingMode() ? child.width() : child.height(); }
236    LayoutUnit logicalHeightForChild(const RenderBox& child) const { return isHorizontalWritingMode() ? child.height() : child.width(); }
237    LayoutSize logicalSizeForChild(const RenderBox& child) const { return isHorizontalWritingMode() ? child.size() : child.size().transposedSize(); }
238    LayoutUnit logicalTopForChild(const RenderBox& child) const { return isHorizontalWritingMode() ? child.y() : child.x(); }
239    void setLogicalLeftForChild(RenderBox& child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
240    void setLogicalTopForChild(RenderBox& child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
241    LayoutUnit marginBeforeForChild(const RenderBoxModelObject& child) const { return child.marginBefore(&style()); }
242    LayoutUnit marginAfterForChild(const RenderBoxModelObject& child) const { return child.marginAfter(&style()); }
243    LayoutUnit marginStartForChild(const RenderBoxModelObject& child) const { return child.marginStart(&style()); }
244    LayoutUnit marginEndForChild(const RenderBoxModelObject& child) const { return child.marginEnd(&style()); }
245    void setMarginStartForChild(RenderBox& child, LayoutUnit value) const { child.setMarginStart(value, &style()); }
246    void setMarginEndForChild(RenderBox& child, LayoutUnit value) const { child.setMarginEnd(value, &style()); }
247    void setMarginBeforeForChild(RenderBox& child, LayoutUnit value) const { child.setMarginBefore(value, &style()); }
248    void setMarginAfterForChild(RenderBox& child, LayoutUnit value) const { child.setMarginAfter(value, &style()); }
249    LayoutUnit collapsedMarginBeforeForChild(const RenderBox& child) const;
250    LayoutUnit collapsedMarginAfterForChild(const RenderBox& child) const;
251
252    virtual void updateFirstLetter();
253    void getFirstLetter(RenderObject*& firstLetter, RenderElement*& firstLetterContainer, RenderObject* skipObject = nullptr);
254
255    virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { }
256
257    LayoutUnit logicalLeftOffsetForContent(RenderRegion*) const;
258    LayoutUnit logicalRightOffsetForContent(RenderRegion*) const;
259    LayoutUnit availableLogicalWidthForContent(RenderRegion* region) const
260    {
261        return std::max<LayoutUnit>(0, logicalRightOffsetForContent(region) - logicalLeftOffsetForContent(region));
262    }
263    LayoutUnit startOffsetForContent(RenderRegion* region) const
264    {
265        return style().isLeftToRightDirection() ? logicalLeftOffsetForContent(region) : logicalWidth() - logicalRightOffsetForContent(region);
266    }
267    LayoutUnit endOffsetForContent(RenderRegion* region) const
268    {
269        return !style().isLeftToRightDirection() ? logicalLeftOffsetForContent(region) : logicalWidth() - logicalRightOffsetForContent(region);
270    }
271    LayoutUnit logicalLeftOffsetForContent(LayoutUnit blockOffset) const
272    {
273        return logicalLeftOffsetForContent(regionAtBlockOffset(blockOffset));
274    }
275    LayoutUnit logicalRightOffsetForContent(LayoutUnit blockOffset) const
276    {
277        return logicalRightOffsetForContent(regionAtBlockOffset(blockOffset));
278    }
279    LayoutUnit availableLogicalWidthForContent(LayoutUnit blockOffset) const
280    {
281        return availableLogicalWidthForContent(regionAtBlockOffset(blockOffset));
282    }
283    LayoutUnit startOffsetForContent(LayoutUnit blockOffset) const
284    {
285        return startOffsetForContent(regionAtBlockOffset(blockOffset));
286    }
287    LayoutUnit endOffsetForContent(LayoutUnit blockOffset) const
288    {
289        return endOffsetForContent(regionAtBlockOffset(blockOffset));
290    }
291    LayoutUnit logicalLeftOffsetForContent() const { return isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
292    LayoutUnit logicalRightOffsetForContent() const { return logicalLeftOffsetForContent() + availableLogicalWidth(); }
293    LayoutUnit startOffsetForContent() const { return style().isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
294    LayoutUnit endOffsetForContent() const { return !style().isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
295
296    LayoutUnit logicalLeftSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
297    LayoutUnit logicalRightSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
298
299    LayoutUnit computeStartPositionDeltaForChildAvoidingFloats(const RenderBox& child, LayoutUnit childMarginStart, RenderRegion* = 0);
300
301#ifndef NDEBUG
302    void checkPositionedObjectsNeedLayout();
303    virtual void showLineTreeAndMark(const InlineBox* = nullptr, const char* = nullptr, const InlineBox* = nullptr, const char* = nullptr, const RenderObject* = nullptr) const;
304#endif
305
306
307#if ENABLE(CSS_SHAPES)
308    virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) override;
309#endif
310
311    virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) override;
312
313    virtual bool canHaveChildren() const override { return true; }
314    virtual bool canCollapseAnonymousBlockChild() const { return true; }
315
316protected:
317    virtual void willBeDestroyed() override;
318
319    virtual void layout() override;
320
321    void layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly = false);
322    void markFixedPositionObjectForLayoutIfNeeded(RenderObject& child);
323
324    LayoutUnit marginIntrinsicLogicalWidthForChild(RenderBox&) const;
325
326    virtual void paint(PaintInfo&, const LayoutPoint&) override;
327    virtual void paintObject(PaintInfo&, const LayoutPoint&) override;
328    virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect);
329    bool paintChild(RenderBox&, PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect);
330
331    LayoutUnit logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
332    {
333        return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
334    }
335    LayoutUnit logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
336    {
337        return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
338    }
339
340    virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
341
342    virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
343    virtual void computePreferredLogicalWidths() override;
344
345    virtual int firstLineBaseline() const override;
346    virtual int inlineBlockBaseline(LineDirectionMode) const override;
347
348    // Delay updating scrollbars until endAndCommitUpdateScrollInfoAfterLayoutTransaction() is called. These functions are used
349    // when a flexbox is laying out its descendants. If multiple calls are made to beginUpdateScrollInfoAfterLayoutTransaction()
350    // then endAndCommitUpdateScrollInfoAfterLayoutTransaction() will do nothing until it is called the same number of times.
351    void beginUpdateScrollInfoAfterLayoutTransaction();
352    void endAndCommitUpdateScrollInfoAfterLayoutTransaction();
353
354    void removeFromUpdateScrollInfoAfterLayoutTransaction();
355
356    void updateScrollInfoAfterLayout();
357
358    virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) override;
359    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
360
361    virtual bool hasLineIfEmpty() const;
362
363    bool simplifiedLayout();
364    virtual void simplifiedNormalFlowLayout();
365
366    bool childBoxIsUnsplittableForFragmentation(const RenderBox& child) const;
367
368public:
369    virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false);
370    void clearLayoutOverflow();
371
372    // Adjust from painting offsets to the local coords of this renderer
373    void offsetForContents(LayoutPoint&) const;
374
375protected:
376    virtual void addOverflowFromChildren();
377    // FIXME-BLOCKFLOW: Remove virtualization when all callers have moved to RenderBlockFlow
378    virtual void addOverflowFromInlineChildren() { }
379    void addOverflowFromBlockChildren();
380    void addOverflowFromPositionedObjects();
381    void addVisualOverflowFromTheme();
382
383    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) override;
384    virtual void addFocusRingRectsForInlineChildren(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer);
385
386    void computeRegionRangeForBoxChild(const RenderBox&) const;
387
388    void estimateRegionRangeForBoxChild(const RenderBox&) const;
389    bool updateRegionRangeForBoxChild(const RenderBox&) const;
390
391    void updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox&);
392
393    void preparePaginationBeforeBlockLayout(bool&);
394
395private:
396    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
397    virtual LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit, LayoutUnit fixedOffset, LayoutUnit) const { return fixedOffset; };
398    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
399    virtual LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit, LayoutUnit fixedOffset, LayoutUnit) const { return fixedOffset; }
400    LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
401    LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
402
403    virtual const char* renderName() const override;
404
405    virtual bool isInlineBlockOrInlineTable() const override final { return isInline() && isReplaced(); }
406
407    void makeChildrenNonInline(RenderObject* insertionPoint = nullptr);
408    virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
409
410    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
411    virtual void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert) { moveAllChildrenTo(toBlock, fullRemoveInsert); }
412
413    void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
414    virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild) override;
415
416    virtual bool isSelfCollapsingBlock() const override final;
417    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
418    virtual bool hasLines() const { return false; }
419
420    void insertIntoTrackedRendererMaps(RenderBox& descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
421    static void removeFromTrackedRendererMaps(RenderBox& descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
422
423    void createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderText* currentTextChild);
424    void updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer);
425
426    Node* nodeForHitTest() const;
427
428    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
429    virtual void paintFloats(PaintInfo&, const LayoutPoint&, bool) { }
430    virtual void paintInlineChildren(PaintInfo&, const LayoutPoint&) { }
431    void paintContents(PaintInfo&, const LayoutPoint&);
432    virtual void paintColumnRules(PaintInfo&, const LayoutPoint&) { };
433    void paintSelection(PaintInfo&, const LayoutPoint&);
434    void paintCaret(PaintInfo&, const LayoutPoint&, CaretType);
435
436    virtual bool avoidsFloats() const override;
437
438    virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
439    // FIXME-BLOCKFLOW: Remove virtualization when all callers have moved to RenderBlockFlow
440    virtual bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&) { return false; }
441    virtual bool hitTestInlineChildren(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction) { return false; }
442
443    virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset);
444
445    // FIXME: Make this method const so we can remove the const_cast in computeIntrinsicLogicalWidths.
446    void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
447    void computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
448
449    // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
450    // children.
451    virtual RenderBlock* firstLineBlock() const override;
452
453    virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const override final;
454    virtual const RenderStyle& outlineStyleForRepaint() const override final;
455
456    virtual RenderElement* hoverAncestor() const override final;
457    virtual void updateDragState(bool dragOn) override final;
458    virtual void childBecameNonInline(RenderObject* child) override final;
459
460    virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool /*clipToVisibleContent*/) override final
461    {
462        return selectionGapRectsForRepaint(repaintContainer);
463    }
464    virtual bool shouldPaintSelectionGaps() const override final;
465    bool isSelectionRoot() const;
466    GapRects selectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
467        LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo* = 0);
468    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
469    virtual GapRects inlineSelectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
470        LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
471    GapRects blockSelectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
472        LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
473    LayoutRect blockSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
474        LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const LogicalSelectionOffsetCaches&, const PaintInfo*);
475
476    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
477    virtual void clipOutFloatingObjects(RenderBlock&, const PaintInfo*, const LayoutPoint&, const LayoutSize&) { };
478    friend class LogicalSelectionOffsetCaches;
479
480    virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const override;
481    virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
482
483    void paintContinuationOutlines(PaintInfo&, const LayoutPoint&);
484
485    virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) override final;
486
487    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
488    virtual VisiblePosition positionForPointWithInlineChildren(const LayoutPoint&, const RenderRegion*);
489
490    bool expandsToEncloseOverhangingFloats() const;
491
492    void splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
493                     RenderObject* beforeChild, RenderBoxModelObject* oldCont);
494    void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
495                   RenderObject* newChild, RenderBoxModelObject* oldCont);
496    RenderPtr<RenderBlock> clone() const;
497    RenderBlock* continuationBefore(RenderObject* beforeChild);
498
499private:
500    bool hasRareData() const;
501
502protected:
503    void dirtyForLayoutFromPercentageHeightDescendants();
504
505protected:
506    bool recomputeLogicalWidth();
507
508public:
509    virtual LayoutUnit offsetFromLogicalTopOfFirstPage() const override;
510    RenderRegion* regionAtBlockOffset(LayoutUnit) const;
511
512    // FIXME: This is temporary to allow us to move code from RenderBlock into RenderBlockFlow that accesses member variables that we haven't moved out of
513    // RenderBlock yet.
514    friend class RenderBlockFlow;
515    // FIXME-BLOCKFLOW: Remove this when the line layout stuff has all moved out of RenderBlock
516    friend class LineBreaker;
517
518    mutable signed m_lineHeight : 25;
519    unsigned m_hasMarginBeforeQuirk : 1; // Note these quirk values can't be put in RenderBlockRareData since they are set too frequently.
520    unsigned m_hasMarginAfterQuirk : 1;
521    unsigned m_beingDestroyed : 1;
522    unsigned m_hasMarkupTruncation : 1;
523    unsigned m_hasBorderOrPaddingLogicalWidthChanged : 1;
524    enum LineLayoutPath { UndeterminedPath, SimpleLinesPath, LineBoxesPath, ForceLineBoxesPath };
525    unsigned m_lineLayoutPath : 2;
526
527    // RenderRubyBase objects need to be able to split and merge, moving their children around
528    // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
529    friend class RenderRubyBase;
530
531private:
532    // Used to store state between styleWillChange and styleDidChange
533    static bool s_canPropagateFloatIntoSibling;
534};
535
536RENDER_OBJECT_TYPE_CASTS(RenderBlock, isRenderBlock())
537
538LayoutUnit blockDirectionOffset(RenderBlock& rootBlock, const LayoutSize& offsetFromRootBlock);
539LayoutUnit inlineDirectionOffset(RenderBlock& rootBlock, const LayoutSize& offsetFromRootBlock);
540VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock&, RenderBox&, const LayoutPoint&);
541
542} // namespace WebCore
543
544#endif // RenderBlock_h
545