layout/svg/nsSVGFilterInstance.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/svg/nsSVGFilterInstance.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,246 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef __NS_SVGFILTERINSTANCE_H__
    1.10 +#define __NS_SVGFILTERINSTANCE_H__
    1.11 +
    1.12 +#include "gfxMatrix.h"
    1.13 +#include "gfxRect.h"
    1.14 +#include "nsSVGFilters.h"
    1.15 +#include "nsSVGNumber2.h"
    1.16 +#include "nsSVGNumberPair.h"
    1.17 +#include "nsTArray.h"
    1.18 +#include "nsIFrame.h"
    1.19 +
    1.20 +class nsIFrame;
    1.21 +class nsSVGFilterFrame;
    1.22 +class nsSVGFilterPaintCallback;
    1.23 +
    1.24 +namespace mozilla {
    1.25 +namespace dom {
    1.26 +class SVGFilterElement;
    1.27 +}
    1.28 +}
    1.29 +
    1.30 +/**
    1.31 + * This class helps nsFilterInstance build its filter graph by processing a
    1.32 + * single SVG reference filter.
    1.33 + *
    1.34 + * In BuildPrimitives, this class iterates through the referenced <filter>
    1.35 + * element's primitive elements, creating a FilterPrimitiveDescription for
    1.36 + * each one.
    1.37 + *
    1.38 + * This class uses several different coordinate spaces, defined as follows:
    1.39 + *
    1.40 + * "user space"
    1.41 + *   The filtered SVG element's user space or the filtered HTML element's
    1.42 + *   CSS pixel space. The origin for an HTML element is the top left corner of
    1.43 + *   its border box.
    1.44 + *
    1.45 + * "filter space"
    1.46 + *   User space scaled to device pixels. Shares the same origin as user space.
    1.47 + *   This space is the same across chained SVG and CSS filters. To compute the
    1.48 + *   overall filter space for a chain, we first need to build each filter's
    1.49 + *   FilterPrimitiveDescriptions in some common space. That space is
    1.50 + *   filter space.
    1.51 + *
    1.52 + * To understand the spaces better, let's take an example filter:
    1.53 + *   <filter id="f">...</filter>
    1.54 + *
    1.55 + * And apply the filter to a div element:
    1.56 + *   <div style="filter: url(#f); ...">...</div>
    1.57 + *
    1.58 + * And let's say there are 2 device pixels for every 1 CSS pixel.
    1.59 + *
    1.60 + * Finally, let's define an arbitrary point in user space:
    1.61 + *   "user space point" = (10, 10)
    1.62 + *
    1.63 + * The point will be inset 10 CSS pixels from both the top and left edges of the
    1.64 + * div element's border box.
    1.65 + *
    1.66 + * Now, let's transform the point from user space to filter space:
    1.67 + *   "filter space point" = "user space point" * "device pixels per CSS pixel"
    1.68 + *   "filter space point" = (10, 10) * 2
    1.69 + *   "filter space point" = (20, 20)
    1.70 + */
    1.71 +class nsSVGFilterInstance
    1.72 +{
    1.73 +  typedef mozilla::gfx::Point3D Point3D;
    1.74 +  typedef mozilla::gfx::IntRect IntRect;
    1.75 +  typedef mozilla::gfx::SourceSurface SourceSurface;
    1.76 +  typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
    1.77 +
    1.78 +public:
    1.79 +  /**
    1.80 +   * @param aFilter The SVG reference filter to process.
    1.81 +   * @param aTargetFrame The frame of the filtered element under consideration.
    1.82 +   * @param aTargetBBox The SVG bbox to use for the target frame, computed by
    1.83 +   *   the caller. The caller may decide to override the actual SVG bbox.
    1.84 +   */
    1.85 +  nsSVGFilterInstance(const nsStyleFilter& aFilter,
    1.86 +                      nsIFrame *aTargetFrame,
    1.87 +                      const gfxRect& aTargetBBox,
    1.88 +                      const gfxSize& aUserSpaceToFilterSpaceScale,
    1.89 +                      const gfxSize& aFilterSpaceToUserSpaceScale);
    1.90 +
    1.91 +  /**
    1.92 +   * Returns true if the filter instance was created successfully.
    1.93 +   */
    1.94 +  bool IsInitialized() const { return mInitialized; }
    1.95 +
    1.96 +  /**
    1.97 +   * Iterates through the <filter> element's primitive elements, creating a
    1.98 +   * FilterPrimitiveDescription for each one. Appends the new
    1.99 +   * FilterPrimitiveDescription(s) to the aPrimitiveDescrs list. Also, appends
   1.100 +   * new images from feImage filter primitive elements to the aInputImages list.
   1.101 +   */
   1.102 +  nsresult BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
   1.103 +                           nsTArray<mozilla::RefPtr<SourceSurface>>& aInputImages);
   1.104 +
   1.105 +  /**
   1.106 +   * Returns the user specified "filter region", in the filtered element's user
   1.107 +   * space, after it has been adjusted out (if necessary) so that its edges
   1.108 +   * coincide with pixel boundaries of the offscreen surface into which the
   1.109 +   * filtered output would/will be painted.
   1.110 +   */
   1.111 +  gfxRect GetFilterRegion() const { return mUserSpaceBounds; }
   1.112 +
   1.113 +  /**
   1.114 +   * Returns the size of the user specified "filter region", in filter space.
   1.115 +   */
   1.116 +  nsIntRect GetFilterSpaceBounds() const { return mFilterSpaceBounds; }
   1.117 +
   1.118 +  float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumber2 *aNumber) const
   1.119 +  {
   1.120 +    return GetPrimitiveNumber(aCtxType, aNumber->GetAnimValue());
   1.121 +  }
   1.122 +  float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumberPair *aNumberPair,
   1.123 +                           nsSVGNumberPair::PairIndex aIndex) const
   1.124 +  {
   1.125 +    return GetPrimitiveNumber(aCtxType, aNumberPair->GetAnimValue(aIndex));
   1.126 +  }
   1.127 +
   1.128 +  /**
   1.129 +   * Converts a userSpaceOnUse/objectBoundingBoxUnits unitless point
   1.130 +   * into filter space, depending on the value of mPrimitiveUnits. (For
   1.131 +   * objectBoundingBoxUnits, the bounding box offset is applied to the point.)
   1.132 +   */
   1.133 +  Point3D ConvertLocation(const Point3D& aPoint) const;
   1.134 +
   1.135 +  /**
   1.136 +   * Transform a rect between user space and filter space.
   1.137 +   */
   1.138 +  gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpaceRect) const;
   1.139 +
   1.140 +private:
   1.141 +  /**
   1.142 +   * Finds the filter frame associated with this SVG filter.
   1.143 +   */
   1.144 +  nsSVGFilterFrame* GetFilterFrame();
   1.145 +
   1.146 +  /**
   1.147 +   * Computes the filter primitive subregion for the given primitive.
   1.148 +   */
   1.149 +  IntRect ComputeFilterPrimitiveSubregion(nsSVGFE* aFilterElement,
   1.150 +                                          const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
   1.151 +                                          const nsTArray<int32_t>& aInputIndices);
   1.152 +
   1.153 +  /**
   1.154 +   * Takes the input indices of a filter primitive and returns for each input
   1.155 +   * whether the input's output is tainted.
   1.156 +   */
   1.157 +  void GetInputsAreTainted(const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
   1.158 +                           const nsTArray<int32_t>& aInputIndices,
   1.159 +                           nsTArray<bool>& aOutInputsAreTainted);
   1.160 +
   1.161 +  /**
   1.162 +   * Scales a numeric filter primitive length in the X, Y or "XY" directions
   1.163 +   * into a length in filter space (no offset is applied).
   1.164 +   */
   1.165 +  float GetPrimitiveNumber(uint8_t aCtxType, float aValue) const;
   1.166 +
   1.167 +  /**
   1.168 +   * Transform a rect between user space and filter space.
   1.169 +   */
   1.170 +  gfxRect FilterSpaceToUserSpace(const gfxRect& aFilterSpaceRect) const;
   1.171 +
   1.172 +  /**
   1.173 +   * Returns the transform from frame space to the coordinate space that
   1.174 +   * GetCanvasTM transforms to. "Frame space" is the origin of a frame, aka the
   1.175 +   * top-left corner of its border box, aka the top left corner of its mRect.
   1.176 +   */
   1.177 +  gfxMatrix GetUserSpaceToFrameSpaceInCSSPxTransform() const;
   1.178 +
   1.179 +  /**
   1.180 +   * Finds the index in aPrimitiveDescrs of each input to aPrimitiveElement.
   1.181 +   * For example, if aPrimitiveElement is:
   1.182 +   *   <feGaussianBlur in="another-primitive" .../>
   1.183 +   * Then, the resulting aSourceIndices will contain the index of the
   1.184 +   * FilterPrimitiveDescription representing "another-primitive".
   1.185 +   */
   1.186 +  nsresult GetSourceIndices(nsSVGFE* aPrimitiveElement,
   1.187 +                            const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
   1.188 +                            const nsDataHashtable<nsStringHashKey, int32_t>& aImageTable,
   1.189 +                            nsTArray<int32_t>& aSourceIndices);
   1.190 +
   1.191 +  /**
   1.192 +   * Compute the filter region in user space, filter space, and filter
   1.193 +   * space.
   1.194 +   */
   1.195 +  nsresult ComputeBounds();
   1.196 +
   1.197 +  /**
   1.198 +   * The SVG reference filter originally from the style system.
   1.199 +   */
   1.200 +  const nsStyleFilter mFilter;
   1.201 +
   1.202 +  /**
   1.203 +   * The frame for the element that is currently being filtered.
   1.204 +   */
   1.205 +  nsIFrame*               mTargetFrame;
   1.206 +
   1.207 +  /**
   1.208 +   * The filter element referenced by mTargetFrame's element.
   1.209 +   */
   1.210 +  const mozilla::dom::SVGFilterElement* mFilterElement;
   1.211 +
   1.212 +  /**
   1.213 +   * The frame for the SVG filter element.
   1.214 +   */
   1.215 +  nsSVGFilterFrame* mFilterFrame;
   1.216 +
   1.217 +  /**
   1.218 +   * The SVG bbox of the element that is being filtered, in user space.
   1.219 +   */
   1.220 +  gfxRect                 mTargetBBox;
   1.221 +
   1.222 +  /**
   1.223 +   * The "filter region" in various spaces.
   1.224 +   */
   1.225 +  gfxRect                 mUserSpaceBounds;
   1.226 +  nsIntRect               mFilterSpaceBounds;
   1.227 +
   1.228 +  /**
   1.229 +   * The scale factors between user space and filter space.
   1.230 +   */
   1.231 +  gfxSize                 mUserSpaceToFilterSpaceScale;
   1.232 +  gfxSize                 mFilterSpaceToUserSpaceScale;
   1.233 +
   1.234 +  /**
   1.235 +   * The 'primitiveUnits' attribute value (objectBoundingBox or userSpaceOnUse).
   1.236 +   */
   1.237 +  uint16_t                mPrimitiveUnits;
   1.238 +
   1.239 +  /**
   1.240 +   * The index of the FilterPrimitiveDescription that this SVG filter should use
   1.241 +   * as its SourceGraphic, or the SourceGraphic keyword index if this is the
   1.242 +   * first filter in a chain.
   1.243 +   */
   1.244 +  int32_t mSourceGraphicIndex;
   1.245 +
   1.246 +  bool                    mInitialized;
   1.247 +};
   1.248 +
   1.249 +#endif

mercurial