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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 addToPropertyMap(m_width); | 94 addToPropertyMap(m_width); |
95 addToPropertyMap(m_height); | 95 addToPropertyMap(m_height); |
96 | 96 |
97 UseCounter::count(doc, UseCounter::SVGSVGElement); | 97 UseCounter::count(doc, UseCounter::SVGSVGElement); |
98 } | 98 } |
99 | 99 |
100 DEFINE_NODE_FACTORY(SVGSVGElement) | 100 DEFINE_NODE_FACTORY(SVGSVGElement) |
101 | 101 |
102 SVGSVGElement::~SVGSVGElement() {} | 102 SVGSVGElement::~SVGSVGElement() {} |
103 | 103 |
104 SVGViewSpec* SVGSVGElement::currentView() { | 104 SVGViewSpec& SVGSVGElement::ensureViewSpec() { |
105 if (!m_viewSpec) | 105 if (!m_viewSpec) |
106 m_viewSpec = SVGViewSpec::create(this); | 106 m_viewSpec = SVGViewSpec::create(); |
107 return m_viewSpec; | 107 return *m_viewSpec; |
108 } | 108 } |
109 | 109 |
110 float SVGSVGElement::currentScale() const { | 110 float SVGSVGElement::currentScale() const { |
111 if (!isConnected() || !isOutermostSVGSVGElement()) | 111 if (!isConnected() || !isOutermostSVGSVGElement()) |
112 return 1; | 112 return 1; |
113 | 113 |
114 return m_currentScale; | 114 return m_currentScale; |
115 } | 115 } |
116 | 116 |
117 void SVGSVGElement::setCurrentScale(float scale) { | 117 void SVGSVGElement::setCurrentScale(float scale) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 updateUserTransform(); | 150 updateUserTransform(); |
151 } | 151 } |
152 | 152 |
153 void SVGSVGElement::updateUserTransform() { | 153 void SVGSVGElement::updateUserTransform() { |
154 if (LayoutObject* object = layoutObject()) | 154 if (LayoutObject* object = layoutObject()) |
155 object->setNeedsLayoutAndFullPaintInvalidation( | 155 object->setNeedsLayoutAndFullPaintInvalidation( |
156 LayoutInvalidationReason::Unknown); | 156 LayoutInvalidationReason::Unknown); |
157 } | 157 } |
158 | 158 |
159 bool SVGSVGElement::zoomAndPanEnabled() const { | 159 bool SVGSVGElement::zoomAndPanEnabled() const { |
160 const SVGZoomAndPan* currentViewSpec = this; | 160 SVGZoomAndPanType zoomAndPan = this->zoomAndPan(); |
161 if (m_useCurrentView) | 161 if (m_useCurrentView) |
162 currentViewSpec = m_viewSpec; | 162 zoomAndPan = m_viewSpec->zoomAndPan(); |
163 DCHECK(currentViewSpec); | 163 return zoomAndPan == SVGZoomAndPanMagnify; |
164 return currentViewSpec->zoomAndPan() == SVGZoomAndPanMagnify; | |
165 } | 164 } |
166 | 165 |
167 void SVGSVGElement::parseAttribute(const QualifiedName& name, | 166 void SVGSVGElement::parseAttribute(const QualifiedName& name, |
168 const AtomicString& oldValue, | 167 const AtomicString& oldValue, |
169 const AtomicString& value) { | 168 const AtomicString& value) { |
170 if (!nearestViewportElement()) { | 169 if (!nearestViewportElement()) { |
171 bool setListener = true; | 170 bool setListener = true; |
172 | 171 |
173 // Only handle events if we're the outermost <svg> element | 172 // Only handle events if we're the outermost <svg> element |
174 if (name == HTMLNames::onunloadAttr) { | 173 if (name == HTMLNames::onunloadAttr) { |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 } | 592 } |
594 | 593 |
595 bool SVGSVGElement::shouldSynthesizeViewBox() const { | 594 bool SVGSVGElement::shouldSynthesizeViewBox() const { |
596 return layoutObject() && layoutObject()->isSVGRoot() && | 595 return layoutObject() && layoutObject()->isSVGRoot() && |
597 toLayoutSVGRoot(layoutObject())->isEmbeddedThroughSVGImage(); | 596 toLayoutSVGRoot(layoutObject())->isEmbeddedThroughSVGImage(); |
598 } | 597 } |
599 | 598 |
600 FloatRect SVGSVGElement::currentViewBoxRect() const { | 599 FloatRect SVGSVGElement::currentViewBoxRect() const { |
601 if (m_useCurrentView) { | 600 if (m_useCurrentView) { |
602 DCHECK(m_viewSpec); | 601 DCHECK(m_viewSpec); |
603 return m_viewSpec->viewBox()->currentValue()->value(); | 602 return m_viewSpec->viewBox()->value(); |
604 } | 603 } |
605 | 604 |
606 FloatRect useViewBox = viewBox()->currentValue()->value(); | 605 FloatRect useViewBox = viewBox()->currentValue()->value(); |
607 if (!useViewBox.isEmpty()) | 606 if (!useViewBox.isEmpty()) |
608 return useViewBox; | 607 return useViewBox; |
609 if (!shouldSynthesizeViewBox()) | 608 if (!shouldSynthesizeViewBox()) |
610 return FloatRect(); | 609 return FloatRect(); |
611 | 610 |
612 // If no viewBox is specified but non-relative width/height values, then we | 611 // If no viewBox is specified but non-relative width/height values, then we |
613 // should always synthesize a viewBox if we're embedded through a SVGImage. | 612 // should always synthesize a viewBox if we're embedded through a SVGImage. |
614 FloatSize synthesizedViewBoxSize(intrinsicWidth(), intrinsicHeight()); | 613 FloatSize synthesizedViewBoxSize(intrinsicWidth(), intrinsicHeight()); |
615 if (!hasIntrinsicWidth()) | 614 if (!hasIntrinsicWidth()) |
616 synthesizedViewBoxSize.setWidth(width()->currentValue()->scaleByPercentage( | 615 synthesizedViewBoxSize.setWidth(width()->currentValue()->scaleByPercentage( |
617 currentViewportSize().width())); | 616 currentViewportSize().width())); |
618 if (!hasIntrinsicHeight()) | 617 if (!hasIntrinsicHeight()) |
619 synthesizedViewBoxSize.setHeight( | 618 synthesizedViewBoxSize.setHeight( |
620 height()->currentValue()->scaleByPercentage( | 619 height()->currentValue()->scaleByPercentage( |
621 currentViewportSize().height())); | 620 currentViewportSize().height())); |
622 return FloatRect(FloatPoint(), synthesizedViewBoxSize); | 621 return FloatRect(FloatPoint(), synthesizedViewBoxSize); |
623 } | 622 } |
624 | 623 |
625 SVGPreserveAspectRatio* SVGSVGElement::currentPreserveAspectRatio() const { | 624 SVGPreserveAspectRatio* SVGSVGElement::currentPreserveAspectRatio() const { |
626 if (m_useCurrentView) { | 625 if (m_useCurrentView) { |
627 DCHECK(m_viewSpec); | 626 DCHECK(m_viewSpec); |
628 return m_viewSpec->preserveAspectRatio()->currentValue(); | 627 return m_viewSpec->preserveAspectRatio(); |
629 } | 628 } |
630 if (!viewBox()->currentValue()->isValid() && shouldSynthesizeViewBox()) { | 629 if (!viewBox()->currentValue()->isValid() && shouldSynthesizeViewBox()) { |
631 // If no viewBox is specified and we're embedded through SVGImage, then | 630 // If no viewBox is specified and we're embedded through SVGImage, then |
632 // synthesize a pAR with the value 'none'. | 631 // synthesize a pAR with the value 'none'. |
633 SVGPreserveAspectRatio* synthesizedPAR = SVGPreserveAspectRatio::create(); | 632 SVGPreserveAspectRatio* synthesizedPAR = SVGPreserveAspectRatio::create(); |
634 synthesizedPAR->setAlign( | 633 synthesizedPAR->setAlign( |
635 SVGPreserveAspectRatio::kSvgPreserveaspectratioNone); | 634 SVGPreserveAspectRatio::kSvgPreserveaspectratioNone); |
636 return synthesizedPAR; | 635 return synthesizedPAR; |
637 } | 636 } |
638 return preserveAspectRatio()->currentValue(); | 637 return preserveAspectRatio()->currentValue(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 Element* anchorNode) { | 706 Element* anchorNode) { |
708 if (m_viewSpec) | 707 if (m_viewSpec) |
709 m_viewSpec->reset(); | 708 m_viewSpec->reset(); |
710 | 709 |
711 // If we previously had a view, we need to layout again, regardless of the | 710 // If we previously had a view, we need to layout again, regardless of the |
712 // state after setting. | 711 // state after setting. |
713 bool needsViewUpdate = m_useCurrentView; | 712 bool needsViewUpdate = m_useCurrentView; |
714 m_useCurrentView = false; | 713 m_useCurrentView = false; |
715 | 714 |
716 if (fragmentIdentifier.startsWith("svgView(")) { | 715 if (fragmentIdentifier.startsWith("svgView(")) { |
717 SVGViewSpec* view = | 716 // Ensure the SVGViewSpec has been created. |
718 currentView(); // Ensure the SVGViewSpec has been created. | 717 SVGViewSpec& view = ensureViewSpec(); |
| 718 view.inheritViewAttributesFromElement(this); |
719 | 719 |
720 view->inheritViewAttributesFromElement(this); | 720 if (view.parseViewSpec(fragmentIdentifier)) { |
721 | |
722 if (view->parseViewSpec(fragmentIdentifier)) { | |
723 UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGView); | 721 UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGView); |
724 m_useCurrentView = true; | 722 m_useCurrentView = true; |
725 needsViewUpdate = true; | 723 needsViewUpdate = true; |
726 } else { | 724 } else { |
727 view->reset(); | 725 view.reset(); |
728 } | 726 } |
729 } else if (isSVGViewElement(anchorNode)) { | 727 } else if (isSVGViewElement(anchorNode)) { |
730 // Spec: If the SVG fragment identifier addresses a 'view' element | 728 // Spec: If the SVG fragment identifier addresses a 'view' element |
731 // within an SVG document (e.g., MyDrawing.svg#MyView or | 729 // within an SVG document (e.g., MyDrawing.svg#MyView or |
732 // MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor | 730 // MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor |
733 // 'svg' element is displayed in the viewport. Any view specification | 731 // 'svg' element is displayed in the viewport. Any view specification |
734 // attributes included on the given 'view' element override the | 732 // attributes included on the given 'view' element override the |
735 // corresponding view specification attributes on the closest ancestor | 733 // corresponding view specification attributes on the closest ancestor |
736 // 'svg' element. | 734 // 'svg' element. |
737 // TODO(ed): The spec text above is a bit unclear. | 735 // TODO(ed): The spec text above is a bit unclear. |
(...skipping 18 matching lines...) Expand all Loading... |
756 markForLayoutAndParentResourceInvalidation(layoutObject); | 754 markForLayoutAndParentResourceInvalidation(layoutObject); |
757 | 755 |
758 // If m_useCurrentView is true we should have a view-spec. | 756 // If m_useCurrentView is true we should have a view-spec. |
759 DCHECK(!m_useCurrentView || m_viewSpec); | 757 DCHECK(!m_useCurrentView || m_viewSpec); |
760 | 758 |
761 // FIXME: We need to decide which <svg> to focus on, and zoom to it. | 759 // FIXME: We need to decide which <svg> to focus on, and zoom to it. |
762 // FIXME: We need to actually "highlight" the viewTarget(s). | 760 // FIXME: We need to actually "highlight" the viewTarget(s). |
763 } | 761 } |
764 | 762 |
765 void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) { | 763 void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) { |
766 SVGViewSpec* view = currentView(); | 764 SVGViewSpec& view = ensureViewSpec(); |
767 m_useCurrentView = true; | 765 m_useCurrentView = true; |
768 UseCounter::count(document(), | 766 UseCounter::count(document(), |
769 UseCounter::SVGSVGElementFragmentSVGViewElement); | 767 UseCounter::SVGSVGElementFragmentSVGViewElement); |
770 view->inheritViewAttributesFromElement(this); | 768 view.inheritViewAttributesFromElement(this); |
771 view->inheritViewAttributesFromElement(viewElement); | 769 view.inheritViewAttributesFromElement(viewElement); |
772 DCHECK(!m_useCurrentView || m_viewSpec); | 770 DCHECK(!m_useCurrentView || m_viewSpec); |
773 } | 771 } |
774 | 772 |
775 void SVGSVGElement::finishParsingChildren() { | 773 void SVGSVGElement::finishParsingChildren() { |
776 SVGGraphicsElement::finishParsingChildren(); | 774 SVGGraphicsElement::finishParsingChildren(); |
777 | 775 |
778 // The outermost SVGSVGElement SVGLoad event is fired through | 776 // The outermost SVGSVGElement SVGLoad event is fired through |
779 // LocalDOMWindow::dispatchWindowLoadEvent. | 777 // LocalDOMWindow::dispatchWindowLoadEvent. |
780 if (isOutermostSVGSVGElement()) | 778 if (isOutermostSVGSVGElement()) |
781 return; | 779 return; |
(...skipping 10 matching lines...) Expand all Loading... |
792 visitor->trace(m_width); | 790 visitor->trace(m_width); |
793 visitor->trace(m_height); | 791 visitor->trace(m_height); |
794 visitor->trace(m_translation); | 792 visitor->trace(m_translation); |
795 visitor->trace(m_timeContainer); | 793 visitor->trace(m_timeContainer); |
796 visitor->trace(m_viewSpec); | 794 visitor->trace(m_viewSpec); |
797 SVGGraphicsElement::trace(visitor); | 795 SVGGraphicsElement::trace(visitor); |
798 SVGFitToViewBox::trace(visitor); | 796 SVGFitToViewBox::trace(visitor); |
799 } | 797 } |
800 | 798 |
801 } // namespace blink | 799 } // namespace blink |
OLD | NEW |