SameSizeAsInlineBox mismatch on ARMV7.
[WebKit-https.git] / Source / WebCore / rendering / InlineBox.cpp
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2006, 2007 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 #include "config.h"
21 #include "InlineBox.h"
22
23 #include "FontMetrics.h"
24 #include "Frame.h"
25 #include "HitTestResult.h"
26 #include "InlineFlowBox.h"
27 #include "RenderBlockFlow.h"
28 #include "RenderLineBreak.h"
29 #include "RootInlineBox.h"
30
31 #if ENABLE(TREE_DEBUGGING)
32 #include <stdio.h>
33 #endif
34
35 namespace WebCore {
36
37 struct SameSizeAsInlineBox {
38     virtual ~SameSizeAsInlineBox() { }
39     void* a[4];
40     FloatPoint b;
41     float c[2];
42     unsigned d : 23;
43 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
44     unsigned s;
45     bool f;
46     bool i;
47 #endif
48 };
49
50 COMPILE_ASSERT(sizeof(InlineBox) == sizeof(SameSizeAsInlineBox), InlineBox_size_guard);
51
52 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
53
54 void InlineBox::assertNotDeleted() const
55 {
56     ASSERT(m_deletionSentinel == deletionSentinelNotDeletedValue);
57 }
58
59 InlineBox::~InlineBox()
60 {
61     invalidateParentChildList();
62     m_deletionSentinel = deletionSentinelDeletedValue;
63 }
64
65 void InlineBox::setHasBadParent()
66 {
67     assertNotDeleted();
68     m_hasBadParent = true;
69 }
70
71 void InlineBox::invalidateParentChildList()
72 {
73     assertNotDeleted();
74     if (!m_hasBadParent && m_parent && m_isEverInChildList)
75         m_parent->setHasBadChildList();
76 }
77
78 #endif
79
80 void InlineBox::removeFromParent()
81
82     if (parent())
83         parent()->removeChild(this);
84 }
85
86 #if ENABLE(TREE_DEBUGGING)
87
88 const char* InlineBox::boxName() const
89 {
90     return "InlineBox";
91 }
92
93 void InlineBox::showNodeTreeForThis() const
94 {
95     m_renderer.showNodeTreeForThis();
96 }
97
98 void InlineBox::showLineTreeForThis() const
99 {
100     m_renderer.containingBlock()->showLineTreeForThis();
101 }
102
103 void InlineBox::showLineTreeAndMark(const InlineBox* markedBox, int depth) const
104 {
105     showLineBox(markedBox == this, depth);
106 }
107
108 void InlineBox::showLineBox(bool mark, int depth) const
109 {
110     fprintf(stderr, "-------- %c-", isDirty() ? 'D' : '-');
111     int printedCharacters = 0;
112     if (mark) {
113         fprintf(stderr, "*");
114         ++printedCharacters;
115     }
116     while (++printedCharacters <= depth * 2)
117         fputc(' ', stderr);
118     fprintf(stderr, "%s  (%.2f, %.2f) (%.2f, %.2f) (%p) renderer->(%p)\n", boxName(), x(), y(), width(), height(), this, &renderer());
119 }
120
121 #endif // ENABLE(TREE_DEBUGGING)
122
123 float InlineBox::logicalHeight() const
124 {
125     if (hasVirtualLogicalHeight())
126         return virtualLogicalHeight();
127
128     const RenderStyle& lineStyle = this->lineStyle();
129     if (renderer().isTextOrLineBreak())
130         return behavesLikeText() ? lineStyle.fontMetrics().height() : 0;
131     if (is<RenderBox>(renderer()) && parent())
132         return isHorizontal() ? downcast<RenderBox>(renderer()).height() : downcast<RenderBox>(renderer()).width();
133
134     ASSERT(isInlineFlowBox());
135     RenderBoxModelObject* flowObject = boxModelObject();
136     const FontMetrics& fontMetrics = lineStyle.fontMetrics();
137     float result = fontMetrics.height();
138     if (parent())
139         result += flowObject->borderAndPaddingLogicalHeight();
140     return result;
141 }
142
143 int InlineBox::baselinePosition(FontBaseline baselineType) const
144 {
145     if (renderer().isLineBreak() && !behavesLikeText())
146         return 0;
147     return boxModelObject()->baselinePosition(baselineType, m_bitfields.firstLine(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
148 }
149
150 LayoutUnit InlineBox::lineHeight() const
151 {
152     if (renderer().isLineBreak() && !behavesLikeText())
153         return 0;
154     return boxModelObject()->lineHeight(m_bitfields.firstLine(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
155 }
156
157 int InlineBox::caretMinOffset() const 
158
159     return m_renderer.caretMinOffset();
160 }
161
162 int InlineBox::caretMaxOffset() const 
163
164     return m_renderer.caretMaxOffset();
165 }
166
167 void InlineBox::dirtyLineBoxes()
168 {
169     markDirty();
170     for (InlineFlowBox* curr = parent(); curr && !curr->isDirty(); curr = curr->parent())
171         curr->markDirty();
172 }
173
174 void InlineBox::adjustPosition(float dx, float dy)
175 {
176     m_topLeft.move(dx, dy);
177
178     if (m_renderer.isOutOfFlowPositioned())
179         return;
180
181     if (m_renderer.isReplaced())
182         downcast<RenderBox>(renderer()).move(dx, dy);
183 }
184
185 const RootInlineBox& InlineBox::root() const
186
187     if (parent())
188         return parent()->root();
189     return downcast<RootInlineBox>(*this);
190 }
191
192 RootInlineBox& InlineBox::root()
193
194     if (parent())
195         return parent()->root();
196     return downcast<RootInlineBox>(*this);
197 }
198
199 bool InlineBox::nextOnLineExists() const
200 {
201     if (!m_bitfields.determinedIfNextOnLineExists()) {
202         m_bitfields.setDeterminedIfNextOnLineExists(true);
203
204         if (!parent())
205             m_bitfields.setNextOnLineExists(false);
206         else if (nextOnLine())
207             m_bitfields.setNextOnLineExists(true);
208         else
209             m_bitfields.setNextOnLineExists(parent()->nextOnLineExists());
210     }
211     return m_bitfields.nextOnLineExists();
212 }
213
214 bool InlineBox::previousOnLineExists() const
215 {
216     if (!parent())
217         return false;
218     if (prevOnLine())
219         return true;
220     return parent()->previousOnLineExists();
221 }
222
223 InlineBox* InlineBox::nextLeafChild() const
224 {
225     InlineBox* leaf = nullptr;
226     for (InlineBox* box = nextOnLine(); box && !leaf; box = box->nextOnLine())
227         leaf = box->isLeaf() ? box : downcast<InlineFlowBox>(*box).firstLeafChild();
228     if (!leaf && parent())
229         leaf = parent()->nextLeafChild();
230     return leaf;
231 }
232     
233 InlineBox* InlineBox::prevLeafChild() const
234 {
235     InlineBox* leaf = nullptr;
236     for (InlineBox* box = prevOnLine(); box && !leaf; box = box->prevOnLine())
237         leaf = box->isLeaf() ? box : downcast<InlineFlowBox>(*box).lastLeafChild();
238     if (!leaf && parent())
239         leaf = parent()->prevLeafChild();
240     return leaf;
241 }
242
243 InlineBox* InlineBox::nextLeafChildIgnoringLineBreak() const
244 {
245     InlineBox* leaf = nextLeafChild();
246     if (leaf && leaf->isLineBreak())
247         return nullptr;
248     return leaf;
249 }
250
251 InlineBox* InlineBox::prevLeafChildIgnoringLineBreak() const
252 {
253     InlineBox* leaf = prevLeafChild();
254     if (leaf && leaf->isLineBreak())
255         return nullptr;
256     return leaf;
257 }
258
259 RenderObject::SelectionState InlineBox::selectionState()
260 {
261     return m_renderer.selectionState();
262 }
263
264 bool InlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth) const
265 {
266     // Non-replaced elements can always accommodate an ellipsis.
267     if (!m_renderer.isReplaced())
268         return true;
269     
270     IntRect boxRect(left(), 0, m_logicalWidth, 10);
271     IntRect ellipsisRect(ltr ? blockEdge - ellipsisWidth : blockEdge, 0, ellipsisWidth, 10);
272     return !(boxRect.intersects(ellipsisRect));
273 }
274
275 float InlineBox::placeEllipsisBox(bool, float, float, float, float& truncatedWidth, bool&)
276 {
277     // Use -1 to mean "we didn't set the position."
278     truncatedWidth += logicalWidth();
279     return -1;
280 }
281
282 void InlineBox::clearKnownToHaveNoOverflow()
283
284     m_bitfields.setKnownToHaveNoOverflow(false);
285     if (parent() && parent()->knownToHaveNoOverflow())
286         parent()->clearKnownToHaveNoOverflow();
287 }
288
289 FloatPoint InlineBox::locationIncludingFlipping()
290 {
291     if (!m_renderer.style().isFlippedBlocksWritingMode())
292         return FloatPoint(x(), y());
293     RenderBlockFlow& block = root().blockFlow();
294     if (block.style().isHorizontalWritingMode())
295         return FloatPoint(x(), block.height() - height() - y());
296     else
297         return FloatPoint(block.width() - width() - x(), y());
298 }
299
300 void InlineBox::flipForWritingMode(FloatRect& rect)
301 {
302     if (!m_renderer.style().isFlippedBlocksWritingMode())
303         return;
304     root().blockFlow().flipForWritingMode(rect);
305 }
306
307 FloatPoint InlineBox::flipForWritingMode(const FloatPoint& point)
308 {
309     if (!m_renderer.style().isFlippedBlocksWritingMode())
310         return point;
311     return root().blockFlow().flipForWritingMode(point);
312 }
313
314 void InlineBox::flipForWritingMode(LayoutRect& rect)
315 {
316     if (!m_renderer.style().isFlippedBlocksWritingMode())
317         return;
318     root().blockFlow().flipForWritingMode(rect);
319 }
320
321 LayoutPoint InlineBox::flipForWritingMode(const LayoutPoint& point)
322 {
323     if (!m_renderer.style().isFlippedBlocksWritingMode())
324         return point;
325     return root().blockFlow().flipForWritingMode(point);
326 }
327
328 } // namespace WebCore
329
330 #if ENABLE(TREE_DEBUGGING)
331
332 void showNodeTree(const WebCore::InlineBox* inlineBox)
333 {
334     if (!inlineBox)
335         return;
336     inlineBox->showNodeTreeForThis();
337 }
338
339 void showLineTree(const WebCore::InlineBox* inlineBox)
340 {
341     if (!inlineBox)
342         return;
343     inlineBox->showLineTreeForThis();
344 }
345
346 #endif