Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(511)

Side by Side Diff: Source/core/layout/FloatingObjects.cpp

Issue 1106533002: Formatting contexts should always expand to enclose floats (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Updated Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 30 matching lines...) Expand all
41 41
42 static_assert(sizeof(FloatingObject) == sizeof(SameSizeAsFloatingObject), "Float ingObject should stay small"); 42 static_assert(sizeof(FloatingObject) == sizeof(SameSizeAsFloatingObject), "Float ingObject should stay small");
43 43
44 FloatingObject::FloatingObject(LayoutBox* layoutObject) 44 FloatingObject::FloatingObject(LayoutBox* layoutObject)
45 : m_layoutObject(layoutObject) 45 : m_layoutObject(layoutObject)
46 , m_originatingLine(0) 46 , m_originatingLine(0)
47 , m_paginationStrut(0) 47 , m_paginationStrut(0)
48 , m_shouldPaint(true) 48 , m_shouldPaint(true)
49 , m_isDescendant(false) 49 , m_isDescendant(false)
50 , m_isPlaced(false) 50 , m_isPlaced(false)
51 , m_isLowestNonOverhangingFloatInChild(false)
51 #if ENABLE(ASSERT) 52 #if ENABLE(ASSERT)
52 , m_isInPlacedTree(false) 53 , m_isInPlacedTree(false)
53 #endif 54 #endif
54 { 55 {
55 EFloat type = layoutObject->style()->floating(); 56 EFloat type = layoutObject->style()->floating();
56 ASSERT(type != NoFloat); 57 ASSERT(type != NoFloat);
57 if (type == LeftFloat) 58 if (type == LeftFloat)
58 m_type = FloatLeft; 59 m_type = FloatLeft;
59 else if (type == RightFloat) 60 else if (type == RightFloat)
60 m_type = FloatRight; 61 m_type = FloatRight;
61 } 62 }
62 63
63 FloatingObject::FloatingObject(LayoutBox* layoutObject, Type type, const LayoutR ect& frameRect, bool shouldPaint, bool isDescendant) 64 FloatingObject::FloatingObject(LayoutBox* layoutObject, Type type, const LayoutR ect& frameRect, bool shouldPaint, bool isDescendant, bool isLowestNonOverhanging FloatInChild)
64 : m_layoutObject(layoutObject) 65 : m_layoutObject(layoutObject)
65 , m_originatingLine(0) 66 , m_originatingLine(0)
66 , m_frameRect(frameRect) 67 , m_frameRect(frameRect)
67 , m_paginationStrut(0) 68 , m_paginationStrut(0)
68 , m_type(type) 69 , m_type(type)
69 , m_shouldPaint(shouldPaint) 70 , m_shouldPaint(shouldPaint)
70 , m_isDescendant(isDescendant) 71 , m_isDescendant(isDescendant)
71 , m_isPlaced(true) 72 , m_isPlaced(true)
73 , m_isLowestNonOverhangingFloatInChild(isLowestNonOverhangingFloatInChild)
72 #if ENABLE(ASSERT) 74 #if ENABLE(ASSERT)
73 , m_isInPlacedTree(false) 75 , m_isInPlacedTree(false)
74 #endif 76 #endif
75 { 77 {
76 } 78 }
77 79
78 PassOwnPtr<FloatingObject> FloatingObject::create(LayoutBox* layoutObject) 80 PassOwnPtr<FloatingObject> FloatingObject::create(LayoutBox* layoutObject)
79 { 81 {
80 OwnPtr<FloatingObject> newObj = adoptPtr(new FloatingObject(layoutObject)); 82 OwnPtr<FloatingObject> newObj = adoptPtr(new FloatingObject(layoutObject));
81 newObj->setShouldPaint(!layoutObject->hasSelfPaintingLayer()); // If a layer exists, the float will paint itself. Otherwise someone else will. 83 newObj->setShouldPaint(!layoutObject->hasSelfPaintingLayer()); // If a layer exists, the float will paint itself. Otherwise someone else will.
82 newObj->setIsDescendant(true); 84 newObj->setIsDescendant(true);
83 85
84 return newObj.release(); 86 return newObj.release();
85 } 87 }
86 88
87 PassOwnPtr<FloatingObject> FloatingObject::copyToNewContainer(LayoutSize offset, bool shouldPaint, bool isDescendant) const 89 PassOwnPtr<FloatingObject> FloatingObject::copyToNewContainer(LayoutSize offset, bool shouldPaint, bool isDescendant) const
88 { 90 {
89 return adoptPtr(new FloatingObject(layoutObject(), type(), LayoutRect(frameR ect().location() - offset, frameRect().size()), shouldPaint, isDescendant)); 91 return adoptPtr(new FloatingObject(layoutObject(), type(), LayoutRect(frameR ect().location() - offset, frameRect().size()), shouldPaint, isDescendant, isLow estNonOverhangingFloatInChild()));
90 } 92 }
91 93
92 PassOwnPtr<FloatingObject> FloatingObject::unsafeClone() const 94 PassOwnPtr<FloatingObject> FloatingObject::unsafeClone() const
93 { 95 {
94 OwnPtr<FloatingObject> cloneObject = adoptPtr(new FloatingObject(layoutObjec t(), type(), m_frameRect, m_shouldPaint, m_isDescendant)); 96 OwnPtr<FloatingObject> cloneObject = adoptPtr(new FloatingObject(layoutObjec t(), type(), m_frameRect, m_shouldPaint, m_isDescendant, false));
95 cloneObject->m_paginationStrut = m_paginationStrut; 97 cloneObject->m_paginationStrut = m_paginationStrut;
96 cloneObject->m_isPlaced = m_isPlaced; 98 cloneObject->m_isPlaced = m_isPlaced;
97 return cloneObject.release(); 99 return cloneObject.release();
98 } 100 }
99 101
100 template <FloatingObject::Type FloatTypeValue> 102 template <FloatingObject::Type FloatTypeValue>
101 class ComputeFloatOffsetAdapter { 103 class ComputeFloatOffsetAdapter {
102 public: 104 public:
103 typedef FloatingObjectInterval IntervalType; 105 typedef FloatingObjectInterval IntervalType;
104 106
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 if (hasLowestFloatLogicalBottomCached(isInHorizontalWritingMode, Floatin gObject::FloatLeft) && hasLowestFloatLogicalBottomCached(isInHorizontalWritingMo de, FloatingObject::FloatRight)) { 204 if (hasLowestFloatLogicalBottomCached(isInHorizontalWritingMode, Floatin gObject::FloatLeft) && hasLowestFloatLogicalBottomCached(isInHorizontalWritingMo de, FloatingObject::FloatRight)) {
203 return std::max(getCachedlowestFloatLogicalBottom(FloatingObject::Fl oatLeft), 205 return std::max(getCachedlowestFloatLogicalBottom(FloatingObject::Fl oatLeft),
204 getCachedlowestFloatLogicalBottom(FloatingObject::FloatRight)); 206 getCachedlowestFloatLogicalBottom(FloatingObject::FloatRight));
205 } 207 }
206 } 208 }
207 209
208 LayoutUnit lowestFloatBottom = 0; 210 LayoutUnit lowestFloatBottom = 0;
209 const FloatingObjectSet& floatingObjectSet = set(); 211 const FloatingObjectSet& floatingObjectSet = set();
210 FloatingObjectSetIterator end = floatingObjectSet.end(); 212 FloatingObjectSetIterator end = floatingObjectSet.end();
211 if (floatType == FloatingObject::FloatLeftRight) { 213 if (floatType == FloatingObject::FloatLeftRight) {
214 FloatingObject* lowestFloatingObjectLeft = nullptr;
215 FloatingObject* lowestFloatingObjectRight = nullptr;
212 LayoutUnit lowestFloatBottomLeft = 0; 216 LayoutUnit lowestFloatBottomLeft = 0;
213 LayoutUnit lowestFloatBottomRight = 0; 217 LayoutUnit lowestFloatBottomRight = 0;
218 FloatingObject* floatingObject = nullptr;
214 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end ; ++it) { 219 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end ; ++it) {
215 FloatingObject* floatingObject = it->get(); 220 floatingObject = it->get();
216 if (floatingObject->isPlaced()) { 221 if (floatingObject->isPlaced()) {
217 FloatingObject::Type curType = floatingObject->type(); 222 FloatingObject::Type curType = floatingObject->type();
218 LayoutUnit curFloatLogicalBottom = m_layoutObject->logicalBottom ForFloat(floatingObject); 223 LayoutUnit curFloatLogicalBottom = m_layoutObject->logicalBottom ForFloat(floatingObject);
219 if (curType & FloatingObject::FloatLeft) 224 if (curType & FloatingObject::FloatLeft && curFloatLogicalBottom > lowestFloatBottomLeft) {
220 lowestFloatBottomLeft = std::max(lowestFloatBottomLeft, curF loatLogicalBottom); 225 lowestFloatBottomLeft = curFloatLogicalBottom;
221 if (curType & FloatingObject::FloatRight) 226 lowestFloatingObjectLeft = floatingObject;
222 lowestFloatBottomRight = std::max(lowestFloatBottomRight, cu rFloatLogicalBottom); 227 }
228 if (curType & FloatingObject::FloatRight && curFloatLogicalBotto m > lowestFloatBottomRight) {
229 lowestFloatBottomRight = curFloatLogicalBottom;
230 lowestFloatingObjectRight = floatingObject;
231 }
223 } 232 }
224 } 233 }
225 lowestFloatBottom = std::max(lowestFloatBottomLeft, lowestFloatBottomRig ht); 234 lowestFloatBottom = std::max(lowestFloatBottomLeft, lowestFloatBottomRig ht);
226 setCachedLowestFloatLogicalBottom(isInHorizontalWritingMode, FloatingObj ect::FloatLeft, lowestFloatBottomLeft); 235 setCachedLowestFloatLogicalBottom(isInHorizontalWritingMode, FloatingObj ect::FloatLeft, lowestFloatingObjectLeft);
227 setCachedLowestFloatLogicalBottom(isInHorizontalWritingMode, FloatingObj ect::FloatRight, lowestFloatBottomRight); 236 setCachedLowestFloatLogicalBottom(isInHorizontalWritingMode, FloatingObj ect::FloatRight, lowestFloatingObjectRight);
228 } else { 237 } else {
238 FloatingObject* lowestFloatingObject = nullptr;
239 FloatingObject* floatingObject = nullptr;
leviw_travelin_and_unemployed 2015/06/02 23:05:41 Nit: don't need to pull this out of the loop
229 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end ; ++it) { 240 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end ; ++it) {
230 FloatingObject* floatingObject = it->get(); 241 floatingObject = it->get();
231 if (floatingObject->isPlaced() && floatingObject->type() == floatTyp e) 242 if (floatingObject->isPlaced() && floatingObject->type() == floatTyp e) {
232 lowestFloatBottom = std::max(lowestFloatBottom, m_layoutObject-> logicalBottomForFloat(floatingObject)); 243 if (m_layoutObject->logicalBottomForFloat(floatingObject) > lowe stFloatBottom) {
244 lowestFloatingObject = floatingObject;
245 lowestFloatBottom = m_layoutObject->logicalBottomForFloat(fl oatingObject);
246 }
247 }
233 } 248 }
234 setCachedLowestFloatLogicalBottom(isInHorizontalWritingMode, floatType, lowestFloatBottom); 249 setCachedLowestFloatLogicalBottom(isInHorizontalWritingMode, floatType, lowestFloatingObject);
235 } 250 }
236 251
237 return lowestFloatBottom; 252 return lowestFloatBottom;
238 } 253 }
239 254
240 bool FloatingObjects::hasLowestFloatLogicalBottomCached(bool isHorizontal, Float ingObject::Type type) const 255 bool FloatingObjects::hasLowestFloatLogicalBottomCached(bool isHorizontal, Float ingObject::Type type) const
241 { 256 {
242 int floatIndex = static_cast<int>(type) - 1; 257 int floatIndex = static_cast<int>(type) - 1;
243 ASSERT(floatIndex < static_cast<int>(sizeof(m_lowestFloatBottomCache) / size of(FloatBottomCachedValue))); 258 ASSERT(floatIndex < static_cast<int>(sizeof(m_lowestFloatBottomCache) / size of(FloatBottomCachedValue)));
244 ASSERT(floatIndex >= 0); 259 ASSERT(floatIndex >= 0);
245 return (m_cachedHorizontalWritingMode == isHorizontal && !m_lowestFloatBotto mCache[floatIndex].dirty); 260 return (m_cachedHorizontalWritingMode == isHorizontal && !m_lowestFloatBotto mCache[floatIndex].dirty);
246 } 261 }
247 262
248 LayoutUnit FloatingObjects::getCachedlowestFloatLogicalBottom(FloatingObject::Ty pe type) const 263 LayoutUnit FloatingObjects::getCachedlowestFloatLogicalBottom(FloatingObject::Ty pe type) const
249 { 264 {
250 int floatIndex = static_cast<int>(type) - 1; 265 int floatIndex = static_cast<int>(type) - 1;
251 ASSERT(floatIndex < static_cast<int>(sizeof(m_lowestFloatBottomCache) / size of(FloatBottomCachedValue))); 266 ASSERT(floatIndex < static_cast<int>(sizeof(m_lowestFloatBottomCache) / size of(FloatBottomCachedValue)));
252 ASSERT(floatIndex >= 0); 267 ASSERT(floatIndex >= 0);
253 return m_lowestFloatBottomCache[floatIndex].value; 268 if (!m_lowestFloatBottomCache[floatIndex].floatingObject)
269 return LayoutUnit();
270 return m_layoutObject->logicalBottomForFloat(m_lowestFloatBottomCache[floatI ndex].floatingObject);
254 } 271 }
255 272
256 void FloatingObjects::setCachedLowestFloatLogicalBottom(bool isHorizontal, Float ingObject::Type type, LayoutUnit value) 273 void FloatingObjects::setCachedLowestFloatLogicalBottom(bool isHorizontal, Float ingObject::Type type, FloatingObject* floatingObject)
257 { 274 {
258 int floatIndex = static_cast<int>(type) - 1; 275 int floatIndex = static_cast<int>(type) - 1;
259 ASSERT(floatIndex < static_cast<int>(sizeof(m_lowestFloatBottomCache) / size of(FloatBottomCachedValue))); 276 ASSERT(floatIndex < static_cast<int>(sizeof(m_lowestFloatBottomCache) / size of(FloatBottomCachedValue)));
260 ASSERT(floatIndex >= 0); 277 ASSERT(floatIndex >= 0);
261 m_cachedHorizontalWritingMode = isHorizontal; 278 m_cachedHorizontalWritingMode = isHorizontal;
262 m_lowestFloatBottomCache[floatIndex].value = value; 279 m_lowestFloatBottomCache[floatIndex].floatingObject = floatingObject;
263 m_lowestFloatBottomCache[floatIndex].dirty = false; 280 m_lowestFloatBottomCache[floatIndex].dirty = false;
264 } 281 }
265 282
283 FloatingObject* FloatingObjects::lowestFloatingObject() const
284 {
285 bool isInHorizontalWritingMode = m_horizontalWritingMode;
286 if (!hasLowestFloatLogicalBottomCached(isInHorizontalWritingMode, FloatingOb ject::FloatLeft) && !hasLowestFloatLogicalBottomCached(isInHorizontalWritingMode , FloatingObject::FloatRight))
287 return nullptr;
288 FloatingObject* lowestLeftObject = m_lowestFloatBottomCache[0].floatingObjec t;
289 FloatingObject* lowestRightObject = m_lowestFloatBottomCache[1].floatingObje ct;
290 LayoutUnit lowestFloatBottomLeft = lowestLeftObject ? m_layoutObject->logica lBottomForFloat(lowestLeftObject) : LayoutUnit();
291 LayoutUnit lowestFloatBottomRight = lowestRightObject ? m_layoutObject->logi calBottomForFloat(lowestRightObject) : LayoutUnit();
292
293 if (lowestFloatBottomLeft > lowestFloatBottomRight)
leviw_travelin_and_unemployed 2015/06/02 23:05:41 return max(lowestFloatBottomLeft, lowestFloatBotto
rhogan 2015/06/03 20:30:55 Look again, I'm returning the object not the value
294 return lowestLeftObject;
295 return lowestRightObject;
296 }
297
266 void FloatingObjects::markLowestFloatLogicalBottomCacheAsDirty() 298 void FloatingObjects::markLowestFloatLogicalBottomCacheAsDirty()
267 { 299 {
268 for (size_t i = 0; i < sizeof(m_lowestFloatBottomCache) / sizeof(FloatBottom CachedValue); ++i) 300 for (size_t i = 0; i < sizeof(m_lowestFloatBottomCache) / sizeof(FloatBottom CachedValue); ++i)
269 m_lowestFloatBottomCache[i].dirty = true; 301 m_lowestFloatBottomCache[i].dirty = true;
270 } 302 }
271 303
272 void FloatingObjects::moveAllToFloatInfoMap(LayoutBoxToFloatInfoMap& map) 304 void FloatingObjects::moveAllToFloatInfoMap(LayoutBoxToFloatInfoMap& map)
273 { 305 {
274 while (!m_set.isEmpty()) { 306 while (!m_set.isEmpty()) {
275 OwnPtr<FloatingObject> floatingObject = m_set.takeFirst(); 307 OwnPtr<FloatingObject> floatingObject = m_set.takeFirst();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 435
404 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUni t logicalTop, LayoutUnit logicalHeight) 436 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUni t logicalTop, LayoutUnit logicalHeight)
405 { 437 {
406 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m _layoutObject, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), f ixedOffset); 438 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m _layoutObject, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), f ixedOffset);
407 placedFloatsTree().allOverlapsWithAdapter(adapter); 439 placedFloatsTree().allOverlapsWithAdapter(adapter);
408 440
409 return std::min(fixedOffset, adapter.offset()); 441 return std::min(fixedOffset, adapter.offset());
410 } 442 }
411 443
412 FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue() 444 FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue()
413 : value(0) 445 : floatingObject(nullptr)
414 , dirty(true) 446 , dirty(true)
415 { 447 {
416 } 448 }
417 449
418 inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop, int objectBottom) 450 inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop, int objectBottom)
419 { 451 {
420 if (objectTop >= floatBottom || objectBottom < floatTop) 452 if (objectTop >= floatBottom || objectBottom < floatTop)
421 return false; 453 return false;
422 454
423 // The top of the object overlaps the float 455 // The top of the object overlaps the float
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 } 558 }
527 559
528 String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObje ct) 560 String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObje ct)
529 { 561 {
530 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 return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->fr ameRect().pixelSnappedX(), floatingObject->frameRect().pixelSnappedY(), floating Object->frameRect().pixelSnappedMaxX(), floatingObject->frameRect().pixelSnapped MaxY());
531 } 563 }
532 #endif 564 #endif
533 565
534 566
535 } // namespace blink 567 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698