Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 return new AXLayoutObject(layoutObject, axObjectCache); | 192 return new AXLayoutObject(layoutObject, axObjectCache); |
| 193 } | 193 } |
| 194 | 194 |
| 195 AXLayoutObject::~AXLayoutObject() | 195 AXLayoutObject::~AXLayoutObject() |
| 196 { | 196 { |
| 197 ASSERT(isDetached()); | 197 ASSERT(isDetached()); |
| 198 } | 198 } |
| 199 | 199 |
| 200 LayoutRect AXLayoutObject::elementRect() const | 200 LayoutRect AXLayoutObject::elementRect() const |
| 201 { | 201 { |
| 202 if (!m_explicitElementRect.isEmpty()) | 202 if (!m_explicitElementRect.isEmpty()) { |
| 203 return m_explicitElementRect; | 203 LayoutRect bounds = m_explicitElementRect; |
| 204 AXObject* canvas = axObjectCache().objectFromAXID(m_explicitContainerID) ; | |
| 205 if (canvas) | |
| 206 bounds.moveBy(canvas->elementRect().location()); | |
| 207 return bounds; | |
| 208 } | |
| 204 | 209 |
| 205 // FIXME(dmazzoni): use relative bounds instead since this is a bottleneck. | 210 // FIXME(dmazzoni): use relative bounds instead since this is a bottleneck. |
| 206 // http://crbug.com/618120 | 211 // http://crbug.com/618120 |
| 207 return computeElementRect(); | 212 return computeElementRect(); |
| 208 } | 213 } |
| 209 | 214 |
| 210 SkMatrix44 AXLayoutObject::transformFromLocalParentFrame() const | 215 SkMatrix44 AXLayoutObject::transformFromLocalParentFrame() const |
| 211 { | 216 { |
| 212 if (!m_layoutObject) | 217 if (!m_layoutObject) |
| 213 return SkMatrix44(); | 218 return SkMatrix44(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 | 250 |
| 246 return box->getScrollableArea(); | 251 return box->getScrollableArea(); |
| 247 } | 252 } |
| 248 | 253 |
| 249 void AXLayoutObject::getRelativeBounds(AXObject** outContainer, FloatRect& outBo undsInContainer, SkMatrix44& outContainerTransform) const | 254 void AXLayoutObject::getRelativeBounds(AXObject** outContainer, FloatRect& outBo undsInContainer, SkMatrix44& outContainerTransform) const |
| 250 { | 255 { |
| 251 *outContainer = nullptr; | 256 *outContainer = nullptr; |
| 252 outBoundsInContainer = FloatRect(); | 257 outBoundsInContainer = FloatRect(); |
| 253 outContainerTransform.setIdentity(); | 258 outContainerTransform.setIdentity(); |
| 254 | 259 |
| 260 if (!m_explicitElementRect.isEmpty()) { | |
|
aboxhall
2016/07/28 18:40:43
Can you add a comment explaining the logic here?
dmazzoni
2016/07/28 21:43:16
Done.
| |
| 261 *outContainer = axObjectCache().objectFromAXID(m_explicitContainerID); | |
| 262 if (*outContainer) { | |
| 263 outBoundsInContainer = FloatRect(m_explicitElementRect); | |
| 264 return; | |
| 265 } | |
| 266 } | |
| 267 | |
| 255 if (!m_layoutObject) | 268 if (!m_layoutObject) |
| 256 return; | 269 return; |
| 257 | 270 |
| 271 if (isWebArea()) { | |
| 272 if (m_layoutObject->frame()->view()) | |
| 273 outBoundsInContainer.setSize(FloatSize(m_layoutObject->frame()->view ()->contentsSize())); | |
| 274 return; | |
| 275 } | |
| 276 | |
| 258 // First compute the container. The container must be an ancestor in the acc essibility tree, and | 277 // First compute the container. The container must be an ancestor in the acc essibility tree, and |
| 259 // its LayoutObject must be an ancestor in the layout tree. Get the first su ch ancestor that's | 278 // its LayoutObject must be an ancestor in the layout tree. Get the first su ch ancestor that's |
| 260 // either scrollable or has a paint layer. | 279 // either scrollable or has a paint layer. |
| 261 AXObject* container = parentObjectUnignored(); | 280 AXObject* container = parentObjectUnignored(); |
| 262 LayoutObject* containerLayoutObject = nullptr; | 281 LayoutObject* containerLayoutObject = nullptr; |
| 263 while (container) { | 282 while (container) { |
| 264 containerLayoutObject = container->getLayoutObject(); | 283 containerLayoutObject = container->getLayoutObject(); |
| 265 if (containerLayoutObject && containerLayoutObject->isBoxModelObject() & & m_layoutObject->isDescendantOf(containerLayoutObject)) { | 284 if (containerLayoutObject && containerLayoutObject->isBoxModelObject() & & m_layoutObject->isDescendantOf(containerLayoutObject)) { |
| 266 if (container->isScrollableContainer() || containerLayoutObject->has Layer()) | 285 if (container->isScrollableContainer() || containerLayoutObject->has Layer()) |
| 267 break; | 286 break; |
| 268 } | 287 } |
| 269 | 288 |
| 270 container = container->parentObjectUnignored(); | 289 container = container->parentObjectUnignored(); |
| 271 } | 290 } |
| 272 | 291 |
| 273 if (!container) | 292 if (!container) |
| 274 return; | 293 return; |
| 275 *outContainer = container; | 294 *outContainer = container; |
| 276 | 295 |
| 277 // Next get the local bounds of this LayoutObject, which is typically | 296 // Next get the local bounds of this LayoutObject, which is typically |
| 278 // a rect at point (0, 0) with the width and height of the LayoutObject. | 297 // a rect at point (0, 0) with the width and height of the LayoutObject. |
| 279 LayoutRect localBounds; | 298 LayoutRect localBounds; |
| 280 if (m_layoutObject->isText()) { | 299 if (m_layoutObject->isText()) { |
| 281 localBounds = toLayoutText(m_layoutObject)->linesBoundingBox(); | 300 Vector<FloatQuad> quads; |
| 301 toLayoutText(m_layoutObject)->quads(quads, LayoutText::ClipToEllipsis, L ayoutText::LocalQuads); | |
| 302 for (const FloatQuad& quad : quads) | |
| 303 localBounds.unite(LayoutRect(quad.boundingBox())); | |
| 282 } else if (m_layoutObject->isLayoutInline()) { | 304 } else if (m_layoutObject->isLayoutInline()) { |
| 283 localBounds = toLayoutInline(m_layoutObject)->linesBoundingBox(); | 305 Vector<LayoutRect> rects; |
| 306 toLayoutInline(m_layoutObject)->addOutlineRects(rects, LayoutPoint(), La youtObject::IncludeBlockVisualOverflow); | |
| 307 localBounds = unionRect(rects); | |
| 284 } else if (m_layoutObject->isBox()) { | 308 } else if (m_layoutObject->isBox()) { |
| 285 localBounds = LayoutRect(LayoutPoint(), toLayoutBox(m_layoutObject)->siz e()); | 309 localBounds = LayoutRect(LayoutPoint(), toLayoutBox(m_layoutObject)->siz e()); |
| 286 } else if (m_layoutObject->isSVG()) { | 310 } else if (m_layoutObject->isSVG()) { |
| 287 localBounds = LayoutRect(m_layoutObject->strokeBoundingBox()); | 311 localBounds = LayoutRect(m_layoutObject->strokeBoundingBox()); |
| 288 } else { | 312 } else { |
| 289 DCHECK(false); | 313 DCHECK(false); |
| 290 } | 314 } |
| 291 outBoundsInContainer = FloatRect(localBounds); | 315 outBoundsInContainer = FloatRect(localBounds); |
| 292 | 316 |
| 293 // If the container has a scroll offset, subtract that out because we want o ur | 317 // If the container has a scroll offset, subtract that out because we want o ur |
| 294 // bounds to be relative to the *unscrolled* position of the container objec t. | 318 // bounds to be relative to the *unscrolled* position of the container objec t. |
| 295 ScrollableArea* scrollableArea = container->getScrollableAreaIfScrollable(); | 319 ScrollableArea* scrollableArea = container->getScrollableAreaIfScrollable(); |
| 296 if (scrollableArea) { | 320 if (scrollableArea && !container->isWebArea()) { |
| 297 IntPoint scrollPosition = scrollableArea->scrollPosition(); | 321 IntPoint scrollPosition = scrollableArea->scrollPosition(); |
| 298 outBoundsInContainer.move(FloatSize(scrollPosition.x(), scrollPosition.y ())); | 322 outBoundsInContainer.move(FloatSize(scrollPosition.x(), scrollPosition.y ())); |
| 299 } | 323 } |
| 300 | 324 |
| 301 // Compute the transform between the container's coordinate space and this o bject. | 325 // Compute the transform between the container's coordinate space and this o bject. |
| 302 // If the transform is just a simple translation, apply that to the bounding box, but | 326 // If the transform is just a simple translation, apply that to the bounding box, but |
| 303 // if it's a non-trivial transformation like a rotation, scaling, etc. then return | 327 // if it's a non-trivial transformation like a rotation, scaling, etc. then return |
| 304 // the full matrix instead. | 328 // the full matrix instead. |
| 305 TransformationMatrix transform = m_layoutObject->localToAncestorTransform(to LayoutBoxModelObject(containerLayoutObject)); | 329 TransformationMatrix transform = m_layoutObject->localToAncestorTransform(to LayoutBoxModelObject(containerLayoutObject)); |
| 306 if (transform.isIdentityOr2DTranslation()) { | 330 if (transform.isIdentityOr2DTranslation()) { |
| (...skipping 2224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2531 if (obj->node()) // If we are a continuation, we want to make sure to use th e primary layoutObject. | 2555 if (obj->node()) // If we are a continuation, we want to make sure to use th e primary layoutObject. |
| 2532 obj = obj->node()->layoutObject(); | 2556 obj = obj->node()->layoutObject(); |
| 2533 | 2557 |
| 2534 // absoluteFocusRingBoundingBox will query the hierarchy below this element, which for large webpages can be very slow. | 2558 // absoluteFocusRingBoundingBox will query the hierarchy below this element, which for large webpages can be very slow. |
| 2535 // For a web area, which will have the most elements of any element, absolut eQuads should be used. | 2559 // For a web area, which will have the most elements of any element, absolut eQuads should be used. |
| 2536 // We should also use absoluteQuads for SVG elements, otherwise transforms w on't be applied. | 2560 // We should also use absoluteQuads for SVG elements, otherwise transforms w on't be applied. |
| 2537 | 2561 |
| 2538 LayoutRect result; | 2562 LayoutRect result; |
| 2539 if (obj->isText()) { | 2563 if (obj->isText()) { |
| 2540 Vector<FloatQuad> quads; | 2564 Vector<FloatQuad> quads; |
| 2541 toLayoutText(obj)->absoluteQuads(quads, LayoutText::ClipToEllipsis); | 2565 toLayoutText(obj)->quads(quads, LayoutText::ClipToEllipsis, LayoutText:: AbsoluteQuads); |
| 2542 result = LayoutRect(boundingBoxForQuads(obj, quads)); | 2566 result = LayoutRect(boundingBoxForQuads(obj, quads)); |
| 2543 } else if (isWebArea() || obj->isSVGRoot()) { | 2567 } else if (isWebArea() || obj->isSVGRoot()) { |
| 2544 result = LayoutRect(obj->absoluteBoundingBoxRect()); | 2568 result = LayoutRect(obj->absoluteBoundingBoxRect()); |
| 2545 } else { | 2569 } else { |
| 2546 result = LayoutRect(obj->absoluteElementBoundingBoxRect()); | 2570 result = LayoutRect(obj->absoluteElementBoundingBoxRect()); |
| 2547 } | 2571 } |
| 2548 | 2572 |
| 2549 Document* document = this->getDocument(); | 2573 Document* document = this->getDocument(); |
| 2550 if (document && document->isSVGDocument()) | 2574 if (document && document->isSVGDocument()) |
| 2551 offsetBoundingBoxForRemoteSVGElement(result); | 2575 offsetBoundingBoxForRemoteSVGElement(result); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 2570 result.unite(labelRect); | 2594 result.unite(labelRect); |
| 2571 } | 2595 } |
| 2572 } | 2596 } |
| 2573 } | 2597 } |
| 2574 } | 2598 } |
| 2575 | 2599 |
| 2576 return result; | 2600 return result; |
| 2577 } | 2601 } |
| 2578 | 2602 |
| 2579 } // namespace blink | 2603 } // namespace blink |
| OLD | NEW |