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#pragma once
24
25#include "GapRects.h"
26#include "LineWidth.h"
27#include "RenderBox.h"
28#include "TextRun.h"
29#include <memory>
30#include <wtf/ListHashSet.h>
31
32namespace WebCore {
33
34class LineLayoutState;
35class LogicalSelectionOffsetCaches;
36class RenderInline;
37class RenderText;
38
39struct BidiRun;
40struct PaintInfo;
41
42typedef WTF::ListHashSet<RenderBox*> TrackedRendererListHashSet;
43
44enum CaretType { CursorCaret, DragCaret };
45enum ContainingBlockState { NewContainingBlock, SameContainingBlock };
46
47enum TextRunFlag {
48 DefaultTextRunFlags = 0,
49 RespectDirection = 1 << 0,
50 RespectDirectionOverride = 1 << 1
51};
52
53typedef unsigned TextRunFlags;
54
55class RenderBlock : public RenderBox {
56 WTF_MAKE_ISO_ALLOCATED(RenderBlock);
57public:
58 friend class LineLayoutState;
59 virtual ~RenderBlock();
60
61protected:
62 RenderBlock(Element&, RenderStyle&&, BaseTypeFlags);
63 RenderBlock(Document&, RenderStyle&&, BaseTypeFlags);
64
65public:
66 // These two functions are overridden for inline-block.
67 LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const final;
68 int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
69
70 LayoutUnit minLineHeightForReplacedRenderer(bool isFirstLine, LayoutUnit replacedHeight) const;
71
72 // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
73 virtual void deleteLines();
74
75 virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0_lu);
76
77 virtual void invalidateLineLayoutPath() { }
78
79 void insertPositionedObject(RenderBox&);
80 static void removePositionedObject(const RenderBox&);
81 void removePositionedObjects(const RenderBlock*, ContainingBlockState = SameContainingBlock);
82
83 TrackedRendererListHashSet* positionedObjects() const;
84 bool hasPositionedObjects() const
85 {
86 TrackedRendererListHashSet* objects = positionedObjects();
87 return objects && !objects->isEmpty();
88 }
89
90 void addPercentHeightDescendant(RenderBox&);
91 static void removePercentHeightDescendant(RenderBox&);
92 TrackedRendererListHashSet* percentHeightDescendants() const;
93 bool hasPercentHeightDescendants() const
94 {
95 TrackedRendererListHashSet* objects = percentHeightDescendants();
96 return objects && !objects->isEmpty();
97 }
98 static bool hasPercentHeightContainerMap();
99 static bool hasPercentHeightDescendant(RenderBox&);
100 static void clearPercentHeightDescendantsFrom(RenderBox&);
101 static void removePercentHeightDescendantIfNeeded(RenderBox&);
102
103 bool isContainingBlockAncestorFor(RenderObject&) const;
104
105 void setHasMarginBeforeQuirk(bool b) { setRenderBlockHasMarginBeforeQuirk(b); }
106 void setHasMarginAfterQuirk(bool b) { setRenderBlockHasMarginAfterQuirk(b); }
107 void setShouldForceRelayoutChildren(bool b) { setRenderBlockShouldForceRelayoutChildren(b); }
108
109 bool hasMarginBeforeQuirk() const { return renderBlockHasMarginBeforeQuirk(); }
110 bool hasMarginAfterQuirk() const { return renderBlockHasMarginAfterQuirk(); }
111 bool hasBorderOrPaddingLogicalWidthChanged() const { return renderBlockShouldForceRelayoutChildren(); }
112
113 bool hasMarginBeforeQuirk(const RenderBox& child) const;
114 bool hasMarginAfterQuirk(const RenderBox& child) const;
115
116 bool generatesLineBoxesForInlineChild(RenderObject*);
117
118 void markPositionedObjectsForLayout();
119 void markForPaginationRelayoutIfNeeded() override;
120
121 // FIXME-BLOCKFLOW: Remove virtualizaion when all of the line layout code has been moved out of RenderBlock
122 virtual bool containsFloats() const { return false; }
123
124 // Versions that can compute line offsets with the fragment and page offset passed in. Used for speed to avoid having to
125 // compute the fragment all over again when you already know it.
126 LayoutUnit availableLogicalWidthForLineInFragment(LayoutUnit position, IndentTextOrNot shouldIndentText, RenderFragmentContainer* fragment, LayoutUnit logicalHeight = 0_lu) const
127 {
128 return std::max<LayoutUnit>(0, logicalRightOffsetForLineInFragment(position, shouldIndentText, fragment, logicalHeight)
129 - logicalLeftOffsetForLineInFragment(position, shouldIndentText, fragment, logicalHeight));
130 }
131 LayoutUnit logicalRightOffsetForLineInFragment(LayoutUnit position, IndentTextOrNot shouldIndentText, RenderFragmentContainer* fragment, LayoutUnit logicalHeight = 0_lu) const
132 {
133 return logicalRightOffsetForLine(position, logicalRightOffsetForContent(fragment), shouldIndentText, logicalHeight);
134 }
135 LayoutUnit logicalLeftOffsetForLineInFragment(LayoutUnit position, IndentTextOrNot shouldIndentText, RenderFragmentContainer* fragment, LayoutUnit logicalHeight = 0_lu) const
136 {
137 return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(fragment), shouldIndentText, logicalHeight);
138 }
139 LayoutUnit startOffsetForLineInFragment(LayoutUnit position, IndentTextOrNot shouldIndentText, RenderFragmentContainer* fragment, LayoutUnit logicalHeight = 0_lu) const
140 {
141 return style().isLeftToRightDirection() ? logicalLeftOffsetForLineInFragment(position, shouldIndentText, fragment, logicalHeight)
142 : logicalWidth() - logicalRightOffsetForLineInFragment(position, shouldIndentText, fragment, logicalHeight);
143 }
144 LayoutUnit endOffsetForLineInFragment(LayoutUnit position, IndentTextOrNot shouldIndentText, RenderFragmentContainer* fragment, LayoutUnit logicalHeight = 0_lu) const
145 {
146 return !style().isLeftToRightDirection() ? logicalLeftOffsetForLineInFragment(position, shouldIndentText, fragment, logicalHeight)
147 : logicalWidth() - logicalRightOffsetForLineInFragment(position, shouldIndentText, fragment, logicalHeight);
148 }
149
150 LayoutUnit availableLogicalWidthForLine(LayoutUnit position, IndentTextOrNot shouldIndentText, LayoutUnit logicalHeight = 0_lu) const
151 {
152 return availableLogicalWidthForLineInFragment(position, shouldIndentText, fragmentAtBlockOffset(position), logicalHeight);
153 }
154 LayoutUnit logicalRightOffsetForLine(LayoutUnit position, IndentTextOrNot shouldIndentText, LayoutUnit logicalHeight = 0_lu) const
155 {
156 return logicalRightOffsetForLine(position, logicalRightOffsetForContent(position), shouldIndentText, logicalHeight);
157 }
158 LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, IndentTextOrNot shouldIndentText, LayoutUnit logicalHeight = 0_lu) const
159 {
160 return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(position), shouldIndentText, logicalHeight);
161 }
162 LayoutUnit startOffsetForLine(LayoutUnit position, IndentTextOrNot shouldIndentText, LayoutUnit logicalHeight = 0_lu) const
163 {
164 return style().isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
165 : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
166 }
167 LayoutUnit endOffsetForLine(LayoutUnit position, IndentTextOrNot shouldIndentText, LayoutUnit logicalHeight = 0_lu) const
168 {
169 return !style().isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
170 : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
171 }
172
173 LayoutUnit textIndentOffset() const;
174
175 VisiblePosition positionForPoint(const LayoutPoint&, const RenderFragmentContainer*) override;
176
177 GapRects selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer);
178 LayoutRect logicalLeftSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
179 RenderBoxModelObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
180 LayoutRect logicalRightSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
181 RenderBoxModelObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
182 void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
183 bool isSelectionRoot() const;
184
185 LayoutRect logicalRectToPhysicalRect(const LayoutPoint& physicalPosition, const LayoutRect& logicalRect);
186
187 void addContinuationWithOutline(RenderInline*);
188 bool paintsContinuationOutline(RenderInline*);
189
190 static RenderPtr<RenderBlock> createAnonymousWithParentRendererAndDisplay(const RenderBox& parent, DisplayType = DisplayType::Block);
191 RenderPtr<RenderBlock> createAnonymousBlock(DisplayType = DisplayType::Block) const;
192
193 RenderPtr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
194
195 static bool shouldSkipCreatingRunsForObject(RenderObject& obj)
196 {
197 return obj.isFloating() || (obj.isOutOfFlowPositioned() && !obj.style().isOriginalDisplayInlineType() && !obj.container()->isRenderInline());
198 }
199
200 static TextRun constructTextRun(StringView, const RenderStyle&,
201 ExpansionBehavior = DefaultExpansion, TextRunFlags = DefaultTextRunFlags);
202 static TextRun constructTextRun(const String&, const RenderStyle&,
203 ExpansionBehavior = DefaultExpansion, TextRunFlags = DefaultTextRunFlags);
204 static TextRun constructTextRun(const AtomString&, const RenderStyle&,
205 ExpansionBehavior = DefaultExpansion, TextRunFlags = DefaultTextRunFlags);
206 static TextRun constructTextRun(const RenderText&, const RenderStyle&,
207 ExpansionBehavior = DefaultExpansion);
208 static TextRun constructTextRun(const RenderText&, unsigned offset, unsigned length, const RenderStyle&,
209 ExpansionBehavior = DefaultExpansion);
210 static TextRun constructTextRun(const LChar* characters, unsigned length, const RenderStyle&,
211 ExpansionBehavior = DefaultExpansion);
212 static TextRun constructTextRun(const UChar* characters, unsigned length, const RenderStyle&,
213 ExpansionBehavior = DefaultExpansion);
214
215 LayoutUnit paginationStrut() const;
216 void setPaginationStrut(LayoutUnit);
217
218 // The page logical offset is the object's offset from the top of the page in the page progression
219 // direction (so an x-offset in vertical text and a y-offset for horizontal text).
220 LayoutUnit pageLogicalOffset() const;
221 void setPageLogicalOffset(LayoutUnit);
222
223 // Fieldset legends that are taller than the fieldset border add in intrinsic border
224 // in order to ensure that content gets properly pushed down across all layout systems
225 // (flexbox, block, etc.)
226 LayoutUnit intrinsicBorderForFieldset() const;
227 void setIntrinsicBorderForFieldset(LayoutUnit);
228 LayoutUnit borderTop() const override;
229 LayoutUnit borderBottom() const override;
230 LayoutUnit borderLeft() const override;
231 LayoutUnit borderRight() const override;
232 LayoutUnit borderBefore() const override;
233 LayoutUnit adjustBorderBoxLogicalHeightForBoxSizing(LayoutUnit height) const override;
234 LayoutUnit adjustContentBoxLogicalHeightForBoxSizing(Optional<LayoutUnit> height) const override;
235 void paintExcludedChildrenInBorder(PaintInfo&, const LayoutPoint&);
236
237 // Accessors for logical width/height and margins in the containing block's block-flow direction.
238 enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
239 LayoutUnit logicalWidthForChild(const RenderBox& child) const { return isHorizontalWritingMode() ? child.width() : child.height(); }
240 LayoutUnit logicalHeightForChild(const RenderBox& child) const { return isHorizontalWritingMode() ? child.height() : child.width(); }
241 LayoutSize logicalSizeForChild(const RenderBox& child) const { return isHorizontalWritingMode() ? child.size() : child.size().transposedSize(); }
242 LayoutUnit logicalTopForChild(const RenderBox& child) const { return isHorizontalWritingMode() ? child.y() : child.x(); }
243 void setLogicalLeftForChild(RenderBox& child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
244 void setLogicalTopForChild(RenderBox& child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
245 LayoutUnit marginBeforeForChild(const RenderBoxModelObject& child) const { return child.marginBefore(&style()); }
246 LayoutUnit marginAfterForChild(const RenderBoxModelObject& child) const { return child.marginAfter(&style()); }
247 LayoutUnit marginStartForChild(const RenderBoxModelObject& child) const { return child.marginStart(&style()); }
248 LayoutUnit marginEndForChild(const RenderBoxModelObject& child) const { return child.marginEnd(&style()); }
249 void setMarginStartForChild(RenderBox& child, LayoutUnit value) const { child.setMarginStart(value, &style()); }
250 void setMarginEndForChild(RenderBox& child, LayoutUnit value) const { child.setMarginEnd(value, &style()); }
251 void setMarginBeforeForChild(RenderBox& child, LayoutUnit value) const { child.setMarginBefore(value, &style()); }
252 void setMarginAfterForChild(RenderBox& child, LayoutUnit value) const { child.setMarginAfter(value, &style()); }
253 LayoutUnit collapsedMarginBeforeForChild(const RenderBox& child) const;
254 LayoutUnit collapsedMarginAfterForChild(const RenderBox& child) const;
255
256 void getFirstLetter(RenderObject*& firstLetter, RenderElement*& firstLetterContainer, RenderObject* skipObject = nullptr);
257
258 virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { }
259
260 LayoutUnit logicalLeftOffsetForContent(RenderFragmentContainer*) const;
261 LayoutUnit logicalRightOffsetForContent(RenderFragmentContainer*) const;
262 LayoutUnit availableLogicalWidthForContent(RenderFragmentContainer* fragment) const
263 {
264 return std::max<LayoutUnit>(0, logicalRightOffsetForContent(fragment) - logicalLeftOffsetForContent(fragment));
265 }
266 LayoutUnit startOffsetForContent(RenderFragmentContainer* fragment) const
267 {
268 return style().isLeftToRightDirection() ? logicalLeftOffsetForContent(fragment) : logicalWidth() - logicalRightOffsetForContent(fragment);
269 }
270 LayoutUnit endOffsetForContent(RenderFragmentContainer* fragment) const
271 {
272 return !style().isLeftToRightDirection() ? logicalLeftOffsetForContent(fragment) : logicalWidth() - logicalRightOffsetForContent(fragment);
273 }
274 LayoutUnit logicalLeftOffsetForContent(LayoutUnit blockOffset) const
275 {
276 return logicalLeftOffsetForContent(fragmentAtBlockOffset(blockOffset));
277 }
278 LayoutUnit logicalRightOffsetForContent(LayoutUnit blockOffset) const
279 {
280 return logicalRightOffsetForContent(fragmentAtBlockOffset(blockOffset));
281 }
282 LayoutUnit availableLogicalWidthForContent(LayoutUnit blockOffset) const
283 {
284 return availableLogicalWidthForContent(fragmentAtBlockOffset(blockOffset));
285 }
286 LayoutUnit startOffsetForContent(LayoutUnit blockOffset) const
287 {
288 return startOffsetForContent(fragmentAtBlockOffset(blockOffset));
289 }
290 LayoutUnit endOffsetForContent(LayoutUnit blockOffset) const
291 {
292 return endOffsetForContent(fragmentAtBlockOffset(blockOffset));
293 }
294 LayoutUnit logicalLeftOffsetForContent() const { return isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
295 LayoutUnit logicalRightOffsetForContent() const { return logicalLeftOffsetForContent() + availableLogicalWidth(); }
296 LayoutUnit startOffsetForContent() const { return style().isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
297 LayoutUnit endOffsetForContent() const { return !style().isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
298
299 LayoutUnit logicalLeftSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
300 LayoutUnit logicalRightSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
301
302 LayoutUnit computeStartPositionDeltaForChildAvoidingFloats(const RenderBox& child, LayoutUnit childMarginStart, RenderFragmentContainer* = 0);
303
304#ifndef NDEBUG
305 void checkPositionedObjectsNeedLayout();
306#endif
307
308 void updateHitTestResult(HitTestResult&, const LayoutPoint&) override;
309
310 bool canHaveChildren() const override { return true; }
311 virtual bool canDropAnonymousBlockChild() const { return true; }
312
313 RenderFragmentedFlow* cachedEnclosingFragmentedFlow() const;
314 void setCachedEnclosingFragmentedFlowNeedsUpdate();
315 virtual bool cachedEnclosingFragmentedFlowNeedsUpdate() const;
316 void resetEnclosingFragmentedFlowAndChildInfoIncludingDescendants(RenderFragmentedFlow* = nullptr) final;
317
318 Optional<LayoutUnit> availableLogicalHeightForPercentageComputation() const;
319 bool hasDefiniteLogicalHeight() const;
320
321protected:
322 RenderFragmentedFlow* locateEnclosingFragmentedFlow() const override;
323 void willBeDestroyed() override;
324
325 void layout() override;
326
327 void layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly = false);
328 virtual void layoutPositionedObject(RenderBox&, bool relayoutChildren, bool fixedPositionObjectsOnly);
329
330 void markFixedPositionObjectForLayoutIfNeeded(RenderBox& child);
331
332 LayoutUnit marginIntrinsicLogicalWidthForChild(RenderBox&) const;
333
334 void paint(PaintInfo&, const LayoutPoint&) override;
335 void paintObject(PaintInfo&, const LayoutPoint&) override;
336 virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect);
337 enum PaintBlockType { PaintAsBlock, PaintAsInlineBlock };
338 bool paintChild(RenderBox&, PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect, PaintBlockType paintType = PaintAsBlock);
339
340 LayoutUnit logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0_lu) const
341 {
342 return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
343 }
344 LayoutUnit logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0_lu) const
345 {
346 return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
347 }
348
349 bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
350
351 void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
352 void computePreferredLogicalWidths() override;
353
354 Optional<int> firstLineBaseline() const override;
355 Optional<int> inlineBlockBaseline(LineDirectionMode) const override;
356
357 // Delay updating scrollbars until endAndCommitUpdateScrollInfoAfterLayoutTransaction() is called. These functions are used
358 // when a flexbox is laying out its descendants. If multiple calls are made to beginUpdateScrollInfoAfterLayoutTransaction()
359 // then endAndCommitUpdateScrollInfoAfterLayoutTransaction() will do nothing until it is called the same number of times.
360 void beginUpdateScrollInfoAfterLayoutTransaction();
361 void endAndCommitUpdateScrollInfoAfterLayoutTransaction();
362
363 void removeFromUpdateScrollInfoAfterLayoutTransaction();
364
365 void updateScrollInfoAfterLayout();
366
367 void styleWillChange(StyleDifference, const RenderStyle& newStyle) override;
368 void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
369
370 virtual bool hasLineIfEmpty() const;
371
372 virtual bool canPerformSimplifiedLayout() const;
373 bool simplifiedLayout();
374 virtual void simplifiedNormalFlowLayout();
375
376 bool childBoxIsUnsplittableForFragmentation(const RenderBox& child) const;
377
378public:
379 virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false);
380 void clearLayoutOverflow();
381
382 // Adjust from painting offsets to the local coords of this renderer
383 void offsetForContents(LayoutPoint&) const;
384 // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
385 // children.
386 RenderBlock* firstLineBlock() const override;
387
388 enum FieldsetFindLegendOption { FieldsetIgnoreFloatingOrOutOfFlow, FieldsetIncludeFloatingOrOutOfFlow };
389 RenderBox* findFieldsetLegend(FieldsetFindLegendOption = FieldsetIgnoreFloatingOrOutOfFlow) const;
390 virtual void layoutExcludedChildren(bool /*relayoutChildren*/);
391 virtual bool computePreferredWidthsForExcludedChildren(LayoutUnit&, LayoutUnit&) const;
392
393 void adjustBorderBoxRectForPainting(LayoutRect&) override;
394 LayoutRect paintRectToClipOutFromBorder(const LayoutRect&) override;
395 bool isInlineBlockOrInlineTable() const final { return isInline() && isReplaced(); }
396
397protected:
398 virtual void addOverflowFromChildren();
399 // FIXME-BLOCKFLOW: Remove virtualization when all callers have moved to RenderBlockFlow
400 virtual void addOverflowFromInlineChildren() { }
401 void addOverflowFromBlockChildren();
402 void addOverflowFromPositionedObjects();
403 void addVisualOverflowFromTheme();
404
405 void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) override;
406 virtual void addFocusRingRectsForInlineChildren(Vector<LayoutRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer);
407
408 void computeFragmentRangeForBoxChild(const RenderBox&) const;
409
410 void estimateFragmentRangeForBoxChild(const RenderBox&) const;
411 bool updateFragmentRangeForBoxChild(const RenderBox&) const;
412
413 void updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox&);
414
415 void preparePaginationBeforeBlockLayout(bool&);
416
417 void computeChildPreferredLogicalWidths(RenderObject&, LayoutUnit& minPreferredLogicalWidth, LayoutUnit& maxPreferredLogicalWidth) const;
418
419 void blockWillBeDestroyed();
420
421private:
422 static RenderPtr<RenderBlock> createAnonymousBlockWithStyleAndDisplay(Document&, const RenderStyle&, DisplayType);
423
424 // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
425 virtual LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit, LayoutUnit fixedOffset, LayoutUnit) const { return fixedOffset; };
426 // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
427 virtual LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit, LayoutUnit fixedOffset, LayoutUnit) const { return fixedOffset; }
428 LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
429 LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
430
431 const char* renderName() const override;
432
433 bool isSelfCollapsingBlock() const override;
434 virtual bool childrenPreventSelfCollapsing() const;
435
436 Node* nodeForHitTest() const;
437
438 // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
439 virtual void paintFloats(PaintInfo&, const LayoutPoint&, bool) { }
440 virtual void paintInlineChildren(PaintInfo&, const LayoutPoint&) { }
441 void paintContents(PaintInfo&, const LayoutPoint&);
442 virtual void paintColumnRules(PaintInfo&, const LayoutPoint&) { };
443 void paintSelection(PaintInfo&, const LayoutPoint&);
444 void paintCaret(PaintInfo&, const LayoutPoint&, CaretType);
445
446 virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
447 // FIXME-BLOCKFLOW: Remove virtualization when all callers have moved to RenderBlockFlow
448 virtual bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&) { return false; }
449 virtual bool hitTestInlineChildren(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction) { return false; }
450 bool hitTestExcludedChildrenInBorder(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
451
452 virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset);
453
454 void computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
455
456 LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const final;
457 const RenderStyle& outlineStyleForRepaint() const final;
458
459 void updateDragState(bool dragOn) final;
460
461 LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool /*clipToVisibleContent*/) final
462 {
463 return selectionGapRectsForRepaint(repaintContainer);
464 }
465 bool shouldPaintSelectionGaps() const final;
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 void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const override;
481 void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
482
483 void paintContinuationOutlines(PaintInfo&, const LayoutPoint&);
484
485 LayoutRect localCaretRect(InlineBox*, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) final;
486
487 // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
488 virtual VisiblePosition positionForPointWithInlineChildren(const LayoutPoint&, const RenderFragmentContainer*);
489
490 RenderPtr<RenderBlock> clone() const;
491
492 RenderFragmentedFlow* updateCachedEnclosingFragmentedFlow(RenderFragmentedFlow*) const;
493
494 void removePositionedObjectsIfNeeded(const RenderStyle& oldStyle, const RenderStyle& newStyle);
495
496private:
497 bool hasRareData() const;
498
499protected:
500 void dirtyForLayoutFromPercentageHeightDescendants();
501
502protected:
503 bool recomputeLogicalWidth();
504
505public:
506 LayoutUnit offsetFromLogicalTopOfFirstPage() const override;
507 RenderFragmentContainer* fragmentAtBlockOffset(LayoutUnit) const;
508
509 // 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
510 // RenderBlock yet.
511 friend class RenderBlockFlow;
512 // FIXME-BLOCKFLOW: Remove this when the line layout stuff has all moved out of RenderBlock
513 friend class LineBreaker;
514
515 // RenderRubyBase objects need to be able to split and merge, moving their children around
516 // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
517 friend class RenderRubyBase;
518
519private:
520 // Used to store state between styleWillChange and styleDidChange
521 static bool s_canPropagateFloatIntoSibling;
522};
523
524LayoutUnit blockDirectionOffset(RenderBlock& rootBlock, const LayoutSize& offsetFromRootBlock);
525LayoutUnit inlineDirectionOffset(RenderBlock& rootBlock, const LayoutSize& offsetFromRootBlock);
526VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock&, RenderBox&, const LayoutPoint&);
527
528inline RenderPtr<RenderBlock> RenderBlock::createAnonymousWithParentRendererAndDisplay(const RenderBox& parent, DisplayType display)
529{
530 return createAnonymousBlockWithStyleAndDisplay(parent.document(), parent.style(), display);
531}
532
533inline RenderPtr<RenderBox> RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
534{
535 return createAnonymousBlockWithStyleAndDisplay(document(), renderer.style(), style().display());
536}
537
538inline RenderPtr<RenderBlock> RenderBlock::createAnonymousBlock(DisplayType display) const
539{
540 return createAnonymousBlockWithStyleAndDisplay(document(), style(), display);
541}
542
543} // namespace WebCore
544
545SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderBlock, isRenderBlock())
546