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

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

Issue 149513005: Stacked floats with shape-outside should allow inline content to interact with the non-outermost fl… (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Replace nullptr with 0 to make linux build happy Created 6 years, 9 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 105
106 ComputeFloatOffsetAdapter(const RenderBlockFlow* renderer, int lineTop, int lineBottom, LayoutUnit offset) 106 ComputeFloatOffsetAdapter(const RenderBlockFlow* renderer, int lineTop, int lineBottom, LayoutUnit offset)
107 : m_renderer(renderer) 107 : m_renderer(renderer)
108 , m_lineTop(lineTop) 108 , m_lineTop(lineTop)
109 , m_lineBottom(lineBottom) 109 , m_lineBottom(lineBottom)
110 , m_offset(offset) 110 , m_offset(offset)
111 , m_outermostFloat(0) 111 , m_outermostFloat(0)
112 { 112 {
113 } 113 }
114 114
115 virtual ~ComputeFloatOffsetAdapter() { }
116
115 int lowValue() const { return m_lineTop; } 117 int lowValue() const { return m_lineTop; }
116 int highValue() const { return m_lineBottom; } 118 int highValue() const { return m_lineBottom; }
117 void collectIfNeeded(const IntervalType&); 119 void collectIfNeeded(const IntervalType&);
118 120
119 LayoutUnit offset() const { return m_offset; } 121 LayoutUnit offset() const { return m_offset; }
120 LayoutUnit shapeOffset() const;
121 LayoutUnit heightRemaining() const;
122 122
123 private: 123 protected:
124 bool updateOffsetIfNeeded(const FloatingObject*); 124 virtual bool updateOffsetIfNeeded(const FloatingObject*) = 0;
125 125
126 const RenderBlockFlow* m_renderer; 126 const RenderBlockFlow* m_renderer;
127 int m_lineTop; 127 int m_lineTop;
128 int m_lineBottom; 128 int m_lineBottom;
129 LayoutUnit m_offset; 129 LayoutUnit m_offset;
130 const FloatingObject* m_outermostFloat; 130 const FloatingObject* m_outermostFloat;
131 }; 131 };
132 132
133 template <FloatingObject::Type FloatTypeValue>
134 class ComputeFloatOffsetForFloatLayoutAdapter : public ComputeFloatOffsetAdapter <FloatTypeValue> {
135 public:
136 ComputeFloatOffsetForFloatLayoutAdapter(const RenderBlockFlow* renderer, Lay outUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
137 : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBotto m, offset)
138 {
139 }
140
141 virtual ~ComputeFloatOffsetForFloatLayoutAdapter() { }
142
143 LayoutUnit heightRemaining() const;
144
145 protected:
146 virtual bool updateOffsetIfNeeded(const FloatingObject*) OVERRIDE FINAL;
147 };
148
149 template <FloatingObject::Type FloatTypeValue>
150 class ComputeFloatOffsetForLineLayoutAdapter : public ComputeFloatOffsetAdapter< FloatTypeValue> {
151 public:
152 ComputeFloatOffsetForLineLayoutAdapter(const RenderBlockFlow* renderer, Layo utUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
153 : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBotto m, offset)
154 {
155 }
156
157 virtual ~ComputeFloatOffsetForLineLayoutAdapter() { }
158
159 protected:
160 virtual bool updateOffsetIfNeeded(const FloatingObject*) OVERRIDE FINAL;
161 };
162
133 163
134 FloatingObjects::~FloatingObjects() 164 FloatingObjects::~FloatingObjects()
135 { 165 {
136 // FIXME: m_set should use OwnPtr instead. 166 // FIXME: m_set should use OwnPtr instead.
137 deleteAllValues(m_set); 167 deleteAllValues(m_set);
138 } 168 }
139 void FloatingObjects::clearLineBoxTreePointers() 169 void FloatingObjects::clearLineBoxTreePointers()
140 { 170 {
141 // Clear references to originating lines, since the lines are being deleted 171 // Clear references to originating lines, since the lines are being deleted
142 FloatingObjectSetIterator end = m_set.end(); 172 FloatingObjectSetIterator end = m_set.end();
143 for (FloatingObjectSetIterator it = m_set.begin(); it != end; ++it) { 173 for (FloatingObjectSetIterator it = m_set.begin(); it != end; ++it) {
144 ASSERT(!((*it)->originatingLine()) || (*it)->originatingLine()->renderer () == m_renderer); 174 ASSERT(!((*it)->originatingLine()) || (*it)->originatingLine()->renderer () == m_renderer);
145 (*it)->setOriginatingLine(0); 175 (*it)->setOriginatingLine(0);
146 } 176 }
147 } 177 }
148 178
149 template<>
150 inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::updateOffsetIf Needed(const FloatingObject* floatingObject)
151 {
152 LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
153 if (logicalRight > m_offset) {
154 m_offset = logicalRight;
155 return true;
156 }
157 return false;
158 }
159
160 FloatingObjects::FloatingObjects(const RenderBlockFlow* renderer, bool horizonta lWritingMode) 179 FloatingObjects::FloatingObjects(const RenderBlockFlow* renderer, bool horizonta lWritingMode)
161 : m_placedFloatsTree(UninitializedTree) 180 : m_placedFloatsTree(UninitializedTree)
162 , m_leftObjectsCount(0) 181 , m_leftObjectsCount(0)
163 , m_rightObjectsCount(0) 182 , m_rightObjectsCount(0)
164 , m_horizontalWritingMode(horizontalWritingMode) 183 , m_horizontalWritingMode(horizontalWritingMode)
165 , m_renderer(renderer) 184 , m_renderer(renderer)
166 , m_cachedHorizontalWritingMode(false) 185 , m_cachedHorizontalWritingMode(false)
167 { 186 {
168 } 187 }
169 188
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 m_placedFloatsTree.initIfNeeded(m_renderer->view()->intervalArena()); 369 m_placedFloatsTree.initIfNeeded(m_renderer->view()->intervalArena());
351 FloatingObjectSetIterator it = m_set.begin(); 370 FloatingObjectSetIterator it = m_set.begin();
352 FloatingObjectSetIterator end = m_set.end(); 371 FloatingObjectSetIterator end = m_set.end();
353 for (; it != end; ++it) { 372 for (; it != end; ++it) {
354 FloatingObject* floatingObject = *it; 373 FloatingObject* floatingObject = *it;
355 if (floatingObject->isPlaced()) 374 if (floatingObject->isPlaced())
356 m_placedFloatsTree.add(intervalForFloatingObject(floatingObject)); 375 m_placedFloatsTree.add(intervalForFloatingObject(floatingObject));
357 } 376 }
358 } 377 }
359 378
360 static inline ShapeOutsideInfo* shapeInfoForFloat(const FloatingObject* floating Object, const RenderBlockFlow* containingBlock, LayoutUnit lineTop, LayoutUnit l ineBottom)
361 {
362 if (floatingObject) {
363 if (ShapeOutsideInfo* shapeOutside = floatingObject->renderer()->shapeOu tsideInfo()) {
364 shapeOutside->updateDeltasForContainingBlockLine(containingBlock, fl oatingObject, lineTop, lineBottom - lineTop);
365 return shapeOutside;
366 }
367 }
368
369 return 0;
370 }
371
372 template<>
373 inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::shapeOff set() const
374 {
375 if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_r enderer, m_lineTop, m_lineBottom))
376 return m_offset + shapeOutside->rightMarginBoxDelta();
377
378 return m_offset;
379 }
380
381 template<>
382 inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::shapeOf fset() const
383 {
384 if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_r enderer, m_lineTop, m_lineBottom))
385 return m_offset + shapeOutside->leftMarginBoxDelta();
386
387 return m_offset;
388 }
389
390 LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe dOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) 379 LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe dOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
391 { 380 {
392 int logicalTopAsInt = roundToInt(logicalTop); 381 int logicalTopAsInt = roundToInt(logicalTop);
393 ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, log icalTopAsInt, logicalTopAsInt, fixedOffset); 382 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft> adapter(m _renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
394 placedFloatsTree().allOverlapsWithAdapter(adapter); 383 placedFloatsTree().allOverlapsWithAdapter(adapter);
395 384
396 if (heightRemaining) 385 if (heightRemaining)
397 *heightRemaining = adapter.heightRemaining(); 386 *heightRemaining = adapter.heightRemaining();
398 387
399 return adapter.offset(); 388 return adapter.offset();
400 } 389 }
401 390
402 LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fix edOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) 391 LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fix edOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
403 { 392 {
404 int logicalTopAsInt = roundToInt(logicalTop); 393 int logicalTopAsInt = roundToInt(logicalTop);
405 ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, lo gicalTopAsInt, logicalTopAsInt, fixedOffset); 394 ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight> adapter( m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
406 placedFloatsTree().allOverlapsWithAdapter(adapter); 395 placedFloatsTree().allOverlapsWithAdapter(adapter);
407 396
408 if (heightRemaining) 397 if (heightRemaining)
409 *heightRemaining = adapter.heightRemaining(); 398 *heightRemaining = adapter.heightRemaining();
410 399
411 return min(fixedOffset, adapter.offset()); 400 return min(fixedOffset, adapter.offset());
412 } 401 }
413 402
414 LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight) 403 LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
415 { 404 {
416 ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, rou ndToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset); 405 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft> adapter(m_ renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedO ffset);
417 placedFloatsTree().allOverlapsWithAdapter(adapter); 406 placedFloatsTree().allOverlapsWithAdapter(adapter);
418 407
419 return adapter.shapeOffset(); 408 return adapter.offset();
420 } 409 }
421 410
422 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUni t logicalTop, LayoutUnit logicalHeight) 411 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUni t logicalTop, LayoutUnit logicalHeight)
423 { 412 {
424 ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, ro undToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset); 413 ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m _renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixed Offset);
425 placedFloatsTree().allOverlapsWithAdapter(adapter); 414 placedFloatsTree().allOverlapsWithAdapter(adapter);
426 415
427 return min(fixedOffset, adapter.shapeOffset()); 416 return min(fixedOffset, adapter.offset());
428 } 417 }
429 418
430 FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue() 419 FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue()
431 : value(0) 420 : value(0)
432 , dirty(true) 421 , dirty(true)
433 { 422 {
434 } 423 }
435 424
436 inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop, int objectBottom) 425 inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop, int objectBottom)
437 { 426 {
438 if (objectTop >= floatBottom || objectBottom < floatTop) 427 if (objectTop >= floatBottom || objectBottom < floatTop)
439 return false; 428 return false;
440 429
441 // The top of the object overlaps the float 430 // The top of the object overlaps the float
442 if (objectTop >= floatTop) 431 if (objectTop >= floatTop)
443 return true; 432 return true;
444 433
445 // The object encloses the float 434 // The object encloses the float
446 if (objectTop < floatTop && objectBottom > floatBottom) 435 if (objectTop < floatTop && objectBottom > floatBottom)
447 return true; 436 return true;
448 437
449 // The bottom of the object overlaps the float 438 // The bottom of the object overlaps the float
450 if (objectBottom > objectTop && objectBottom > floatTop && objectBottom <= f loatBottom) 439 if (objectBottom > objectTop && objectBottom > floatTop && objectBottom <= f loatBottom)
451 return true; 440 return true;
452 441
453 return false; 442 return false;
454 } 443 }
455 444
456 template<> 445 template<>
457 inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::updateOffsetI fNeeded(const FloatingObject* floatingObject) 446 inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>:: updateOffsetIfNeeded(const FloatingObject* floatingObject)
447 {
448 LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
449 if (logicalRight > m_offset) {
450 m_offset = logicalRight;
451 return true;
452 }
453 return false;
454 }
455
456 template<>
457 inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight>: :updateOffsetIfNeeded(const FloatingObject* floatingObject)
458 { 458 {
459 LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(floatingObject); 459 LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(floatingObject);
460 if (logicalLeft < m_offset) { 460 if (logicalLeft < m_offset) {
461 m_offset = logicalLeft; 461 m_offset = logicalLeft;
462 return true; 462 return true;
463 } 463 }
464 return false; 464 return false;
465 } 465 }
466 466
467 template <FloatingObject::Type FloatTypeValue> 467 template <FloatingObject::Type FloatTypeValue>
468 LayoutUnit ComputeFloatOffsetForFloatLayoutAdapter<FloatTypeValue>::heightRemain ing() const
469 {
470 return this->m_outermostFloat ? this->m_renderer->logicalBottomForFloat(this ->m_outermostFloat) - this->m_lineTop : LayoutUnit(1);
471 }
472
473 template <FloatingObject::Type FloatTypeValue>
468 inline void ComputeFloatOffsetAdapter<FloatTypeValue>::collectIfNeeded(const Int ervalType& interval) 474 inline void ComputeFloatOffsetAdapter<FloatTypeValue>::collectIfNeeded(const Int ervalType& interval)
469 { 475 {
470 const FloatingObject* floatingObject = interval.data(); 476 const FloatingObject* floatingObject = interval.data();
471 if (floatingObject->type() != FloatTypeValue || !rangesIntersect(interval.lo w(), interval.high(), m_lineTop, m_lineBottom)) 477 if (floatingObject->type() != FloatTypeValue || !rangesIntersect(interval.lo w(), interval.high(), m_lineTop, m_lineBottom))
472 return; 478 return;
473 479
474 // Make sure the float hasn't changed since it was added to the placed float s tree. 480 // Make sure the float hasn't changed since it was added to the placed float s tree.
475 ASSERT(floatingObject->isPlaced()); 481 ASSERT(floatingObject->isPlaced());
476 ASSERT(interval.low() == m_renderer->pixelSnappedLogicalTopForFloat(floating Object)); 482 ASSERT(interval.low() == m_renderer->pixelSnappedLogicalTopForFloat(floating Object));
477 ASSERT(interval.high() == m_renderer->pixelSnappedLogicalBottomForFloat(floa tingObject)); 483 ASSERT(interval.high() == m_renderer->pixelSnappedLogicalBottomForFloat(floa tingObject));
478 484
479 bool floatIsNewExtreme = updateOffsetIfNeeded(floatingObject); 485 bool floatIsNewExtreme = updateOffsetIfNeeded(floatingObject);
480 if (floatIsNewExtreme) 486 if (floatIsNewExtreme)
481 m_outermostFloat = floatingObject; 487 m_outermostFloat = floatingObject;
482 } 488 }
483 489
484 template <FloatingObject::Type FloatTypeValue> 490 static inline ShapeOutsideInfo* shapeInfoForFloat(const FloatingObject* floating Object, const RenderBlockFlow* containingBlock, LayoutUnit lineTop, LayoutUnit l ineBottom)
485 LayoutUnit ComputeFloatOffsetAdapter<FloatTypeValue>::heightRemaining() const
486 { 491 {
487 return m_outermostFloat ? m_renderer->logicalBottomForFloat(m_outermostFloat ) - m_lineTop : LayoutUnit(1); 492 if (floatingObject) {
493 if (ShapeOutsideInfo* shapeOutside = floatingObject->renderer()->shapeOu tsideInfo()) {
494 shapeOutside->updateDeltasForContainingBlockLine(containingBlock, fl oatingObject, lineTop, lineBottom - lineTop);
495 return shapeOutside;
496 }
497 }
498
499 return 0;
500 }
501
502 template<>
503 inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::u pdateOffsetIfNeeded(const FloatingObject* floatingObject)
504 {
505 LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
506 if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(floatingObject, m_ren derer, m_lineTop, m_lineBottom)) {
507 if (!shapeOutside->lineOverlapsShape())
508 return false;
509
510 logicalRight += shapeOutside->rightMarginBoxDelta();
511 }
512 if (logicalRight > m_offset) {
513 m_offset = logicalRight;
514 return true;
515 }
516
517 return false;
518 }
519
520 template<>
521 inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>:: updateOffsetIfNeeded(const FloatingObject* floatingObject)
522 {
523 LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(floatingObject);
524 if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(floatingObject, m_ren derer, m_lineTop, m_lineBottom)) {
525 if (!shapeOutside->lineOverlapsShape())
526 return false;
527
528 logicalLeft += shapeOutside->leftMarginBoxDelta();
529 }
530 if (logicalLeft < m_offset) {
531 m_offset = logicalLeft;
532 return true;
533 }
534
535 return false;
488 } 536 }
489 537
490 #ifndef NDEBUG 538 #ifndef NDEBUG
491 // These helpers are only used by the PODIntervalTree for debugging purposes. 539 // These helpers are only used by the PODIntervalTree for debugging purposes.
492 String ValueToString<int>::string(const int value) 540 String ValueToString<int>::string(const int value)
493 { 541 {
494 return String::number(value); 542 return String::number(value);
495 } 543 }
496 544
497 String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObje ct) 545 String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObje ct)
498 { 546 {
499 return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->fr ameRect().pixelSnappedX(), floatingObject->frameRect().pixelSnappedY(), floating Object->frameRect().pixelSnappedMaxX(), floatingObject->frameRect().pixelSnapped MaxY()); 547 return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->fr ameRect().pixelSnappedX(), floatingObject->frameRect().pixelSnappedY(), floating Object->frameRect().pixelSnappedMaxX(), floatingObject->frameRect().pixelSnapped MaxY());
500 } 548 }
501 #endif 549 #endif
502 550
503 551
504 } // namespace WebCore 552 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698