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

Side by Side Diff: Source/core/layout/LayoutBlock.cpp

Issue 1142283004: Implement a Hit Test Cache. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 7 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) 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 2140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2151 { 2151 {
2152 LayoutPoint adjustedLocation(accumulatedOffset + location()); 2152 LayoutPoint adjustedLocation(accumulatedOffset + location());
2153 LayoutSize localOffset = toLayoutSize(adjustedLocation); 2153 LayoutSize localOffset = toLayoutSize(adjustedLocation);
2154 2154
2155 if (!isLayoutView()) { 2155 if (!isLayoutView()) {
2156 // Check if we need to do anything at all. 2156 // Check if we need to do anything at all.
2157 // If we have clipping, then we can't have any spillout. 2157 // If we have clipping, then we can't have any spillout.
2158 LayoutRect overflowBox = hasOverflowClip() ? borderBoxRect() : visualOve rflowRect(); 2158 LayoutRect overflowBox = hasOverflowClip() ? borderBoxRect() : visualOve rflowRect();
2159 flipForWritingMode(overflowBox); 2159 flipForWritingMode(overflowBox);
2160 overflowBox.moveBy(adjustedLocation); 2160 overflowBox.moveBy(adjustedLocation);
2161 if (!locationInContainer.intersects(overflowBox)) 2161 if (!locationInContainer.intersects(overflowBox)) {
2162 result.shrinkValidityRect(overflowBox);
2162 return false; 2163 return false;
2164 }
2163 } 2165 }
2164 2166
2165 if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChil dBlockBackground) 2167 if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChil dBlockBackground)
2166 && visibleToHitTestRequest(result.hitTestRequest()) 2168 && visibleToHitTestRequest(result.hitTestRequest())
2167 && isPointInOverflowControl(result, locationInContainer.point(), adjuste dLocation)) { 2169 && isPointInOverflowControl(result, locationInContainer.point(), adjuste dLocation)) {
2168 updateHitTestResult(result, locationInContainer.point() - localOffset); 2170 // TODO(dtapuska): calculate the layout rect
2171
2172 updateHitTestResult(result, locationInContainer.point() - localOffset, r esult.validityRect());
2169 // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet . 2173 // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet .
2170 if (!result.addNodeToListBasedTestResult(nodeForHitTest(), locationInCon tainer)) 2174 if (!result.addNodeToListBasedTestResult(nodeForHitTest(), locationInCon tainer))
2171 return true; 2175 return true;
2172 } 2176 }
2173 2177
2174 if (style()->clipPath()) { 2178 if (style()->clipPath()) {
2175 switch (style()->clipPath()->type()) { 2179 switch (style()->clipPath()->type()) {
2176 case ClipPathOperation::SHAPE: { 2180 case ClipPathOperation::SHAPE: {
2177 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()- >clipPath()); 2181 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()- >clipPath());
2178 // FIXME: handle marginBox etc. 2182 // FIXME: handle marginBox etc.
2179 if (!clipPath->path(borderBoxRect()).contains(FloatPoint(locationInC ontainer.point() - localOffset), clipPath->windRule())) 2183 if (!clipPath->path(borderBoxRect()).contains(FloatPoint(locationInC ontainer.point() - localOffset), clipPath->windRule()))
2180 return false; 2184 return false;
2181 break; 2185 break;
2182 } 2186 }
2183 case ClipPathOperation::REFERENCE: 2187 case ClipPathOperation::REFERENCE:
2184 // FIXME: handle REFERENCE 2188 // FIXME: handle REFERENCE
2185 break; 2189 break;
2186 } 2190 }
2187 } 2191 }
2188 2192
2189 // If we have clipping, then we can't have any spillout. 2193 // If we have clipping, then we can't have any spillout.
2190 bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer(); 2194 bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
2191 bool useClip = (hasControlClip() || useOverflowClip); 2195 bool useClip = (hasControlClip() || useOverflowClip);
2192 bool checkChildren = !useClip; 2196 bool checkChildren = !useClip;
2193 if (!checkChildren) { 2197 if (!checkChildren) {
2198 LayoutRect clipRect;
2194 if (hasControlClip()) { 2199 if (hasControlClip()) {
2195 checkChildren = locationInContainer.intersects(controlClipRect(adjus tedLocation)); 2200 clipRect = controlClipRect(adjustedLocation);
2201 checkChildren = locationInContainer.intersects(clipRect);
2196 } else { 2202 } else {
2197 LayoutRect clipRect = overflowClipRect(adjustedLocation, IncludeOver layScrollbarSize); 2203 clipRect = overflowClipRect(adjustedLocation, IncludeOverlayScrollba rSize);
2198 if (style()->hasBorderRadius()) 2204 if (style()->hasBorderRadius())
2199 checkChildren = locationInContainer.intersects(style()->getRound edBorderFor(clipRect)); 2205 checkChildren = locationInContainer.intersects(style()->getRound edBorderFor(clipRect));
2200 else 2206 else
2201 checkChildren = locationInContainer.intersects(clipRect); 2207 checkChildren = locationInContainer.intersects(clipRect);
2202 } 2208 }
2209 if (!checkChildren)
2210 result.shrinkValidityRect(clipRect);
2211 else
2212 result.intersectValidityRect(clipRect);
2203 } 2213 }
2204 if (checkChildren) { 2214 if (checkChildren) {
2205 // Hit test descendants first. 2215 // Hit test descendants first.
2206 LayoutSize scrolledOffset(localOffset); 2216 LayoutSize scrolledOffset(localOffset);
2207 if (hasOverflowClip()) 2217 if (hasOverflowClip())
2208 scrolledOffset -= scrolledContentOffset(); 2218 scrolledOffset -= scrolledContentOffset();
2209 2219
2210 // Hit test contents if we don't have columns. 2220 // Hit test contents if we don't have columns.
2211 if (!hasColumns()) { 2221 if (!hasColumns()) {
2212 if (hitTestContents(result, locationInContainer, toLayoutPoint(scrol ledOffset), hitTestAction)) { 2222 if (hitTestContents(result, locationInContainer, toLayoutPoint(scrol ledOffset), hitTestAction)) {
2213 updateHitTestResult(result, flipForWritingMode(locationInContain er.point() - localOffset)); 2223 // TODO(dtapuska): calculate the layout rect
2224
2225 updateHitTestResult(result, flipForWritingMode(locationInContain er.point() - localOffset), result.validityRect());
2214 return true; 2226 return true;
2215 } 2227 }
2216 if (hitTestAction == HitTestFloat && hitTestFloats(result, locationI nContainer, toLayoutPoint(scrolledOffset))) 2228 if (hitTestAction == HitTestFloat && hitTestFloats(result, locationI nContainer, toLayoutPoint(scrolledOffset)))
2217 return true; 2229 return true;
2218 } else if (hitTestColumns(result, locationInContainer, toLayoutPoint(scr olledOffset), hitTestAction)) { 2230 } else if (hitTestColumns(result, locationInContainer, toLayoutPoint(scr olledOffset), hitTestAction)) {
2219 updateHitTestResult(result, flipForWritingMode(locationInContainer.p oint() - localOffset)); 2231 // TODO(dtapuska): calculate the layout rect
2232 updateHitTestResult(result, flipForWritingMode(locationInContainer.p oint() - localOffset), result.validityRect());
2220 return true; 2233 return true;
2221 } 2234 }
2222 } 2235 }
2223 2236
2224 // Check if the point is outside radii. 2237 // Check if the point is outside radii.
2225 if (style()->hasBorderRadius()) { 2238 if (style()->hasBorderRadius()) {
2226 LayoutRect borderRect = borderBoxRect(); 2239 LayoutRect borderRect = borderBoxRect();
2227 borderRect.moveBy(adjustedLocation); 2240 borderRect.moveBy(adjustedLocation);
2228 FloatRoundedRect border = style()->getRoundedBorderFor(borderRect); 2241 FloatRoundedRect border = style()->getRoundedBorderFor(borderRect);
2229 if (!locationInContainer.intersects(border)) 2242 if (!locationInContainer.intersects(border)) {
2243 result.shrinkValidityRect(borderRect);
2230 return false; 2244 return false;
2245 }
2231 } 2246 }
2232 2247
2233 // Now hit test our background 2248 // Now hit test our background
2234 if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChild BlockBackground) { 2249 if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChild BlockBackground) {
2235 LayoutRect boundsRect(adjustedLocation, size()); 2250 LayoutRect boundsRect(adjustedLocation, size());
2236 if (visibleToHitTestRequest(result.hitTestRequest()) && locationInContai ner.intersects(boundsRect)) { 2251 if (visibleToHitTestRequest(result.hitTestRequest()) && locationInContai ner.intersects(boundsRect)) {
2237 updateHitTestResult(result, flipForWritingMode(locationInContainer.p oint() - localOffset)); 2252 updateHitTestResult(result, flipForWritingMode(locationInContainer.p oint() - localOffset), boundsRect);
2238 if (!result.addNodeToListBasedTestResult(nodeForHitTest(), locationI nContainer, boundsRect)) 2253 if (!result.addNodeToListBasedTestResult(nodeForHitTest(), locationI nContainer, boundsRect))
2239 return true; 2254 return true;
2240 } 2255 }
2256 result.shrinkValidityRect(boundsRect);
2241 } 2257 }
2242 2258
2243 return false; 2259 return false;
2244 } 2260 }
2245 2261
2246 class ColumnRectIterator { 2262 class ColumnRectIterator {
2247 WTF_MAKE_NONCOPYABLE(ColumnRectIterator); 2263 WTF_MAKE_NONCOPYABLE(ColumnRectIterator);
2248 public: 2264 public:
2249 ColumnRectIterator(const LayoutBlock& block) 2265 ColumnRectIterator(const LayoutBlock& block)
2250 : m_block(block) 2266 : m_block(block)
(...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after
3480 } 3496 }
3481 3497
3482 void LayoutBlock::childBecameNonInline(LayoutObject*) 3498 void LayoutBlock::childBecameNonInline(LayoutObject*)
3483 { 3499 {
3484 makeChildrenNonInline(); 3500 makeChildrenNonInline();
3485 if (isAnonymousBlock() && parent() && parent()->isLayoutBlock()) 3501 if (isAnonymousBlock() && parent() && parent()->isLayoutBlock())
3486 toLayoutBlock(parent())->removeLeftoverAnonymousBlock(this); 3502 toLayoutBlock(parent())->removeLeftoverAnonymousBlock(this);
3487 // |this| may be dead here 3503 // |this| may be dead here
3488 } 3504 }
3489 3505
3490 void LayoutBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint& point) 3506 void LayoutBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint& point, const LayoutRect& rect)
3491 { 3507 {
3492 if (result.innerNode()) 3508 if (result.innerNode())
3493 return; 3509 return;
3494 3510
3511 result.intersectValidityRect(rect);
3495 if (Node* n = nodeForHitTest()) 3512 if (Node* n = nodeForHitTest())
3496 result.setNodeAndPosition(n, point); 3513 result.setNodeAndPosition(n, point);
3497 } 3514 }
3498 3515
3499 // An inline-block uses its inlineBox as the inlineBoxWrapper, 3516 // An inline-block uses its inlineBox as the inlineBoxWrapper,
3500 // so the firstChild() is nullptr if the only child is an empty inline-block. 3517 // so the firstChild() is nullptr if the only child is an empty inline-block.
3501 inline bool LayoutBlock::isInlineBoxWrapperActuallyChild() const 3518 inline bool LayoutBlock::isInlineBoxWrapperActuallyChild() const
3502 { 3519 {
3503 return isInlineBlockOrInlineTable() && !size().isEmpty() && node() && editin gIgnoresContent(node()); 3520 return isInlineBlockOrInlineTable() && !size().isEmpty() && node() && editin gIgnoresContent(node());
3504 } 3521 }
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
3921 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const 3938 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const
3922 { 3939 {
3923 showLayoutObject(); 3940 showLayoutObject();
3924 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) 3941 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box())
3925 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); 3942 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1);
3926 } 3943 }
3927 3944
3928 #endif 3945 #endif
3929 3946
3930 } // namespace blink 3947 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698