| 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 |