2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved.
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.
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.
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.
24 #include "RenderBoxModelObject.h"
25 #include "TextDirection.h"
33 // InlineBox represents a rectangle that occurs on a line. It corresponds to
34 // some RenderObject (i.e., it represents a portion of that RenderObject).
37 InlineBox(RenderObject* obj)
44 , m_constructed(false)
45 , m_bidiEmbeddingLevel(0)
49 , m_hasVirtualLogicalHeight(false)
51 , m_isHorizontal(true)
52 , m_endsWithBreak(false)
53 , m_hasSelectedChildrenOrCanHaveLeadingExpansion(false)
54 , m_knownToHaveNoOverflow(true)
55 , m_hasEllipsisBoxOrHyphen(false)
56 , m_dirOverride(false)
58 , m_determinedIfNextOnLineExists(false)
59 , m_determinedIfPrevOnLineExists(false)
60 , m_nextOnLineExists(false)
61 , m_prevOnLineExists(false)
64 , m_hasBadParent(false)
69 InlineBox(RenderObject* obj, FloatPoint topLeft, float logicalWidth, bool firstLine, bool constructed,
70 bool dirty, bool extracted, bool isHorizontal, InlineBox* next, InlineBox* prev, InlineFlowBox* parent)
76 , m_logicalWidth(logicalWidth)
77 , m_firstLine(firstLine)
78 , m_constructed(constructed)
79 , m_bidiEmbeddingLevel(0)
81 , m_extracted(extracted)
83 , m_hasVirtualLogicalHeight(false)
85 , m_isHorizontal(isHorizontal)
86 , m_endsWithBreak(false)
87 , m_hasSelectedChildrenOrCanHaveLeadingExpansion(false)
88 , m_knownToHaveNoOverflow(true)
89 , m_hasEllipsisBoxOrHyphen(false)
90 , m_dirOverride(false)
92 , m_determinedIfNextOnLineExists(false)
93 , m_determinedIfPrevOnLineExists(false)
94 , m_nextOnLineExists(false)
95 , m_prevOnLineExists(false)
98 , m_hasBadParent(false)
103 virtual ~InlineBox();
105 virtual void destroy(RenderArena*);
107 virtual void deleteLine(RenderArena*);
108 virtual void extractLine();
109 virtual void attachLine();
111 virtual bool isLineBreak() const { return false; }
113 virtual void adjustPosition(float dx, float dy);
114 void adjustLineDirectionPosition(float delta)
117 adjustPosition(delta, 0);
119 adjustPosition(0, delta);
121 void adjustBlockDirectionPosition(float delta)
124 adjustPosition(0, delta);
126 adjustPosition(delta, 0);
129 virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
130 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom);
132 InlineBox* next() const { return m_next; }
134 // Overloaded new operator.
135 void* operator new(size_t, RenderArena*) throw();
137 // Overridden to prevent the normal delete from being called.
138 void operator delete(void*, size_t);
141 // The normal operator new is disallowed.
142 void* operator new(size_t) throw();
146 void showTreeForThis() const;
147 void showLineTreeForThis() const;
149 virtual void showBox(int = 0) const;
150 virtual void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0, int = 0) const;
151 virtual const char* boxName() const;
154 bool isText() const { return m_isText; }
155 void setIsText(bool b) { m_isText = b; }
157 virtual bool isInlineFlowBox() const { return false; }
158 virtual bool isInlineTextBox() const { return false; }
159 virtual bool isRootInlineBox() const { return false; }
161 virtual bool isSVGInlineTextBox() const { return false; }
162 virtual bool isSVGInlineFlowBox() const { return false; }
163 virtual bool isSVGRootInlineBox() const { return false; }
166 bool hasVirtualLogicalHeight() const { return m_hasVirtualLogicalHeight; }
167 void setHasVirtualLogicalHeight() { m_hasVirtualLogicalHeight = true; }
168 virtual int virtualLogicalHeight() const
170 ASSERT_NOT_REACHED();
174 bool isHorizontal() const { return m_isHorizontal; }
175 void setIsHorizontal(bool horizontal) { m_isHorizontal = horizontal; }
177 virtual IntRect calculateBoundaries() const
179 ASSERT_NOT_REACHED();
183 bool isConstructed() { return m_constructed; }
184 virtual void setConstructed() { m_constructed = true; }
186 void setExtracted(bool b = true) { m_extracted = b; }
188 void setFirstLineStyleBit(bool f) { m_firstLine = f; }
189 bool isFirstLineStyle() const { return m_firstLine; }
193 InlineBox* nextOnLine() const { return m_next; }
194 InlineBox* prevOnLine() const { return m_prev; }
195 void setNextOnLine(InlineBox* next)
197 ASSERT(m_parent || !next);
200 void setPrevOnLine(InlineBox* prev)
202 ASSERT(m_parent || !prev);
205 bool nextOnLineExists() const;
206 bool prevOnLineExists() const;
208 virtual bool isLeaf() const { return true; }
210 InlineBox* nextLeafChild() const;
211 InlineBox* prevLeafChild() const;
213 RenderObject* renderer() const { return m_renderer; }
215 InlineFlowBox* parent() const
217 ASSERT(!m_hasBadParent);
220 void setParent(InlineFlowBox* par) { m_parent = par; }
222 const RootInlineBox* root() const;
223 RootInlineBox* root();
225 // x() is the left side of the box in the containing block's coordinate system.
226 void setX(float x) { m_topLeft.setX(x); }
227 float x() const { return m_topLeft.x(); }
228 float left() const { return m_topLeft.x(); }
230 // y() is the top side of the box in the containing block's coordinate system.
231 void setY(float y) { m_topLeft.setY(y); }
232 float y() const { return m_topLeft.y(); }
233 float top() const { return m_topLeft.y(); }
235 const FloatPoint& topLeft() const { return m_topLeft; }
237 float width() const { return isHorizontal() ? logicalWidth() : logicalHeight(); }
238 float height() const { return isHorizontal() ? logicalHeight() : logicalWidth(); }
239 FloatSize size() const { return IntSize(width(), height()); }
240 float right() const { return left() + width(); }
241 float bottom() const { return top() + height(); }
243 // The logicalLeft position is the left edge of the line box in a horizontal line and the top edge in a vertical line.
244 float logicalLeft() const { return isHorizontal() ? m_topLeft.x() : m_topLeft.y(); }
245 float logicalRight() const { return logicalLeft() + logicalWidth(); }
246 void setLogicalLeft(float left)
253 int pixelSnappedLogicalLeft() const { return logicalLeft(); }
254 int pixelSnappedLogicalRight() const { return ceilf(logicalRight()); }
256 // The logicalTop[ position is the top edge of the line box in a horizontal line and the left edge in a vertical line.
257 LayoutUnit logicalTop() const { return isHorizontal() ? m_topLeft.y() : m_topLeft.x(); }
258 LayoutUnit logicalBottom() const { return logicalTop() + logicalHeight(); }
259 void setLogicalTop(LayoutUnit top)
267 // The logical width is our extent in the line's overall inline direction, i.e., width for horizontal text and height for vertical text.
268 void setLogicalWidth(float w) { m_logicalWidth = w; }
269 float logicalWidth() const { return m_logicalWidth; }
271 // The logical height is our extent in the block flow direction, i.e., height for horizontal text and width for vertical text.
272 LayoutUnit logicalHeight() const;
274 FloatRect logicalFrameRect() const { return isHorizontal() ? FloatRect(m_topLeft.x(), m_topLeft.y(), m_logicalWidth, logicalHeight()) : FloatRect(m_topLeft.y(), m_topLeft.x(), m_logicalWidth, logicalHeight()); }
276 virtual LayoutUnit baselinePosition(FontBaseline baselineType) const { return boxModelObject()->baselinePosition(baselineType, m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
277 virtual LayoutUnit lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
279 virtual int caretMinOffset() const;
280 virtual int caretMaxOffset() const;
281 virtual unsigned caretMaxRenderedOffset() const;
283 unsigned char bidiLevel() const { return m_bidiEmbeddingLevel; }
284 void setBidiLevel(unsigned char level) { m_bidiEmbeddingLevel = level; }
285 TextDirection direction() const { return m_bidiEmbeddingLevel % 2 ? RTL : LTR; }
286 bool isLeftToRightDirection() const { return direction() == LTR; }
287 int caretLeftmostOffset() const { return isLeftToRightDirection() ? caretMinOffset() : caretMaxOffset(); }
288 int caretRightmostOffset() const { return isLeftToRightDirection() ? caretMaxOffset() : caretMinOffset(); }
290 virtual void clearTruncation() { }
292 bool isDirty() const { return m_dirty; }
293 void markDirty(bool dirty = true) { m_dirty = dirty; }
295 void dirtyLineBoxes();
297 virtual RenderObject::SelectionState selectionState();
299 virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
300 // visibleLeftEdge, visibleRightEdge are in the parent's coordinate system.
301 virtual float placeEllipsisBox(bool ltr, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, bool&);
303 void setHasBadParent();
305 int expansion() const { return m_expansion; }
307 bool visibleToHitTesting() const { return renderer()->style()->visibility() == VISIBLE && renderer()->style()->pointerEvents() != PE_NONE; }
309 EVerticalAlign verticalAlign() const { return renderer()->style(m_firstLine)->verticalAlign(); }
311 // Use with caution! The type is not checked!
312 RenderBoxModelObject* boxModelObject() const
314 if (!m_renderer->isText())
315 return toRenderBoxModelObject(m_renderer);
319 FloatPoint locationIncludingFlipping();
320 void flipForWritingMode(FloatRect&);
321 FloatPoint flipForWritingMode(const FloatPoint&);
322 void flipForWritingMode(IntRect&);
323 IntPoint flipForWritingMode(const IntPoint&);
325 bool knownToHaveNoOverflow() const { return m_knownToHaveNoOverflow; }
326 void clearKnownToHaveNoOverflow();
329 InlineBox* m_next; // The next element on the same line as us.
330 InlineBox* m_prev; // The previous element on the same line as us.
332 InlineFlowBox* m_parent; // The box that contains us.
335 RenderObject* m_renderer;
337 FloatPoint m_topLeft;
338 float m_logicalWidth;
340 // Some of these bits are actually for subclasses and moved here to compact the structures.
344 bool m_firstLine : 1;
346 bool m_constructed : 1;
347 unsigned char m_bidiEmbeddingLevel : 6;
350 bool m_extracted : 1;
351 bool m_hasVirtualLogicalHeight : 1;
353 bool m_isHorizontal : 1;
356 bool m_endsWithBreak : 1; // Whether the line ends with a <br>.
357 // shared between RootInlineBox and InlineTextBox
358 bool m_hasSelectedChildrenOrCanHaveLeadingExpansion : 1; // Whether we have any children selected (this bit will also be set if the <br> that terminates our line is selected).
359 bool m_knownToHaveNoOverflow : 1;
360 bool m_hasEllipsisBoxOrHyphen : 1;
364 bool m_dirOverride : 1;
365 bool m_isText : 1; // Whether or not this object represents text with a non-zero height. Includes non-image list markers, text boxes.
367 mutable bool m_determinedIfNextOnLineExists : 1;
368 mutable bool m_determinedIfPrevOnLineExists : 1;
369 mutable bool m_nextOnLineExists : 1;
370 mutable bool m_prevOnLineExists : 1;
371 signed m_expansion : 11; // for justified text
380 inline InlineBox::~InlineBox()
385 inline void InlineBox::setHasBadParent()
388 m_hasBadParent = true;
392 } // namespace WebCore
395 // Outside the WebCore namespace for ease of invocation from gdb.
396 void showTree(const WebCore::InlineBox*);
397 void showLineTree(const WebCore::InlineBox*);
400 #endif // InlineBox_h