WeakPtrFactory should populate m_ref lazily.
[WebKit-https.git] / Source / WebCore / rendering / RootInlineBox.h
1 /*
2  * Copyright (C) 2003, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #pragma once
22
23 #include "BidiContext.h"
24 #include "InlineFlowBox.h"
25 #include <wtf/WeakPtr.h>
26
27 namespace WebCore {
28
29 class EllipsisBox;
30 class HitTestResult;
31 class LogicalSelectionOffsetCaches;
32 class RenderBlockFlow;
33 class RenderRegion;
34
35 struct BidiStatus;
36 struct GapRects;
37
38 class RootInlineBox : public InlineFlowBox {
39 public:
40     explicit RootInlineBox(RenderBlockFlow&);
41     virtual ~RootInlineBox();
42     WeakPtr<RootInlineBox> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); }
43
44     RenderBlockFlow& blockFlow() const;
45
46     void detachEllipsisBox();
47
48     RootInlineBox* nextRootBox() const;
49     RootInlineBox* prevRootBox() const;
50
51     void adjustPosition(float dx, float dy) final;
52
53     LayoutUnit lineTop() const { return m_lineTop; }
54     LayoutUnit lineBottom() const { return m_lineBottom; }
55
56     LayoutUnit lineTopWithLeading() const { return m_lineTopWithLeading; }
57     LayoutUnit lineBottomWithLeading() const { return m_lineBottomWithLeading; }
58     
59     LayoutUnit paginationStrut() const { return m_paginationStrut; }
60     void setPaginationStrut(LayoutUnit strut) { m_paginationStrut = strut; }
61
62     bool isFirstAfterPageBreak() const { return m_isFirstAfterPageBreak; }
63     void setIsFirstAfterPageBreak(bool isFirstAfterPageBreak) { m_isFirstAfterPageBreak = isFirstAfterPageBreak; }
64
65     LayoutUnit paginatedLineWidth() const { return m_paginatedLineWidth; }
66     void setPaginatedLineWidth(LayoutUnit width) { m_paginatedLineWidth = width; }
67
68     // It should not be assumed the containingRegion() is always valid.
69     // It can also be nullptr if the flow has no region chain.
70     RenderRegion* containingRegion() const;
71     void setContainingRegion(RenderRegion&);
72     void clearContainingRegion();
73
74     LayoutUnit selectionTop() const;
75     LayoutUnit selectionBottom() const;
76     LayoutUnit selectionHeight() const { return std::max<LayoutUnit>(0, selectionBottom() - selectionTop()); }
77
78     LayoutUnit selectionTopAdjustedForPrecedingBlock() const;
79     LayoutUnit selectionHeightAdjustedForPrecedingBlock() const { return std::max<LayoutUnit>(0, selectionBottom() - selectionTopAdjustedForPrecedingBlock()); }
80
81     int blockDirectionPointInLine() const;
82
83     LayoutUnit alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
84     void setLineTopBottomPositions(LayoutUnit top, LayoutUnit bottom, LayoutUnit topWithLeading, LayoutUnit bottomWithLeading)
85     { 
86         m_lineTop = top; 
87         m_lineBottom = bottom;
88         m_lineTopWithLeading = topWithLeading;
89         m_lineBottomWithLeading = bottomWithLeading;
90     }
91
92     RenderObject* lineBreakObj() const { return m_lineBreakObj; }
93     BidiStatus lineBreakBidiStatus() const;
94     void setLineBreakInfo(RenderObject*, unsigned breakPos, const BidiStatus&);
95
96     unsigned lineBreakPos() const { return m_lineBreakPos; }
97     void setLineBreakPos(unsigned p) { m_lineBreakPos = p; }
98
99     using InlineBox::endsWithBreak;
100     using InlineBox::setEndsWithBreak;
101
102     void childRemoved(InlineBox* box);
103
104     bool lineCanAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
105     // Return the truncatedWidth, the width of the truncated text + ellipsis.
106     float placeEllipsis(const AtomicString& ellipsisStr, bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, InlineBox* markupBox = nullptr);
107     // Return the position of the EllipsisBox or -1.
108     float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) final;
109
110     using InlineBox::hasEllipsisBox;
111     EllipsisBox* ellipsisBox() const;
112
113     void paintEllipsisBox(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) const;
114
115     void clearTruncation() final;
116
117     bool isHyphenated() const;
118
119     int baselinePosition(FontBaseline baselineType) const final;
120     LayoutUnit lineHeight() const final;
121
122     void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
123     bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction) override;
124
125     using InlineBox::hasSelectedChildren;
126     using InlineBox::setHasSelectedChildren;
127
128     RenderObject::SelectionState selectionState() final;
129     InlineBox* firstSelectedBox();
130     InlineBox* lastSelectedBox();
131
132     GapRects lineSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
133         LayoutUnit selTop, LayoutUnit selHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
134
135     IntRect computeCaretRect(float logicalLeftPosition, unsigned caretWidth, LayoutUnit* extraWidthToEndOfLine) const;
136
137     InlineBox* closestLeafChildForPoint(const IntPoint&, bool onlyEditableLeaves);
138     InlineBox* closestLeafChildForLogicalLeftPosition(int, bool onlyEditableLeaves = false);
139
140     void appendFloat(RenderBox& floatingBox)
141     {
142         ASSERT(!isDirty());
143         if (m_floats)
144             m_floats->append(&floatingBox);
145         else
146             m_floats = std::make_unique<Vector<RenderBox*>>(1, &floatingBox);
147     }
148
149     void removeFloat(RenderBox& floatingBox)
150     {
151         ASSERT(m_floats);
152         ASSERT(m_floats->contains(&floatingBox));
153         m_floats->remove(m_floats->find(&floatingBox));
154     }
155
156     Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_floats.get(); }
157
158     void extractLineBoxFromRenderObject() final;
159     void attachLineBoxToRenderObject() final;
160     void removeLineBoxFromRenderObject() final;
161     
162     FontBaseline baselineType() const { return static_cast<FontBaseline>(m_baselineType); }
163
164     bool hasAnnotationsBefore() const { return m_hasAnnotationsBefore; }
165     bool hasAnnotationsAfter() const { return m_hasAnnotationsAfter; }
166
167     LayoutRect paddedLayoutOverflowRect(LayoutUnit endPadding) const;
168
169     void ascentAndDescentForBox(InlineBox&, GlyphOverflowAndFallbackFontsMap&, int& ascent, int& descent, bool& affectsAscent, bool& affectsDescent) const;
170     LayoutUnit verticalPositionForBox(InlineBox*, VerticalPositionCache&);
171     bool fitsToGlyphs() const;
172     bool includesRootLineBoxFontOrLeading() const;
173     
174     LayoutUnit logicalTopVisualOverflow() const
175     {
176         return InlineFlowBox::logicalTopVisualOverflow(lineTop());
177     }
178     LayoutUnit logicalBottomVisualOverflow() const
179     {
180         return InlineFlowBox::logicalBottomVisualOverflow(lineBottom());
181     }
182     LayoutUnit logicalTopLayoutOverflow() const
183     {
184         return InlineFlowBox::logicalTopLayoutOverflow(lineTop());
185     }
186     LayoutUnit logicalBottomLayoutOverflow() const
187     {
188         return InlineFlowBox::logicalBottomLayoutOverflow(lineBottom());
189     }
190
191     Node* getLogicalStartBoxWithNode(InlineBox*&) const;
192     Node* getLogicalEndBoxWithNode(InlineBox*&) const;
193
194     virtual bool isTrailingFloatsRootInlineBox() const { return false; }
195
196 #if ENABLE(TREE_DEBUGGING)
197     const char* boxName() const final;
198 #endif
199 private:
200     bool isRootInlineBox() const final { return true; }
201
202     bool includeLeadingForBox(InlineBox&) const;
203     bool includeFontForBox(InlineBox&) const;
204     bool includeGlyphsForBox(InlineBox&) const;
205     bool includeInitialLetterForBox(InlineBox&) const;
206     bool includeMarginForBox(InlineBox&) const;
207
208     LayoutUnit lineSnapAdjustment(LayoutUnit delta = 0) const;
209
210     LayoutUnit beforeAnnotationsAdjustment() const;
211
212     // This folds into the padding at the end of InlineFlowBox on 64-bit.
213     unsigned m_lineBreakPos;
214
215     // Where this line ended.  The exact object and the position within that object are stored so that
216     // we can create an InlineIterator beginning just after the end of this line.
217     RenderObject* m_lineBreakObj;
218     RefPtr<BidiContext> m_lineBreakContext;
219
220     LayoutUnit m_lineTop;
221     LayoutUnit m_lineBottom;
222
223     LayoutUnit m_lineTopWithLeading;
224     LayoutUnit m_lineBottomWithLeading;
225
226     LayoutUnit m_paginationStrut;
227     LayoutUnit m_paginatedLineWidth;
228
229     // Floats hanging off the line are pushed into this vector during layout. It is only
230     // good for as long as the line has not been marked dirty.
231     std::unique_ptr<Vector<RenderBox*>> m_floats;
232     WeakPtrFactory<RootInlineBox> m_weakPtrFactory;
233 };
234
235 inline RootInlineBox* RootInlineBox::nextRootBox() const
236 {
237     return downcast<RootInlineBox>(m_nextLineBox);
238 }
239
240 inline RootInlineBox* RootInlineBox::prevRootBox() const
241 {
242     return downcast<RootInlineBox>(m_prevLineBox);
243 }
244
245 } // namespace WebCore
246
247 SPECIALIZE_TYPE_TRAITS_INLINE_BOX(RootInlineBox, isRootInlineBox())