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