• 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 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