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 EllipsisBox;
32 class HitTestResult;
33
34 struct BidiStatus;
35 struct GapRects;
36
37 class RootInlineBox : public InlineFlowBox {
38 public:
RootInlineBox(RenderObject * obj)39 RootInlineBox(RenderObject* obj)
40 : InlineFlowBox(obj)
41 , m_overflow(0)
42 , m_lineBreakObj(0)
43 , m_lineBreakPos(0)
44 {
45 }
46
isRootInlineBox()47 virtual bool isRootInlineBox() const { return true; }
48
49 virtual void destroy(RenderArena*);
50 void detachEllipsisBox(RenderArena*);
51
nextRootBox()52 RootInlineBox* nextRootBox() { return static_cast<RootInlineBox*>(m_nextLine); }
prevRootBox()53 RootInlineBox* prevRootBox() { return static_cast<RootInlineBox*>(m_prevLine); }
54
55 virtual void adjustPosition(int dx, int dy);
56
topOverflow()57 virtual int topOverflow() const { return m_overflow ? m_overflow->m_topOverflow : m_y; }
bottomOverflow()58 virtual int bottomOverflow() const { return m_overflow ? m_overflow->m_bottomOverflow : m_y + m_renderer->style(m_firstLine)->font().height(); }
leftOverflow()59 virtual int leftOverflow() const { return m_overflow ? m_overflow->m_leftOverflow : m_x; }
rightOverflow()60 virtual int rightOverflow() const { return m_overflow ? m_overflow->m_rightOverflow : m_x + m_width; }
61
62 virtual void setVerticalOverflowPositions(int top, int bottom);
63 void setHorizontalOverflowPositions(int left, int right);
64
65 virtual void setVerticalSelectionPositions(int top, int bottom);
66
67 virtual RenderLineBoxList* rendererLineBoxes() const;
68
69 #if ENABLE(SVG)
computePerCharacterLayoutInformation()70 virtual void computePerCharacterLayoutInformation() { }
71 #endif
72
lineBreakObj()73 RenderObject* lineBreakObj() const { return m_lineBreakObj; }
74 BidiStatus lineBreakBidiStatus() const;
75 void setLineBreakInfo(RenderObject*, unsigned breakPos, const BidiStatus&);
76
lineBreakPos()77 unsigned lineBreakPos() const { return m_lineBreakPos; }
setLineBreakPos(unsigned p)78 void setLineBreakPos(unsigned p) { m_lineBreakPos = p; }
79
blockHeight()80 int blockHeight() const { return m_blockHeight; }
setBlockHeight(int h)81 void setBlockHeight(int h) { m_blockHeight = h; }
82
endsWithBreak()83 bool endsWithBreak() const { return m_endsWithBreak; }
setEndsWithBreak(bool b)84 void setEndsWithBreak(bool b) { m_endsWithBreak = b; }
85
86 void childRemoved(InlineBox* box);
87
88 bool canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
89 void placeEllipsis(const AtomicString& ellipsisStr, bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, InlineBox* markupBox = 0);
90 virtual int placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, bool& foundBox);
91
92 EllipsisBox* ellipsisBox() const;
93
94 void paintEllipsisBox(RenderObject::PaintInfo&, int tx, int ty) const;
95 bool hitTestEllipsisBox(HitTestResult&, int x, int y, int tx, int ty, HitTestAction, bool);
96
97 virtual void clearTruncation();
98
99 #if PLATFORM(MAC)
100 void addHighlightOverflow();
101 void paintCustomHighlight(RenderObject::PaintInfo&, int tx, int ty, const AtomicString& highlightType);
102 #endif
103
104 virtual void paint(RenderObject::PaintInfo&, int tx, int ty);
105 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int);
106
hasSelectedChildren()107 bool hasSelectedChildren() const { return m_hasSelectedChildren; }
108 void setHasSelectedChildren(bool);
109
110 virtual RenderObject::SelectionState selectionState();
111 InlineBox* firstSelectedBox();
112 InlineBox* lastSelectedBox();
113
114 GapRects fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY,
115 int tx, int ty, const RenderObject::PaintInfo*);
116
117 RenderBlock* block() const;
118
119 int selectionTop();
selectionBottom()120 int selectionBottom() { return m_overflow ? m_overflow->m_selectionBottom : m_y + height(); }
selectionHeight()121 int selectionHeight() { return max(0, selectionBottom() - selectionTop()); }
122
123 InlineBox* closestLeafChildForXPos(int x, bool onlyEditableLeaves = false);
124
floats()125 Vector<RenderBox*>& floats()
126 {
127 ASSERT(!isDirty());
128 if (!m_overflow)
129 m_overflow = new (m_renderer->renderArena()) Overflow(this);
130 return m_overflow->floats;
131 }
132
floatsPtr()133 Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_overflow ? &m_overflow->floats : 0; }
134
135 virtual void extractLineBoxFromRenderObject();
136 virtual void attachLineBoxToRenderObject();
137 virtual void removeLineBoxFromRenderObject();
138
139 protected:
140 // Normally we are only as tall as the style on our block dictates, but we might have content
141 // that spills out above the height of our font (e.g, a tall image), or something that extends further
142 // below our line (e.g., a child whose font has a huge descent).
143
144 // Allocated only when some of these fields have non-default values
145 struct Overflow {
OverflowOverflow146 Overflow(RootInlineBox* box)
147 : m_topOverflow(box->m_y)
148 , m_bottomOverflow(box->m_y + box->height())
149 , m_leftOverflow(box->m_x)
150 , m_rightOverflow(box->m_x + box->m_width)
151 , m_selectionTop(box->m_y)
152 , m_selectionBottom(box->m_y + box->height())
153 {
154 }
155
156 void destroy(RenderArena*);
157 void* operator new(size_t, RenderArena*) throw();
158 void operator delete(void*, size_t);
159
160 int m_topOverflow;
161 int m_bottomOverflow;
162 int m_leftOverflow;
163 int m_rightOverflow;
164 int m_selectionTop;
165 int m_selectionBottom;
166 // Floats hanging off the line are pushed into this vector during layout. It is only
167 // good for as long as the line has not been marked dirty.
168 Vector<RenderBox*> floats;
169 private:
170 void* operator new(size_t) throw();
171 };
172
173 Overflow* m_overflow;
174
175 // Where this line ended. The exact object and the position within that object are stored so that
176 // we can create an InlineIterator beginning just after the end of this line.
177 RenderObject* m_lineBreakObj;
178 unsigned m_lineBreakPos;
179 RefPtr<BidiContext> m_lineBreakContext;
180
181 // The height of the block at the end of this line. This is where the next line starts.
182 int m_blockHeight;
183
184 WTF::Unicode::Direction m_lineBreakBidiStatusEor : 5;
185 WTF::Unicode::Direction m_lineBreakBidiStatusLastStrong : 5;
186 WTF::Unicode::Direction m_lineBreakBidiStatusLast : 5;
187 };
188
setHorizontalOverflowPositions(int left,int right)189 inline void RootInlineBox::setHorizontalOverflowPositions(int left, int right)
190 {
191 if (!m_overflow) {
192 if (left == m_x && right == m_x + m_width)
193 return;
194 m_overflow = new (m_renderer->renderArena()) Overflow(this);
195 }
196 m_overflow->m_leftOverflow = left;
197 m_overflow->m_rightOverflow = right;
198 }
199
setVerticalSelectionPositions(int top,int bottom)200 inline void RootInlineBox::setVerticalSelectionPositions(int top, int bottom)
201 {
202 if (!m_overflow) {
203 const Font& font = m_renderer->style(m_firstLine)->font();
204 if (top == m_y && bottom == m_y + font.height())
205 return;
206 m_overflow = new (m_renderer->renderArena()) Overflow(this);
207 }
208 m_overflow->m_selectionTop = top;
209 m_overflow->m_selectionBottom = bottom;
210 }
211
212 } // namespace WebCore
213
214 #endif // RootInlineBox_h
215