/src/3rdparty/webkit/Source/WebCore/rendering/InlineBox.h

https://bitbucket.org/ultra_iter/qt-vtl · C Header · 397 lines · 288 code · 71 blank · 38 comment · 11 complexity · 6cb0a944887bf548ce3ad3d04e1a1232 MD5 · raw file

  1. /*
  2. * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 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. #ifndef InlineBox_h
  21. #define InlineBox_h
  22. #include "RenderBoxModelObject.h"
  23. #include "TextDirection.h"
  24. namespace WebCore {
  25. class HitTestRequest;
  26. class HitTestResult;
  27. class RootInlineBox;
  28. // InlineBox represents a rectangle that occurs on a line. It corresponds to
  29. // some RenderObject (i.e., it represents a portion of that RenderObject).
  30. class InlineBox {
  31. public:
  32. InlineBox(RenderObject* obj)
  33. : m_next(0)
  34. , m_prev(0)
  35. , m_parent(0)
  36. , m_renderer(obj)
  37. , m_x(0)
  38. , m_y(0)
  39. , m_logicalWidth(0)
  40. , m_firstLine(false)
  41. , m_constructed(false)
  42. , m_bidiEmbeddingLevel(0)
  43. , m_dirty(false)
  44. , m_extracted(false)
  45. #if ENABLE(SVG)
  46. , m_hasVirtualLogicalHeight(false)
  47. #endif
  48. , m_isHorizontal(true)
  49. , m_endsWithBreak(false)
  50. , m_hasSelectedChildrenOrCanHaveLeadingExpansion(false)
  51. , m_knownToHaveNoOverflow(true)
  52. , m_hasEllipsisBoxOrHyphen(false)
  53. , m_dirOverride(false)
  54. , m_isText(false)
  55. , m_determinedIfNextOnLineExists(false)
  56. , m_determinedIfPrevOnLineExists(false)
  57. , m_nextOnLineExists(false)
  58. , m_prevOnLineExists(false)
  59. , m_expansion(0)
  60. #ifndef NDEBUG
  61. , m_hasBadParent(false)
  62. #endif
  63. {
  64. }
  65. InlineBox(RenderObject* obj, float x, float y, float logicalWidth, bool firstLine, bool constructed,
  66. bool dirty, bool extracted, bool isHorizontal, InlineBox* next, InlineBox* prev, InlineFlowBox* parent)
  67. : m_next(next)
  68. , m_prev(prev)
  69. , m_parent(parent)
  70. , m_renderer(obj)
  71. , m_x(x)
  72. , m_y(y)
  73. , m_logicalWidth(logicalWidth)
  74. , m_firstLine(firstLine)
  75. , m_constructed(constructed)
  76. , m_bidiEmbeddingLevel(0)
  77. , m_dirty(dirty)
  78. , m_extracted(extracted)
  79. #if ENABLE(SVG)
  80. , m_hasVirtualLogicalHeight(false)
  81. #endif
  82. , m_isHorizontal(isHorizontal)
  83. , m_endsWithBreak(false)
  84. , m_hasSelectedChildrenOrCanHaveLeadingExpansion(false)
  85. , m_knownToHaveNoOverflow(true)
  86. , m_hasEllipsisBoxOrHyphen(false)
  87. , m_dirOverride(false)
  88. , m_isText(false)
  89. , m_determinedIfNextOnLineExists(false)
  90. , m_determinedIfPrevOnLineExists(false)
  91. , m_nextOnLineExists(false)
  92. , m_prevOnLineExists(false)
  93. , m_expansion(0)
  94. #ifndef NDEBUG
  95. , m_hasBadParent(false)
  96. #endif
  97. {
  98. }
  99. virtual ~InlineBox();
  100. virtual void destroy(RenderArena*);
  101. virtual void deleteLine(RenderArena*);
  102. virtual void extractLine();
  103. virtual void attachLine();
  104. virtual bool isLineBreak() const { return false; }
  105. virtual void adjustPosition(float dx, float dy);
  106. void adjustLineDirectionPosition(float delta)
  107. {
  108. if (isHorizontal())
  109. adjustPosition(delta, 0);
  110. else
  111. adjustPosition(0, delta);
  112. }
  113. void adjustBlockDirectionPosition(float delta)
  114. {
  115. if (isHorizontal())
  116. adjustPosition(0, delta);
  117. else
  118. adjustPosition(delta, 0);
  119. }
  120. virtual void paint(PaintInfo&, int tx, int ty, int lineTop, int lineBottom);
  121. virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, int lineTop, int lineBottom);
  122. InlineBox* next() const { return m_next; }
  123. // Overloaded new operator.
  124. void* operator new(size_t, RenderArena*) throw();
  125. // Overridden to prevent the normal delete from being called.
  126. void operator delete(void*, size_t);
  127. private:
  128. // The normal operator new is disallowed.
  129. void* operator new(size_t) throw();
  130. public:
  131. #ifndef NDEBUG
  132. void showTreeForThis() const;
  133. void showLineTreeForThis() const;
  134. virtual void showBox(int = 0) const;
  135. virtual void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0, int = 0) const;
  136. virtual const char* boxName() const;
  137. #endif
  138. bool isText() const { return m_isText; }
  139. void setIsText(bool b) { m_isText = b; }
  140. virtual bool isInlineFlowBox() const { return false; }
  141. virtual bool isInlineTextBox() const { return false; }
  142. virtual bool isRootInlineBox() const { return false; }
  143. #if ENABLE(SVG)
  144. virtual bool isSVGInlineTextBox() const { return false; }
  145. virtual bool isSVGInlineFlowBox() const { return false; }
  146. virtual bool isSVGRootInlineBox() const { return false; }
  147. #endif
  148. bool hasVirtualLogicalHeight() const { return m_hasVirtualLogicalHeight; }
  149. void setHasVirtualLogicalHeight() { m_hasVirtualLogicalHeight = true; }
  150. virtual int virtualLogicalHeight() const
  151. {
  152. ASSERT_NOT_REACHED();
  153. return 0;
  154. }
  155. bool isHorizontal() const { return m_isHorizontal; }
  156. void setIsHorizontal(bool horizontal) { m_isHorizontal = horizontal; }
  157. virtual IntRect calculateBoundaries() const
  158. {
  159. ASSERT_NOT_REACHED();
  160. return IntRect();
  161. }
  162. bool isConstructed() { return m_constructed; }
  163. virtual void setConstructed() { m_constructed = true; }
  164. void setExtracted(bool b = true) { m_extracted = b; }
  165. void setFirstLineStyleBit(bool f) { m_firstLine = f; }
  166. bool isFirstLineStyle() const { return m_firstLine; }
  167. void remove();
  168. InlineBox* nextOnLine() const { return m_next; }
  169. InlineBox* prevOnLine() const { return m_prev; }
  170. void setNextOnLine(InlineBox* next)
  171. {
  172. ASSERT(m_parent || !next);
  173. m_next = next;
  174. }
  175. void setPrevOnLine(InlineBox* prev)
  176. {
  177. ASSERT(m_parent || !prev);
  178. m_prev = prev;
  179. }
  180. bool nextOnLineExists() const;
  181. bool prevOnLineExists() const;
  182. virtual bool isLeaf() const { return true; }
  183. InlineBox* nextLeafChild() const;
  184. InlineBox* prevLeafChild() const;
  185. RenderObject* renderer() const { return m_renderer; }
  186. InlineFlowBox* parent() const
  187. {
  188. ASSERT(!m_hasBadParent);
  189. return m_parent;
  190. }
  191. void setParent(InlineFlowBox* par) { m_parent = par; }
  192. const RootInlineBox* root() const;
  193. RootInlineBox* root();
  194. // x() is the left side of the box in the containing block's coordinate system.
  195. void setX(float x) { m_x = x; }
  196. float x() const { return m_x; }
  197. // y() is the top side of the box in the containing block's coordinate system.
  198. void setY(float y) { m_y = y; }
  199. float y() const { return m_y; }
  200. float width() const { return isHorizontal() ? logicalWidth() : logicalHeight(); }
  201. float height() const { return isHorizontal() ? logicalHeight() : logicalWidth(); }
  202. // The logicalLeft position is the left edge of the line box in a horizontal line and the top edge in a vertical line.
  203. float logicalLeft() const { return isHorizontal() ? m_x : m_y; }
  204. float logicalRight() const { return logicalLeft() + logicalWidth(); }
  205. void setLogicalLeft(float left)
  206. {
  207. if (isHorizontal())
  208. m_x = left;
  209. else
  210. m_y = left;
  211. }
  212. int pixelSnappedLogicalLeft() const { return logicalLeft(); }
  213. int pixelSnappedLogicalRight() const { return ceilf(logicalRight()); }
  214. // The logicalTop[ position is the top edge of the line box in a horizontal line and the left edge in a vertical line.
  215. int logicalTop() const { return isHorizontal() ? m_y : m_x; }
  216. int logicalBottom() const { return logicalTop() + logicalHeight(); }
  217. void setLogicalTop(int top)
  218. {
  219. if (isHorizontal())
  220. m_y = top;
  221. else
  222. m_x = top;
  223. }
  224. // The logical width is our extent in the line's overall inline direction, i.e., width for horizontal text and height for vertical text.
  225. void setLogicalWidth(float w) { m_logicalWidth = w; }
  226. float logicalWidth() const { return m_logicalWidth; }
  227. // The logical height is our extent in the block flow direction, i.e., height for horizontal text and width for vertical text.
  228. int logicalHeight() const;
  229. FloatRect logicalFrameRect() const { return isHorizontal() ? IntRect(m_x, m_y, m_logicalWidth, logicalHeight()) : IntRect(m_y, m_x, m_logicalWidth, logicalHeight()); }
  230. virtual int baselinePosition(FontBaseline baselineType) const { return boxModelObject()->baselinePosition(baselineType, m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
  231. virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); }
  232. virtual int caretMinOffset() const;
  233. virtual int caretMaxOffset() const;
  234. virtual unsigned caretMaxRenderedOffset() const;
  235. unsigned char bidiLevel() const { return m_bidiEmbeddingLevel; }
  236. void setBidiLevel(unsigned char level) { m_bidiEmbeddingLevel = level; }
  237. TextDirection direction() const { return m_bidiEmbeddingLevel % 2 ? RTL : LTR; }
  238. bool isLeftToRightDirection() const { return direction() == LTR; }
  239. int caretLeftmostOffset() const { return isLeftToRightDirection() ? caretMinOffset() : caretMaxOffset(); }
  240. int caretRightmostOffset() const { return isLeftToRightDirection() ? caretMaxOffset() : caretMinOffset(); }
  241. virtual void clearTruncation() { }
  242. bool isDirty() const { return m_dirty; }
  243. void markDirty(bool dirty = true) { m_dirty = dirty; }
  244. void dirtyLineBoxes();
  245. virtual RenderObject::SelectionState selectionState();
  246. virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
  247. // visibleLeftEdge, visibleRightEdge are in the parent's coordinate system.
  248. virtual float placeEllipsisBox(bool ltr, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, bool&);
  249. void setHasBadParent();
  250. int expansion() const { return m_expansion; }
  251. bool visibleToHitTesting() const { return renderer()->style()->visibility() == VISIBLE && renderer()->style()->pointerEvents() != PE_NONE; }
  252. EVerticalAlign verticalAlign() const { return renderer()->style(m_firstLine)->verticalAlign(); }
  253. // Use with caution! The type is not checked!
  254. RenderBoxModelObject* boxModelObject() const
  255. {
  256. if (!m_renderer->isText())
  257. return toRenderBoxModelObject(m_renderer);
  258. return 0;
  259. }
  260. FloatPoint locationIncludingFlipping();
  261. void flipForWritingMode(FloatRect&);
  262. FloatPoint flipForWritingMode(const FloatPoint&);
  263. void flipForWritingMode(IntRect&);
  264. IntPoint flipForWritingMode(const IntPoint&);
  265. bool knownToHaveNoOverflow() const { return m_knownToHaveNoOverflow; }
  266. void clearKnownToHaveNoOverflow();
  267. private:
  268. InlineBox* m_next; // The next element on the same line as us.
  269. InlineBox* m_prev; // The previous element on the same line as us.
  270. InlineFlowBox* m_parent; // The box that contains us.
  271. public:
  272. RenderObject* m_renderer;
  273. float m_x;
  274. float m_y;
  275. float m_logicalWidth;
  276. // Some of these bits are actually for subclasses and moved here to compact the structures.
  277. // for this class
  278. protected:
  279. bool m_firstLine : 1;
  280. private:
  281. bool m_constructed : 1;
  282. unsigned char m_bidiEmbeddingLevel : 6;
  283. protected:
  284. bool m_dirty : 1;
  285. bool m_extracted : 1;
  286. bool m_hasVirtualLogicalHeight : 1;
  287. bool m_isHorizontal : 1;
  288. // for RootInlineBox
  289. bool m_endsWithBreak : 1; // Whether the line ends with a <br>.
  290. // shared between RootInlineBox and InlineTextBox
  291. 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).
  292. bool m_knownToHaveNoOverflow : 1;
  293. bool m_hasEllipsisBoxOrHyphen : 1;
  294. // for InlineTextBox
  295. public:
  296. bool m_dirOverride : 1;
  297. bool m_isText : 1; // Whether or not this object represents text with a non-zero height. Includes non-image list markers, text boxes.
  298. protected:
  299. mutable bool m_determinedIfNextOnLineExists : 1;
  300. mutable bool m_determinedIfPrevOnLineExists : 1;
  301. mutable bool m_nextOnLineExists : 1;
  302. mutable bool m_prevOnLineExists : 1;
  303. int m_expansion : 11; // for justified text
  304. #ifndef NDEBUG
  305. private:
  306. bool m_hasBadParent;
  307. #endif
  308. };
  309. #ifdef NDEBUG
  310. inline InlineBox::~InlineBox()
  311. {
  312. }
  313. #endif
  314. inline void InlineBox::setHasBadParent()
  315. {
  316. #ifndef NDEBUG
  317. m_hasBadParent = true;
  318. #endif
  319. }
  320. } // namespace WebCore
  321. #ifndef NDEBUG
  322. // Outside the WebCore namespace for ease of invocation from gdb.
  323. void showTree(const WebCore::InlineBox*);
  324. void showLineTree(const WebCore::InlineBox*);
  325. #endif
  326. #endif // InlineBox_h