| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org> |
| 4 * Copyright (C) 2007 Apple Inc. All rights reserved. | 4 * Copyright (C) 2007 Apple Inc. All rights reserved. |
| 5 * Copyright (C) 2014 Google, Inc. | 5 * Copyright (C) 2014 Google, Inc. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 if (!inDocument() || !isOutermostSVGSVGElement()) | 138 if (!inDocument() || !isOutermostSVGSVGElement()) |
| 139 return 1; | 139 return 1; |
| 140 | 140 |
| 141 LocalFrame* frame = document().frame(); | 141 LocalFrame* frame = document().frame(); |
| 142 if (!frame) | 142 if (!frame) |
| 143 return 1; | 143 return 1; |
| 144 | 144 |
| 145 const FrameTree& frameTree = frame->tree(); | 145 const FrameTree& frameTree = frame->tree(); |
| 146 | 146 |
| 147 // The behaviour of currentScale() is undefined, when we're dealing with non
-standalone SVG documents. | 147 // The behaviour of currentScale() is undefined, when we're dealing with non
-standalone SVG documents. |
| 148 // If the svg is embedded, the scaling is handled by the host renderer, so w
hen asking from inside | 148 // If the svg is embedded, the scaling is handled by the host layoutObject,
so when asking from inside |
| 149 // the SVG document, a scale value of 1 seems reasonable, as it doesn't know
anything about the parent scale. | 149 // the SVG document, a scale value of 1 seems reasonable, as it doesn't know
anything about the parent scale. |
| 150 return frameTree.parent() ? 1 : frame->pageZoomFactor(); | 150 return frameTree.parent() ? 1 : frame->pageZoomFactor(); |
| 151 } | 151 } |
| 152 | 152 |
| 153 void SVGSVGElement::setCurrentScale(float scale) | 153 void SVGSVGElement::setCurrentScale(float scale) |
| 154 { | 154 { |
| 155 ASSERT(std::isfinite(scale)); | 155 ASSERT(std::isfinite(scale)); |
| 156 if (!inDocument() || !isOutermostSVGSVGElement()) | 156 if (!inDocument() || !isOutermostSVGSVGElement()) |
| 157 return; | 157 return; |
| 158 | 158 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 { | 335 { |
| 336 if (r1.width() < 0 || r1.height() < 0 || r2.width() < 0 || r2.height() < 0) | 336 if (r1.width() < 0 || r1.height() < 0 || r2.width() < 0 || r2.height() < 0) |
| 337 return false; | 337 return false; |
| 338 | 338 |
| 339 return r1.x() < r2.maxX() && r2.x() < r1.maxX() | 339 return r1.x() < r2.maxX() && r2.x() < r1.maxX() |
| 340 && r1.y() < r2.maxY() && r2.y() < r1.maxY(); | 340 && r1.y() < r2.maxY() && r2.y() < r1.maxY(); |
| 341 } | 341 } |
| 342 | 342 |
| 343 // One of the element types that can cause graphics to be drawn onto the target
canvas. | 343 // One of the element types that can cause graphics to be drawn onto the target
canvas. |
| 344 // Specifically: circle, ellipse, image, line, path, polygon, polyline, rect, te
xt and use. | 344 // Specifically: circle, ellipse, image, line, path, polygon, polyline, rect, te
xt and use. |
| 345 static bool isIntersectionOrEnclosureTarget(LayoutObject* renderer) | 345 static bool isIntersectionOrEnclosureTarget(LayoutObject* layoutObject) |
| 346 { | 346 { |
| 347 return renderer->isSVGShape() | 347 return layoutObject->isSVGShape() |
| 348 || renderer->isSVGText() | 348 || layoutObject->isSVGText() |
| 349 || renderer->isSVGImage() | 349 || layoutObject->isSVGImage() |
| 350 || isSVGUseElement(*renderer->node()); | 350 || isSVGUseElement(*layoutObject->node()); |
| 351 } | 351 } |
| 352 | 352 |
| 353 bool SVGSVGElement::checkIntersectionOrEnclosure(const SVGElement& element, cons
t FloatRect& rect, | 353 bool SVGSVGElement::checkIntersectionOrEnclosure(const SVGElement& element, cons
t FloatRect& rect, |
| 354 CheckIntersectionOrEnclosure mode) const | 354 CheckIntersectionOrEnclosure mode) const |
| 355 { | 355 { |
| 356 LayoutObject* renderer = element.layoutObject(); | 356 LayoutObject* layoutObject = element.layoutObject(); |
| 357 ASSERT(!renderer || renderer->style()); | 357 ASSERT(!layoutObject || layoutObject->style()); |
| 358 if (!renderer || renderer->style()->pointerEvents() == PE_NONE) | 358 if (!layoutObject || layoutObject->style()->pointerEvents() == PE_NONE) |
| 359 return false; | 359 return false; |
| 360 | 360 |
| 361 if (!isIntersectionOrEnclosureTarget(renderer)) | 361 if (!isIntersectionOrEnclosureTarget(layoutObject)) |
| 362 return false; | 362 return false; |
| 363 | 363 |
| 364 AffineTransform ctm = toSVGGraphicsElement(element).computeCTM(AncestorScope
, DisallowStyleUpdate, this); | 364 AffineTransform ctm = toSVGGraphicsElement(element).computeCTM(AncestorScope
, DisallowStyleUpdate, this); |
| 365 FloatRect mappedRepaintRect = ctm.mapRect(renderer->paintInvalidationRectInL
ocalCoordinates()); | 365 FloatRect mappedRepaintRect = ctm.mapRect(layoutObject->paintInvalidationRec
tInLocalCoordinates()); |
| 366 | 366 |
| 367 bool result = false; | 367 bool result = false; |
| 368 switch (mode) { | 368 switch (mode) { |
| 369 case CheckIntersection: | 369 case CheckIntersection: |
| 370 result = intersectsAllowingEmpty(rect, mappedRepaintRect); | 370 result = intersectsAllowingEmpty(rect, mappedRepaintRect); |
| 371 break; | 371 break; |
| 372 case CheckEnclosure: | 372 case CheckEnclosure: |
| 373 result = rect.contains(mappedRepaintRect); | 373 result = rect.contains(mappedRepaintRect); |
| 374 break; | 374 break; |
| 375 default: | 375 default: |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 if (!hasEmptyViewBox()) { | 486 if (!hasEmptyViewBox()) { |
| 487 FloatSize size = currentViewportSize(); | 487 FloatSize size = currentViewportSize(); |
| 488 viewBoxTransform = viewBoxToViewTransform(size.width(), size.height()); | 488 viewBoxTransform = viewBoxToViewTransform(size.width(), size.height()); |
| 489 } | 489 } |
| 490 | 490 |
| 491 AffineTransform transform; | 491 AffineTransform transform; |
| 492 if (!isOutermostSVGSVGElement()) { | 492 if (!isOutermostSVGSVGElement()) { |
| 493 SVGLengthContext lengthContext(this); | 493 SVGLengthContext lengthContext(this); |
| 494 transform.translate(m_x->currentValue()->value(lengthContext), m_y->curr
entValue()->value(lengthContext)); | 494 transform.translate(m_x->currentValue()->value(lengthContext), m_y->curr
entValue()->value(lengthContext)); |
| 495 } else if (mode == SVGElement::ScreenScope) { | 495 } else if (mode == SVGElement::ScreenScope) { |
| 496 if (LayoutObject* renderer = this->layoutObject()) { | 496 if (LayoutObject* layoutObject = this->layoutObject()) { |
| 497 FloatPoint location; | 497 FloatPoint location; |
| 498 float zoomFactor = 1; | 498 float zoomFactor = 1; |
| 499 | 499 |
| 500 // At the SVG/HTML boundary (aka LayoutSVGRoot), we apply the localT
oBorderBoxTransform | 500 // At the SVG/HTML boundary (aka LayoutSVGRoot), we apply the localT
oBorderBoxTransform |
| 501 // to map an element from SVG viewport coordinates to CSS box coordi
nates. | 501 // to map an element from SVG viewport coordinates to CSS box coordi
nates. |
| 502 // LayoutSVGRoot's localToAbsolute method expects CSS box coordinate
s. | 502 // LayoutSVGRoot's localToAbsolute method expects CSS box coordinate
s. |
| 503 // We also need to adjust for the zoom level factored into CSS coord
inates (bug #96361). | 503 // We also need to adjust for the zoom level factored into CSS coord
inates (bug #96361). |
| 504 if (renderer->isSVGRoot()) { | 504 if (layoutObject->isSVGRoot()) { |
| 505 location = toLayoutSVGRoot(renderer)->localToBorderBoxTransform(
).mapPoint(location); | 505 location = toLayoutSVGRoot(layoutObject)->localToBorderBoxTransf
orm().mapPoint(location); |
| 506 zoomFactor = 1 / renderer->style()->effectiveZoom(); | 506 zoomFactor = 1 / layoutObject->style()->effectiveZoom(); |
| 507 } | 507 } |
| 508 | 508 |
| 509 // Translate in our CSS parent coordinate space | 509 // Translate in our CSS parent coordinate space |
| 510 // FIXME: This doesn't work correctly with CSS transforms. | 510 // FIXME: This doesn't work correctly with CSS transforms. |
| 511 location = renderer->localToAbsolute(location, UseTransforms); | 511 location = layoutObject->localToAbsolute(location, UseTransforms); |
| 512 location.scale(zoomFactor, zoomFactor); | 512 location.scale(zoomFactor, zoomFactor); |
| 513 | 513 |
| 514 // Be careful here! localToBorderBoxTransform() included the x/y off
set coming from the viewBoxToViewTransform(), | 514 // Be careful here! localToBorderBoxTransform() included the x/y off
set coming from the viewBoxToViewTransform(), |
| 515 // so we have to subtract it here (original cause of bug #27183) | 515 // so we have to subtract it here (original cause of bug #27183) |
| 516 transform.translate(location.x() - viewBoxTransform.e(), location.y(
) - viewBoxTransform.f()); | 516 transform.translate(location.x() - viewBoxTransform.e(), location.y(
) - viewBoxTransform.f()); |
| 517 | 517 |
| 518 // Respect scroll offset. | 518 // Respect scroll offset. |
| 519 if (FrameView* view = document().view()) { | 519 if (FrameView* view = document().view()) { |
| 520 LayoutSize scrollOffset(view->scrollOffset()); | 520 LayoutSize scrollOffset(view->scrollOffset()); |
| 521 scrollOffset.scale(zoomFactor); | 521 scrollOffset.scale(zoomFactor); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 | 684 |
| 685 AffineTransform transform; | 685 AffineTransform transform; |
| 686 if (transformList->concatenate(transform)) | 686 if (transformList->concatenate(transform)) |
| 687 ctm *= transform; | 687 ctm *= transform; |
| 688 | 688 |
| 689 return ctm; | 689 return ctm; |
| 690 } | 690 } |
| 691 | 691 |
| 692 void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element*
anchorNode) | 692 void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element*
anchorNode) |
| 693 { | 693 { |
| 694 LayoutObject* renderer = this->layoutObject(); | 694 LayoutObject* layoutObject = this->layoutObject(); |
| 695 SVGViewSpec* view = m_viewSpec.get(); | 695 SVGViewSpec* view = m_viewSpec.get(); |
| 696 if (view) | 696 if (view) |
| 697 view->reset(); | 697 view->reset(); |
| 698 | 698 |
| 699 bool hadUseCurrentView = m_useCurrentView; | 699 bool hadUseCurrentView = m_useCurrentView; |
| 700 m_useCurrentView = false; | 700 m_useCurrentView = false; |
| 701 | 701 |
| 702 if (fragmentIdentifier.startsWith("xpointer(")) { | 702 if (fragmentIdentifier.startsWith("xpointer(")) { |
| 703 // FIXME: XPointer references are ignored (https://bugs.webkit.org/show_
bug.cgi?id=17491) | 703 // FIXME: XPointer references are ignored (https://bugs.webkit.org/show_
bug.cgi?id=17491) |
| 704 if (renderer && hadUseCurrentView) | 704 if (layoutObject && hadUseCurrentView) |
| 705 markForLayoutAndParentResourceInvalidation(renderer); | 705 markForLayoutAndParentResourceInvalidation(layoutObject); |
| 706 return; | 706 return; |
| 707 } | 707 } |
| 708 | 708 |
| 709 if (fragmentIdentifier.startsWith("svgView(")) { | 709 if (fragmentIdentifier.startsWith("svgView(")) { |
| 710 if (!view) | 710 if (!view) |
| 711 view = currentView(); // Create the SVGViewSpec. | 711 view = currentView(); // Create the SVGViewSpec. |
| 712 | 712 |
| 713 view->inheritViewAttributesFromElement(this); | 713 view->inheritViewAttributesFromElement(this); |
| 714 | 714 |
| 715 if (view->parseViewSpec(fragmentIdentifier)) | 715 if (view->parseViewSpec(fragmentIdentifier)) |
| 716 m_useCurrentView = true; | 716 m_useCurrentView = true; |
| 717 else | 717 else |
| 718 view->reset(); | 718 view->reset(); |
| 719 | 719 |
| 720 if (renderer && (hadUseCurrentView || m_useCurrentView)) | 720 if (layoutObject && (hadUseCurrentView || m_useCurrentView)) |
| 721 markForLayoutAndParentResourceInvalidation(renderer); | 721 markForLayoutAndParentResourceInvalidation(layoutObject); |
| 722 return; | 722 return; |
| 723 } | 723 } |
| 724 | 724 |
| 725 // Spec: If the SVG fragment identifier addresses a 'view' element within an
SVG document (e.g., MyDrawing.svg#MyView | 725 // Spec: If the SVG fragment identifier addresses a 'view' element within an
SVG document (e.g., MyDrawing.svg#MyView |
| 726 // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor 'svg'
element is displayed in the viewport. | 726 // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor 'svg'
element is displayed in the viewport. |
| 727 // Any view specification attributes included on the given 'view' element ov
erride the corresponding view specification | 727 // Any view specification attributes included on the given 'view' element ov
erride the corresponding view specification |
| 728 // attributes on the closest ancestor 'svg' element. | 728 // attributes on the closest ancestor 'svg' element. |
| 729 // TODO(ed): The spec text above is a bit unclear. | 729 // TODO(ed): The spec text above is a bit unclear. |
| 730 // Should the transform from outermost svg to nested svg be applied to "disp
lay" | 730 // Should the transform from outermost svg to nested svg be applied to "disp
lay" |
| 731 // the inner svg in the viewport, then let the view element override the inn
er | 731 // the inner svg in the viewport, then let the view element override the inn
er |
| 732 // svg's view specification attributes. Should it fill/override the outer vi
ewport? | 732 // svg's view specification attributes. Should it fill/override the outer vi
ewport? |
| 733 if (isSVGViewElement(anchorNode)) { | 733 if (isSVGViewElement(anchorNode)) { |
| 734 SVGViewElement& viewElement = toSVGViewElement(*anchorNode); | 734 SVGViewElement& viewElement = toSVGViewElement(*anchorNode); |
| 735 | 735 |
| 736 if (SVGSVGElement* svg = viewElement.ownerSVGElement()) { | 736 if (SVGSVGElement* svg = viewElement.ownerSVGElement()) { |
| 737 svg->inheritViewAttributes(&viewElement); | 737 svg->inheritViewAttributes(&viewElement); |
| 738 | 738 |
| 739 if (LayoutObject* renderer = svg->layoutObject()) | 739 if (LayoutObject* layoutObject = svg->layoutObject()) |
| 740 markForLayoutAndParentResourceInvalidation(renderer); | 740 markForLayoutAndParentResourceInvalidation(layoutObject); |
| 741 | 741 |
| 742 return; | 742 return; |
| 743 } | 743 } |
| 744 } | 744 } |
| 745 | 745 |
| 746 // If we previously had a view and didn't get a new one, we need to | 746 // If we previously had a view and didn't get a new one, we need to |
| 747 // layout again. | 747 // layout again. |
| 748 if (renderer && hadUseCurrentView) | 748 if (layoutObject && hadUseCurrentView) |
| 749 markForLayoutAndParentResourceInvalidation(renderer); | 749 markForLayoutAndParentResourceInvalidation(layoutObject); |
| 750 | 750 |
| 751 // FIXME: We need to decide which <svg> to focus on, and zoom to it. | 751 // FIXME: We need to decide which <svg> to focus on, and zoom to it. |
| 752 // FIXME: We need to actually "highlight" the viewTarget(s). | 752 // FIXME: We need to actually "highlight" the viewTarget(s). |
| 753 } | 753 } |
| 754 | 754 |
| 755 void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) | 755 void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) |
| 756 { | 756 { |
| 757 SVGViewSpec* view = currentView(); | 757 SVGViewSpec* view = currentView(); |
| 758 m_useCurrentView = true; | 758 m_useCurrentView = true; |
| 759 view->inheritViewAttributesFromElement(this); | 759 view->inheritViewAttributesFromElement(this); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 780 visitor->trace(m_width); | 780 visitor->trace(m_width); |
| 781 visitor->trace(m_height); | 781 visitor->trace(m_height); |
| 782 visitor->trace(m_translation); | 782 visitor->trace(m_translation); |
| 783 visitor->trace(m_timeContainer); | 783 visitor->trace(m_timeContainer); |
| 784 visitor->trace(m_viewSpec); | 784 visitor->trace(m_viewSpec); |
| 785 SVGGraphicsElement::trace(visitor); | 785 SVGGraphicsElement::trace(visitor); |
| 786 SVGFitToViewBox::trace(visitor); | 786 SVGFitToViewBox::trace(visitor); |
| 787 } | 787 } |
| 788 | 788 |
| 789 } // namespace blink | 789 } // namespace blink |
| OLD | NEW |