LCOV - code coverage report
Current view: top level - layout/svg - nsFilterInstance.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 6 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 5 0.0 %
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 __NS_FILTERINSTANCE_H__
       7             : #define __NS_FILTERINSTANCE_H__
       8             : 
       9             : #include "gfxMatrix.h"
      10             : #include "gfxPoint.h"
      11             : #include "gfxRect.h"
      12             : #include "nsCOMPtr.h"
      13             : #include "nsHashKeys.h"
      14             : #include "nsPoint.h"
      15             : #include "nsRect.h"
      16             : #include "nsSize.h"
      17             : #include "nsSVGFilters.h"
      18             : #include "nsSVGNumber2.h"
      19             : #include "nsSVGNumberPair.h"
      20             : #include "nsTArray.h"
      21             : #include "nsIFrame.h"
      22             : #include "mozilla/gfx/2D.h"
      23             : 
      24             : class gfxContext;
      25             : class nsIFrame;
      26             : class nsSVGFilterPaintCallback;
      27             : 
      28             : namespace mozilla {
      29             : namespace dom {
      30             : class UserSpaceMetrics;
      31             : } // namespace dom
      32             : } // namespace mozilla
      33             : 
      34             : /**
      35             :  * This class performs all filter processing.
      36             :  *
      37             :  * We build a graph of the filter image data flow, essentially
      38             :  * converting the filter graph to SSA. This lets us easily propagate
      39             :  * analysis data (such as bounding-boxes) over the filter primitive graph.
      40             :  *
      41             :  * Definition of "filter space": filter space is a coordinate system that is
      42             :  * aligned with the user space of the filtered element, with its origin located
      43             :  * at the top left of the filter region, and with one unit equal in size to one
      44             :  * pixel of the offscreen surface into which the filter output would/will be
      45             :  * painted.
      46             :  *
      47             :  * The definition of "filter region" can be found here:
      48             :  * http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion
      49             :  */
      50           0 : class nsFilterInstance
      51             : {
      52             :   typedef mozilla::gfx::IntRect IntRect;
      53             :   typedef mozilla::gfx::SourceSurface SourceSurface;
      54             :   typedef mozilla::gfx::DrawTarget DrawTarget;
      55             :   typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
      56             :   typedef mozilla::gfx::FilterDescription FilterDescription;
      57             :   typedef mozilla::dom::UserSpaceMetrics UserSpaceMetrics;
      58             :   typedef mozilla::image::imgDrawingParams imgDrawingParams;
      59             : public:
      60             :   /**
      61             :    * Create a FilterDescription for the supplied filter. All coordinates in
      62             :    * the description are in filter space.
      63             :    * @param aFilterInputIsTainted Describes whether the SourceImage / SourceAlpha
      64             :    *   input is tainted. This affects whether feDisplacementMap will respect
      65             :    *   the filter input as its map input, and it affects the IsTainted() state
      66             :    *   on the filter primitives in the FilterDescription. "Tainted" is a term
      67             :    *   from the filters spec and means security-sensitive content, i.e. pixels
      68             :    *   that JS should not be able to read in any way.
      69             :    * @param aOutAdditionalImages Will contain additional images needed to
      70             :    *   render the filter (from feImage primitives).
      71             :    * @return A FilterDescription describing the filter.
      72             :    */
      73             :   static FilterDescription GetFilterDescription(nsIContent* aFilteredElement,
      74             :                                                 const nsTArray<nsStyleFilter>& aFilterChain,
      75             :                                                 bool aFilterInputIsTainted,
      76             :                                                 const UserSpaceMetrics& aMetrics,
      77             :                                                 const gfxRect& aBBox,
      78             :                                                 nsTArray<RefPtr<SourceSurface>>& aOutAdditionalImages);
      79             : 
      80             :   /**
      81             :    * Paint the given filtered frame.
      82             :    * @param aDirtyArea The area than needs to be painted, in aFilteredFrame's
      83             :    *   frame space (i.e. relative to its origin, the top-left corner of its
      84             :    *   border box).
      85             :    */
      86             :   static void PaintFilteredFrame(nsIFrame *aFilteredFrame,
      87             :                                  DrawTarget* aDrawTarget,
      88             :                                  const gfxMatrix& aTransform,
      89             :                                  nsSVGFilterPaintCallback *aPaintCallback,
      90             :                                  const nsRegion* aDirtyArea,
      91             :                                  imgDrawingParams& aImgParams);
      92             : 
      93             :   /**
      94             :    * Returns the post-filter area that could be dirtied when the given
      95             :    * pre-filter area of aFilteredFrame changes.
      96             :    * @param aPreFilterDirtyRegion The pre-filter area of aFilteredFrame that has
      97             :    *   changed, relative to aFilteredFrame, in app units.
      98             :    */
      99             :   static nsRegion GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
     100             :                                          const nsRegion& aPreFilterDirtyRegion);
     101             : 
     102             :   /**
     103             :    * Returns the pre-filter area that is needed from aFilteredFrame when the
     104             :    * given post-filter area needs to be repainted.
     105             :    * @param aPostFilterDirtyRegion The post-filter area that is dirty, relative
     106             :    *   to aFilteredFrame, in app units.
     107             :    */
     108             :   static nsRegion GetPreFilterNeededArea(nsIFrame *aFilteredFrame,
     109             :                                          const nsRegion& aPostFilterDirtyRegion);
     110             : 
     111             :   /**
     112             :    * Returns the post-filter visual overflow rect (paint bounds) of
     113             :    * aFilteredFrame.
     114             :    * @param aOverrideBBox A user space rect, in user units, that should be used
     115             :    *   as aFilteredFrame's bbox ('bbox' is a specific SVG term), if non-null.
     116             :    * @param aPreFilterBounds The pre-filter visual overflow rect of
     117             :    *   aFilteredFrame, if non-null.
     118             :    */
     119             :   static nsRect GetPostFilterBounds(nsIFrame *aFilteredFrame,
     120             :                                     const gfxRect *aOverrideBBox = nullptr,
     121             :                                     const nsRect *aPreFilterBounds = nullptr);
     122             : 
     123             : private:
     124             :   /**
     125             :    * @param aTargetFrame The frame of the filtered element under consideration,
     126             :    *   may be null.
     127             :    * @param aTargetContent The filtered element itself.
     128             :    * @param aMetrics The metrics to resolve SVG lengths against.
     129             :    * @param aFilterChain The list of filters to apply.
     130             :    * @param aFilterInputIsTainted Describes whether the SourceImage / SourceAlpha
     131             :    *   input is tainted. This affects whether feDisplacementMap will respect
     132             :    *   the filter input as its map input.
     133             :    * @param aPaintCallback [optional] The callback that Render() should use to
     134             :    *   paint. Only required if you will call Render().
     135             :    * @param aPaintTransform The transform to apply to convert to
     136             :    *   aTargetFrame's SVG user space. Only used when painting.
     137             :    * @param aPostFilterDirtyRegion [optional] The post-filter area
     138             :    *   that has to be repainted, in app units. Only required if you will
     139             :    *   call ComputeSourceNeededRect() or Render().
     140             :    * @param aPreFilterDirtyRegion [optional] The pre-filter area of
     141             :    *   the filtered element that changed, in app units. Only required if you
     142             :    *   will call ComputePostFilterDirtyRegion().
     143             :    * @param aOverridePreFilterVisualOverflowRect [optional] Use a different
     144             :    *   visual overflow rect for the target element.
     145             :    * @param aOverrideBBox [optional] Use a different SVG bbox for the target
     146             :    *   element. Must be non-null if aTargetFrame is null.
     147             :    */
     148             :   nsFilterInstance(nsIFrame *aTargetFrame,
     149             :                    nsIContent* aTargetContent,
     150             :                    const UserSpaceMetrics& aMetrics,
     151             :                    const nsTArray<nsStyleFilter>& aFilterChain,
     152             :                    bool aFilterInputIsTainted,
     153             :                    nsSVGFilterPaintCallback *aPaintCallback,
     154             :                    const gfxMatrix& aPaintTransform,
     155             :                    const nsRegion *aPostFilterDirtyRegion = nullptr,
     156             :                    const nsRegion *aPreFilterDirtyRegion = nullptr,
     157             :                    const nsRect *aOverridePreFilterVisualOverflowRect = nullptr,
     158             :                    const gfxRect *aOverrideBBox = nullptr);
     159             : 
     160             :   /**
     161             :    * Returns true if the filter instance was created successfully.
     162             :    */
     163           0 :   bool IsInitialized() const { return mInitialized; }
     164             : 
     165             :   /**
     166             :    * Draws the filter output into aDrawTarget. The area that
     167             :    * needs to be painted must have been specified before calling this method
     168             :    * by passing it as the aPostFilterDirtyRegion argument to the
     169             :    * nsFilterInstance constructor.
     170             :    */
     171             :   void Render(DrawTarget* aDrawTarget, imgDrawingParams& aImgParams);
     172             : 
     173           0 :   const FilterDescription& ExtractDescriptionAndAdditionalImages(nsTArray<RefPtr<SourceSurface>>& aOutAdditionalImages)
     174             :   {
     175           0 :     mInputImages.SwapElements(aOutAdditionalImages);
     176           0 :     return mFilterDescription;
     177             :   }
     178             : 
     179             :   /**
     180             :    * Sets the aPostFilterDirtyRegion outparam to the post-filter area in frame
     181             :    * space that would be dirtied by mTargetFrame when a given
     182             :    * pre-filter area of mTargetFrame is dirtied. The pre-filter area must have
     183             :    * been specified before calling this method by passing it as the
     184             :    * aPreFilterDirtyRegion argument to the nsFilterInstance constructor.
     185             :    */
     186             :   nsRegion ComputePostFilterDirtyRegion();
     187             : 
     188             :   /**
     189             :    * Sets the aPostFilterExtents outparam to the post-filter bounds in frame
     190             :    * space for the whole filter output. This is not necessarily equivalent to
     191             :    * the area that would be dirtied in the result when the entire pre-filter
     192             :    * area is dirtied, because some filter primitives can generate output
     193             :    * without any input.
     194             :    */
     195             :   nsRect ComputePostFilterExtents();
     196             : 
     197             :   /**
     198             :    * Sets the aDirty outparam to the pre-filter bounds in frame space of the
     199             :    * area of mTargetFrame that is needed in order to paint the filtered output
     200             :    * for a given post-filter dirtied area. The post-filter area must have been
     201             :    * specified before calling this method by passing it as the aPostFilterDirtyRegion
     202             :    * argument to the nsFilterInstance constructor.
     203             :    */
     204             :   nsRect ComputeSourceNeededRect();
     205             : 
     206           0 :   struct SourceInfo {
     207             :     // Specifies which parts of the source need to be rendered.
     208             :     // Set by ComputeNeededBoxes().
     209             :     nsIntRect mNeededBounds;
     210             : 
     211             :     // The surface that contains the input rendering.
     212             :     // Set by BuildSourceImage / BuildSourcePaint.
     213             :     RefPtr<SourceSurface> mSourceSurface;
     214             : 
     215             :     // The position and size of mSourceSurface in filter space.
     216             :     // Set by BuildSourceImage / BuildSourcePaint.
     217             :     IntRect mSurfaceRect;
     218             :   };
     219             : 
     220             :   /**
     221             :    * Creates a SourceSurface for either the FillPaint or StrokePaint graph
     222             :    * nodes
     223             :    */
     224             :   void BuildSourcePaint(SourceInfo *aPrimitive, imgDrawingParams& aImgParams);
     225             : 
     226             :   /**
     227             :    * Creates a SourceSurface for either the FillPaint and StrokePaint graph
     228             :    * nodes, fills its contents and assigns it to mFillPaint.mSourceSurface and
     229             :    * mStrokePaint.mSourceSurface respectively.
     230             :    */
     231             :   void BuildSourcePaints(imgDrawingParams& aImgParams);
     232             : 
     233             :   /**
     234             :    * Creates the SourceSurface for the SourceGraphic graph node, paints its
     235             :    * contents, and assigns it to mSourceGraphic.mSourceSurface.
     236             :    */
     237             :   void BuildSourceImage(imgDrawingParams& aImgParams);
     238             : 
     239             :   /**
     240             :    * Build the list of FilterPrimitiveDescriptions that describes the filter's
     241             :    * filter primitives and their connections. This populates
     242             :    * mPrimitiveDescriptions and mInputImages. aFilterInputIsTainted describes
     243             :    * whether the SourceGraphic is tainted.
     244             :    */
     245             :   nsresult BuildPrimitives(const nsTArray<nsStyleFilter>& aFilterChain,
     246             :                            nsIFrame* aTargetFrame,
     247             :                            bool aFilterInputIsTainted);
     248             : 
     249             :   /**
     250             :    * Add to the list of FilterPrimitiveDescriptions for a particular SVG
     251             :    * reference filter or CSS filter. This populates mPrimitiveDescriptions and
     252             :    * mInputImages. aInputIsTainted describes whether the input to aFilter is
     253             :    * tainted.
     254             :    */
     255             :   nsresult BuildPrimitivesForFilter(const nsStyleFilter& aFilter,
     256             :                                     nsIFrame* aTargetFrame,
     257             :                                     bool aInputIsTainted);
     258             : 
     259             :   /**
     260             :    * Computes the filter space bounds of the areas that we actually *need* from
     261             :    * the filter sources, based on the value of mPostFilterDirtyRegion.
     262             :    * This sets mNeededBounds on the corresponding SourceInfo structs.
     263             :    */
     264             :   void ComputeNeededBoxes();
     265             : 
     266             :   /**
     267             :    * Returns the output bounds of the final FilterPrimitiveDescription.
     268             :    */
     269             :   nsIntRect OutputFilterSpaceBounds() const;
     270             : 
     271             :   /**
     272             :    * Compute the scale factors between user space and filter space.
     273             :    */
     274             :   bool ComputeUserSpaceToFilterSpaceScale();
     275             : 
     276             :   /**
     277             :    * Transform a rect between user space and filter space.
     278             :    */
     279             :   gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpace) const;
     280             :   gfxRect FilterSpaceToUserSpace(const gfxRect& aFilterSpaceRect) const;
     281             : 
     282             :   /**
     283             :    * Converts an nsRect or an nsRegion that is relative to a filtered frame's
     284             :    * origin (i.e. the top-left corner of its border box) into filter space,
     285             :    * rounding out.
     286             :    * Returns the entire filter region if aRect / aRegion is null, or if the
     287             :    * result is too large to be stored in an nsIntRect.
     288             :    */
     289             :   nsIntRect FrameSpaceToFilterSpace(const nsRect* aRect) const;
     290             :   nsIntRegion FrameSpaceToFilterSpace(const nsRegion* aRegion) const;
     291             : 
     292             :   /**
     293             :    * Converts an nsIntRect or an nsIntRegion from filter space into the space
     294             :    * that is relative to a filtered frame's origin (i.e. the top-left corner
     295             :    * of its border box) in app units, rounding out.
     296             :    */
     297             :   nsRect FilterSpaceToFrameSpace(const nsIntRect& aRect) const;
     298             :   nsRegion FilterSpaceToFrameSpace(const nsIntRegion& aRegion) const;
     299             : 
     300             :   /**
     301             :    * Returns the transform from frame space to the coordinate space that
     302             :    * GetCanvasTM transforms to. "Frame space" is the origin of a frame, aka the
     303             :    * top-left corner of its border box, aka the top left corner of its mRect.
     304             :    */
     305             :   gfxMatrix GetUserSpaceToFrameSpaceInCSSPxTransform() const;
     306             : 
     307             :   bool ComputeTargetBBoxInFilterSpace();
     308             : 
     309             :   /**
     310             :    * The frame for the element that is currently being filtered.
     311             :    */
     312             :   nsIFrame* mTargetFrame;
     313             : 
     314             :   /**
     315             :    * The filtered element.
     316             :    */
     317             :   nsIContent* mTargetContent;
     318             : 
     319             :   /**
     320             :    * The user space metrics of the filtered frame.
     321             :    */
     322             :   const UserSpaceMetrics& mMetrics;
     323             : 
     324             :   nsSVGFilterPaintCallback* mPaintCallback;
     325             : 
     326             :   /**
     327             :    * The SVG bbox of the element that is being filtered, in user space.
     328             :    */
     329             :   gfxRect mTargetBBox;
     330             : 
     331             :   /**
     332             :    * The SVG bbox of the element that is being filtered, in filter space.
     333             :    */
     334             :   nsIntRect mTargetBBoxInFilterSpace;
     335             : 
     336             :   /**
     337             :    * Transform rects between filter space and frame space in CSS pixels.
     338             :    */
     339             :   gfxMatrix mFilterSpaceToFrameSpaceInCSSPxTransform;
     340             :   gfxMatrix mFrameSpaceInCSSPxToFilterSpaceTransform;
     341             : 
     342             :   /**
     343             :    * The scale factors between user space and filter space.
     344             :    */
     345             :   gfxSize mUserSpaceToFilterSpaceScale;
     346             :   gfxSize mFilterSpaceToUserSpaceScale;
     347             : 
     348             :   /**
     349             :    * Pre-filter paint bounds of the element that is being filtered, in filter
     350             :    * space.
     351             :    */
     352             :   nsIntRect mTargetBounds;
     353             : 
     354             :   /**
     355             :    * The dirty area that needs to be repainted, in filter space.
     356             :    */
     357             :   nsIntRegion mPostFilterDirtyRegion;
     358             : 
     359             :   /**
     360             :    * The pre-filter area of the filtered element that changed, in filter space.
     361             :    */
     362             :   nsIntRegion mPreFilterDirtyRegion;
     363             : 
     364             :   SourceInfo mSourceGraphic;
     365             :   SourceInfo mFillPaint;
     366             :   SourceInfo mStrokePaint;
     367             : 
     368             :   /**
     369             :    * The transform to the SVG user space of mTargetFrame.
     370             :    */
     371             :   gfxMatrix               mPaintTransform;
     372             : 
     373             :   nsTArray<RefPtr<SourceSurface>> mInputImages;
     374             :   nsTArray<FilterPrimitiveDescription> mPrimitiveDescriptions;
     375             :   FilterDescription mFilterDescription;
     376             :   bool mInitialized;
     377             : };
     378             : 
     379             : #endif

Generated by: LCOV version 1.13