| 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 | |
| 34 using namespace WTF; | 32 using namespace WTF; |
| 35 | 33 |
| 36 namespace blink { | 34 namespace blink { |
| 37 | 35 |
| 38 struct SameSizeAsFloatingObject { | 36 struct SameSizeAsFloatingObject { |
| 39 void* pointers[2]; | 37 void* pointers[2]; |
| 40 LayoutRect rect; | 38 LayoutRect rect; |
| 41 int paginationStrut; | 39 int paginationStrut; |
| 42 uint32_t bitfields : 8; | 40 uint32_t bitfields : 8; |
| 43 }; | 41 }; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 } | 93 } |
| 96 | 94 |
| 97 PassOwnPtr<FloatingObject> FloatingObject::unsafeClone() const | 95 PassOwnPtr<FloatingObject> FloatingObject::unsafeClone() const |
| 98 { | 96 { |
| 99 OwnPtr<FloatingObject> cloneObject = adoptPtr(new FloatingObject(layoutObjec
t(), type(), m_frameRect, m_shouldPaint, m_isDescendant, false)); | 97 OwnPtr<FloatingObject> cloneObject = adoptPtr(new FloatingObject(layoutObjec
t(), type(), m_frameRect, m_shouldPaint, m_isDescendant, false)); |
| 100 cloneObject->m_paginationStrut = m_paginationStrut; | 98 cloneObject->m_paginationStrut = m_paginationStrut; |
| 101 cloneObject->m_isPlaced = m_isPlaced; | 99 cloneObject->m_isPlaced = m_isPlaced; |
| 102 return cloneObject.release(); | 100 return cloneObject.release(); |
| 103 } | 101 } |
| 104 | 102 |
| 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 | |
| 125 template <FloatingObject::Type FloatTypeValue> | 103 template <FloatingObject::Type FloatTypeValue> |
| 126 class ComputeFloatOffsetAdapter { | 104 class ComputeFloatOffsetAdapter { |
| 127 public: | 105 public: |
| 128 typedef FloatingObjectInterval IntervalType; | 106 typedef FloatingObjectInterval IntervalType; |
| 129 | 107 |
| 130 ComputeFloatOffsetAdapter(const LayoutBlockFlow* layoutObject, LayoutUnit li
neTop, LayoutUnit lineBottom, LayoutUnit offset) | 108 ComputeFloatOffsetAdapter(const LayoutBlockFlow* layoutObject, int lineTop,
int lineBottom, LayoutUnit offset) |
| 131 : m_layoutObject(layoutObject) | 109 : m_layoutObject(layoutObject) |
| 132 , m_lineTop(roundToInt(lineTop)) | 110 , m_lineTop(lineTop) |
| 133 , m_lineBottom(roundToInt(lineBottom)) | 111 , m_lineBottom(lineBottom) |
| 134 , m_offset(offset) | 112 , m_offset(offset) |
| 135 , m_outermostFloat(nullptr) | 113 , m_outermostFloat(nullptr) |
| 136 { | 114 { |
| 137 } | 115 } |
| 138 | 116 |
| 139 virtual ~ComputeFloatOffsetAdapter() { } | 117 virtual ~ComputeFloatOffsetAdapter() { } |
| 140 | 118 |
| 141 int lowValue() const { return m_lineTop; } | 119 int lowValue() const { return m_lineTop; } |
| 142 int highValue() const { return m_lineBottom; } | 120 int highValue() const { return m_lineBottom; } |
| 143 void collectIfNeeded(const IntervalType&); | 121 void collectIfNeeded(const IntervalType&); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 : ComputeFloatOffsetAdapter<FloatTypeValue>(layoutObject, lineTop, lineB
ottom, offset) | 155 : ComputeFloatOffsetAdapter<FloatTypeValue>(layoutObject, lineTop, lineB
ottom, offset) |
| 178 { | 156 { |
| 179 } | 157 } |
| 180 | 158 |
| 181 ~ComputeFloatOffsetForLineLayoutAdapter() override { } | 159 ~ComputeFloatOffsetForLineLayoutAdapter() override { } |
| 182 | 160 |
| 183 protected: | 161 protected: |
| 184 bool updateOffsetIfNeeded(const FloatingObject&) final; | 162 bool updateOffsetIfNeeded(const FloatingObject&) final; |
| 185 }; | 163 }; |
| 186 | 164 |
| 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 } | |
| 253 | 165 |
| 254 FloatingObjects::~FloatingObjects() | 166 FloatingObjects::~FloatingObjects() |
| 255 { | 167 { |
| 256 } | 168 } |
| 257 void FloatingObjects::clearLineBoxTreePointers() | 169 void FloatingObjects::clearLineBoxTreePointers() |
| 258 { | 170 { |
| 259 // Clear references to originating lines, since the lines are being deleted | 171 // Clear references to originating lines, since the lines are being deleted |
| 260 FloatingObjectSetIterator end = m_set.end(); | 172 FloatingObjectSetIterator end = m_set.end(); |
| 261 for (FloatingObjectSetIterator it = m_set.begin(); it != end; ++it) { | 173 for (FloatingObjectSetIterator it = m_set.begin(); it != end; ++it) { |
| 262 ASSERT(!((*it)->originatingLine()) || (*it)->originatingLine()->layoutOb
ject() == m_layoutObject); | 174 ASSERT(!((*it)->originatingLine()) || (*it)->originatingLine()->layoutOb
ject() == m_layoutObject); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 FloatingObjectSetIterator end = m_set.end(); | 395 FloatingObjectSetIterator end = m_set.end(); |
| 484 for (; it != end; ++it) { | 396 for (; it != end; ++it) { |
| 485 FloatingObject& floatingObject = *it->get(); | 397 FloatingObject& floatingObject = *it->get(); |
| 486 if (floatingObject.isPlaced()) | 398 if (floatingObject.isPlaced()) |
| 487 m_placedFloatsTree.add(intervalForFloatingObject(floatingObject)); | 399 m_placedFloatsTree.add(intervalForFloatingObject(floatingObject)); |
| 488 } | 400 } |
| 489 } | 401 } |
| 490 | 402 |
| 491 LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe
dOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) | 403 LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe
dOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) |
| 492 { | 404 { |
| 493 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft> adapter(m
_layoutObject, logicalTop, logicalTop, fixedOffset); | 405 int logicalTopAsInt = roundToInt(logicalTop); |
| 406 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft> adapter(m
_layoutObject, logicalTopAsInt, logicalTopAsInt, fixedOffset); |
| 494 placedFloatsTree().allOverlapsWithAdapter(adapter); | 407 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 495 | 408 |
| 496 if (heightRemaining) | 409 if (heightRemaining) |
| 497 *heightRemaining = adapter.heightRemaining(); | 410 *heightRemaining = adapter.heightRemaining(); |
| 498 | 411 |
| 499 return adapter.offset(); | 412 return adapter.offset(); |
| 500 } | 413 } |
| 501 | 414 |
| 502 LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fix
edOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) | 415 LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fix
edOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) |
| 503 { | 416 { |
| 504 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight> adapter(
m_layoutObject, logicalTop, logicalTop, fixedOffset); | 417 int logicalTopAsInt = roundToInt(logicalTop); |
| 418 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight> adapter(
m_layoutObject, logicalTopAsInt, logicalTopAsInt, fixedOffset); |
| 505 placedFloatsTree().allOverlapsWithAdapter(adapter); | 419 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 506 | 420 |
| 507 if (heightRemaining) | 421 if (heightRemaining) |
| 508 *heightRemaining = adapter.heightRemaining(); | 422 *heightRemaining = adapter.heightRemaining(); |
| 509 | 423 |
| 510 return std::min(fixedOffset, adapter.offset()); | 424 return std::min(fixedOffset, adapter.offset()); |
| 511 } | 425 } |
| 512 | 426 |
| 513 LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit
logicalTop, LayoutUnit logicalHeight) | 427 LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit
logicalTop, LayoutUnit logicalHeight) |
| 514 { | 428 { |
| 515 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft> adapter(m_
layoutObject, logicalTop, logicalTop + logicalHeight, fixedOffset); | 429 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft> adapter(m_
layoutObject, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fi
xedOffset); |
| 516 placedFloatsTree().allOverlapsWithAdapter(adapter); | 430 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 517 | 431 |
| 518 return adapter.offset(); | 432 return adapter.offset(); |
| 519 } | 433 } |
| 520 | 434 |
| 521 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUni
t logicalTop, LayoutUnit logicalHeight) | 435 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUni
t logicalTop, LayoutUnit logicalHeight) |
| 522 { | 436 { |
| 523 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m
_layoutObject, logicalTop, logicalTop + logicalHeight, fixedOffset); | 437 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m
_layoutObject, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), f
ixedOffset); |
| 524 placedFloatsTree().allOverlapsWithAdapter(adapter); | 438 placedFloatsTree().allOverlapsWithAdapter(adapter); |
| 525 | 439 |
| 526 return std::min(fixedOffset, adapter.offset()); | 440 return std::min(fixedOffset, adapter.offset()); |
| 527 } | 441 } |
| 528 | 442 |
| 529 FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue() | 443 FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue() |
| 530 : floatingObject(nullptr) | 444 : floatingObject(nullptr) |
| 531 , dirty(true) | 445 , dirty(true) |
| 532 { | 446 { |
| 533 } | 447 } |
| 534 | 448 |
| 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 |
| 535 template<> | 469 template<> |
| 536 inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::
updateOffsetIfNeeded(const FloatingObject& floatingObject) | 470 inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::
updateOffsetIfNeeded(const FloatingObject& floatingObject) |
| 537 { | 471 { |
| 538 LayoutUnit logicalRight = m_layoutObject->logicalRightForFloat(floatingObjec
t); | 472 LayoutUnit logicalRight = m_layoutObject->logicalRightForFloat(floatingObjec
t); |
| 539 if (logicalRight > m_offset) { | 473 if (logicalRight > m_offset) { |
| 540 m_offset = logicalRight; | 474 m_offset = logicalRight; |
| 541 return true; | 475 return true; |
| 542 } | 476 } |
| 543 return false; | 477 return false; |
| 544 } | 478 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 } | 557 } |
| 624 | 558 |
| 625 String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObje
ct) | 559 String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObje
ct) |
| 626 { | 560 { |
| 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()); | 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()); |
| 628 } | 562 } |
| 629 #endif | 563 #endif |
| 630 | 564 |
| 631 | 565 |
| 632 } // namespace blink | 566 } // namespace blink |
| OLD | NEW |