OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU Library General Public License | 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 | 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, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
18 */ | 18 */ |
19 | 19 |
20 #include "config.h" | 20 #include "config.h" |
21 #include "core/layout/line/InlineFlowBox.h" | 21 #include "core/layout/line/InlineFlowBox.h" |
22 | 22 |
23 #include "core/CSSPropertyNames.h" | 23 #include "core/CSSPropertyNames.h" |
24 #include "core/dom/Document.h" | 24 #include "core/dom/Document.h" |
25 #include "core/layout/HitTestResult.h" | 25 #include "core/layout/HitTestResult.h" |
26 #include "core/layout/Layer.h" | 26 #include "core/layout/Layer.h" |
| 27 #include "core/layout/LayoutObjectInlines.h" |
27 #include "core/layout/LayoutRubyBase.h" | 28 #include "core/layout/LayoutRubyBase.h" |
28 #include "core/layout/LayoutRubyRun.h" | 29 #include "core/layout/LayoutRubyRun.h" |
29 #include "core/layout/LayoutRubyText.h" | 30 #include "core/layout/LayoutRubyText.h" |
30 #include "core/layout/line/InlineTextBox.h" | 31 #include "core/layout/line/InlineTextBox.h" |
31 #include "core/layout/line/RootInlineBox.h" | 32 #include "core/layout/line/RootInlineBox.h" |
32 #include "core/paint/BoxPainter.h" | 33 #include "core/paint/BoxPainter.h" |
33 #include "core/paint/InlineFlowBoxPainter.h" | 34 #include "core/paint/InlineFlowBoxPainter.h" |
34 #include "core/rendering/RenderBlock.h" | 35 #include "core/rendering/RenderBlock.h" |
35 #include "core/rendering/RenderInline.h" | 36 #include "core/rendering/RenderInline.h" |
36 #include "core/rendering/RenderListMarker.h" | 37 #include "core/rendering/RenderListMarker.h" |
37 #include "core/rendering/RenderObjectInlines.h" | |
38 #include "core/rendering/RenderView.h" | 38 #include "core/rendering/RenderView.h" |
39 #include "core/rendering/style/ShadowList.h" | 39 #include "core/rendering/style/ShadowList.h" |
40 #include "platform/fonts/Font.h" | 40 #include "platform/fonts/Font.h" |
41 #include "platform/graphics/GraphicsContextStateSaver.h" | 41 #include "platform/graphics/GraphicsContextStateSaver.h" |
42 | 42 |
43 #include <math.h> | 43 #include <math.h> |
44 | 44 |
45 namespace blink { | 45 namespace blink { |
46 | 46 |
47 struct SameSizeAsInlineFlowBox : public InlineBox { | 47 struct SameSizeAsInlineFlowBox : public InlineBox { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 child->setParent(0); | 213 child->setParent(0); |
214 #endif | 214 #endif |
215 child->deleteLine(); | 215 child->deleteLine(); |
216 child = next; | 216 child = next; |
217 } | 217 } |
218 #if ENABLE(ASSERT) | 218 #if ENABLE(ASSERT) |
219 m_firstChild = 0; | 219 m_firstChild = 0; |
220 m_lastChild = 0; | 220 m_lastChild = 0; |
221 #endif | 221 #endif |
222 | 222 |
223 removeLineBoxFromRenderObject(); | 223 removeLineBoxFromLayoutObject(); |
224 destroy(); | 224 destroy(); |
225 } | 225 } |
226 | 226 |
227 void InlineFlowBox::removeLineBoxFromRenderObject() | 227 void InlineFlowBox::removeLineBoxFromLayoutObject() |
228 { | 228 { |
229 rendererLineBoxes()->removeLineBox(this); | 229 rendererLineBoxes()->removeLineBox(this); |
230 } | 230 } |
231 | 231 |
232 void InlineFlowBox::extractLine() | 232 void InlineFlowBox::extractLine() |
233 { | 233 { |
234 if (!extracted()) | 234 if (!extracted()) |
235 extractLineBoxFromRenderObject(); | 235 extractLineBoxFromLayoutObject(); |
236 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) | 236 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) |
237 child->extractLine(); | 237 child->extractLine(); |
238 } | 238 } |
239 | 239 |
240 void InlineFlowBox::extractLineBoxFromRenderObject() | 240 void InlineFlowBox::extractLineBoxFromLayoutObject() |
241 { | 241 { |
242 rendererLineBoxes()->extractLineBox(this); | 242 rendererLineBoxes()->extractLineBox(this); |
243 } | 243 } |
244 | 244 |
245 void InlineFlowBox::attachLine() | 245 void InlineFlowBox::attachLine() |
246 { | 246 { |
247 if (extracted()) | 247 if (extracted()) |
248 attachLineBoxToRenderObject(); | 248 attachLineBoxToLayoutObject(); |
249 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) | 249 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) |
250 child->attachLine(); | 250 child->attachLine(); |
251 } | 251 } |
252 | 252 |
253 void InlineFlowBox::attachLineBoxToRenderObject() | 253 void InlineFlowBox::attachLineBoxToLayoutObject() |
254 { | 254 { |
255 rendererLineBoxes()->attachLineBox(this); | 255 rendererLineBoxes()->attachLineBox(this); |
256 } | 256 } |
257 | 257 |
258 void InlineFlowBox::adjustPosition(FloatWillBeLayoutUnit dx, FloatWillBeLayoutUn
it dy) | 258 void InlineFlowBox::adjustPosition(FloatWillBeLayoutUnit dx, FloatWillBeLayoutUn
it dy) |
259 { | 259 { |
260 InlineBox::adjustPosition(dx, dy); | 260 InlineBox::adjustPosition(dx, dy); |
261 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) | 261 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) |
262 child->adjustPosition(dx, dy); | 262 child->adjustPosition(dx, dy); |
263 if (m_overflow) | 263 if (m_overflow) |
264 m_overflow->move(dx, dy); // FIXME: Rounding error here since overflow w
as pixel snapped, but nobody other than list markers passes non-integral values
here. | 264 m_overflow->move(dx, dy); // FIXME: Rounding error here since overflow w
as pixel snapped, but nobody other than list markers passes non-integral values
here. |
265 } | 265 } |
266 | 266 |
267 RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const | 267 RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const |
268 { | 268 { |
269 return toRenderInline(renderer()).lineBoxes(); | 269 return toRenderInline(renderer()).lineBoxes(); |
270 } | 270 } |
271 | 271 |
272 static inline bool isLastChildForRenderer(RenderObject* ancestor, RenderObject*
child) | 272 static inline bool isLastChildForRenderer(LayoutObject* ancestor, LayoutObject*
child) |
273 { | 273 { |
274 if (!child) | 274 if (!child) |
275 return false; | 275 return false; |
276 | 276 |
277 if (child == ancestor) | 277 if (child == ancestor) |
278 return true; | 278 return true; |
279 | 279 |
280 RenderObject* curr = child; | 280 LayoutObject* curr = child; |
281 RenderObject* parent = curr->parent(); | 281 LayoutObject* parent = curr->parent(); |
282 while (parent && (!parent->isRenderBlock() || parent->isInline())) { | 282 while (parent && (!parent->isRenderBlock() || parent->isInline())) { |
283 if (parent->slowLastChild() != curr) | 283 if (parent->slowLastChild() != curr) |
284 return false; | 284 return false; |
285 if (parent == ancestor) | 285 if (parent == ancestor) |
286 return true; | 286 return true; |
287 | 287 |
288 curr = parent; | 288 curr = parent; |
289 parent = curr->parent(); | 289 parent = curr->parent(); |
290 } | 290 } |
291 | 291 |
292 return true; | 292 return true; |
293 } | 293 } |
294 | 294 |
295 static bool isAnsectorAndWithinBlock(RenderObject* ancestor, RenderObject* child
) | 295 static bool isAnsectorAndWithinBlock(LayoutObject* ancestor, LayoutObject* child
) |
296 { | 296 { |
297 RenderObject* object = child; | 297 LayoutObject* object = child; |
298 while (object && (!object->isRenderBlock() || object->isInline())) { | 298 while (object && (!object->isRenderBlock() || object->isInline())) { |
299 if (object == ancestor) | 299 if (object == ancestor) |
300 return true; | 300 return true; |
301 object = object->parent(); | 301 object = object->parent(); |
302 } | 302 } |
303 return false; | 303 return false; |
304 } | 304 } |
305 | 305 |
306 void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, bool isLogically
LastRunWrapped, RenderObject* logicallyLastRunRenderer) | 306 void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, bool isLogically
LastRunWrapped, LayoutObject* logicallyLastRunRenderer) |
307 { | 307 { |
308 // All boxes start off open. They will not apply any margins/border/padding
on | 308 // All boxes start off open. They will not apply any margins/border/padding
on |
309 // any side. | 309 // any side. |
310 bool includeLeftEdge = false; | 310 bool includeLeftEdge = false; |
311 bool includeRightEdge = false; | 311 bool includeRightEdge = false; |
312 | 312 |
313 // The root inline box never has borders/margins/padding. | 313 // The root inline box never has borders/margins/padding. |
314 if (parent()) { | 314 if (parent()) { |
315 bool ltr = renderer().style()->isLeftToRightDirection(); | 315 bool ltr = renderer().style()->isLeftToRightDirection(); |
316 | 316 |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 | 1003 |
1004 bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit lineTop, LayoutUnit lineBottom) | 1004 bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit lineTop, LayoutUnit lineBottom) |
1005 { | 1005 { |
1006 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); | 1006 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); |
1007 flipForWritingMode(overflowRect); | 1007 flipForWritingMode(overflowRect); |
1008 overflowRect.moveBy(accumulatedOffset); | 1008 overflowRect.moveBy(accumulatedOffset); |
1009 if (!locationInContainer.intersects(overflowRect)) | 1009 if (!locationInContainer.intersects(overflowRect)) |
1010 return false; | 1010 return false; |
1011 | 1011 |
1012 // We need to hit test both our inline children (InlineBoxes) and culled inl
ines | 1012 // We need to hit test both our inline children (InlineBoxes) and culled inl
ines |
1013 // (RenderObjects). We check our inlines in the same order as line layout bu
t | 1013 // (LayoutObjects). We check our inlines in the same order as line layout bu
t |
1014 // for each inline we additionally need to hit test its culled inline parent
s. | 1014 // for each inline we additionally need to hit test its culled inline parent
s. |
1015 // While hit testing culled inline parents, we can stop once we reach | 1015 // While hit testing culled inline parents, we can stop once we reach |
1016 // a non-inline parent or a culled inline associated with a different inline
box. | 1016 // a non-inline parent or a culled inline associated with a different inline
box. |
1017 InlineBox* prev; | 1017 InlineBox* prev; |
1018 for (InlineBox* curr = lastChild(); curr; curr = prev) { | 1018 for (InlineBox* curr = lastChild(); curr; curr = prev) { |
1019 prev = curr->prevOnLine(); | 1019 prev = curr->prevOnLine(); |
1020 | 1020 |
1021 // Layers will handle hit testing themselves. | 1021 // Layers will handle hit testing themselves. |
1022 if (curr->boxModelObject() && curr->boxModelObject()->hasSelfPaintingLay
er()) | 1022 if (curr->boxModelObject() && curr->boxModelObject()->hasSelfPaintingLay
er()) |
1023 continue; | 1023 continue; |
1024 | 1024 |
1025 if (curr->nodeAtPoint(request, result, locationInContainer, accumulatedO
ffset, lineTop, lineBottom)) { | 1025 if (curr->nodeAtPoint(request, result, locationInContainer, accumulatedO
ffset, lineTop, lineBottom)) { |
1026 renderer().updateHitTestResult(result, locationInContainer.point() -
toLayoutSize(accumulatedOffset)); | 1026 renderer().updateHitTestResult(result, locationInContainer.point() -
toLayoutSize(accumulatedOffset)); |
1027 return true; | 1027 return true; |
1028 } | 1028 } |
1029 | 1029 |
1030 // If the current inlinebox's renderer and the previous inlinebox's rend
erer are same, | 1030 // If the current inlinebox's renderer and the previous inlinebox's rend
erer are same, |
1031 // we should yield the hit-test to the previous inlinebox. | 1031 // we should yield the hit-test to the previous inlinebox. |
1032 if (prev && curr->renderer() == prev->renderer()) | 1032 if (prev && curr->renderer() == prev->renderer()) |
1033 continue; | 1033 continue; |
1034 | 1034 |
1035 RenderObject* culledParent = &curr->renderer(); | 1035 LayoutObject* culledParent = &curr->renderer(); |
1036 while (true) { | 1036 while (true) { |
1037 RenderObject* sibling = culledParent->style()->isLeftToRightDirectio
n() ? culledParent->previousSibling() : culledParent->nextSibling(); | 1037 LayoutObject* sibling = culledParent->style()->isLeftToRightDirectio
n() ? culledParent->previousSibling() : culledParent->nextSibling(); |
1038 culledParent = culledParent->parent(); | 1038 culledParent = culledParent->parent(); |
1039 ASSERT(culledParent); | 1039 ASSERT(culledParent); |
1040 | 1040 |
1041 if (culledParent == renderer() || (sibling && prev && prev->renderer
().isDescendantOf(culledParent))) | 1041 if (culledParent == renderer() || (sibling && prev && prev->renderer
().isDescendantOf(culledParent))) |
1042 break; | 1042 break; |
1043 | 1043 |
1044 if (culledParent->isRenderInline() && toRenderInline(culledParent)->
hitTestCulledInline(request, result, locationInContainer, accumulatedOffset)) | 1044 if (culledParent->isRenderInline() && toRenderInline(culledParent)->
hitTestCulledInline(request, result, locationInContainer, accumulatedOffset)) |
1045 return true; | 1045 return true; |
1046 } | 1046 } |
1047 } | 1047 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 } | 1101 } |
1102 | 1102 |
1103 InlineBox* InlineFlowBox::lastLeafChild() const | 1103 InlineBox* InlineFlowBox::lastLeafChild() const |
1104 { | 1104 { |
1105 InlineBox* leaf = 0; | 1105 InlineBox* leaf = 0; |
1106 for (InlineBox* child = lastChild(); child && !leaf; child = child->prevOnLi
ne()) | 1106 for (InlineBox* child = lastChild(); child && !leaf; child = child->prevOnLi
ne()) |
1107 leaf = child->isLeaf() ? child : toInlineFlowBox(child)->lastLeafChild()
; | 1107 leaf = child->isLeaf() ? child : toInlineFlowBox(child)->lastLeafChild()
; |
1108 return leaf; | 1108 return leaf; |
1109 } | 1109 } |
1110 | 1110 |
1111 RenderObject::SelectionState InlineFlowBox::selectionState() const | 1111 LayoutObject::SelectionState InlineFlowBox::selectionState() const |
1112 { | 1112 { |
1113 return RenderObject::SelectionNone; | 1113 return LayoutObject::SelectionNone; |
1114 } | 1114 } |
1115 | 1115 |
1116 bool InlineFlowBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsis
Width) const | 1116 bool InlineFlowBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsis
Width) const |
1117 { | 1117 { |
1118 for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) { | 1118 for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) { |
1119 if (!box->canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth)) | 1119 if (!box->canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth)) |
1120 return false; | 1120 return false; |
1121 } | 1121 } |
1122 return true; | 1122 return true; |
1123 } | 1123 } |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1306 } | 1306 } |
1307 } | 1307 } |
1308 | 1308 |
1309 #ifndef NDEBUG | 1309 #ifndef NDEBUG |
1310 | 1310 |
1311 const char* InlineFlowBox::boxName() const | 1311 const char* InlineFlowBox::boxName() const |
1312 { | 1312 { |
1313 return "InlineFlowBox"; | 1313 return "InlineFlowBox"; |
1314 } | 1314 } |
1315 | 1315 |
1316 void InlineFlowBox::showLineTreeAndMark(const InlineBox* markedBox1, const char*
markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Rend
erObject* obj, int depth) const | 1316 void InlineFlowBox::showLineTreeAndMark(const InlineBox* markedBox1, const char*
markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layo
utObject* obj, int depth) const |
1317 { | 1317 { |
1318 InlineBox::showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedL
abel2, obj, depth); | 1318 InlineBox::showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedL
abel2, obj, depth); |
1319 for (const InlineBox* box = firstChild(); box; box = box->nextOnLine()) | 1319 for (const InlineBox* box = firstChild(); box; box = box->nextOnLine()) |
1320 box->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLab
el2, obj, depth + 1); | 1320 box->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLab
el2, obj, depth + 1); |
1321 } | 1321 } |
1322 | 1322 |
1323 #endif | 1323 #endif |
1324 | 1324 |
1325 #if ENABLE(ASSERT) | 1325 #if ENABLE(ASSERT) |
1326 void InlineFlowBox::checkConsistency() const | 1326 void InlineFlowBox::checkConsistency() const |
1327 { | 1327 { |
1328 #ifdef CHECK_CONSISTENCY | 1328 #ifdef CHECK_CONSISTENCY |
1329 ASSERT(!m_hasBadChildList); | 1329 ASSERT(!m_hasBadChildList); |
1330 const InlineBox* prev = 0; | 1330 const InlineBox* prev = 0; |
1331 for (const InlineBox* child = m_firstChild; child; child = child->nextOnLine
()) { | 1331 for (const InlineBox* child = m_firstChild; child; child = child->nextOnLine
()) { |
1332 ASSERT(child->parent() == this); | 1332 ASSERT(child->parent() == this); |
1333 ASSERT(child->prevOnLine() == prev); | 1333 ASSERT(child->prevOnLine() == prev); |
1334 prev = child; | 1334 prev = child; |
1335 } | 1335 } |
1336 ASSERT(prev == m_lastChild); | 1336 ASSERT(prev == m_lastChild); |
1337 #endif | 1337 #endif |
1338 } | 1338 } |
1339 | 1339 |
1340 #endif | 1340 #endif |
1341 | 1341 |
1342 } // namespace blink | 1342 } // namespace blink |
OLD | NEW |