Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: third_party/WebKit/Source/core/svg/SVGSVGElement.cpp

Issue 2552513002: Rework SVGViewSpec<->SVGSVGElement integration (Closed)
Patch Set: Move setup back to SVGSVGElement Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 21 matching lines...) Expand all
32 #include "core/dom/StyleChangeReason.h" 32 #include "core/dom/StyleChangeReason.h"
33 #include "core/editing/FrameSelection.h" 33 #include "core/editing/FrameSelection.h"
34 #include "core/events/EventListener.h" 34 #include "core/events/EventListener.h"
35 #include "core/frame/Deprecation.h" 35 #include "core/frame/Deprecation.h"
36 #include "core/frame/FrameView.h" 36 #include "core/frame/FrameView.h"
37 #include "core/frame/LocalFrame.h" 37 #include "core/frame/LocalFrame.h"
38 #include "core/layout/LayoutObject.h" 38 #include "core/layout/LayoutObject.h"
39 #include "core/layout/svg/LayoutSVGModelObject.h" 39 #include "core/layout/svg/LayoutSVGModelObject.h"
40 #include "core/layout/svg/LayoutSVGRoot.h" 40 #include "core/layout/svg/LayoutSVGRoot.h"
41 #include "core/layout/svg/LayoutSVGViewportContainer.h" 41 #include "core/layout/svg/LayoutSVGViewportContainer.h"
42 #include "core/page/FrameTree.h"
43 #include "core/svg/SVGAngleTearOff.h" 42 #include "core/svg/SVGAngleTearOff.h"
44 #include "core/svg/SVGDocumentExtensions.h" 43 #include "core/svg/SVGDocumentExtensions.h"
45 #include "core/svg/SVGLengthTearOff.h" 44 #include "core/svg/SVGLengthTearOff.h"
46 #include "core/svg/SVGMatrixTearOff.h" 45 #include "core/svg/SVGMatrixTearOff.h"
47 #include "core/svg/SVGNumberTearOff.h" 46 #include "core/svg/SVGNumberTearOff.h"
48 #include "core/svg/SVGPointTearOff.h" 47 #include "core/svg/SVGPointTearOff.h"
49 #include "core/svg/SVGPreserveAspectRatio.h" 48 #include "core/svg/SVGPreserveAspectRatio.h"
50 #include "core/svg/SVGRectTearOff.h" 49 #include "core/svg/SVGRectTearOff.h"
51 #include "core/svg/SVGTransform.h" 50 #include "core/svg/SVGTransform.h"
52 #include "core/svg/SVGTransformList.h" 51 #include "core/svg/SVGTransformList.h"
(...skipping 22 matching lines...) Expand all
75 CSSPropertyY)), 74 CSSPropertyY)),
76 m_width(SVGAnimatedLength::create(this, 75 m_width(SVGAnimatedLength::create(this,
77 SVGNames::widthAttr, 76 SVGNames::widthAttr,
78 SVGLength::create(SVGLengthMode::Width), 77 SVGLength::create(SVGLengthMode::Width),
79 CSSPropertyWidth)), 78 CSSPropertyWidth)),
80 m_height( 79 m_height(
81 SVGAnimatedLength::create(this, 80 SVGAnimatedLength::create(this,
82 SVGNames::heightAttr, 81 SVGNames::heightAttr,
83 SVGLength::create(SVGLengthMode::Height), 82 SVGLength::create(SVGLengthMode::Height),
84 CSSPropertyHeight)), 83 CSSPropertyHeight)),
85 m_useCurrentView(false),
86 m_timeContainer(SMILTimeContainer::create(*this)), 84 m_timeContainer(SMILTimeContainer::create(*this)),
87 m_translation(SVGPoint::create()), 85 m_translation(SVGPoint::create()),
88 m_currentScale(1) { 86 m_currentScale(1) {
89 m_width->setDefaultValueAsString("100%"); 87 m_width->setDefaultValueAsString("100%");
90 m_height->setDefaultValueAsString("100%"); 88 m_height->setDefaultValueAsString("100%");
91 89
92 addToPropertyMap(m_x); 90 addToPropertyMap(m_x);
93 addToPropertyMap(m_y); 91 addToPropertyMap(m_y);
94 addToPropertyMap(m_width); 92 addToPropertyMap(m_width);
95 addToPropertyMap(m_height); 93 addToPropertyMap(m_height);
96 94
97 UseCounter::count(doc, UseCounter::SVGSVGElement); 95 UseCounter::count(doc, UseCounter::SVGSVGElement);
98 } 96 }
99 97
100 DEFINE_NODE_FACTORY(SVGSVGElement) 98 DEFINE_NODE_FACTORY(SVGSVGElement)
101 99
102 SVGSVGElement::~SVGSVGElement() {} 100 SVGSVGElement::~SVGSVGElement() {}
103 101
104 SVGViewSpec& SVGSVGElement::ensureViewSpec() {
105 if (!m_viewSpec)
106 m_viewSpec = SVGViewSpec::create();
107 return *m_viewSpec;
108 }
109
110 float SVGSVGElement::currentScale() const { 102 float SVGSVGElement::currentScale() const {
111 if (!isConnected() || !isOutermostSVGSVGElement()) 103 if (!isConnected() || !isOutermostSVGSVGElement())
112 return 1; 104 return 1;
113 105
114 return m_currentScale; 106 return m_currentScale;
115 } 107 }
116 108
117 void SVGSVGElement::setCurrentScale(float scale) { 109 void SVGSVGElement::setCurrentScale(float scale) {
118 ASSERT(std::isfinite(scale)); 110 ASSERT(std::isfinite(scale));
119 if (!isConnected() || !isOutermostSVGSVGElement()) 111 if (!isConnected() || !isOutermostSVGSVGElement())
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 } 143 }
152 144
153 void SVGSVGElement::updateUserTransform() { 145 void SVGSVGElement::updateUserTransform() {
154 if (LayoutObject* object = layoutObject()) 146 if (LayoutObject* object = layoutObject())
155 object->setNeedsLayoutAndFullPaintInvalidation( 147 object->setNeedsLayoutAndFullPaintInvalidation(
156 LayoutInvalidationReason::Unknown); 148 LayoutInvalidationReason::Unknown);
157 } 149 }
158 150
159 bool SVGSVGElement::zoomAndPanEnabled() const { 151 bool SVGSVGElement::zoomAndPanEnabled() const {
160 SVGZoomAndPanType zoomAndPan = this->zoomAndPan(); 152 SVGZoomAndPanType zoomAndPan = this->zoomAndPan();
161 if (m_useCurrentView) 153 if (m_viewSpec)
162 zoomAndPan = m_viewSpec->zoomAndPan(); 154 zoomAndPan = m_viewSpec->zoomAndPan();
163 return zoomAndPan == SVGZoomAndPanMagnify; 155 return zoomAndPan == SVGZoomAndPanMagnify;
164 } 156 }
165 157
166 void SVGSVGElement::parseAttribute(const QualifiedName& name, 158 void SVGSVGElement::parseAttribute(const QualifiedName& name,
167 const AtomicString& oldValue, 159 const AtomicString& oldValue,
168 const AtomicString& value) { 160 const AtomicString& value) {
169 if (!nearestViewportElement()) { 161 if (!nearestViewportElement()) {
170 bool setListener = true; 162 bool setListener = true;
171 163
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 m_width->currentValue()->isRelative() || 582 m_width->currentValue()->isRelative() ||
591 m_height->currentValue()->isRelative(); 583 m_height->currentValue()->isRelative();
592 } 584 }
593 585
594 bool SVGSVGElement::shouldSynthesizeViewBox() const { 586 bool SVGSVGElement::shouldSynthesizeViewBox() const {
595 return layoutObject() && layoutObject()->isSVGRoot() && 587 return layoutObject() && layoutObject()->isSVGRoot() &&
596 toLayoutSVGRoot(layoutObject())->isEmbeddedThroughSVGImage(); 588 toLayoutSVGRoot(layoutObject())->isEmbeddedThroughSVGImage();
597 } 589 }
598 590
599 FloatRect SVGSVGElement::currentViewBoxRect() const { 591 FloatRect SVGSVGElement::currentViewBoxRect() const {
600 if (m_useCurrentView) { 592 if (m_viewSpec)
601 DCHECK(m_viewSpec);
602 return m_viewSpec->viewBox()->value(); 593 return m_viewSpec->viewBox()->value();
603 }
604 594
605 FloatRect useViewBox = viewBox()->currentValue()->value(); 595 FloatRect useViewBox = viewBox()->currentValue()->value();
606 if (!useViewBox.isEmpty()) 596 if (!useViewBox.isEmpty())
607 return useViewBox; 597 return useViewBox;
608 if (!shouldSynthesizeViewBox()) 598 if (!shouldSynthesizeViewBox())
609 return FloatRect(); 599 return FloatRect();
610 600
611 // If no viewBox is specified but non-relative width/height values, then we 601 // If no viewBox is specified but non-relative width/height values, then we
612 // should always synthesize a viewBox if we're embedded through a SVGImage. 602 // should always synthesize a viewBox if we're embedded through a SVGImage.
613 FloatSize synthesizedViewBoxSize(intrinsicWidth(), intrinsicHeight()); 603 FloatSize synthesizedViewBoxSize(intrinsicWidth(), intrinsicHeight());
614 if (!hasIntrinsicWidth()) 604 if (!hasIntrinsicWidth())
615 synthesizedViewBoxSize.setWidth(width()->currentValue()->scaleByPercentage( 605 synthesizedViewBoxSize.setWidth(width()->currentValue()->scaleByPercentage(
616 currentViewportSize().width())); 606 currentViewportSize().width()));
617 if (!hasIntrinsicHeight()) 607 if (!hasIntrinsicHeight())
618 synthesizedViewBoxSize.setHeight( 608 synthesizedViewBoxSize.setHeight(
619 height()->currentValue()->scaleByPercentage( 609 height()->currentValue()->scaleByPercentage(
620 currentViewportSize().height())); 610 currentViewportSize().height()));
621 return FloatRect(FloatPoint(), synthesizedViewBoxSize); 611 return FloatRect(FloatPoint(), synthesizedViewBoxSize);
622 } 612 }
623 613
624 SVGPreserveAspectRatio* SVGSVGElement::currentPreserveAspectRatio() const { 614 SVGPreserveAspectRatio* SVGSVGElement::currentPreserveAspectRatio() const {
625 if (m_useCurrentView) { 615 if (m_viewSpec)
626 DCHECK(m_viewSpec);
627 return m_viewSpec->preserveAspectRatio(); 616 return m_viewSpec->preserveAspectRatio();
628 } 617
629 if (!viewBox()->currentValue()->isValid() && shouldSynthesizeViewBox()) { 618 if (!viewBox()->currentValue()->isValid() && shouldSynthesizeViewBox()) {
630 // If no viewBox is specified and we're embedded through SVGImage, then 619 // If no viewBox is specified and we're embedded through SVGImage, then
631 // synthesize a pAR with the value 'none'. 620 // synthesize a pAR with the value 'none'.
632 SVGPreserveAspectRatio* synthesizedPAR = SVGPreserveAspectRatio::create(); 621 SVGPreserveAspectRatio* synthesizedPAR = SVGPreserveAspectRatio::create();
633 synthesizedPAR->setAlign( 622 synthesizedPAR->setAlign(
634 SVGPreserveAspectRatio::kSvgPreserveaspectratioNone); 623 SVGPreserveAspectRatio::kSvgPreserveaspectratioNone);
635 return synthesizedPAR; 624 return synthesizedPAR;
636 } 625 }
637 return preserveAspectRatio()->currentValue(); 626 return preserveAspectRatio()->currentValue();
638 } 627 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 669
681 SVGLengthContext lengthContext(this); 670 SVGLengthContext lengthContext(this);
682 return height()->currentValue()->value(lengthContext); 671 return height()->currentValue()->value(lengthContext);
683 } 672 }
684 673
685 AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, 674 AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth,
686 float viewHeight) const { 675 float viewHeight) const {
687 AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform( 676 AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(
688 currentViewBoxRect(), currentPreserveAspectRatio(), viewWidth, 677 currentViewBoxRect(), currentPreserveAspectRatio(), viewWidth,
689 viewHeight); 678 viewHeight);
690 if (!m_useCurrentView) 679 if (!m_viewSpec)
691 return ctm; 680 return ctm;
692 DCHECK(m_viewSpec);
693 681
694 SVGTransformList* transformList = m_viewSpec->transform(); 682 SVGTransformList* transformList = m_viewSpec->transform();
695 if (transformList->isEmpty()) 683 if (transformList->isEmpty())
696 return ctm; 684 return ctm;
697 685
698 AffineTransform transform; 686 AffineTransform transform;
699 if (transformList->concatenate(transform)) 687 if (transformList->concatenate(transform))
700 ctm *= transform; 688 ctm *= transform;
701 689
702 return ctm; 690 return ctm;
703 } 691 }
704 692
693 void SVGSVGElement::setViewSpec(SVGViewSpec* viewSpec) {
694 // Even if the viewspec object itself doesn't change, it could still
695 // have been mutated, so only treat a "no viewspec" -> "no viewspec"
696 // transition as a no-op.
697 if (!m_viewSpec && !viewSpec)
698 return;
699 m_viewSpec = viewSpec;
700 if (LayoutObject* layoutObject = this->layoutObject())
701 markForLayoutAndParentResourceInvalidation(layoutObject);
702 }
703
705 void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, 704 void SVGSVGElement::setupInitialView(const String& fragmentIdentifier,
706 Element* anchorNode) { 705 Element* anchorNode) {
707 if (m_viewSpec)
708 m_viewSpec->reset();
709
710 // If we previously had a view, we need to layout again, regardless of the
711 // state after setting.
712 bool needsViewUpdate = m_useCurrentView;
713 m_useCurrentView = false;
714
715 if (fragmentIdentifier.startsWith("svgView(")) { 706 if (fragmentIdentifier.startsWith("svgView(")) {
716 // Ensure the SVGViewSpec has been created. 707 SVGViewSpec* viewSpec = SVGViewSpec::createForElement(*this);
717 SVGViewSpec& view = ensureViewSpec(); 708 if (viewSpec->parseViewSpec(fragmentIdentifier)) {
718 view.inheritViewAttributesFromElement(this);
719
720 if (view.parseViewSpec(fragmentIdentifier)) {
721 UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGView); 709 UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGView);
722 m_useCurrentView = true; 710 setViewSpec(viewSpec);
723 needsViewUpdate = true;
724 } else {
725 view.reset();
726 }
727 } else if (isSVGViewElement(anchorNode)) {
728 // Spec: If the SVG fragment identifier addresses a 'view' element
729 // within an SVG document (e.g., MyDrawing.svg#MyView or
730 // MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor
731 // 'svg' element is displayed in the viewport. Any view specification
732 // attributes included on the given 'view' element override the
733 // corresponding view specification attributes on the closest ancestor
734 // 'svg' element.
735 // TODO(ed): The spec text above is a bit unclear.
736 // Should the transform from outermost svg to nested svg be applied to
737 // "display" the inner svg in the viewport, then let the view element
738 // override the inner svg's view specification attributes. Should it
739 // fill/override the outer viewport?
740 SVGViewElement& viewElement = toSVGViewElement(*anchorNode);
741
742 if (SVGSVGElement* svg = viewElement.ownerSVGElement()) {
743 svg->inheritViewAttributes(&viewElement);
744
745 if (LayoutObject* layoutObject = svg->layoutObject())
746 markForLayoutAndParentResourceInvalidation(layoutObject);
747
748 return; 711 return;
749 } 712 }
750 } 713 }
751 714
752 LayoutObject* layoutObject = this->layoutObject(); 715 setViewSpec(nullptr);
753 if (layoutObject && needsViewUpdate)
754 markForLayoutAndParentResourceInvalidation(layoutObject);
755 716
756 // If m_useCurrentView is true we should have a view-spec. 717 if (!isSVGViewElement(anchorNode))
757 DCHECK(!m_useCurrentView || m_viewSpec); 718 return;
758 719
759 // FIXME: We need to decide which <svg> to focus on, and zoom to it. 720 SVGViewElement& viewElement = toSVGViewElement(*anchorNode);
760 // FIXME: We need to actually "highlight" the viewTarget(s).
761 }
762 721
763 void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) { 722 // Spec: If the SVG fragment identifier addresses a 'view' element
764 SVGViewSpec& view = ensureViewSpec(); 723 // within an SVG document (e.g., MyDrawing.svg#MyView) then the
765 m_useCurrentView = true; 724 // closest ancestor 'svg' element is displayed in the
766 UseCounter::count(document(), 725 // viewport. Any view specification attributes included on the
726 // given 'view' element override the corresponding view
727 // specification attributes on the closest ancestor 'svg' element.
728 // TODO(ed): The spec text above is a bit unclear.
729 // Should the transform from outermost svg to nested svg be applied to
730 // "display" the inner svg in the viewport, then let the view element
731 // override the inner svg's view specification attributes. Should it
732 // fill/override the outer viewport?
733 SVGSVGElement* svg = viewElement.ownerSVGElement();
734 if (!svg)
735 return;
736 SVGViewSpec* viewSpec = SVGViewSpec::createForElement(*svg);
737 viewSpec->inheritViewAttributesFromElement(viewElement);
738 UseCounter::count(svg->document(),
767 UseCounter::SVGSVGElementFragmentSVGViewElement); 739 UseCounter::SVGSVGElementFragmentSVGViewElement);
768 view.inheritViewAttributesFromElement(this); 740 svg->setViewSpec(viewSpec);
769 view.inheritViewAttributesFromElement(viewElement);
770 DCHECK(!m_useCurrentView || m_viewSpec);
771 } 741 }
772 742
773 void SVGSVGElement::finishParsingChildren() { 743 void SVGSVGElement::finishParsingChildren() {
774 SVGGraphicsElement::finishParsingChildren(); 744 SVGGraphicsElement::finishParsingChildren();
775 745
776 // The outermost SVGSVGElement SVGLoad event is fired through 746 // The outermost SVGSVGElement SVGLoad event is fired through
777 // LocalDOMWindow::dispatchWindowLoadEvent. 747 // LocalDOMWindow::dispatchWindowLoadEvent.
778 if (isOutermostSVGSVGElement()) 748 if (isOutermostSVGSVGElement())
779 return; 749 return;
780 750
781 // finishParsingChildren() is called when the close tag is reached for an 751 // finishParsingChildren() is called when the close tag is reached for an
782 // element (e.g. </svg>) we send SVGLoad events here if we can, otherwise 752 // element (e.g. </svg>) we send SVGLoad events here if we can, otherwise
783 // they'll be sent when any required loads finish 753 // they'll be sent when any required loads finish
784 sendSVGLoadEventIfPossible(); 754 sendSVGLoadEventIfPossible();
785 } 755 }
786 756
787 DEFINE_TRACE(SVGSVGElement) { 757 DEFINE_TRACE(SVGSVGElement) {
788 visitor->trace(m_x); 758 visitor->trace(m_x);
789 visitor->trace(m_y); 759 visitor->trace(m_y);
790 visitor->trace(m_width); 760 visitor->trace(m_width);
791 visitor->trace(m_height); 761 visitor->trace(m_height);
792 visitor->trace(m_translation); 762 visitor->trace(m_translation);
793 visitor->trace(m_timeContainer); 763 visitor->trace(m_timeContainer);
794 visitor->trace(m_viewSpec); 764 visitor->trace(m_viewSpec);
795 SVGGraphicsElement::trace(visitor); 765 SVGGraphicsElement::trace(visitor);
796 SVGFitToViewBox::trace(visitor); 766 SVGFitToViewBox::trace(visitor);
797 } 767 }
798 768
799 } // namespace blink 769 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/svg/SVGSVGElement.h ('k') | third_party/WebKit/Source/core/svg/SVGViewSpec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698