| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |