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