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