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

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: Fix comment quoting. 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()))
wkorman 2016/07/12 23:36:15 For future work -- changes to this method appear t
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);
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 // Skip table row because cells and rows are in the same coordinate space.
2048 if (container->isTableRow()) {
2049 DCHECK(isTableCell());
2050 localContainingBlock = toLayoutBox(container->parent());
2051 container = container->parent();
2052 }
2055 if (!container) 2053 if (!container)
2056 return true; 2054 return true;
2057 2055
2058 if (filterOrReflectionSkipped) 2056 if (filterOrReflectionSkipped)
2059 inflateVisualRectForReflectionAndFilterUnderContainer(rect, *container, ancestor); 2057 inflateVisualRectForReflectionAndFilterUnderContainer(rect, *container, ancestor);
2060 2058
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 2059 // 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. 2060 // in the parent's coordinate space that encloses us.
2076 if (hasLayer() && layer()->transform()) { 2061 if (hasLayer() && layer()->transform()) {
2077 // Use enclosingIntRect because we cannot properly compute pixel snappin g for painted elements within 2062 // 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 2063 // the transform since we don't know the desired subpixel accumulation a t this point, and the transform may
2079 // include a scale. 2064 // include a scale.
2080 rect = LayoutRect(layer()->transform()->mapRect(enclosingIntRect(rect))) ; 2065 rect = LayoutRect(layer()->transform()->mapRect(enclosingIntRect(rect))) ;
2081 topLeft = rect.location();
2082 topLeft.move(locationOffset());
2083 } 2066 }
2067 LayoutPoint topLeft = rect.location();
2068 // TODO(wkorman): Look into and document why this conditional is needed.
2069 // Currently present following logic in PaintLayer::updateLayerPosition.
2070 if (!(isInline() && isLayoutInline()))
2071 topLeft.moveBy(topLeftLocation(localContainingBlock));
2084 2072
2085 const ComputedStyle& styleToUse = styleRef(); 2073 const ComputedStyle& styleToUse = styleRef();
2086 EPosition position = styleToUse.position(); 2074 EPosition position = styleToUse.position();
2087 if (position == AbsolutePosition && container->isInFlowPositioned() && conta iner->isLayoutInline()) { 2075 if (position == AbsolutePosition && container->isInFlowPositioned() && conta iner->isLayoutInline()) {
2088 topLeft += toLayoutInline(container)->offsetForInFlowPositionedInline(*t his); 2076 topLeft += toLayoutInline(container)->offsetForInFlowPositionedInline(*t his);
2089 } else if (styleToUse.hasInFlowPosition() && layer()) { 2077 } else if (styleToUse.hasInFlowPosition() && layer()) {
2090 // Apply the relative position offset when invalidating a rectangle. Th e layer 2078 // 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 2079 // 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 2080 // 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(). 2081 // flag on the LayoutObject has been cleared, so use the one on the styl e().
2094 topLeft += layer()->offsetForInFlowPosition(); 2082 topLeft += layer()->offsetForInFlowPosition();
2095 } 2083 }
2096 2084
2097 // FIXME: We ignore the lightweight clipping rect that controls use, since i f |o| is in mid-layout, 2085 // 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. 2086 // its controlClipRect will be wrong. For overflow clip we use the values ca ched by the layer.
2099 rect.setLocation(topLeft); 2087 rect.setLocation(topLeft);
2100 2088
2101 if (container->isBox() && !toLayoutBox(container)->mapScrollingContentsRectT oBoxSpace(rect, container == ancestor ? ApplyNonScrollOverflowClip : ApplyOverfl owClip, visualRectFlags)) 2089 if (container->isBox() && !toLayoutBox(container)->mapScrollingContentsRectT oBoxSpace(rect, container == ancestor ? ApplyNonScrollOverflowClip : ApplyOverfl owClip, visualRectFlags))
2102 return false; 2090 return false;
2103 2091
2104 if (ancestorSkipped) { 2092 if (ancestorSkipped) {
2105 // If the ancestor is below o, then we need to map the rect into ancesto r's coordinates. 2093 // 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); 2094 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(conta iner);
2107 rect.move(-containerOffset); 2095 rect.move(-containerOffset);
2108 // If the ancestor is fixed, then the rect is already in its coordinates so doesn't need viewport-adjusting. 2096 // 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) 2097 if (ancestor->style()->position() != FixedPosition && container->isLayou tView() && position == FixedPosition)
2110 toLayoutView(container)->adjustOffsetForFixedPosition(rect); 2098 toLayoutView(container)->adjustOffsetForFixedPosition(rect);
2111 return true; 2099 return true;
2112 } 2100 }
2113 2101
2114 if (container->isLayoutView()) 2102 if (container->isLayoutView())
2115 return toLayoutView(container)->mapToVisualRectInAncestorSpace(ancestor, rect, position == FixedPosition ? IsFixed : 0, visualRectFlags); 2103 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 4456 LayoutPoint LayoutBox::flipForWritingModeForChild(const LayoutBox* child, const LayoutPoint& point) const
4469 { 4457 {
4470 if (!style()->isFlippedBlocksWritingMode()) 4458 if (!style()->isFlippedBlocksWritingMode())
4471 return point; 4459 return point;
4472 4460
4473 // The child is going to add in its x(), so we have to make sure it ends up in 4461 // The child is going to add in its x(), so we have to make sure it ends up in
4474 // the right place. 4462 // the right place.
4475 return LayoutPoint(point.x() + size().width() - child->size().width() - (2 * child->location().x()), point.y()); 4463 return LayoutPoint(point.x() + size().width() - child->size().width() - (2 * child->location().x()), point.y());
4476 } 4464 }
4477 4465
4478 LayoutPoint LayoutBox::topLeftLocation() const 4466 LayoutPoint LayoutBox::topLeftLocation(const LayoutBox* flippedBlocksContainer) const
4479 { 4467 {
4480 LayoutBlock* containerBlock = containingBlock(); 4468 const LayoutBox* containerBox = flippedBlocksContainer ? flippedBlocksContai ner : containingBlock();
4481 if (!containerBlock || containerBlock == this) 4469 if (!containerBox || containerBox == this)
4482 return location(); 4470 return location();
4483 return containerBlock->flipForWritingModeForChild(this, location()); 4471 return containerBox->flipForWritingModeForChild(this, location());
4484 } 4472 }
4485 4473
4486 bool LayoutBox::hasRelativeLogicalWidth() const 4474 bool LayoutBox::hasRelativeLogicalWidth() const
4487 { 4475 {
4488 return style()->logicalWidth().hasPercent() 4476 return style()->logicalWidth().hasPercent()
4489 || style()->logicalMinWidth().hasPercent() 4477 || style()->logicalMinWidth().hasPercent()
4490 || style()->logicalMaxWidth().hasPercent(); 4478 || style()->logicalMaxWidth().hasPercent();
4491 } 4479 }
4492 4480
4493 bool LayoutBox::hasRelativeLogicalHeight() const 4481 bool LayoutBox::hasRelativeLogicalHeight() const
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
4935 m_rareData->m_snapAreas->remove(&snapArea); 4923 m_rareData->m_snapAreas->remove(&snapArea);
4936 } 4924 }
4937 } 4925 }
4938 4926
4939 SnapAreaSet* LayoutBox::snapAreas() const 4927 SnapAreaSet* LayoutBox::snapAreas() const
4940 { 4928 {
4941 return m_rareData ? m_rareData->m_snapAreas.get() : nullptr; 4929 return m_rareData ? m_rareData->m_snapAreas.get() : nullptr;
4942 } 4930 }
4943 4931
4944 } // namespace blink 4932 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBox.h ('k') | third_party/WebKit/Source/core/layout/LayoutFlowThread.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698