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