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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBox.cpp

Issue 2073563002: Rework mapToVisualRectInAncestorSpace to handle flipped blocks correctly. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Don't need to flip in CLM. Created 4 years, 5 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
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) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed.
7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 result.expand(-verticalScrollbarWidth(), 0); 984 result.expand(-verticalScrollbarWidth(), 0);
985 return result; 985 return result;
986 } 986 }
987 987
988 bool LayoutBox::mapScrollingContentsRectToBoxSpace(LayoutRect& rect, ApplyOverfl owClipFlag applyOverflowClip, VisualRectFlags visualRectFlags) const 988 bool LayoutBox::mapScrollingContentsRectToBoxSpace(LayoutRect& rect, ApplyOverfl owClipFlag applyOverflowClip, VisualRectFlags visualRectFlags) const
989 { 989 {
990 if (!hasOverflowClip()) 990 if (!hasOverflowClip())
991 return true; 991 return true;
992 992
993 LayoutSize offset = LayoutSize(-scrolledContentOffset()); 993 LayoutSize offset = LayoutSize(-scrolledContentOffset());
994 if (UNLIKELY(hasFlippedBlocksWritingMode()))
995 offset.setWidth(-offset.width());
996 rect.move(offset); 994 rect.move(offset);
997 995
998 if (applyOverflowClip == ApplyNonScrollOverflowClip && scrollsOverflow()) 996 if (applyOverflowClip == ApplyNonScrollOverflowClip && scrollsOverflow())
999 return true; 997 return true;
1000 998
1001 flipForWritingMode(rect);
chrishtr 2016/07/09 00:15:57 Do you know what the code in this method was tryin
wkorman 2016/07/09 01:16:08 No, I'm not sure what this was aiming to handle. D
chrishtr 2016/07/11 17:35:55 Yes we have some test coverage for IntersectionObs
1002
1003 LayoutRect clipRect = overflowClipRect(LayoutPoint()); 999 LayoutRect clipRect = overflowClipRect(LayoutPoint());
1004 1000
1005 bool doesIntersect; 1001 bool doesIntersect;
1006 if (visualRectFlags & EdgeInclusive) { 1002 if (visualRectFlags & EdgeInclusive) {
1007 doesIntersect = rect.inclusiveIntersect(clipRect); 1003 doesIntersect = rect.inclusiveIntersect(clipRect);
1008 } else { 1004 } else {
1009 rect.intersect(clipRect); 1005 rect.intersect(clipRect);
1010 doesIntersect = !rect.isEmpty(); 1006 doesIntersect = !rect.isEmpty();
1011 } 1007 }
1012 if (doesIntersect)
1013 flipForWritingMode(rect);
1014 return doesIntersect; 1008 return doesIntersect;
1015 } 1009 }
1016 1010
1017 void LayoutBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layou tUnit& maxLogicalWidth) const 1011 void LayoutBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layou tUnit& maxLogicalWidth) const
1018 { 1012 {
1019 minLogicalWidth = minPreferredLogicalWidth() - borderAndPaddingLogicalWidth( ); 1013 minLogicalWidth = minPreferredLogicalWidth() - borderAndPaddingLogicalWidth( );
1020 maxLogicalWidth = maxPreferredLogicalWidth() - borderAndPaddingLogicalWidth( ); 1014 maxLogicalWidth = maxPreferredLogicalWidth() - borderAndPaddingLogicalWidth( );
1021 } 1015 }
1022 1016
1023 LayoutUnit LayoutBox::minPreferredLogicalWidth() const 1017 LayoutUnit LayoutBox::minPreferredLogicalWidth() const
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after
2036 if (parent == ancestorToStopAt) 2030 if (parent == ancestorToStopAt)
2037 break; 2031 break;
2038 } 2032 }
2039 rect.move(-offsetFromContainer); 2033 rect.move(-offsetFromContainer);
2040 } 2034 }
2041 2035
2042 bool LayoutBox::mapToVisualRectInAncestorSpace(const LayoutBoxModelObject* ances tor, LayoutRect& rect, VisualRectFlags visualRectFlags) const 2036 bool LayoutBox::mapToVisualRectInAncestorSpace(const LayoutBoxModelObject* ances tor, LayoutRect& rect, VisualRectFlags visualRectFlags) const
2043 { 2037 {
2044 inflateVisualRectForReflectionAndFilter(rect); 2038 inflateVisualRectForReflectionAndFilter(rect);
2045 2039
2046 if (ancestor == this) { 2040 if (ancestor == this)
2047 // The final rect returned is always in the physical coordinate space of the ancestor.
2048 flipForWritingMode(rect);
2049 return true; 2041 return true;
2050 }
2051 2042
2052 bool ancestorSkipped; 2043 bool ancestorSkipped;
2053 bool filterOrReflectionSkipped; 2044 bool filterOrReflectionSkipped;
2054 LayoutObject* container = this->container(ancestor, &ancestorSkipped, &filte rOrReflectionSkipped); 2045 LayoutObject* container = this->container(ancestor, &ancestorSkipped, &filte rOrReflectionSkipped);
2046 LayoutBox* localContainingBlock = containingBlock();
2047 if (container->isTableRow()) {
chrishtr 2016/07/09 00:15:57 Add a comment explaining what's going on here: ski
wkorman 2016/07/09 01:16:08 Done.
2048 localContainingBlock = toLayoutBox(container->parent());
2049 container = container->parent();
2050 }
2055 if (!container) 2051 if (!container)
2056 return true; 2052 return true;
2057 2053
2058 if (filterOrReflectionSkipped) 2054 if (filterOrReflectionSkipped)
2059 inflateVisualRectForReflectionAndFilterUnderContainer(rect, *container, ancestor); 2055 inflateVisualRectForReflectionAndFilterUnderContainer(rect, *container, ancestor);
2060 2056
2061 // The rect we compute at each step is shifted by our x/y offset in the pare nt container's coordinate space.
2062 // Only when we cross a writing mode boundary will we have to possibly flipF orWritingMode (to convert into a more
2063 // appropriate offset corner for the enclosing container).
2064 if (isWritingModeRoot()) {
2065 flipForWritingMode(rect);
2066 // Then flip rect currently in physical direction to container's block d irection.
2067 if (container->styleRef().isFlippedBlocksWritingMode())
2068 rect.setX(m_frameRect.width() - rect.maxX());
2069 }
2070
2071 LayoutPoint topLeft = rect.location();
2072 topLeft.move(locationOffset());
2073
2074 // We are now in our parent container's coordinate space. Apply our transfo rm to obtain a bounding box 2057 // We are now in our parent container's coordinate space. Apply our transfo rm to obtain a bounding box
2075 // in the parent's coordinate space that encloses us. 2058 // in the parent's coordinate space that encloses us.
2076 if (hasLayer() && layer()->transform()) { 2059 if (hasLayer() && layer()->transform()) {
2077 // Use enclosingIntRect because we cannot properly compute pixel snappin g for painted elements within 2060 // Use enclosingIntRect because we cannot properly compute pixel snappin g for painted elements within
2078 // the transform since we don't know the desired subpixel accumulation a t this point, and the transform may 2061 // the transform since we don't know the desired subpixel accumulation a t this point, and the transform may
2079 // include a scale. 2062 // include a scale.
2080 rect = LayoutRect(layer()->transform()->mapRect(enclosingIntRect(rect))) ; 2063 rect = LayoutRect(layer()->transform()->mapRect(enclosingIntRect(rect))) ;
2081 topLeft = rect.location();
2082 topLeft.move(locationOffset());
2083 } 2064 }
2065 LayoutPoint topLeft = rect.location();
2066 if (!(isInline() && isLayoutInline()))
2067 topLeft.moveBy(topLeftLocation(localContainingBlock));
2084 2068
2085 const ComputedStyle& styleToUse = styleRef(); 2069 const ComputedStyle& styleToUse = styleRef();
2086 EPosition position = styleToUse.position(); 2070 EPosition position = styleToUse.position();
2087 if (position == AbsolutePosition && container->isInFlowPositioned() && conta iner->isLayoutInline()) { 2071 if (position == AbsolutePosition && container->isInFlowPositioned() && conta iner->isLayoutInline()) {
2088 topLeft += toLayoutInline(container)->offsetForInFlowPositionedInline(*t his); 2072 topLeft += toLayoutInline(container)->offsetForInFlowPositionedInline(*t his);
2089 } else if (styleToUse.hasInFlowPosition() && layer()) { 2073 } else if (styleToUse.hasInFlowPosition() && layer()) {
2090 // Apply the relative position offset when invalidating a rectangle. Th e layer 2074 // Apply the relative position offset when invalidating a rectangle. Th e layer
2091 // is translated, but the layout box isn't, so we need to do this to get the 2075 // is translated, but the layout box isn't, so we need to do this to get the
2092 // right dirty rect. Since this is called from LayoutObject::setStyle, the relative position 2076 // right dirty rect. Since this is called from LayoutObject::setStyle, the relative position
2093 // flag on the LayoutObject has been cleared, so use the one on the styl e(). 2077 // flag on the LayoutObject has been cleared, so use the one on the styl e().
2094 topLeft += layer()->offsetForInFlowPosition(); 2078 topLeft += layer()->offsetForInFlowPosition();
2095 } 2079 }
2096 2080
2097 // FIXME: We ignore the lightweight clipping rect that controls use, since i f |o| is in mid-layout, 2081 // FIXME: We ignore the lightweight clipping rect that controls use, since i f |o| is in mid-layout,
2098 // its controlClipRect will be wrong. For overflow clip we use the values ca ched by the layer. 2082 // its controlClipRect will be wrong. For overflow clip we use the values ca ched by the layer.
2099 rect.setLocation(topLeft); 2083 rect.setLocation(topLeft);
2100 2084
2101 if (container->isBox() && !toLayoutBox(container)->mapScrollingContentsRectT oBoxSpace(rect, container == ancestor ? ApplyNonScrollOverflowClip : ApplyOverfl owClip, visualRectFlags)) 2085 if (container->isBox() && !toLayoutBox(container)->mapScrollingContentsRectT oBoxSpace(rect, container == ancestor ? ApplyNonScrollOverflowClip : ApplyOverfl owClip, visualRectFlags))
2102 return false; 2086 return false;
2103 2087
2104 if (ancestorSkipped) { 2088 if (ancestorSkipped) {
2105 // If the ancestor is below o, then we need to map the rect into ancesto r's coordinates. 2089 // If the ancestor is below the container, then we need to map the rect into ancestor's coordinates.
2106 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(conta iner); 2090 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(conta iner);
2107 rect.move(-containerOffset); 2091 rect.move(-containerOffset);
2108 // If the ancestor is fixed, then the rect is already in its coordinates so doesn't need viewport-adjusting. 2092 // If the ancestor is fixed, then the rect is already in its coordinates so doesn't need viewport-adjusting.
2109 if (ancestor->style()->position() != FixedPosition && container->isLayou tView() && position == FixedPosition) 2093 if (ancestor->style()->position() != FixedPosition && container->isLayou tView() && position == FixedPosition)
2110 toLayoutView(container)->adjustOffsetForFixedPosition(rect); 2094 toLayoutView(container)->adjustOffsetForFixedPosition(rect);
2111 return true; 2095 return true;
2112 } 2096 }
2113 2097
2114 if (container->isLayoutView()) 2098 if (container->isLayoutView())
2115 return toLayoutView(container)->mapToVisualRectInAncestorSpace(ancestor, rect, position == FixedPosition ? IsFixed : 0, visualRectFlags); 2099 return toLayoutView(container)->mapToVisualRectInAncestorSpace(ancestor, rect, position == FixedPosition ? IsFixed : 0, visualRectFlags);
(...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after
4468 LayoutPoint LayoutBox::flipForWritingModeForChild(const LayoutBox* child, const LayoutPoint& point) const 4452 LayoutPoint LayoutBox::flipForWritingModeForChild(const LayoutBox* child, const LayoutPoint& point) const
4469 { 4453 {
4470 if (!style()->isFlippedBlocksWritingMode()) 4454 if (!style()->isFlippedBlocksWritingMode())
4471 return point; 4455 return point;
4472 4456
4473 // The child is going to add in its x(), so we have to make sure it ends up in 4457 // The child is going to add in its x(), so we have to make sure it ends up in
4474 // the right place. 4458 // the right place.
4475 return LayoutPoint(point.x() + size().width() - child->size().width() - (2 * child->location().x()), point.y()); 4459 return LayoutPoint(point.x() + size().width() - child->size().width() - (2 * child->location().x()), point.y());
4476 } 4460 }
4477 4461
4478 LayoutPoint LayoutBox::topLeftLocation() const 4462 LayoutPoint LayoutBox::topLeftLocation(const LayoutBox* container) const
4479 { 4463 {
chrishtr 2016/07/09 00:15:57 Just noticed that you can put in an early out: if
wkorman 2016/07/09 01:16:08 Wouldn't we need instead: if (container && !conta
chrishtr 2016/07/11 17:35:56 Oh right. Yes seems worthwhile to do it just if co
4480 LayoutBlock* containerBlock = containingBlock(); 4464 const LayoutBox* containerBox = container ? container : containingBlock();
4481 if (!containerBlock || containerBlock == this) 4465 if (!containerBox || containerBox == this)
4482 return location(); 4466 return location();
4483 return containerBlock->flipForWritingModeForChild(this, location()); 4467 return containerBox->flipForWritingModeForChild(this, location());
4484 } 4468 }
4485 4469
4486 bool LayoutBox::hasRelativeLogicalWidth() const 4470 bool LayoutBox::hasRelativeLogicalWidth() const
4487 { 4471 {
4488 return style()->logicalWidth().hasPercent() 4472 return style()->logicalWidth().hasPercent()
4489 || style()->logicalMinWidth().hasPercent() 4473 || style()->logicalMinWidth().hasPercent()
4490 || style()->logicalMaxWidth().hasPercent(); 4474 || style()->logicalMaxWidth().hasPercent();
4491 } 4475 }
4492 4476
4493 bool LayoutBox::hasRelativeLogicalHeight() const 4477 bool LayoutBox::hasRelativeLogicalHeight() const
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
4935 m_rareData->m_snapAreas->remove(&snapArea); 4919 m_rareData->m_snapAreas->remove(&snapArea);
4936 } 4920 }
4937 } 4921 }
4938 4922
4939 SnapAreaSet* LayoutBox::snapAreas() const 4923 SnapAreaSet* LayoutBox::snapAreas() const
4940 { 4924 {
4941 return m_rareData ? m_rareData->m_snapAreas.get() : nullptr; 4925 return m_rareData ? m_rareData->m_snapAreas.get() : nullptr;
4942 } 4926 }
4943 4927
4944 } // namespace blink 4928 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698