Bug 1289011 - Part 3. Handle view-box. r=heycam
authorcku <cku@mozilla.com>
Tue, 30 Aug 2016 10:27:30 +0800
changeset 312829 8eacb8a7c6cfd89b18c82bde40b5f00db19bb9ef
parent 312828 11871df86ff8f9972770e46d91b6115ed6338a13
child 312830 b803d96ab1a52fc23dc3c150fed268803ebb5cc0
push id30661
push userkwierso@gmail.com
push dateWed, 07 Sep 2016 00:28:11 +0000
treeherdermozilla-central@3ba67e3bb588 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1289011
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1289011 - Part 3. Handle view-box. r=heycam MozReview-Commit-ID: 3GsivsTYPYK
dom/svg/SVGSVGElement.cpp
dom/svg/SVGSVGElement.h
layout/svg/nsCSSClipPathInstance.cpp
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -1017,17 +1017,17 @@ SVGSVGElement::GetLengthInfo()
 
 nsSVGElement::EnumAttributesInfo
 SVGSVGElement::GetEnumInfo()
 {
   return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
                             ArrayLength(sEnumInfo));
 }
 
-nsSVGViewBox *
+nsSVGViewBox*
 SVGSVGElement::GetViewBox()
 {
   return &mViewBox;
 }
 
 SVGAnimatedPreserveAspectRatio *
 SVGSVGElement::GetPreserveAspectRatio()
 {
--- a/dom/svg/SVGSVGElement.h
+++ b/dom/svg/SVGSVGElement.h
@@ -283,16 +283,17 @@ public:
   already_AddRefed<SVGIRect> CreateSVGRect();
   already_AddRefed<SVGTransform> CreateSVGTransform();
   already_AddRefed<SVGTransform> CreateSVGTransformFromMatrix(SVGMatrix& matrix);
   using nsINode::GetElementById; // This does what we want
   already_AddRefed<SVGAnimatedRect> ViewBox();
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
   uint16_t ZoomAndPan();
   void SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv);
+  virtual nsSVGViewBox* GetViewBox() override;
 
 private:
   // nsSVGElement overrides
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) override;
   virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
@@ -373,17 +374,16 @@ private:
 
   virtual EnumAttributesInfo GetEnumInfo() override;
 
   enum { ZOOMANDPAN };
   nsSVGEnum mEnumAttributes[1];
   static nsSVGEnumMapping sZoomAndPanMap[];
   static EnumInfo sEnumInfo[1];
 
-  virtual nsSVGViewBox *GetViewBox() override;
   virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;
 
   nsSVGViewBox                   mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 
   // mCurrentViewID and mSVGView are mutually exclusive; we can have
   // at most one non-null.
   nsAutoPtr<nsString>            mCurrentViewID;
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -60,22 +60,52 @@ nsCSSClipPathInstance::HitTestBasicShape
   float pixelRatio = float(nsPresContext::AppUnitsPerCSSPixel()) /
                      aFrame->PresContext()->AppUnitsPerDevPixel();
   return path->ContainsPoint(ToPoint(aPoint) * pixelRatio, Matrix());
 }
 
 nsRect
 nsCSSClipPathInstance::ComputeSVGReferenceRect()
 {
+  MOZ_ASSERT(mTargetFrame->GetContent()->IsSVGElement());
   nsRect r;
 
   // For SVG elements without associated CSS layout box, the used value for
   // content-box, padding-box, border-box and margin-box is fill-box.
   switch (mClipPathStyle.GetReferenceBox()) {
+    case StyleClipPathGeometryBox::View: {
+      nsIContent* content = mTargetFrame->GetContent();
+      nsSVGElement* element = static_cast<nsSVGElement*>(content);
+      SVGSVGElement* svgElement = element->GetCtx();
+      MOZ_ASSERT(svgElement);
 
+      if (svgElement && svgElement->HasViewBoxRect()) {
+        // If a ‘viewBox‘ attribute is specified for the SVG viewport creating
+        // element:
+        // 1. The reference box is positioned at the origin of the coordinate
+        //    system established by the ‘viewBox‘ attribute.
+        // 2. The dimension of the reference box is set to the width and height
+        //    values of the ‘viewBox‘ attribute.
+        nsSVGViewBox* viewBox = svgElement->GetViewBox();
+        const nsSVGViewBoxRect& value = viewBox->GetAnimValue();
+        r = nsRect(nsPresContext::CSSPixelsToAppUnits(value.x),
+                   nsPresContext::CSSPixelsToAppUnits(value.y),
+                   nsPresContext::CSSPixelsToAppUnits(value.width),
+                   nsPresContext::CSSPixelsToAppUnits(value.height));
+      } else {
+        // No viewBox is specified, uses the nearest SVG viewport as reference
+        // box.
+        svgFloatSize viewportSize = svgElement->GetViewportSize();
+        r = nsRect(0, 0,
+                   nsPresContext::CSSPixelsToAppUnits(viewportSize.width),
+                   nsPresContext::CSSPixelsToAppUnits(viewportSize.height));
+      }
+
+      break;
+    }
     case StyleClipPathGeometryBox::NoBox:
     case StyleClipPathGeometryBox::Border:
     case StyleClipPathGeometryBox::Content:
     case StyleClipPathGeometryBox::Padding:
     case StyleClipPathGeometryBox::Margin:
     case StyleClipPathGeometryBox::Fill: {
       gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
                                          nsSVGUtils::eBBoxIncludeFill);