• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the line box implementation for KDE.
3  *
4  * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef RootInlineBox_h
24 #define RootInlineBox_h
25 
26 #include "BidiContext.h"
27 #include "InlineFlowBox.h"
28 
29 namespace WebCore {
30 
31 class BidiStatus;
32 class EllipsisBox;
33 class HitTestResult;
34 struct GapRects;
35 
36 class RootInlineBox : public InlineFlowBox {
37 public:
RootInlineBox(RenderObject * obj)38     RootInlineBox(RenderObject* obj)
39         : InlineFlowBox(obj)
40         , m_overflow(0)
41         , m_lineBreakObj(0)
42         , m_lineBreakPos(0)
43     {
44     }
45 
isRootInlineBox()46     virtual bool isRootInlineBox() { return true; }
47 
48     virtual void destroy(RenderArena*);
49     void detachEllipsisBox(RenderArena*);
50 
nextRootBox()51     RootInlineBox* nextRootBox() { return static_cast<RootInlineBox*>(m_nextLine); }
prevRootBox()52     RootInlineBox* prevRootBox() { return static_cast<RootInlineBox*>(m_prevLine); }
53 
54     virtual void adjustPosition(int dx, int dy);
55 
topOverflow()56     virtual int topOverflow() { return m_overflow ? m_overflow->m_topOverflow : m_y; }
bottomOverflow()57     virtual int bottomOverflow() { return m_overflow ? m_overflow->m_bottomOverflow : m_y + m_height; }
leftOverflow()58     virtual int leftOverflow() { return m_overflow ? m_overflow->m_leftOverflow : m_x; }
rightOverflow()59     virtual int rightOverflow() { return m_overflow ? m_overflow->m_rightOverflow : m_x + m_width; }
60 
61     virtual void setVerticalOverflowPositions(int top, int bottom);
62     void setHorizontalOverflowPositions(int left, int right);
63 
64     virtual void setVerticalSelectionPositions(int top, int bottom);
65 
66 #if ENABLE(SVG)
computePerCharacterLayoutInformation()67     virtual void computePerCharacterLayoutInformation() { }
68 #endif
69 
lineBreakObj()70     RenderObject* lineBreakObj() const { return m_lineBreakObj; }
71     BidiStatus lineBreakBidiStatus() const;
72     void setLineBreakInfo(RenderObject*, unsigned breakPos, const BidiStatus&);
73 
lineBreakPos()74     unsigned lineBreakPos() const { return m_lineBreakPos; }
setLineBreakPos(unsigned p)75     void setLineBreakPos(unsigned p) { m_lineBreakPos = p; }
76 
blockHeight()77     int blockHeight() const { return m_blockHeight; }
setBlockHeight(int h)78     void setBlockHeight(int h) { m_blockHeight = h; }
79 
endsWithBreak()80     bool endsWithBreak() const { return m_endsWithBreak; }
setEndsWithBreak(bool b)81     void setEndsWithBreak(bool b) { m_endsWithBreak = b; }
82 
83     void childRemoved(InlineBox* box);
84 
85     bool canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
86     void placeEllipsis(const AtomicString& ellipsisStr, bool ltr, int blockEdge, int ellipsisWidth, InlineBox* markupBox = 0);
87     virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool& foundBox);
88 
89     EllipsisBox* ellipsisBox() const;
90 
91     void paintEllipsisBox(RenderObject::PaintInfo&, int tx, int ty) const;
92     bool hitTestEllipsisBox(HitTestResult&, int x, int y, int tx, int ty, HitTestAction, bool);
93 
94     virtual void clearTruncation();
95 
96 #if PLATFORM(MAC)
97     void addHighlightOverflow();
98     void paintCustomHighlight(RenderObject::PaintInfo&, int tx, int ty, const AtomicString& highlightType);
99 #endif
100 
101     virtual void paint(RenderObject::PaintInfo&, int tx, int ty);
102     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int);
103 
hasSelectedChildren()104     bool hasSelectedChildren() const { return m_hasSelectedChildren; }
105     void setHasSelectedChildren(bool);
106 
107     virtual RenderObject::SelectionState selectionState();
108     InlineBox* firstSelectedBox();
109     InlineBox* lastSelectedBox();
110 
111     GapRects fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY,
112                                   int tx, int ty, const RenderObject::PaintInfo*);
113 
114     RenderBlock* block() const;
115 
116     int selectionTop();
selectionBottom()117     int selectionBottom() { return m_overflow ? m_overflow->m_selectionBottom : m_y + m_height; }
selectionHeight()118     int selectionHeight() { return max(0, selectionBottom() - selectionTop()); }
119 
120     InlineBox* closestLeafChildForXPos(int x, bool onlyEditableLeaves = false);
121 
floats()122     Vector<RenderBox*>& floats()
123     {
124         ASSERT(!isDirty());
125         if (!m_overflow)
126             m_overflow = new (m_object->renderArena()) Overflow(this);
127         return m_overflow->floats;
128     }
129 
floatsPtr()130     Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_overflow ? &m_overflow->floats : 0; }
131 
132 protected:
133     // Normally we are only as tall as the style on our block dictates, but we might have content
134     // that spills out above the height of our font (e.g, a tall image), or something that extends further
135     // below our line (e.g., a child whose font has a huge descent).
136 
137     // Allocated only when some of these fields have non-default values
138     struct Overflow {
OverflowOverflow139         Overflow(RootInlineBox* box)
140             : m_topOverflow(box->m_y)
141             , m_bottomOverflow(box->m_y + box->m_height)
142             , m_leftOverflow(box->m_x)
143             , m_rightOverflow(box->m_x + box->m_width)
144             , m_selectionTop(box->m_y)
145             , m_selectionBottom(box->m_y + box->m_height)
146         {
147         }
148 
149         void destroy(RenderArena*);
150         void* operator new(size_t, RenderArena*) throw();
151         void operator delete(void*, size_t);
152 
153         int m_topOverflow;
154         int m_bottomOverflow;
155         int m_leftOverflow;
156         int m_rightOverflow;
157         int m_selectionTop;
158         int m_selectionBottom;
159         // Floats hanging off the line are pushed into this vector during layout. It is only
160         // good for as long as the line has not been marked dirty.
161         Vector<RenderBox*> floats;
162     private:
163         void* operator new(size_t) throw();
164     };
165 
166     Overflow* m_overflow;
167 
168     // Where this line ended.  The exact object and the position within that object are stored so that
169     // we can create an InlineIterator beginning just after the end of this line.
170     RenderObject* m_lineBreakObj;
171     unsigned m_lineBreakPos;
172     RefPtr<BidiContext> m_lineBreakContext;
173 
174     // The height of the block at the end of this line.  This is where the next line starts.
175     int m_blockHeight;
176 
177     WTF::Unicode::Direction m_lineBreakBidiStatusEor : 5;
178     WTF::Unicode::Direction m_lineBreakBidiStatusLastStrong : 5;
179     WTF::Unicode::Direction m_lineBreakBidiStatusLast : 5;
180 };
181 
setHorizontalOverflowPositions(int left,int right)182 inline void RootInlineBox::setHorizontalOverflowPositions(int left, int right)
183 {
184     if (!m_overflow) {
185         if (left == m_x && right == m_x + m_width)
186             return;
187         m_overflow = new (m_object->renderArena()) Overflow(this);
188     }
189     m_overflow->m_leftOverflow = left;
190     m_overflow->m_rightOverflow = right;
191 }
192 
setVerticalSelectionPositions(int top,int bottom)193 inline void RootInlineBox::setVerticalSelectionPositions(int top, int bottom)
194 {
195     if (!m_overflow) {
196         if (top == m_y && bottom == m_y + m_height)
197             return;
198         m_overflow = new (m_object->renderArena()) Overflow(this);
199     }
200     m_overflow->m_selectionTop = top;
201     m_overflow->m_selectionBottom = bottom;
202 }
203 
204 } // namespace WebCore
205 
206 #endif // RootInlineBox_h
207