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