LCOV - code coverage report
Current view: top level - layout/svg - SVGContextPaint.h (source / functions) Hit Total Coverage
Test: output.info Lines: 31 65 47.7 %
Date: 2017-07-14 16:53:18 Functions: 14 32 43.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef MOZILLA_SVGCONTEXTPAINT_H_
       7             : #define MOZILLA_SVGCONTEXTPAINT_H_
       8             : 
       9             : #include "DrawMode.h"
      10             : #include "gfxMatrix.h"
      11             : #include "gfxPattern.h"
      12             : #include "gfxTypes.h"
      13             : #include "gfxUtils.h"
      14             : #include "mozilla/AlreadyAddRefed.h"
      15             : #include "mozilla/Assertions.h"
      16             : #include "mozilla/gfx/2D.h"
      17             : #include "nsColor.h"
      18             : #include "nsStyleStruct.h"
      19             : #include "nsTArray.h"
      20             : #include "DrawResult.h"
      21             : 
      22             : class gfxContext;
      23             : class nsIDocument;
      24             : class nsSVGPaintServerFrame;
      25             : 
      26             : namespace mozilla {
      27             : 
      28             : /**
      29             :  * This class is used to pass information about a context element through to
      30             :  * SVG painting code in order to resolve the 'context-fill' and related
      31             :  * keywords. See:
      32             :  *
      33             :  *   https://www.w3.org/TR/SVG2/painting.html#context-paint
      34             :  *
      35             :  * This feature allows the color in an SVG-in-OpenType glyph to come from the
      36             :  * computed style for the text that is being drawn, for example, or for color
      37             :  * in an SVG embedded by an <img> element to come from the embedding <img>
      38             :  * element.
      39             :  *
      40             :  * This class is reference counted so that it can be shared among many similar
      41             :  * SVGImageContext objects. (SVGImageContext objects are frequently
      42             :  * copy-constructed with small modifications, and we'd like for those copies to
      43             :  * be able to share their context-paint data cheaply.)  However, in most cases,
      44             :  * SVGContextPaint instances are stored in a local RefPtr and only last for the
      45             :  * duration of a function call.
      46             :  * XXX Note: SVGImageContext doesn't actually have a SVGContextPaint member yet,
      47             :  * but it will in a later patch in the patch series that added this comment.
      48             :  */
      49             : class SVGContextPaint : public RefCounted<SVGContextPaint>
      50             : {
      51             : protected:
      52             :   typedef mozilla::gfx::DrawTarget DrawTarget;
      53             :   typedef mozilla::image::imgDrawingParams imgDrawingParams;
      54             : 
      55          53 :   SVGContextPaint()
      56          53 :     : mDashOffset(0.0f)
      57          53 :     , mStrokeWidth(0.0f)
      58          53 :   {}
      59             : 
      60             : public:
      61             : 
      62         568 :   MOZ_DECLARE_REFCOUNTED_TYPENAME(SVGContextPaint)
      63             : 
      64          40 :   virtual ~SVGContextPaint() {}
      65             : 
      66             :   virtual already_AddRefed<gfxPattern>
      67             :   GetFillPattern(const DrawTarget* aDrawTarget,
      68             :                  float aOpacity,
      69             :                  const gfxMatrix& aCTM,
      70             :                  imgDrawingParams& aImgParams) = 0;
      71             :   virtual already_AddRefed<gfxPattern>
      72             :   GetStrokePattern(const DrawTarget* aDrawTarget,
      73             :                    float aOpacity,
      74             :                    const gfxMatrix& aCTM,
      75             :                    imgDrawingParams& aImgParams) = 0;
      76             :   virtual float GetFillOpacity() const = 0;
      77             :   virtual float GetStrokeOpacity() const = 0;
      78             : 
      79             :   already_AddRefed<gfxPattern>
      80           0 :   GetFillPattern(const DrawTarget* aDrawTarget, const gfxMatrix& aCTM,
      81             :                  imgDrawingParams& aImgParams) {
      82           0 :     return GetFillPattern(aDrawTarget, GetFillOpacity(), aCTM, aImgParams);
      83             :   }
      84             : 
      85             :   already_AddRefed<gfxPattern>
      86             :   GetStrokePattern(const DrawTarget* aDrawTarget, const gfxMatrix& aCTM,
      87             :                    imgDrawingParams& aImgParams) {
      88             :     return GetStrokePattern(aDrawTarget, GetStrokeOpacity(), aCTM, aImgParams);
      89             :   }
      90             : 
      91             :   static SVGContextPaint* GetContextPaint(nsIContent* aContent);
      92             : 
      93             :   // XXX This gets the geometry params from the gfxContext.  We should get that
      94             :   // information from the actual paint context!
      95             :   void InitStrokeGeometry(gfxContext *aContext,
      96             :                           float devUnitsPerSVGUnit);
      97             : 
      98         160 :   const FallibleTArray<gfxFloat>& GetStrokeDashArray() const {
      99         160 :     return mDashes;
     100             :   }
     101             : 
     102         160 :   gfxFloat GetStrokeDashOffset() const {
     103         160 :     return mDashOffset;
     104             :   }
     105             : 
     106         160 :   gfxFloat GetStrokeWidth() const {
     107         160 :     return mStrokeWidth;
     108             :   }
     109             : 
     110           0 :   virtual uint32_t Hash() const {
     111           0 :     MOZ_ASSERT_UNREACHABLE("Only VectorImage needs to hash, and that should "
     112             :                            "only be operating on our SVGEmbeddingContextPaint "
     113             :                            "subclass");
     114             :     return 0;
     115             :   }
     116             : 
     117             :   /**
     118             :    * Returns true if image context paint is allowed to be used in an image that
     119             :    * has the given URI, else returns false.
     120             :    */
     121             :   static bool IsAllowedForImageFromURI(nsIURI* aURI);
     122             : 
     123             : private:
     124             :   // Member-vars are initialized in InitStrokeGeometry.
     125             :   FallibleTArray<gfxFloat> mDashes;
     126             :   MOZ_INIT_OUTSIDE_CTOR gfxFloat mDashOffset;
     127             :   MOZ_INIT_OUTSIDE_CTOR gfxFloat mStrokeWidth;
     128             : };
     129             : 
     130             : /**
     131             :  * RAII class used to temporarily set and remove an SVGContextPaint while a
     132             :  * piece of SVG is being painted.  The context paint is set on the SVG's owner
     133             :  * document, as expected by SVGContextPaint::GetContextPaint.  Any pre-existing
     134             :  * context paint is restored after this class removes the context paint that it
     135             :  * set.
     136             :  */
     137             : class MOZ_RAII AutoSetRestoreSVGContextPaint
     138             : {
     139             : public:
     140             :   AutoSetRestoreSVGContextPaint(const SVGContextPaint* aContextPaint,
     141             :                                 nsIDocument* aSVGDocument);
     142             :   ~AutoSetRestoreSVGContextPaint();
     143             : private:
     144             :   nsIDocument* mSVGDocument;
     145             :   // The context paint that needs to be restored by our dtor after it removes
     146             :   // aContextPaint:
     147             :   void* mOuterContextPaint;
     148             : };
     149             : 
     150             : 
     151             : /**
     152             :  * This class should be flattened into SVGContextPaint once we get rid of the
     153             :  * other sub-class (SimpleTextContextPaint).
     154             :  */
     155           0 : struct SVGContextPaintImpl : public SVGContextPaint
     156             : {
     157             : protected:
     158             :   typedef mozilla::gfx::DrawTarget DrawTarget;
     159             : 
     160             : public:
     161             : 
     162             :   DrawMode
     163             :   Init(const DrawTarget* aDrawTarget,
     164             :        const gfxMatrix& aContextMatrix,
     165             :        nsIFrame* aFrame,
     166             :        SVGContextPaint* aOuterContextPaint,
     167             :        imgDrawingParams& aImgParams);
     168             : 
     169             :   already_AddRefed<gfxPattern>
     170             :   GetFillPattern(const DrawTarget* aDrawTarget,
     171             :                  float aOpacity,
     172             :                  const gfxMatrix& aCTM,
     173             :                  imgDrawingParams& aImgParams) override;
     174             :   already_AddRefed<gfxPattern>
     175             :   GetStrokePattern(const DrawTarget* aDrawTarget,
     176             :                    float aOpacity,
     177             :                    const gfxMatrix& aCTM,
     178             :                    imgDrawingParams& aImgParams) override;
     179             : 
     180           0 :   void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
     181           0 :   float GetFillOpacity() const override { return mFillOpacity; }
     182             : 
     183           0 :   void SetStrokeOpacity(float aOpacity) { mStrokeOpacity = aOpacity; }
     184           0 :   float GetStrokeOpacity() const override { return mStrokeOpacity; }
     185             : 
     186           0 :   struct Paint {
     187           0 :     Paint() : mPaintType(eStyleSVGPaintType_None) {}
     188             : 
     189           0 :     void SetPaintServer(nsIFrame* aFrame,
     190             :                         const gfxMatrix& aContextMatrix,
     191             :                         nsSVGPaintServerFrame* aPaintServerFrame) {
     192           0 :       mPaintType = eStyleSVGPaintType_Server;
     193           0 :       mPaintDefinition.mPaintServerFrame = aPaintServerFrame;
     194           0 :       mFrame = aFrame;
     195           0 :       mContextMatrix = aContextMatrix;
     196           0 :     }
     197             : 
     198           0 :     void SetColor(const nscolor &aColor) {
     199           0 :       mPaintType = eStyleSVGPaintType_Color;
     200           0 :       mPaintDefinition.mColor = aColor;
     201           0 :     }
     202             : 
     203           0 :     void SetContextPaint(SVGContextPaint* aContextPaint,
     204             :                          nsStyleSVGPaintType aPaintType) {
     205           0 :       NS_ASSERTION(aPaintType == eStyleSVGPaintType_ContextFill ||
     206             :                    aPaintType == eStyleSVGPaintType_ContextStroke,
     207             :                    "Invalid context paint type");
     208           0 :       mPaintType = aPaintType;
     209           0 :       mPaintDefinition.mContextPaint = aContextPaint;
     210           0 :     }
     211             : 
     212             :     union {
     213             :       nsSVGPaintServerFrame* mPaintServerFrame;
     214             :       SVGContextPaint* mContextPaint;
     215             :       nscolor mColor;
     216             :     } mPaintDefinition;
     217             : 
     218             :     // Initialized (if needed) in SetPaintServer():
     219             :     MOZ_INIT_OUTSIDE_CTOR nsIFrame* mFrame;
     220             :     // CTM defining the user space for the pattern we will use.
     221             :     gfxMatrix mContextMatrix;
     222             :     nsStyleSVGPaintType mPaintType;
     223             : 
     224             :     // Device-space-to-pattern-space
     225             :     gfxMatrix mPatternMatrix;
     226             :     nsRefPtrHashtable<nsFloatHashKey, gfxPattern> mPatternCache;
     227             : 
     228             :     already_AddRefed<gfxPattern>
     229             :     GetPattern(const DrawTarget* aDrawTarget,
     230             :                float aOpacity,
     231             :                nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
     232             :                const gfxMatrix& aCTM,
     233             :                imgDrawingParams& aImgParams);
     234             :   };
     235             : 
     236             :   Paint mFillPaint;
     237             :   Paint mStrokePaint;
     238             : 
     239             :   float mFillOpacity;
     240             :   float mStrokeOpacity;
     241             : };
     242             : 
     243             : /**
     244             :  * This class is used to pass context paint to an SVG image when an element
     245             :  * references that image (e.g. via HTML <img> or SVG <image>, or by referencing
     246             :  * it from a CSS property such as 'background-image').  In this case we only
     247             :  * support context colors and not paint servers.
     248             :  */
     249         120 : class SVGEmbeddingContextPaint : public SVGContextPaint
     250             : {
     251             :   typedef gfx::Color Color;
     252             : 
     253             : public:
     254          53 :   SVGEmbeddingContextPaint()
     255          53 :     : mFillOpacity(1.0f)
     256          53 :     , mStrokeOpacity(1.0f)
     257          53 :   {}
     258             : 
     259          80 :   bool operator==(const SVGEmbeddingContextPaint& aOther) const {
     260          80 :     MOZ_ASSERT(GetStrokeWidth() == aOther.GetStrokeWidth() &&
     261             :                GetStrokeDashOffset() == aOther.GetStrokeDashOffset() &&
     262             :                GetStrokeDashArray() == aOther.GetStrokeDashArray(),
     263             :                "We don't currently include these in the context information "
     264             :                "from an embedding element");
     265         160 :     return mFill == aOther.mFill &&
     266         160 :            mStroke == aOther.mStroke &&
     267         240 :            mFillOpacity == aOther.mFillOpacity &&
     268         160 :            mStrokeOpacity == aOther.mStrokeOpacity;
     269             :   }
     270             : 
     271          53 :   void SetFill(nscolor aFill) {
     272          53 :     mFill.emplace(gfx::ToDeviceColor(aFill));
     273          53 :   }
     274           0 :   void SetStroke(nscolor aStroke) {
     275           0 :     mStroke.emplace(gfx::ToDeviceColor(aStroke));
     276           0 :   }
     277             : 
     278             :   /**
     279             :    * Returns a pattern of type PatternType::COLOR, or else nullptr.
     280             :    */
     281             :   already_AddRefed<gfxPattern>
     282             :   GetFillPattern(const DrawTarget* aDrawTarget, float aFillOpacity,
     283             :                  const gfxMatrix& aCTM, imgDrawingParams& aImgParams) override;
     284             : 
     285             :   /**
     286             :    * Returns a pattern of type PatternType::COLOR, or else nullptr.
     287             :    */
     288             :   already_AddRefed<gfxPattern>
     289             :   GetStrokePattern(const DrawTarget* aDrawTarget, float aStrokeOpacity,
     290             :                    const gfxMatrix& aCTM, imgDrawingParams& aImgParams) override;
     291             : 
     292           7 :   void SetFillOpacity(float aOpacity) {
     293           7 :     mFillOpacity = aOpacity;
     294           7 :   }
     295           3 :   float GetFillOpacity() const override {
     296           3 :     return mFillOpacity;
     297             :   };
     298             : 
     299           0 :   void SetStrokeOpacity(float aOpacity) {
     300           0 :     mStrokeOpacity = aOpacity;
     301           0 :   }
     302           0 :   float GetStrokeOpacity() const override {
     303           0 :     return mStrokeOpacity;
     304             :   };
     305             : 
     306             :   uint32_t Hash() const override;
     307             : 
     308             : private:
     309             :   Maybe<Color> mFill;
     310             :   Maybe<Color> mStroke;
     311             :   float mFillOpacity;
     312             :   float mStrokeOpacity;
     313             : };
     314             : 
     315             : } // namespace mozilla
     316             : 
     317             : #endif // MOZILLA_SVGCONTEXTPAINT_H_
     318             : 

Generated by: LCOV version 1.13