ce4cd4725599744faf9488890e417350d09d6152
[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
26 namespace WebCore {
27
28 class EllipsisBox;
29 class HitTestResult;
30 class LogicalSelectionOffsetCaches;
31 class RenderBlockFlow;
32 class RenderRegion;
33
34 struct BidiStatus;
35 struct GapRects;
36
37 class RootInlineBox : public InlineFlowBox {
38 public:
39     explicit RootInlineBox(RenderBlockFlow&);
40     virtual ~RootInlineBox();
41
42     RenderBlockFlow& blockFlow() const;
43
44     void detachEllipsisBox();
45
46     RootInlineBox* nextRootBox() const;
47     RootInlineBox* prevRootBox() const;
48
49     void adjustPosition(float dx, float dy) final;
50
51     LayoutUnit lineTop() const { return m_lineTop; }
52     LayoutUnit lineBottom() const { return m_lineBottom; }
53
54     LayoutUnit lineTopWithLeading() const { return m_lineTopWithLeading; }
55     LayoutUnit lineBottomWithLeading() const { return m_lineBottomWithLeading; }
56     
57     LayoutUnit paginationStrut() const { return m_paginationStrut; }
58     void setPaginationStrut(LayoutUnit strut) { m_paginationStrut = strut; }
59
60     bool isFirstAfterPageBreak() const { return m_isFirstAfterPageBreak; }
61     void setIsFirstAfterPageBreak(bool isFirstAfterPageBreak) { m_isFirstAfterPageBreak = isFirstAfterPageBreak; }
62
63     LayoutUnit paginatedLineWidth() const { return m_paginatedLineWidth; }
64     void setPaginatedLineWidth(LayoutUnit width) { m_paginatedLineWidth = width; }
65
66     // It should not be assumed the containingRegion() is always valid.
67     // It can also be nullptr if the flow has no region chain.
68     RenderRegion* containingRegion() const;
69     void setContainingRegion(RenderRegion&);
70     void clearContainingRegion();
71
72     LayoutUnit selectionTop() const;
73     LayoutUnit selectionBottom() const;
74     LayoutUnit selectionHeight() const { return std::max<LayoutUnit>(0, selectionBottom() - selectionTop()); }
75
76     LayoutUnit selectionTopAdjustedForPrecedingBlock() const;
77     LayoutUnit selectionHeightAdjustedForPrecedingBlock() const { return std::max<LayoutUnit>(0, selectionBottom() - selectionTopAdjustedForPrecedingBlock()); }
78
79     int blockDirectionPointInLine() const;
80
81     LayoutUnit alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
82     void setLineTopBottomPositions(LayoutUnit top, LayoutUnit bottom, LayoutUnit topWithLeading, LayoutUnit bottomWithLeading)
83     { 
84         m_lineTop = top; 
85         m_lineBottom = bottom;
86         m_lineTopWithLeading = topWithLeading;
87         m_lineBottomWithLeading = bottomWithLeading;
88     }
89
90     RenderObject* lineBreakObj() const { return m_lineBreakObj; }
91     BidiStatus lineBreakBidiStatus() const;
92     void setLineBreakInfo(RenderObject*, unsigned breakPos, const BidiStatus&);
93
94     unsigned lineBreakPos() const { return m_lineBreakPos; }
95     void setLineBreakPos(unsigned p) { m_lineBreakPos = p; }
96
97     using InlineBox::endsWithBreak;
98     using InlineBox::setEndsWithBreak;
99
100     void childRemoved(InlineBox* box);
101
102     bool lineCanAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
103     // Return the truncatedWidth, the width of the truncated text + ellipsis.
104     float placeEllipsis(const AtomicString& ellipsisStr, bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, InlineBox* markupBox = nullptr);
105     // Return the position of the EllipsisBox or -1.
106     float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) final;
107
108     using InlineBox::hasEllipsisBox;
109     EllipsisBox* ellipsisBox() const;
110
111     void paintEllipsisBox(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) const;
112
113     void clearTruncation() final;
114
115     bool isHyphenated() const;
116
117     int baselinePosition(FontBaseline baselineType) const final;
118     LayoutUnit lineHeight() const final;
119
120     void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
121     bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction) override;
122
123     using InlineBox::hasSelectedChildren;
124     using InlineBox::setHasSelectedChildren;
125
126     RenderObject::SelectionState selectionState() final;
127     InlineBox* firstSelectedBox();
128     InlineBox* lastSelectedBox();
129
130     GapRects lineSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
131         LayoutUnit selTop, LayoutUnit selHeight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
132
133     IntRect computeCaretRect(float logicalLeftPosition, unsigned caretWidth, LayoutUnit* extraWidthToEndOfLine) const;
134
135     InlineBox* closestLeafChildForPoint(const IntPoint&, bool onlyEditableLeaves);
136     InlineBox* closestLeafChildForLogicalLeftPosition(int, bool onlyEditableLeaves = false);
137
138     void appendFloat(RenderBox& floatingBox)
139     {
140         ASSERT(!isDirty());
141         if (m_floats)
142             m_floats->append(&floatingBox);
143         else
144             m_floats = std::make_unique<Vector<RenderBox*>>(1, &floatingBox);
145     }
146
147     void removeFloat(RenderBox& floatingBox)
148     {
149         ASSERT(m_floats);
150         ASSERT(m_floats->contains(&floatingBox));
151         m_floats->remove(m_floats->find(&floatingBox));
152     }
153
154     Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_floats.get(); }
155
156     void extractLineBoxFromRenderObject() final;
157     void attachLineBoxToRenderObject() final;
158     void removeLineBoxFromRenderObject() final;
159     
160     FontBaseline baselineType() const { return static_cast<FontBaseline>(m_baselineType); }
161
162     bool hasAnnotationsBefore() const { return m_hasAnnotationsBefore; }
163     bool hasAnnotationsAfter() const { return m_hasAnnotationsAfter; }
164
165     LayoutRect paddedLayoutOverflowRect(LayoutUnit endPadding) const;
166
167     void ascentAndDescentForBox(InlineBox&, GlyphOverflowAndFallbackFontsMap&, int& ascent, int& descent, bool& affectsAscent, bool& affectsDescent) const;
168     LayoutUnit verticalPositionForBox(InlineBox*, VerticalPositionCache&);
169     bool fitsToGlyphs() const;
170     bool includesRootLineBoxFontOrLeading() const;
171     
172     LayoutUnit logicalTopVisualOverflow() const
173     {
174         return InlineFlowBox::logicalTopVisualOverflow(lineTop());
175     }
176     LayoutUnit logicalBottomVisualOverflow() const
177     {
178         return InlineFlowBox::logicalBottomVisualOverflow(lineBottom());
179     }
180     LayoutUnit logicalTopLayoutOverflow() const
181     {
182         return InlineFlowBox::logicalTopLayoutOverflow(lineTop());
183     }
184     LayoutUnit logicalBottomLayoutOverflow() const
185     {
186         return InlineFlowBox::logicalBottomLayoutOverflow(lineBottom());
187     }
188
189     Node* getLogicalStartBoxWithNode(InlineBox*&) const;
190     Node* getLogicalEndBoxWithNode(InlineBox*&) const;
191
192     virtual bool isTrailingFloatsRootInlineBox() const { return false; }
193
194 #if ENABLE(TREE_DEBUGGING)
195     const char* boxName() const final;
196 #endif
197 private:
198     bool isRootInlineBox() const final { return true; }
199
200     bool includeLeadingForBox(InlineBox&) const;
201     bool includeFontForBox(InlineBox&) const;
202     bool includeGlyphsForBox(InlineBox&) const;
203     bool includeInitialLetterForBox(InlineBox&) const;
204     bool includeMarginForBox(InlineBox&) const;
205
206     LayoutUnit lineSnapAdjustment(LayoutUnit delta = 0) const;
207
208     LayoutUnit beforeAnnotationsAdjustment() const;
209
210     // This folds into the padding at the end of InlineFlowBox on 64-bit.
211     unsigned m_lineBreakPos;
212
213     // Where this line ended.  The exact object and the position within that object are stored so that
214     // we can create an InlineIterator beginning just after the end of this line.
215     RenderObject* m_lineBreakObj;
216     RefPtr<BidiContext> m_lineBreakContext;
217
218     LayoutUnit m_lineTop;
219     LayoutUnit m_lineBottom;
220
221     LayoutUnit m_lineTopWithLeading;
222     LayoutUnit m_lineBottomWithLeading;
223
224     LayoutUnit m_paginationStrut;
225     LayoutUnit m_paginatedLineWidth;
226
227     // Floats hanging off the line are pushed into this vector during layout. It is only
228     // good for as long as the line has not been marked dirty.
229     std::unique_ptr<Vector<RenderBox*>> m_floats;
230 };
231
232 inline RootInlineBox* RootInlineBox::nextRootBox() const
233 {
234     return downcast<RootInlineBox>(m_nextLineBox);
235 }
236
237 inline RootInlineBox* RootInlineBox::prevRootBox() const
238 {
239     return downcast<RootInlineBox>(m_prevLineBox);
240 }
241
242 } // namespace WebCore
243
244 SPECIALIZE_TYPE_TRAITS_INLINE_BOX(RootInlineBox, isRootInlineBox())