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

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

Powered by Google App Engine
This is Rietveld 408576698