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