Changeset 167930 in webkit
- Timestamp:
- Apr 29, 2014 7:54:47 AM (10 years ago)
- Location:
- trunk
- Files:
-
- 20 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r167928 r167930 1 2014-04-29 Andrei Bucur <abucur@adobe.com> 2 3 [CSS Regions] Fix getClientRects() for content nodes 4 https://bugs.webkit.org/show_bug.cgi?id=117407 5 6 Reviewed by David Hyatt. 7 8 Tests verifying getClientRects works correctly in different situations. 9 10 * fast/regions/cssom/client-rects-fixed-content-expected.txt: Added. 11 * fast/regions/cssom/client-rects-fixed-content.html: Added. 12 * fast/regions/cssom/client-rects-forced-breaks-expected.txt: Added. 13 * fast/regions/cssom/client-rects-forced-breaks.html: Added. 14 * fast/regions/cssom/client-rects-inline-complex-expected.txt: Added. 15 * fast/regions/cssom/client-rects-inline-complex.html: Added. 16 * fast/regions/cssom/client-rects-inline-expected.txt: Added. 17 * fast/regions/cssom/client-rects-inline.html: Added. 18 * fast/regions/cssom/client-rects-nested-regions-expected.txt: Added. 19 * fast/regions/cssom/client-rects-nested-regions.html: Added. 20 * fast/regions/cssom/client-rects-positioned-expected.txt: Added. 21 * fast/regions/cssom/client-rects-positioned.html: Added. 22 * fast/regions/cssom/client-rects-relative-position-expected.txt: Added. 23 * fast/regions/cssom/client-rects-relative-position.html: Added. 24 * fast/regions/cssom/client-rects-simple-block-expected.txt: Added. 25 * fast/regions/cssom/client-rects-simple-block.html: Added. 26 * fast/regions/cssom/client-rects-transforms-expected.txt: Added. 27 * fast/regions/cssom/client-rects-transforms.html: Added. 28 * fast/regions/cssom/client-rects-unsplittable-float-expected.txt: Added. 29 * fast/regions/cssom/client-rects-unsplittable-float.html: Added. 30 * fast/regions/resources/helper.js: 31 (testClientRects): Function that compares the actual client rects for an 32 element to a list of expected client rects. 33 1 34 2014-04-29 Andrei Bucur <abucur@adobe.com> 2 35 -
trunk/LayoutTests/fast/regions/resources/helper.js
r160978 r167930 70 70 var rect = document.getElementById(name).getBoundingClientRect(); 71 71 assertEqualRects(results, name, rectToArray(rect), expectedBoundingRects[name], tolerance); 72 } 73 74 document.write("<p>" + (results.length ? results.join("<br />") : "PASS") + "</p>"); 75 76 return !results.length; 77 } 78 79 function testClientRects(id, expectedClientRects, tolerance) 80 { 81 if (tolerance === undefined) 82 tolerance = 0; 83 84 var results = []; 85 var actualRects = document.getElementById(id).getClientRects(); 86 if (actualRects.length != expectedClientRects.length) 87 results.push("FAIL: The element #" + id + " has a wrong count of client rects: " + actualRects.length + "(actual) vs. " + expectedClientRects.length + "(expected)"); 88 else { 89 for (var i = 0; i < expectedClientRects.length; ++i) { 90 var expectedRect = expectedClientRects[i]; 91 var actualRect = actualRects[i]; 92 assertEqualRects(results, id, rectToArray(actualRect), expectedRect, tolerance); 93 } 72 94 } 73 95 -
trunk/Source/WebCore/ChangeLog
r167928 r167930 1 2014-04-29 Andrei Bucur <abucur@adobe.com> 2 3 [CSS Regions] Fix getClientRects() for content nodes 4 https://bugs.webkit.org/show_bug.cgi?id=117407 5 6 Reviewed by David Hyatt. 7 8 This patch modifies getClientRects() to return a list of fragments 9 for a fragmented box instead of a single rectangle positioned inside 10 the region where the box center would appear. 11 12 The approach is to split the border box of the element in regions using 13 the layout positioning. Then each fragment is mapped to the view coordinates 14 and the result added to the list of rectangles. To preserve the originating 15 region when mapping the fragment through the ancestor tree I've introduced 16 the concept of a current region. The current region is stored inside a 17 CurrentRenderRegionMaintainer object, created whenever an algorithm needing 18 it needs to run. When the maintainer is destroyed, the cleanup is made 19 automatically. The RenderFlowThread holds a pointer to this structure for 20 easy access. 21 22 Tests: fast/regions/cssom/client-rects-fixed-content.html 23 fast/regions/cssom/client-rects-forced-breaks.html 24 fast/regions/cssom/client-rects-inline-complex.html 25 fast/regions/cssom/client-rects-inline.html 26 fast/regions/cssom/client-rects-nested-regions.html 27 fast/regions/cssom/client-rects-positioned.html 28 fast/regions/cssom/client-rects-relative-position.html 29 fast/regions/cssom/client-rects-simple-block.html 30 fast/regions/cssom/client-rects-transforms.html 31 fast/regions/cssom/client-rects-unsplittable-float.html 32 33 * rendering/RenderBlock.cpp: 34 (WebCore::RenderBlock::absoluteQuads): Split the box in fragments. 35 * rendering/RenderBox.cpp: 36 (WebCore::RenderBox::absoluteQuads): Split the box in fragments. 37 * rendering/RenderFlowThread.cpp: 38 (WebCore::RenderFlowThread::RenderFlowThread): 39 (WebCore::RenderFlowThread::mapFromFlowToRegion): 40 (WebCore::RenderFlowThread::mapLocalToContainer): 41 (WebCore::RenderFlowThread::currentRegion): 42 * rendering/RenderFlowThread.h: 43 * rendering/RenderNamedFlowFragment.cpp: 44 (WebCore::RenderNamedFlowFragment::absoluteQuadsForBoxInRegion): Get 45 the fragments for this box in the region. 46 * rendering/RenderNamedFlowFragment.h: 47 * rendering/RenderNamedFlowThread.cpp: 48 (WebCore::RenderNamedFlowThread::absoluteQuadsForBox): Virtual function 49 that can be used to implement fragments to client rects mapping. 50 * rendering/RenderNamedFlowThread.h: 51 * rendering/RenderRegion.cpp: 52 (WebCore::RenderRegion::rectFlowPortionForBox): Small change to correctly 53 map empty rectangles to containers. 54 (WebCore::CurrentRenderRegionMaintainer::CurrentRenderRegionMaintainer): 55 (WebCore::CurrentRenderRegionMaintainer::~CurrentRenderRegionMaintainer): 56 * rendering/RenderRegion.h: 57 (WebCore::RenderRegion::absoluteQuadsForBoxInRegion): 58 (WebCore::CurrentRenderRegionMaintainer::region): 59 1 60 2014-04-29 Andrei Bucur <abucur@adobe.com> 2 61 -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r167820 r167930 4699 4699 // inline boxes above and below us (thus getting merged with them to form a single irregular 4700 4700 // shape). 4701 if (isAnonymousBlockContinuation()) { 4702 // FIXME: This is wrong for block-flows that are horizontal. 4703 // https://bugs.webkit.org/show_bug.cgi?id=46781 4704 FloatRect localRect(0, -collapsedMarginBefore(), 4705 width(), height() + collapsedMarginBefore() + collapsedMarginAfter()); 4701 FloatRect localRect = isAnonymousBlockContinuation() 4702 ? FloatRect(0, -collapsedMarginBefore(), width(), height() + collapsedMarginBefore() + collapsedMarginAfter()) 4703 : FloatRect(0, 0, width(), height()); 4704 4705 // FIXME: This is wrong for block-flows that are horizontal. 4706 // https://bugs.webkit.org/show_bug.cgi?id=46781 4707 RenderFlowThread* flowThread = flowThreadContainingBlock(); 4708 if (!flowThread || !flowThread->absoluteQuadsForBox(quads, wasFixed, this, localRect.y(), localRect.maxY())) 4706 4709 quads.append(localToAbsoluteQuad(localRect, 0 /* mode */, wasFixed)); 4710 4711 if (isAnonymousBlockContinuation()) 4707 4712 continuation()->absoluteQuads(quads, wasFixed); 4708 } else4709 quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed));4710 4713 } 4711 4714 -
trunk/Source/WebCore/rendering/RenderBox.cpp
r167810 r167930 556 556 void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const 557 557 { 558 quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed)); 558 FloatRect localRect(0, 0, width(), height()); 559 560 RenderFlowThread* flowThread = flowThreadContainingBlock(); 561 if (flowThread && flowThread->absoluteQuadsForBox(quads, wasFixed, this, localRect.y(), localRect.maxY())) 562 return; 563 564 quads.append(localToAbsoluteQuad(localRect, 0 /* mode */, wasFixed)); 559 565 } 560 566 -
trunk/Source/WebCore/rendering/RenderFlowThread.cpp
r167928 r167930 56 56 , m_previousRegionCount(0) 57 57 , m_autoLogicalHeightRegionsCount(0) 58 , m_currentRegionMaintainer(nullptr) 58 59 , m_regionsInvalidated(false) 59 60 , m_regionsHaveUniformLogicalWidth(true) … … 543 544 return 0; 544 545 545 LayoutRect boxRect = transformState.mappedQuad().enclosingBoundingBox(); 546 flipForWritingMode(boxRect); 547 548 // FIXME: We need to refactor RenderObject::absoluteQuads to be able to split the quads across regions, 549 // for now we just take the center of the mapped enclosing box and map it to a region. 550 // Note: Using the center in order to avoid rounding errors. 551 552 LayoutPoint center = boxRect.center(); 553 RenderRegion* renderRegion = const_cast<RenderFlowThread*>(this)->regionAtBlockOffset(this, isHorizontalWritingMode() ? center.y() : center.x(), true, DisallowRegionAutoGeneration); 554 if (!renderRegion) 555 return 0; 546 RenderRegion* renderRegion = currentRegion(); 547 if (!renderRegion) { 548 LayoutRect boxRect = transformState.mappedQuad().enclosingBoundingBox(); 549 flipForWritingMode(boxRect); 550 551 LayoutPoint center = boxRect.center(); 552 renderRegion = const_cast<RenderFlowThread*>(this)->regionAtBlockOffset(this, isHorizontalWritingMode() ? center.y() : center.x(), true, DisallowRegionAutoGeneration); 553 if (!renderRegion) 554 return 0; 555 } 556 556 557 557 LayoutRect flippedRegionRect(renderRegion->flowThreadPortionRect()); … … 1224 1224 if (RenderRegion* region = mapFromFlowToRegion(transformState)) { 1225 1225 // FIXME: The cast below is probably not the best solution, we may need to find a better way. 1226 static_cast<const RenderObject*>(region)->mapLocalToContainer(region->containerForRepaint(), transformState, mode, wasFixed); 1226 const RenderObject* regionObject = static_cast<const RenderObject*>(region); 1227 1228 // If the repaint container is nullptr, we have to climb up to the RenderView, otherwise swap 1229 // it with the region's repaint container. 1230 repaintContainer = repaintContainer ? region->containerForRepaint() : nullptr; 1231 1232 if (RenderFlowThread* regionFlowThread = region->flowThreadContainingBlock()) { 1233 RenderRegion* startRegion = nullptr; 1234 RenderRegion* endRegion = nullptr; 1235 if (regionFlowThread->getRegionRangeForBox(region, startRegion, endRegion)) { 1236 CurrentRenderRegionMaintainer regionMaintainer(*startRegion); 1237 regionObject->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed); 1238 return; 1239 } 1240 } 1241 1242 regionObject->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed); 1227 1243 } 1228 1244 } … … 1444 1460 } 1445 1461 1462 RenderRegion* RenderFlowThread::currentRegion() const 1463 { 1464 return m_currentRegionMaintainer ? &m_currentRegionMaintainer->region() : nullptr; 1465 } 1466 1446 1467 ContainingRegionMap& RenderFlowThread::containingRegionMap() 1447 1468 { -
trunk/Source/WebCore/rendering/RenderFlowThread.h
r167928 r167930 39 39 namespace WebCore { 40 40 41 class CurrentRenderRegionMaintainer; 41 42 struct LayerFragment; 42 43 typedef Vector<LayerFragment, 1> LayerFragments; … … 221 222 // Used to estimate the maximum height of the flow thread. 222 223 static LayoutUnit maxLogicalHeight() { return LayoutUnit::max() / 2; } 223 224 224 225 bool regionInRange(const RenderRegion* targetRegion, const RenderRegion* startRegion, const RenderRegion* endRegion) const; 225 226 227 virtual bool absoluteQuadsForBox(Vector<FloatQuad>&, bool*, const RenderBox*, float, float) const { return false; } 228 226 229 virtual void layout() override; 230 231 void setCurrentRegionMaintainer(CurrentRenderRegionMaintainer* currentRegionMaintainer) { m_currentRegionMaintainer = currentRegionMaintainer; } 232 RenderRegion* currentRegion() const; 227 233 228 234 ContainingRegionMap& containingRegionMap(); … … 354 360 RegionIntervalTree m_regionIntervalTree; 355 361 362 CurrentRenderRegionMaintainer* m_currentRegionMaintainer; 363 356 364 bool m_regionsInvalidated : 1; 357 365 bool m_regionsHaveUniformLogicalWidth : 1; -
trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp
r166867 r167930 525 525 } 526 526 527 void RenderNamedFlowFragment::absoluteQuadsForBoxInRegion(Vector<FloatQuad>& quads, bool* wasFixed, const RenderBox* renderer, float localTop, float localBottom) 528 { 529 LayoutRect layoutLocalRect(0, localTop, renderer->borderBoxRectInRegion(this).width(), localBottom - localTop); 530 LayoutRect fragmentRect = rectFlowPortionForBox(renderer, layoutLocalRect); 531 532 // We want to skip the 0px height fragments for non-empty boxes that may appear in case the bottom of the box 533 // overlaps the bottom of a region. 534 if (localBottom != localTop && !fragmentRect.height()) 535 return; 536 537 CurrentRenderRegionMaintainer regionMaintainer(*this); 538 quads.append(renderer->localToAbsoluteQuad(FloatRect(fragmentRect), 0 /* mode */, wasFixed)); 539 } 540 527 541 } // namespace WebCore -
trunk/Source/WebCore/rendering/RenderNamedFlowFragment.h
r166781 r167930 117 117 void updateRegionFlags(); 118 118 119 virtual void absoluteQuadsForBoxInRegion(Vector<FloatQuad>&, bool*, const RenderBox*, float, float) override; 120 119 121 private: 120 122 virtual const char* renderName() const override { return "RenderNamedFlowFragment"; } -
trunk/Source/WebCore/rendering/RenderNamedFlowThread.cpp
r167707 r167930 840 840 } 841 841 842 } 842 bool RenderNamedFlowThread::absoluteQuadsForBox(Vector<FloatQuad>& quads, bool* wasFixed, const RenderBox* renderer, float localTop, float localBottom) const 843 { 844 RenderRegion* startRegion = nullptr; 845 RenderRegion* endRegion = nullptr; 846 // If the box doesn't have a range, we don't know how it is fragmented so fallback to the default behaviour. 847 if (!getRegionRangeForBox(renderer, startRegion, endRegion)) 848 return false; 849 850 for (auto iter = m_regionList.find(startRegion), end = m_regionList.end(); iter != end; ++iter) { 851 RenderRegion* region = *iter; 852 853 region->absoluteQuadsForBoxInRegion(quads, wasFixed, renderer, localTop, localBottom); 854 855 if (region == endRegion) 856 break; 857 } 858 859 return true; 860 } 861 862 } -
trunk/Source/WebCore/rendering/RenderNamedFlowThread.h
r167707 r167930 100 100 void setDispatchRegionOversetChangeEvent(bool value) { m_dispatchRegionOversetChangeEvent = value; } 101 101 102 virtual bool absoluteQuadsForBox(Vector<FloatQuad>&, bool*, const RenderBox*, float, float) const override; 103 102 104 protected: 103 105 void setMarkForDestruction(); -
trunk/Source/WebCore/rendering/RenderRegion.cpp
r167810 r167930 484 484 } 485 485 486 return m appedRect.isEmpty() ? mappedRect : m_flowThread->mapFromFlowThreadToLocal(box, mappedRect);486 return m_flowThread->mapFromFlowThreadToLocal(box, mappedRect); 487 487 } 488 488 … … 574 574 } 575 575 576 CurrentRenderRegionMaintainer::CurrentRenderRegionMaintainer(RenderRegion& region) 577 : m_region(region) 578 { 579 RenderFlowThread* flowThread = region.flowThread(); 580 // A flow thread can have only one current region. 581 ASSERT(!flowThread->currentRegion()); 582 flowThread->setCurrentRegionMaintainer(this); 583 } 584 585 CurrentRenderRegionMaintainer::~CurrentRenderRegionMaintainer() 586 { 587 RenderFlowThread* flowThread = m_region.flowThread(); 588 flowThread->setCurrentRegionMaintainer(nullptr); 589 } 590 576 591 } // namespace WebCore -
trunk/Source/WebCore/rendering/RenderRegion.h
r167803 r167930 129 129 virtual bool hasAutoLogicalHeight() const { return false; } 130 130 131 virtual void absoluteQuadsForBoxInRegion(Vector<FloatQuad>&, bool*, const RenderBox*, float, float) { } 132 131 133 protected: 132 134 RenderRegion(Element&, PassRef<RenderStyle>, RenderFlowThread*); … … 180 182 RENDER_OBJECT_TYPE_CASTS(RenderRegion, isRenderRegion()) 181 183 184 class CurrentRenderRegionMaintainer { 185 WTF_MAKE_NONCOPYABLE(CurrentRenderRegionMaintainer); 186 public: 187 CurrentRenderRegionMaintainer(RenderRegion&); 188 ~CurrentRenderRegionMaintainer(); 189 190 RenderRegion& region() const { return m_region; } 191 private: 192 RenderRegion& m_region; 193 }; 194 182 195 } // namespace WebCore 183 196
Note: See TracChangeset
for help on using the changeset viewer.