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 2142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2153 } | 2153 } |
2154 | 2154 |
2155 Node* LayoutBlock::nodeForHitTest() const | 2155 Node* LayoutBlock::nodeForHitTest() const |
2156 { | 2156 { |
2157 // If we are in the margins of block elements that are part of a | 2157 // If we are in the margins of block elements that are part of a |
2158 // continuation we're actually still inside the enclosing element | 2158 // continuation we're actually still inside the enclosing element |
2159 // that was split. Use the appropriate inner node. | 2159 // that was split. Use the appropriate inner node. |
2160 return isAnonymousBlockContinuation() ? continuation()->node() : node(); | 2160 return isAnonymousBlockContinuation() ? continuation()->node() : node(); |
2161 } | 2161 } |
2162 | 2162 |
2163 bool LayoutBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
lt, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOf
fset, HitTestAction hitTestAction) | 2163 bool LayoutBlock::nodeAtPoint(HitTestResult& result, const HitTestLocation& loca
tionInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestActi
on) |
2164 { | 2164 { |
2165 LayoutPoint adjustedLocation(accumulatedOffset + location()); | 2165 LayoutPoint adjustedLocation(accumulatedOffset + location()); |
2166 LayoutSize localOffset = toLayoutSize(adjustedLocation); | 2166 LayoutSize localOffset = toLayoutSize(adjustedLocation); |
2167 | 2167 |
2168 if (!isLayoutView()) { | 2168 if (!isLayoutView()) { |
2169 // Check if we need to do anything at all. | 2169 // Check if we need to do anything at all. |
2170 // If we have clipping, then we can't have any spillout. | 2170 // If we have clipping, then we can't have any spillout. |
2171 LayoutRect overflowBox = hasOverflowClip() ? borderBoxRect() : visualOve
rflowRect(); | 2171 LayoutRect overflowBox = hasOverflowClip() ? borderBoxRect() : visualOve
rflowRect(); |
2172 flipForWritingMode(overflowBox); | 2172 flipForWritingMode(overflowBox); |
2173 overflowBox.moveBy(adjustedLocation); | 2173 overflowBox.moveBy(adjustedLocation); |
2174 if (!locationInContainer.intersects(overflowBox)) | 2174 if (!locationInContainer.intersects(overflowBox)) |
2175 return false; | 2175 return false; |
2176 } | 2176 } |
2177 | 2177 |
2178 if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChil
dBlockBackground) | 2178 if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChil
dBlockBackground) |
2179 && visibleToHitTestRequest(request) | 2179 && visibleToHitTestRequest(result.hitTestRequest()) |
2180 && isPointInOverflowControl(result, locationInContainer.point(), adjuste
dLocation)) { | 2180 && isPointInOverflowControl(result, locationInContainer.point(), adjuste
dLocation)) { |
2181 updateHitTestResult(result, locationInContainer.point() - localOffset); | 2181 updateHitTestResult(result, locationInContainer.point() - localOffset); |
2182 // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet
. | 2182 // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet
. |
2183 if (!result.addNodeToListBasedTestResult(nodeForHitTest(), request, loca
tionInContainer)) | 2183 if (!result.addNodeToListBasedTestResult(nodeForHitTest(), locationInCon
tainer)) |
2184 return true; | 2184 return true; |
2185 } | 2185 } |
2186 | 2186 |
2187 if (style()->clipPath()) { | 2187 if (style()->clipPath()) { |
2188 switch (style()->clipPath()->type()) { | 2188 switch (style()->clipPath()->type()) { |
2189 case ClipPathOperation::SHAPE: { | 2189 case ClipPathOperation::SHAPE: { |
2190 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()-
>clipPath()); | 2190 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()-
>clipPath()); |
2191 // FIXME: handle marginBox etc. | 2191 // FIXME: handle marginBox etc. |
2192 if (!clipPath->path(borderBoxRect()).contains(FloatPoint(locationInC
ontainer.point() - localOffset), clipPath->windRule())) | 2192 if (!clipPath->path(borderBoxRect()).contains(FloatPoint(locationInC
ontainer.point() - localOffset), clipPath->windRule())) |
2193 return false; | 2193 return false; |
(...skipping 21 matching lines...) Expand all Loading... |
2215 } | 2215 } |
2216 } | 2216 } |
2217 if (checkChildren) { | 2217 if (checkChildren) { |
2218 // Hit test descendants first. | 2218 // Hit test descendants first. |
2219 LayoutSize scrolledOffset(localOffset); | 2219 LayoutSize scrolledOffset(localOffset); |
2220 if (hasOverflowClip()) | 2220 if (hasOverflowClip()) |
2221 scrolledOffset -= scrolledContentOffset(); | 2221 scrolledOffset -= scrolledContentOffset(); |
2222 | 2222 |
2223 // Hit test contents if we don't have columns. | 2223 // Hit test contents if we don't have columns. |
2224 if (!hasColumns()) { | 2224 if (!hasColumns()) { |
2225 if (hitTestContents(request, result, locationInContainer, toLayoutPo
int(scrolledOffset), hitTestAction)) { | 2225 if (hitTestContents(result, locationInContainer, toLayoutPoint(scrol
ledOffset), hitTestAction)) { |
2226 updateHitTestResult(result, flipForWritingMode(locationInContain
er.point() - localOffset)); | 2226 updateHitTestResult(result, flipForWritingMode(locationInContain
er.point() - localOffset)); |
2227 return true; | 2227 return true; |
2228 } | 2228 } |
2229 if (hitTestAction == HitTestFloat && hitTestFloats(request, result,
locationInContainer, toLayoutPoint(scrolledOffset))) | 2229 if (hitTestAction == HitTestFloat && hitTestFloats(result, locationI
nContainer, toLayoutPoint(scrolledOffset))) |
2230 return true; | 2230 return true; |
2231 } else if (hitTestColumns(request, result, locationInContainer, toLayout
Point(scrolledOffset), hitTestAction)) { | 2231 } else if (hitTestColumns(result, locationInContainer, toLayoutPoint(scr
olledOffset), hitTestAction)) { |
2232 updateHitTestResult(result, flipForWritingMode(locationInContainer.p
oint() - localOffset)); | 2232 updateHitTestResult(result, flipForWritingMode(locationInContainer.p
oint() - localOffset)); |
2233 return true; | 2233 return true; |
2234 } | 2234 } |
2235 } | 2235 } |
2236 | 2236 |
2237 // Check if the point is outside radii. | 2237 // Check if the point is outside radii. |
2238 if (style()->hasBorderRadius()) { | 2238 if (style()->hasBorderRadius()) { |
2239 LayoutRect borderRect = borderBoxRect(); | 2239 LayoutRect borderRect = borderBoxRect(); |
2240 borderRect.moveBy(adjustedLocation); | 2240 borderRect.moveBy(adjustedLocation); |
2241 FloatRoundedRect border = style()->getRoundedBorderFor(borderRect); | 2241 FloatRoundedRect border = style()->getRoundedBorderFor(borderRect); |
2242 if (!locationInContainer.intersects(border)) | 2242 if (!locationInContainer.intersects(border)) |
2243 return false; | 2243 return false; |
2244 } | 2244 } |
2245 | 2245 |
2246 // Now hit test our background | 2246 // Now hit test our background |
2247 if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChild
BlockBackground) { | 2247 if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChild
BlockBackground) { |
2248 LayoutRect boundsRect(adjustedLocation, size()); | 2248 LayoutRect boundsRect(adjustedLocation, size()); |
2249 if (visibleToHitTestRequest(request) && locationInContainer.intersects(b
oundsRect)) { | 2249 if (visibleToHitTestRequest(result.hitTestRequest()) && locationInContai
ner.intersects(boundsRect)) { |
2250 updateHitTestResult(result, flipForWritingMode(locationInContainer.p
oint() - localOffset)); | 2250 updateHitTestResult(result, flipForWritingMode(locationInContainer.p
oint() - localOffset)); |
2251 if (!result.addNodeToListBasedTestResult(nodeForHitTest(), request,
locationInContainer, boundsRect)) | 2251 if (!result.addNodeToListBasedTestResult(nodeForHitTest(), locationI
nContainer, boundsRect)) |
2252 return true; | 2252 return true; |
2253 } | 2253 } |
2254 } | 2254 } |
2255 | 2255 |
2256 return false; | 2256 return false; |
2257 } | 2257 } |
2258 | 2258 |
2259 class ColumnRectIterator { | 2259 class ColumnRectIterator { |
2260 WTF_MAKE_NONCOPYABLE(ColumnRectIterator); | 2260 WTF_MAKE_NONCOPYABLE(ColumnRectIterator); |
2261 public: | 2261 public: |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2308 const LayoutBlock& m_block; | 2308 const LayoutBlock& m_block; |
2309 const ColumnInfo* const m_colInfo; | 2309 const ColumnInfo* const m_colInfo; |
2310 const int m_direction; | 2310 const int m_direction; |
2311 const bool m_isHorizontal; | 2311 const bool m_isHorizontal; |
2312 const LayoutUnit m_logicalLeft; | 2312 const LayoutUnit m_logicalLeft; |
2313 int m_colIndex; | 2313 int m_colIndex; |
2314 LayoutUnit m_currLogicalTopOffset; | 2314 LayoutUnit m_currLogicalTopOffset; |
2315 LayoutRect m_colRect; | 2315 LayoutRect m_colRect; |
2316 }; | 2316 }; |
2317 | 2317 |
2318 bool LayoutBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r
esult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulate
dOffset, HitTestAction hitTestAction) | 2318 bool LayoutBlock::hitTestColumns(HitTestResult& result, const HitTestLocation& l
ocationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestA
ction) |
2319 { | 2319 { |
2320 // We need to do multiple passes, breaking up our hit testing into strips. | 2320 // We need to do multiple passes, breaking up our hit testing into strips. |
2321 if (!hasColumns()) | 2321 if (!hasColumns()) |
2322 return false; | 2322 return false; |
2323 | 2323 |
2324 for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) { | 2324 for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) { |
2325 LayoutRect hitRect = LayoutRect(locationInContainer.boundingBox()); | 2325 LayoutRect hitRect = LayoutRect(locationInContainer.boundingBox()); |
2326 LayoutRect colRect = it.columnRect(); | 2326 LayoutRect colRect = it.columnRect(); |
2327 colRect.moveBy(accumulatedOffset); | 2327 colRect.moveBy(accumulatedOffset); |
2328 if (locationInContainer.intersects(colRect)) { | 2328 if (locationInContainer.intersects(colRect)) { |
2329 // The point is inside this column. | 2329 // The point is inside this column. |
2330 // Adjust accumulatedOffset to change where we hit test. | 2330 // Adjust accumulatedOffset to change where we hit test. |
2331 LayoutSize offset; | 2331 LayoutSize offset; |
2332 it.adjust(offset); | 2332 it.adjust(offset); |
2333 LayoutPoint finalLocation = accumulatedOffset + offset; | 2333 LayoutPoint finalLocation = accumulatedOffset + offset; |
2334 if (!result.isRectBasedTest() || colRect.contains(hitRect)) | 2334 if (!result.isRectBasedTest() || colRect.contains(hitRect)) |
2335 return hitTestContents(request, result, locationInContainer, fin
alLocation, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(re
quest, result, locationInContainer, finalLocation)); | 2335 return hitTestContents(result, locationInContainer, finalLocatio
n, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(result, loc
ationInContainer, finalLocation)); |
2336 | 2336 |
2337 hitTestContents(request, result, locationInContainer, finalLocation,
hitTestAction); | 2337 hitTestContents(result, locationInContainer, finalLocation, hitTestA
ction); |
2338 } | 2338 } |
2339 } | 2339 } |
2340 | 2340 |
2341 return false; | 2341 return false; |
2342 } | 2342 } |
2343 | 2343 |
2344 void LayoutBlock::adjustForColumnRect(LayoutSize& offset, const LayoutPoint& loc
ationInContainer) const | 2344 void LayoutBlock::adjustForColumnRect(LayoutSize& offset, const LayoutPoint& loc
ationInContainer) const |
2345 { | 2345 { |
2346 for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) { | 2346 for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) { |
2347 LayoutRect colRect = it.columnRect(); | 2347 LayoutRect colRect = it.columnRect(); |
2348 if (colRect.contains(locationInContainer)) { | 2348 if (colRect.contains(locationInContainer)) { |
2349 it.adjust(offset); | 2349 it.adjust(offset); |
2350 return; | 2350 return; |
2351 } | 2351 } |
2352 } | 2352 } |
2353 } | 2353 } |
2354 | 2354 |
2355 bool LayoutBlock::hitTestContents(const HitTestRequest& request, HitTestResult&
result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulat
edOffset, HitTestAction hitTestAction) | 2355 bool LayoutBlock::hitTestContents(HitTestResult& result, const HitTestLocation&
locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTest
Action) |
2356 { | 2356 { |
2357 if (childrenInline() && !isTable()) { | 2357 if (childrenInline() && !isTable()) { |
2358 // We have to hit-test our line boxes. | 2358 // We have to hit-test our line boxes. |
2359 if (m_lineBoxes.hitTest(this, request, result, locationInContainer, accu
mulatedOffset, hitTestAction)) | 2359 if (m_lineBoxes.hitTest(this, result, locationInContainer, accumulatedOf
fset, hitTestAction)) |
2360 return true; | 2360 return true; |
2361 } else { | 2361 } else { |
2362 // Hit test our children. | 2362 // Hit test our children. |
2363 HitTestAction childHitTest = hitTestAction; | 2363 HitTestAction childHitTest = hitTestAction; |
2364 if (hitTestAction == HitTestChildBlockBackgrounds) | 2364 if (hitTestAction == HitTestChildBlockBackgrounds) |
2365 childHitTest = HitTestChildBlockBackground; | 2365 childHitTest = HitTestChildBlockBackground; |
2366 for (LayoutBox* child = lastChildBox(); child; child = child->previousSi
blingBox()) { | 2366 for (LayoutBox* child = lastChildBox(); child; child = child->previousSi
blingBox()) { |
2367 LayoutPoint childPoint = flipForWritingModeForChild(child, accumulat
edOffset); | 2367 LayoutPoint childPoint = flipForWritingModeForChild(child, accumulat
edOffset); |
2368 if (!child->hasSelfPaintingLayer() && !child->isFloating() && !child
->isColumnSpanAll() && child->nodeAtPoint(request, result, locationInContainer,
childPoint, childHitTest)) | 2368 if (!child->hasSelfPaintingLayer() && !child->isFloating() && !child
->isColumnSpanAll() && child->nodeAtPoint(result, locationInContainer, childPoin
t, childHitTest)) |
2369 return true; | 2369 return true; |
2370 } | 2370 } |
2371 } | 2371 } |
2372 | 2372 |
2373 return false; | 2373 return false; |
2374 } | 2374 } |
2375 | 2375 |
2376 Position LayoutBlock::positionForBox(InlineBox *box, bool start) const | 2376 Position LayoutBlock::positionForBox(InlineBox *box, bool start) const |
2377 { | 2377 { |
2378 if (!box) | 2378 if (!box) |
(...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3939 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout
Object* obj) const | 3939 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout
Object* obj) const |
3940 { | 3940 { |
3941 showLayoutObject(); | 3941 showLayoutObject(); |
3942 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) | 3942 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) |
3943 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); | 3943 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); |
3944 } | 3944 } |
3945 | 3945 |
3946 #endif | 3946 #endif |
3947 | 3947 |
3948 } // namespace blink | 3948 } // namespace blink |
OLD | NEW |