| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. |
| 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 #include "config.h" | 24 #include "config.h" |
| 25 #include "core/layout/FloatingObjects.h" | 25 #include "core/layout/FloatingObjects.h" |
| 26 | 26 |
| 27 #include "core/layout/LayoutBlockFlow.h" | 27 #include "core/layout/LayoutBlockFlow.h" |
| 28 #include "core/layout/LayoutBox.h" | 28 #include "core/layout/LayoutBox.h" |
| 29 #include "core/layout/LayoutView.h" | 29 #include "core/layout/LayoutView.h" |
| 30 #include "core/layout/shapes/ShapeOutsideInfo.h" | 30 #include "core/layout/shapes/ShapeOutsideInfo.h" |
| 31 | 31 |
| 32 #include <algorithm> |
| 33 |
| 32 using namespace WTF; | 34 using namespace WTF; |
| 33 | 35 |
| 34 namespace blink { | 36 namespace blink { |
| 35 | 37 |
| 36 struct SameSizeAsFloatingObject { | 38 struct SameSizeAsFloatingObject { |
| 37 void* pointers[2]; | 39 void* pointers[2]; |
| 38 LayoutRect rect; | 40 LayoutRect rect; |
| 39 int paginationStrut; | 41 int paginationStrut; |
| 40 uint32_t bitfields : 8; | 42 uint32_t bitfields : 8; |
| 41 }; | 43 }; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 } | 95 } |
| 94 | 96 |
| 95 PassOwnPtr<FloatingObject> FloatingObject::unsafeClone() const | 97 PassOwnPtr<FloatingObject> FloatingObject::unsafeClone() const |
| 96 { | 98 { |
| 97 OwnPtr<FloatingObject> cloneObject = adoptPtr(new FloatingObject(layoutObjec
t(), type(), m_frameRect, m_shouldPaint, m_isDescendant, false)); | 99 OwnPtr<FloatingObject> cloneObject = adoptPtr(new FloatingObject(layoutObjec
t(), type(), m_frameRect, m_shouldPaint, m_isDescendant, false)); |
| 98 cloneObject->m_paginationStrut = m_paginationStrut; | 100 cloneObject->m_paginationStrut = m_paginationStrut; |
| 99 cloneObject->m_isPlaced = m_isPlaced; | 101 cloneObject->m_isPlaced = m_isPlaced; |
| 100 return cloneObject.release(); | 102 return cloneObject.release(); |
| 101 } | 103 } |
| 102 | 104 |
| 105 inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop,
int objectBottom) |
| 106 { |
| 107 if (objectTop >= floatBottom || objectBottom < floatTop) |
| 108 return false; |
| 109 |
| 110 // The top of the object overlaps the float |
| 111 if (objectTop >= floatTop) |
| 112 return true; |
| 113 |
| 114 // The object encloses the float |
| 115 if (objectTop < floatTop && objectBottom > floatBottom) |
| 116 return true; |
| 117 |
| 118 // The bottom of the object overlaps the float |
| 119 if (objectBottom > objectTop && objectBottom > floatTop && objectBottom <= f
loatBottom) |
| 120 return true; |
| 121 |
| 122 return false; |
| 123 } |
| 124 |
| 103 template <FloatingObject::Type FloatTypeValue> | 125 template <FloatingObject::Type FloatTypeValue> |
| 104 class ComputeFloatOffsetAdapter { | 126 class ComputeFloatOffsetAdapter { |
| 105 public: | 127 public: |
| 106 typedef FloatingObjectInterval IntervalType; | 128 typedef FloatingObjectInterval IntervalType; |
| 107 | 129 |
| 108 ComputeFloatOffsetAdapter(const LayoutBlockFlow* layoutObject, int lineTop,
int lineBottom, LayoutUnit offset) | 130 ComputeFloatOffsetAdapter(const LayoutBlockFlow* layoutObject, LayoutUnit li
neTop, LayoutUnit lineBottom, LayoutUnit offset) |
| 109 : m_layoutObject(layoutObject) | 131 : m_layoutObject(layoutObject) |
| 110 , m_lineTop(lineTop) | 132 , m_lineTop(roundToInt(lineTop)) |
| 111 , m_lineBottom(lineBottom) | 133 , m_lineBottom(roundToInt(lineBottom)) |
| 112 , m_offset(offset) | 134 , m_offset(offset) |
| 113 , m_outermostFloat(nullptr) | 135 , m_outermostFloat(nullptr) |
| 114 { | 136 { |
| 115 } | 137 } |
| 116 | 138 |
| 117 virtual ~ComputeFloatOffsetAdapter() { } | 139 virtual ~ComputeFloatOffsetAdapter() { } |
| 118 | 140 |
| 119 int lowValue() const { return m_lineTop; } | 141 int lowValue() const { return m_lineTop; } |
| 120 int highValue() const { return m_lineBottom; } | 142 int highValue() const { return m_lineBottom; } |
| 121 void collectIfNeeded(const IntervalType&); | 143 void collectIfNeeded(const IntervalType&); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 : ComputeFloatOffsetAdapter<FloatTypeValue>(layoutObject, lineTop, lineB
ottom, offset) | 177 : ComputeFloatOffsetAdapter<FloatTypeValue>(layoutObject, lineTop, lineB
ottom, offset) |
| 156 { | 178 { |
| 157 } | 179 } |
| 158 | 180 |
| 159 ~ComputeFloatOffsetForLineLayoutAdapter() override { } | 181 ~ComputeFloatOffsetForLineLayoutAdapter() override { } |
| 160 | 182 |
| 161 protected: | 183 protected: |
| 162 bool updateOffsetIfNeeded(const FloatingObject&) final; | 184 bool updateOffsetIfNeeded(const FloatingObject&) final; |
| 163 }; | 185 }; |
| 164 | 186 |
| 187 class FindNextFloatLogicalBottomAdapter { |
| 188 public: |
| 189 typedef FloatingObjectInterval IntervalType; |
| 190 |
| 191 FindNextFloatLogicalBottomAdapter(const LayoutBlockFlow& renderer, LayoutUni
t belowLogicalHeight) |
| 192 : m_layoutObject(renderer) |
| 193 , m_belowLogicalHeight(floorToInt(belowLogicalHeight)) |
| 194 , m_aboveLogicalHeight(roundToInt(LayoutUnit::max())) |
| 195 , m_nextLogicalBottom() |
| 196 , m_nextShapeLogicalBottom() |
| 197 { |
| 198 } |
| 199 |
| 200 int lowValue() const { return m_belowLogicalHeight; } |
| 201 int highValue() const { return m_aboveLogicalHeight; } |
| 202 void collectIfNeeded(const IntervalType&); |
| 203 |
| 204 LayoutUnit nextLogicalBottom() { return m_nextLogicalBottom; } |
| 205 LayoutUnit nextShapeLogicalBottom() { return m_nextShapeLogicalBottom; } |
| 206 |
| 207 private: |
| 208 const LayoutBlockFlow& m_layoutObject; |
| 209 int m_belowLogicalHeight; |
| 210 int m_aboveLogicalHeight; |
| 211 LayoutUnit m_nextLogicalBottom; |
| 212 LayoutUnit m_nextShapeLogicalBottom; |
| 213 }; |
| 214 |
| 215 inline void FindNextFloatLogicalBottomAdapter::collectIfNeeded(const IntervalTyp
e& interval) |
| 216 { |
| 217 const FloatingObject& floatingObject = *(interval.data()); |
| 218 if (!rangesIntersect(interval.low(), interval.high(), m_belowLogicalHeight,
m_aboveLogicalHeight)) |
| 219 return; |
| 220 |
| 221 // All the objects returned from the tree should be already placed. |
| 222 ASSERT(floatingObject.isPlaced()); |
| 223 ASSERT(rangesIntersect(m_layoutObject.pixelSnappedLogicalTopForFloat(floatin
gObject), m_layoutObject.pixelSnappedLogicalBottomForFloat(floatingObject), m_be
lowLogicalHeight, m_aboveLogicalHeight)); |
| 224 |
| 225 LayoutUnit floatBottom = m_layoutObject.logicalBottomForFloat(floatingObject
); |
| 226 |
| 227 if (ShapeOutsideInfo* shapeOutside = floatingObject.layoutObject()->shapeOut
sideInfo()) { |
| 228 LayoutUnit shapeBottom = m_layoutObject.logicalTopForFloat(floatingObjec
t) + m_layoutObject.marginBeforeForChild(*floatingObject.layoutObject()) + shape
Outside->shapeLogicalBottom(); |
| 229 // Use the shapeBottom unless it extends outside of the margin box, in w
hich case it is clipped. |
| 230 m_nextShapeLogicalBottom = m_nextShapeLogicalBottom ? std::min(shapeBott
om, floatBottom) : shapeBottom; |
| 231 } else { |
| 232 m_nextShapeLogicalBottom = m_nextShapeLogicalBottom ? std::min(m_nextSha
peLogicalBottom, floatBottom) : floatBottom; |
| 233 } |
| 234 |
| 235 m_nextLogicalBottom = m_nextLogicalBottom ? std::min(m_nextLogicalBottom, fl
oatBottom) : floatBottom; |
| 236 } |
| 237 |
| 238 LayoutUnit FloatingObjects::findNextFloatLogicalBottomBelow(LayoutUnit logicalHe
ight) |
| 239 { |
| 240 FindNextFloatLogicalBottomAdapter adapter(*m_layoutObject, logicalHeight); |
| 241 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 242 |
| 243 return adapter.nextShapeLogicalBottom(); |
| 244 } |
| 245 |
| 246 LayoutUnit FloatingObjects::findNextFloatLogicalBottomBelowForBlock(LayoutUnit l
ogicalHeight) |
| 247 { |
| 248 FindNextFloatLogicalBottomAdapter adapter(*m_layoutObject, logicalHeight); |
| 249 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 250 |
| 251 return adapter.nextLogicalBottom(); |
| 252 } |
| 165 | 253 |
| 166 FloatingObjects::~FloatingObjects() | 254 FloatingObjects::~FloatingObjects() |
| 167 { | 255 { |
| 168 } | 256 } |
| 169 void FloatingObjects::clearLineBoxTreePointers() | 257 void FloatingObjects::clearLineBoxTreePointers() |
| 170 { | 258 { |
| 171 // Clear references to originating lines, since the lines are being deleted | 259 // Clear references to originating lines, since the lines are being deleted |
| 172 FloatingObjectSetIterator end = m_set.end(); | 260 FloatingObjectSetIterator end = m_set.end(); |
| 173 for (FloatingObjectSetIterator it = m_set.begin(); it != end; ++it) { | 261 for (FloatingObjectSetIterator it = m_set.begin(); it != end; ++it) { |
| 174 ASSERT(!((*it)->originatingLine()) || (*it)->originatingLine()->layoutOb
ject() == m_layoutObject); | 262 ASSERT(!((*it)->originatingLine()) || (*it)->originatingLine()->layoutOb
ject() == m_layoutObject); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 FloatingObjectSetIterator end = m_set.end(); | 483 FloatingObjectSetIterator end = m_set.end(); |
| 396 for (; it != end; ++it) { | 484 for (; it != end; ++it) { |
| 397 FloatingObject& floatingObject = *it->get(); | 485 FloatingObject& floatingObject = *it->get(); |
| 398 if (floatingObject.isPlaced()) | 486 if (floatingObject.isPlaced()) |
| 399 m_placedFloatsTree.add(intervalForFloatingObject(floatingObject)); | 487 m_placedFloatsTree.add(intervalForFloatingObject(floatingObject)); |
| 400 } | 488 } |
| 401 } | 489 } |
| 402 | 490 |
| 403 LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe
dOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) | 491 LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe
dOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) |
| 404 { | 492 { |
| 405 int logicalTopAsInt = roundToInt(logicalTop); | 493 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft> adapter(m
_layoutObject, logicalTop, logicalTop, fixedOffset); |
| 406 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft> adapter(m
_layoutObject, logicalTopAsInt, logicalTopAsInt, fixedOffset); | |
| 407 placedFloatsTree().allOverlapsWithAdapter(adapter); | 494 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 408 | 495 |
| 409 if (heightRemaining) | 496 if (heightRemaining) |
| 410 *heightRemaining = adapter.heightRemaining(); | 497 *heightRemaining = adapter.heightRemaining(); |
| 411 | 498 |
| 412 return adapter.offset(); | 499 return adapter.offset(); |
| 413 } | 500 } |
| 414 | 501 |
| 415 LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fix
edOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) | 502 LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fix
edOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) |
| 416 { | 503 { |
| 417 int logicalTopAsInt = roundToInt(logicalTop); | 504 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight> adapter(
m_layoutObject, logicalTop, logicalTop, fixedOffset); |
| 418 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight> adapter(
m_layoutObject, logicalTopAsInt, logicalTopAsInt, fixedOffset); | |
| 419 placedFloatsTree().allOverlapsWithAdapter(adapter); | 505 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 420 | 506 |
| 421 if (heightRemaining) | 507 if (heightRemaining) |
| 422 *heightRemaining = adapter.heightRemaining(); | 508 *heightRemaining = adapter.heightRemaining(); |
| 423 | 509 |
| 424 return std::min(fixedOffset, adapter.offset()); | 510 return std::min(fixedOffset, adapter.offset()); |
| 425 } | 511 } |
| 426 | 512 |
| 427 LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit
logicalTop, LayoutUnit logicalHeight) | 513 LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit
logicalTop, LayoutUnit logicalHeight) |
| 428 { | 514 { |
| 429 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft> adapter(m_
layoutObject, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fi
xedOffset); | 515 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft> adapter(m_
layoutObject, logicalTop, logicalTop + logicalHeight, fixedOffset); |
| 430 placedFloatsTree().allOverlapsWithAdapter(adapter); | 516 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 431 | 517 |
| 432 return adapter.offset(); | 518 return adapter.offset(); |
| 433 } | 519 } |
| 434 | 520 |
| 435 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUni
t logicalTop, LayoutUnit logicalHeight) | 521 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUni
t logicalTop, LayoutUnit logicalHeight) |
| 436 { | 522 { |
| 437 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m
_layoutObject, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), f
ixedOffset); | 523 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m
_layoutObject, logicalTop, logicalTop + logicalHeight, fixedOffset); |
| 438 placedFloatsTree().allOverlapsWithAdapter(adapter); | 524 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 439 | 525 |
| 440 return std::min(fixedOffset, adapter.offset()); | 526 return std::min(fixedOffset, adapter.offset()); |
| 441 } | 527 } |
| 442 | 528 |
| 443 FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue() | 529 FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue() |
| 444 : floatingObject(nullptr) | 530 : floatingObject(nullptr) |
| 445 , dirty(true) | 531 , dirty(true) |
| 446 { | 532 { |
| 447 } | 533 } |
| 448 | 534 |
| 449 inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop,
int objectBottom) | |
| 450 { | |
| 451 if (objectTop >= floatBottom || objectBottom < floatTop) | |
| 452 return false; | |
| 453 | |
| 454 // The top of the object overlaps the float | |
| 455 if (objectTop >= floatTop) | |
| 456 return true; | |
| 457 | |
| 458 // The object encloses the float | |
| 459 if (objectTop < floatTop && objectBottom > floatBottom) | |
| 460 return true; | |
| 461 | |
| 462 // The bottom of the object overlaps the float | |
| 463 if (objectBottom > objectTop && objectBottom > floatTop && objectBottom <= f
loatBottom) | |
| 464 return true; | |
| 465 | |
| 466 return false; | |
| 467 } | |
| 468 | |
| 469 template<> | 535 template<> |
| 470 inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::
updateOffsetIfNeeded(const FloatingObject& floatingObject) | 536 inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::
updateOffsetIfNeeded(const FloatingObject& floatingObject) |
| 471 { | 537 { |
| 472 LayoutUnit logicalRight = m_layoutObject->logicalRightForFloat(floatingObjec
t); | 538 LayoutUnit logicalRight = m_layoutObject->logicalRightForFloat(floatingObjec
t); |
| 473 if (logicalRight > m_offset) { | 539 if (logicalRight > m_offset) { |
| 474 m_offset = logicalRight; | 540 m_offset = logicalRight; |
| 475 return true; | 541 return true; |
| 476 } | 542 } |
| 477 return false; | 543 return false; |
| 478 } | 544 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 } | 623 } |
| 558 | 624 |
| 559 String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObje
ct) | 625 String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObje
ct) |
| 560 { | 626 { |
| 561 return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->fr
ameRect().pixelSnappedX(), floatingObject->frameRect().pixelSnappedY(), floating
Object->frameRect().pixelSnappedMaxX(), floatingObject->frameRect().pixelSnapped
MaxY()); | 627 return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->fr
ameRect().pixelSnappedX(), floatingObject->frameRect().pixelSnappedY(), floating
Object->frameRect().pixelSnappedMaxX(), floatingObject->frameRect().pixelSnapped
MaxY()); |
| 562 } | 628 } |
| 563 #endif | 629 #endif |
| 564 | 630 |
| 565 | 631 |
| 566 } // namespace blink | 632 } // namespace blink |
| OLD | NEW |