Bug 1058040, part 5 - Move the code from nsSVGUtils::SetupContextPaint and nsSVGUtils::GetContextPaint into SVGContextPaint. r=dholbert
authorJonathan Watt <jwatt@jwatt.org>
Mon, 25 Jul 2016 17:34:18 +0100
changeset 308317 6a38b96af1400152930d33982db7aa08a8bbdd54
parent 308316 17233e72c54650d9fb24dffbe930a12c3de06294
child 308318 0f66d9a52316fd7fe265ee667d34b7ac29a78dcc
push id31092
push usercbook@mozilla.com
push dateFri, 05 Aug 2016 10:16:59 +0000
treeherderautoland@b97dd7dd3cb9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1058040
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 1058040, part 5 - Move the code from nsSVGUtils::SetupContextPaint and nsSVGUtils::GetContextPaint into SVGContextPaint. r=dholbert
layout/svg/SVGContextPaint.cpp
layout/svg/SVGContextPaint.h
layout/svg/SVGTextFrame.cpp
layout/svg/nsSVGPathGeometryFrame.cpp
layout/svg/nsSVGUtils.cpp
layout/svg/nsSVGUtils.h
--- a/layout/svg/SVGContextPaint.cpp
+++ b/layout/svg/SVGContextPaint.cpp
@@ -1,34 +1,156 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SVGContextPaint.h"
 
 #include "gfxContext.h"
+#include "mozilla/gfx/2D.h"
 #include "nsIDocument.h"
 #include "nsSVGPaintServerFrame.h"
+#include "nsSVGEffects.h"
+#include "nsSVGPaintServerFrame.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 
+/**
+ * Stores in |aTargetPaint| information on how to reconstruct the current
+ * fill or stroke pattern. Will also set the paint opacity to transparent if
+ * the paint is set to "none".
+ * @param aOuterContextPaint pattern information from the outer text context
+ * @param aTargetPaint where to store the current pattern information
+ * @param aFillOrStroke member pointer to the paint we are setting up
+ * @param aProperty the frame property descriptor of the fill or stroke paint
+ *   server frame
+ */
+static void
+SetupInheritablePaint(const DrawTarget* aDrawTarget,
+                      const gfxMatrix& aContextMatrix,
+                      nsIFrame* aFrame,
+                      float& aOpacity,
+                      SVGContextPaint* aOuterContextPaint,
+                      SVGContextPaintImpl::Paint& aTargetPaint,
+                      nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
+                      nsSVGEffects::PaintingPropertyDescriptor aProperty)
+{
+  const nsStyleSVG *style = aFrame->StyleSVG();
+  nsSVGPaintServerFrame *ps =
+    nsSVGEffects::GetPaintServer(aFrame, aFillOrStroke, aProperty);
+
+  if (ps) {
+    RefPtr<gfxPattern> pattern =
+      ps->GetPaintServerPattern(aFrame, aDrawTarget, aContextMatrix,
+                                aFillOrStroke, aOpacity);
+    if (pattern) {
+      aTargetPaint.SetPaintServer(aFrame, aContextMatrix, ps);
+      return;
+    }
+  }
+  if (aOuterContextPaint) {
+    RefPtr<gfxPattern> pattern;
+    switch ((style->*aFillOrStroke).mType) {
+    case eStyleSVGPaintType_ContextFill:
+      pattern = aOuterContextPaint->GetFillPattern(aDrawTarget, aOpacity,
+                                                   aContextMatrix);
+      break;
+    case eStyleSVGPaintType_ContextStroke:
+      pattern = aOuterContextPaint->GetStrokePattern(aDrawTarget, aOpacity,
+                                                     aContextMatrix);
+      break;
+    default:
+      ;
+    }
+    if (pattern) {
+      aTargetPaint.SetContextPaint(aOuterContextPaint, (style->*aFillOrStroke).mType);
+      return;
+    }
+  }
+  nscolor color =
+    nsSVGUtils::GetFallbackOrPaintColor(aFrame->StyleContext(), aFillOrStroke);
+  aTargetPaint.SetColor(color);
+}
+
+DrawMode
+SVGContextPaintImpl::Init(const DrawTarget* aDrawTarget,
+                          const gfxMatrix& aContextMatrix,
+                          nsIFrame* aFrame,
+                          SVGContextPaint* aOuterContextPaint)
+{
+  DrawMode toDraw = DrawMode(0);
+
+  const nsStyleSVG *style = aFrame->StyleSVG();
+
+  // fill:
+  if (style->mFill.mType == eStyleSVGPaintType_None) {
+    SetFillOpacity(0.0f);
+  } else {
+    float opacity = nsSVGUtils::GetOpacity(style->FillOpacitySource(),
+                                           style->mFillOpacity,
+                                           aOuterContextPaint);
+
+    SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
+                          opacity, aOuterContextPaint,
+                          mFillPaint, &nsStyleSVG::mFill,
+                          nsSVGEffects::FillProperty());
+
+    SetFillOpacity(opacity);
+
+    toDraw |= DrawMode::GLYPH_FILL;
+  }
+
+  // stroke:
+  if (style->mStroke.mType == eStyleSVGPaintType_None) {
+    SetStrokeOpacity(0.0f);
+  } else {
+    float opacity = nsSVGUtils::GetOpacity(style->StrokeOpacitySource(),
+                                           style->mStrokeOpacity,
+                                           aOuterContextPaint);
+
+    SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
+                          opacity, aOuterContextPaint,
+                          mStrokePaint, &nsStyleSVG::mStroke,
+                          nsSVGEffects::StrokeProperty());
+
+    SetStrokeOpacity(opacity);
+
+    toDraw |= DrawMode::GLYPH_STROKE;
+  }
+
+  return toDraw;
+}
+
 void
 SVGContextPaint::InitStrokeGeometry(gfxContext* aContext,
                                     float devUnitsPerSVGUnit)
 {
   mStrokeWidth = aContext->CurrentLineWidth() / devUnitsPerSVGUnit;
   aContext->CurrentDash(mDashes, &mDashOffset);
   for (uint32_t i = 0; i < mDashes.Length(); i++) {
     mDashes[i] /= devUnitsPerSVGUnit;
   }
   mDashOffset /= devUnitsPerSVGUnit;
 }
 
+/* static */ SVGContextPaint*
+SVGContextPaint::GetContextPaint(nsIContent* aContent)
+{
+  nsIDocument* ownerDoc = aContent->OwnerDoc();
+
+  if (!ownerDoc->IsBeingUsedAsImage()) {
+    return nullptr;
+  }
+
+  return static_cast<SVGContextPaint*>(
+           ownerDoc->GetProperty(nsGkAtoms::svgContextPaint));
+}
+
 already_AddRefed<gfxPattern>
 SVGContextPaintImpl::GetFillPattern(const DrawTarget* aDrawTarget,
                                     float aOpacity,
                                     const gfxMatrix& aCTM)
 {
   return mFillPaint.GetPattern(aDrawTarget, aOpacity, &nsStyleSVG::mFill, aCTM);
 }
 
@@ -113,17 +235,17 @@ AutoSetRestoreSVGContextPaint::AutoSetRe
   , mOuterContextPaint(aSVGDocument->GetProperty(nsGkAtoms::svgContextPaint))
 {
   // The way that we supply context paint is to temporarily set the context
   // paint on the owner document of the SVG that we're painting while it's
   // being painted.
 
   MOZ_ASSERT(aContextPaint);
   MOZ_ASSERT(aSVGDocument->IsBeingUsedAsImage(),
-             "nsSVGUtils::GetContextPaint assumes this");
+             "SVGContextPaint::GetContextPaint assumes this");
 
   if (mOuterContextPaint) {
     mSVGDocument->UnsetProperty(nsGkAtoms::svgContextPaint);
   }
 
   DebugOnly<nsresult> res =
     mSVGDocument->SetProperty(nsGkAtoms::svgContextPaint, aContextPaint);
 
--- a/layout/svg/SVGContextPaint.h
+++ b/layout/svg/SVGContextPaint.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_SVGCONTEXTPAINT_H_
 #define MOZILLA_SVGCONTEXTPAINT_H_
 
+#include "DrawMode.h"
 #include "gfxMatrix.h"
 #include "gfxPattern.h"
 #include "gfxTypes.h"
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/gfx/2D.h"
 #include "nsStyleStruct.h"
 #include "nsTArray.h"
 
@@ -56,16 +57,18 @@ public:
     return GetFillPattern(aDrawTarget, GetFillOpacity(), aCTM);
   }
 
   already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
                                                 const gfxMatrix& aCTM) {
     return GetStrokePattern(aDrawTarget, GetStrokeOpacity(), aCTM);
   }
 
+  static SVGContextPaint* GetContextPaint(nsIContent* aContent);
+
   // XXX This gets the geometry params from the gfxContext.  We should get that
   // information from the actual paint context!
   void InitStrokeGeometry(gfxContext *aContext,
                           float devUnitsPerSVGUnit);
 
   FallibleTArray<gfxFloat>& GetStrokeDashArray() {
     return mDashes;
   }
@@ -82,17 +85,17 @@ private:
   FallibleTArray<gfxFloat> mDashes;
   gfxFloat mDashOffset;
   gfxFloat mStrokeWidth;
 };
 
 /**
  * RAII class used to temporarily set and remove an SVGContextPaint while a
  * piece of SVG is being painted.  The context paint is set on the SVG's owner
- * document, as expected by nsSVGUtils::GetContextPaint.  Any pre-existing
+ * document, as expected by SVGContextPaint::GetContextPaint.  Any pre-existing
  * context paint is restored after this class removes the context paint that it
  * set.
  */
 class MOZ_RAII AutoSetRestoreSVGContextPaint
 {
 public:
   AutoSetRestoreSVGContextPaint(SVGContextPaint* aContextPaint,
                                 nsIDocument* aSVGDocument);
@@ -109,16 +112,21 @@ private:
  * This class should be flattened into SVGContextPaint once we get rid of the
  * other sub-class (SimpleTextContextPaint).
  */
 struct SVGContextPaintImpl : public SVGContextPaint
 {
 protected:
   typedef mozilla::gfx::DrawTarget DrawTarget;
 public:
+  DrawMode Init(const DrawTarget* aDrawTarget,
+                const gfxMatrix& aContextMatrix,
+                nsIFrame* aFrame,
+                SVGContextPaint* aOuterContextPaint);
+
   already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
                                               float aOpacity,
                                               const gfxMatrix& aCTM) override;
   already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
                                                 float aOpacity,
                                                 const gfxMatrix& aCTM) override;
 
   void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -3633,35 +3633,36 @@ SVGTextFrame::PaintSVG(gfxContext& aCont
 
   RefPtr<nsCaret> caret = presContext->PresShell()->GetCaret();
   nsRect caretRect;
   nsIFrame* caretFrame = caret->GetPaintGeometry(&caretRect);
 
   TextRenderedRunIterator it(this, TextRenderedRunIterator::eVisibleFrames);
   TextRenderedRun run = it.Current();
 
-  SVGContextPaint* outerContextPaint = nsSVGUtils::GetContextPaint(mContent);
+  SVGContextPaint* outerContextPaint =
+    SVGContextPaint::GetContextPaint(mContent);
 
   nsRenderingContext rendCtx(&aContext);
 
   while (run.mFrame) {
     nsTextFrame* frame = run.mFrame;
 
     // Determine how much of the left and right edges of the text frame we
     // need to ignore.
     SVGCharClipDisplayItem item(run);
 
     // Set up the fill and stroke so that SVG glyphs can get painted correctly
     // when they use context-fill etc.
     aContext.SetMatrix(initialMatrix);
 
     SVGContextPaintImpl contextPaint;
-    DrawMode drawMode =
-      nsSVGUtils::SetupContextPaint(&aDrawTarget, aContext.CurrentMatrix(),
-                                    frame, outerContextPaint, &contextPaint);
+    DrawMode drawMode = contextPaint.Init(&aDrawTarget,
+                                          aContext.CurrentMatrix(),
+                                          frame, outerContextPaint);
 
     if (drawMode & DrawMode::GLYPH_STROKE) {
       // This may change the gfxContext's transform (for non-scaling stroke),
       // in which case this needs to happen before we call SetMatrix() below.
       nsSVGUtils::SetupCairoStrokeGeometry(frame, &aContext, outerContextPaint);
     }
 
     // Set up the transform for painting the text frame for the substring
--- a/layout/svg/nsSVGPathGeometryFrame.cpp
+++ b/layout/svg/nsSVGPathGeometryFrame.cpp
@@ -804,17 +804,17 @@ nsSVGPathGeometryFrame::Render(gfxContex
   element->GetAsSimplePath(&simplePath);
   if (!simplePath.IsPath()) {
     path = element->GetOrBuildPath(*drawTarget, fillRule);
     if (!path) {
       return;
     }
   }
 
-  SVGContextPaint* contextPaint = nsSVGUtils::GetContextPaint(mContent);
+  SVGContextPaint* contextPaint = SVGContextPaint::GetContextPaint(mContent);
 
   if (aRenderComponents & eRenderFill) {
     GeneralPattern fillPattern;
     nsSVGUtils::MakeFillPatternFor(this, aContext, &fillPattern, contextPaint);
     if (fillPattern.GetPattern()) {
       DrawOptions drawOptions(1.0f, CompositionOp::OP_OVER, aaMode);
       if (simplePath.IsRect()) {
         drawTarget->FillRect(simplePath.AsRect(), fillPattern, drawOptions);
@@ -872,17 +872,17 @@ nsSVGPathGeometryFrame::Render(gfxContex
     }
   }
 }
 
 void
 nsSVGPathGeometryFrame::PaintMarkers(gfxContext& aContext,
                                      const gfxMatrix& aTransform)
 {
-  SVGContextPaint* contextPaint = nsSVGUtils::GetContextPaint(mContent);
+  SVGContextPaint* contextPaint = SVGContextPaint::GetContextPaint(mContent);
 
   if (static_cast<nsSVGPathGeometryElement*>(mContent)->IsMarkable()) {
     MarkerProperties properties = GetMarkerProperties(this);
 
     if (properties.MarkersExist()) {
       float strokeWidth = nsSVGUtils::GetStrokeWidth(this, contextPaint);
 
       nsTArray<nsSVGMark> marks;
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1295,136 +1295,16 @@ nsSVGUtils::GetFallbackOrPaintColor(nsSt
       nscolor colors[2] = { color, paintIfVisited.mPaint.mColor };
       return nsStyleContext::CombineVisitedColors(
                colors, aStyleContext->RelevantLinkVisited());
     }
   }
   return color;
 }
 
-/* static */ SVGContextPaint*
-nsSVGUtils::GetContextPaint(nsIContent* aContent)
-{
-  nsIDocument* ownerDoc = aContent->OwnerDoc();
-
-  if (!ownerDoc->IsBeingUsedAsImage()) {
-    return nullptr;
-  }
-
-  return static_cast<SVGContextPaint*>(
-           ownerDoc->GetProperty(nsGkAtoms::svgContextPaint));
-}
-
-/**
- * Stores in |aTargetPaint| information on how to reconstruct the current
- * fill or stroke pattern. Will also set the paint opacity to transparent if
- * the paint is set to "none".
- * @param aOuterContextPaint pattern information from the outer text context
- * @param aTargetPaint where to store the current pattern information
- * @param aFillOrStroke member pointer to the paint we are setting up
- * @param aProperty the frame property descriptor of the fill or stroke paint
- *   server frame
- */
-static void
-SetupInheritablePaint(const DrawTarget* aDrawTarget,
-                      const gfxMatrix& aContextMatrix,
-                      nsIFrame* aFrame,
-                      float& aOpacity,
-                      SVGContextPaint* aOuterContextPaint,
-                      SVGContextPaintImpl::Paint& aTargetPaint,
-                      nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
-                      nsSVGEffects::PaintingPropertyDescriptor aProperty)
-{
-  const nsStyleSVG *style = aFrame->StyleSVG();
-  nsSVGPaintServerFrame *ps =
-    nsSVGEffects::GetPaintServer(aFrame, aFillOrStroke, aProperty);
-
-  if (ps) {
-    RefPtr<gfxPattern> pattern =
-      ps->GetPaintServerPattern(aFrame, aDrawTarget, aContextMatrix,
-                                aFillOrStroke, aOpacity);
-    if (pattern) {
-      aTargetPaint.SetPaintServer(aFrame, aContextMatrix, ps);
-      return;
-    }
-  }
-  if (aOuterContextPaint) {
-    RefPtr<gfxPattern> pattern;
-    switch ((style->*aFillOrStroke).mType) {
-    case eStyleSVGPaintType_ContextFill:
-      pattern = aOuterContextPaint->GetFillPattern(aDrawTarget, aOpacity,
-                                                   aContextMatrix);
-      break;
-    case eStyleSVGPaintType_ContextStroke:
-      pattern = aOuterContextPaint->GetStrokePattern(aDrawTarget, aOpacity,
-                                                     aContextMatrix);
-      break;
-    default:
-      ;
-    }
-    if (pattern) {
-      aTargetPaint.SetContextPaint(aOuterContextPaint, (style->*aFillOrStroke).mType);
-      return;
-    }
-  }
-  nscolor color =
-    nsSVGUtils::GetFallbackOrPaintColor(aFrame->StyleContext(), aFillOrStroke);
-  aTargetPaint.SetColor(color);
-}
-
-/* static */ DrawMode
-nsSVGUtils::SetupContextPaint(const DrawTarget* aDrawTarget,
-                              const gfxMatrix& aContextMatrix,
-                              nsIFrame* aFrame,
-                              SVGContextPaint* aOuterContextPaint,
-                              SVGContextPaintImpl* aThisContextPaint)
-{
-  DrawMode toDraw = DrawMode(0);
-
-  const nsStyleSVG *style = aFrame->StyleSVG();
-
-  // fill:
-  if (style->mFill.mType == eStyleSVGPaintType_None) {
-    aThisContextPaint->SetFillOpacity(0.0f);
-  } else {
-    float opacity = nsSVGUtils::GetOpacity(style->FillOpacitySource(),
-                                           style->mFillOpacity,
-                                           aOuterContextPaint);
-
-    SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
-                          opacity, aOuterContextPaint,
-                          aThisContextPaint->mFillPaint, &nsStyleSVG::mFill,
-                          nsSVGEffects::FillProperty());
-
-    aThisContextPaint->SetFillOpacity(opacity);
-
-    toDraw |= DrawMode::GLYPH_FILL;
-  }
-
-  // stroke:
-  if (style->mStroke.mType == eStyleSVGPaintType_None) {
-    aThisContextPaint->SetStrokeOpacity(0.0f);
-  } else {
-    float opacity = nsSVGUtils::GetOpacity(style->StrokeOpacitySource(),
-                                           style->mStrokeOpacity,
-                                           aOuterContextPaint);
-
-    SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
-                          opacity, aOuterContextPaint,
-                          aThisContextPaint->mStrokePaint, &nsStyleSVG::mStroke,
-                          nsSVGEffects::StrokeProperty());
-
-    aThisContextPaint->SetStrokeOpacity(opacity);
-
-    toDraw |= DrawMode::GLYPH_STROKE;
-  }
-
-  return toDraw;
-}
-
 /* static */ void
 nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
                                gfxContext* aContext,
                                GeneralPattern* aOutPattern,
                                SVGContextPaint* aContextPaint)
 {
   const nsStyleSVG* style = aFrame->StyleSVG();
   if (style->mFill.mType == eStyleSVGPaintType_None) {
--- a/layout/svg/nsSVGUtils.h
+++ b/layout/svg/nsSVGUtils.h
@@ -493,25 +493,16 @@ public:
   {
     return NS_lround(std::max(double(INT32_MIN),
                             std::min(double(INT32_MAX), aVal)));
   }
 
   static nscolor GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
                                          nsStyleSVGPaint nsStyleSVG::*aFillOrStroke);
 
-  static SVGContextPaint* GetContextPaint(nsIContent* aContent);
-
-  static DrawMode
-  SetupContextPaint(const DrawTarget* aDrawTarget,
-                    const gfxMatrix& aContextMatrix,
-                    nsIFrame* aFrame,
-                    SVGContextPaint* aOuterContextPaint,
-                    SVGContextPaintImpl* aThisContextPaint);
-
   static void
   MakeFillPatternFor(nsIFrame *aFrame,
                      gfxContext* aContext,
                      GeneralPattern* aOutPattern,
                      SVGContextPaint* aContextPaint = nullptr);
 
   static void
   MakeStrokePatternFor(nsIFrame* aFrame,