layout/svg/nsFilterInstance.h

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef __NS_FILTERINSTANCE_H__
michael@0 7 #define __NS_FILTERINSTANCE_H__
michael@0 8
michael@0 9 #include "gfxMatrix.h"
michael@0 10 #include "gfxPoint.h"
michael@0 11 #include "gfxRect.h"
michael@0 12 #include "nsCOMPtr.h"
michael@0 13 #include "nsHashKeys.h"
michael@0 14 #include "nsPoint.h"
michael@0 15 #include "nsRect.h"
michael@0 16 #include "nsSize.h"
michael@0 17 #include "nsSVGFilters.h"
michael@0 18 #include "nsSVGNumber2.h"
michael@0 19 #include "nsSVGNumberPair.h"
michael@0 20 #include "nsTArray.h"
michael@0 21 #include "nsIFrame.h"
michael@0 22 #include "mozilla/gfx/2D.h"
michael@0 23
michael@0 24 class gfxASurface;
michael@0 25 class nsIFrame;
michael@0 26 class nsSVGFilterPaintCallback;
michael@0 27
michael@0 28 /**
michael@0 29 * This class performs all filter processing.
michael@0 30 *
michael@0 31 * We build a graph of the filter image data flow, essentially
michael@0 32 * converting the filter graph to SSA. This lets us easily propagate
michael@0 33 * analysis data (such as bounding-boxes) over the filter primitive graph.
michael@0 34 *
michael@0 35 * Definition of "filter space": filter space is a coordinate system that is
michael@0 36 * aligned with the user space of the filtered element, with its origin located
michael@0 37 * at the top left of the filter region, and with one unit equal in size to one
michael@0 38 * pixel of the offscreen surface into which the filter output would/will be
michael@0 39 * painted.
michael@0 40 *
michael@0 41 * The definition of "filter region" can be found here:
michael@0 42 * http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion
michael@0 43 */
michael@0 44 class nsFilterInstance
michael@0 45 {
michael@0 46 typedef mozilla::gfx::IntRect IntRect;
michael@0 47 typedef mozilla::gfx::SourceSurface SourceSurface;
michael@0 48 typedef mozilla::gfx::DrawTarget DrawTarget;
michael@0 49 typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
michael@0 50
michael@0 51 public:
michael@0 52 /**
michael@0 53 * Paint the given filtered frame.
michael@0 54 * @param aDirtyArea The area than needs to be painted, in aFilteredFrame's
michael@0 55 * frame space (i.e. relative to its origin, the top-left corner of its
michael@0 56 * border box).
michael@0 57 */
michael@0 58 static nsresult PaintFilteredFrame(nsRenderingContext *aContext,
michael@0 59 nsIFrame *aFilteredFrame,
michael@0 60 nsSVGFilterPaintCallback *aPaintCallback,
michael@0 61 const nsRegion* aDirtyArea,
michael@0 62 nsIFrame* aTransformRoot = nullptr);
michael@0 63
michael@0 64 /**
michael@0 65 * Returns the post-filter area that could be dirtied when the given
michael@0 66 * pre-filter area of aFilteredFrame changes.
michael@0 67 * @param aPreFilterDirtyRegion The pre-filter area of aFilteredFrame that has
michael@0 68 * changed, relative to aFilteredFrame, in app units.
michael@0 69 */
michael@0 70 static nsRegion GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
michael@0 71 const nsRegion& aPreFilterDirtyRegion);
michael@0 72
michael@0 73 /**
michael@0 74 * Returns the pre-filter area that is needed from aFilteredFrame when the
michael@0 75 * given post-filter area needs to be repainted.
michael@0 76 * @param aPostFilterDirtyRegion The post-filter area that is dirty, relative
michael@0 77 * to aFilteredFrame, in app units.
michael@0 78 */
michael@0 79 static nsRegion GetPreFilterNeededArea(nsIFrame *aFilteredFrame,
michael@0 80 const nsRegion& aPostFilterDirtyRegion);
michael@0 81
michael@0 82 /**
michael@0 83 * Returns the post-filter visual overflow rect (paint bounds) of
michael@0 84 * aFilteredFrame.
michael@0 85 * @param aOverrideBBox A user space rect, in user units, that should be used
michael@0 86 * as aFilteredFrame's bbox ('bbox' is a specific SVG term), if non-null.
michael@0 87 * @param aPreFilterBounds The pre-filter visual overflow rect of
michael@0 88 * aFilteredFrame, if non-null.
michael@0 89 */
michael@0 90 static nsRect GetPostFilterBounds(nsIFrame *aFilteredFrame,
michael@0 91 const gfxRect *aOverrideBBox = nullptr,
michael@0 92 const nsRect *aPreFilterBounds = nullptr);
michael@0 93
michael@0 94 /**
michael@0 95 * @param aTargetFrame The frame of the filtered element under consideration.
michael@0 96 * @param aPaintCallback [optional] The callback that Render() should use to
michael@0 97 * paint. Only required if you will call Render().
michael@0 98 * @param aPostFilterDirtyRegion [optional] The post-filter area
michael@0 99 * that has to be repainted, in app units. Only required if you will
michael@0 100 * call ComputeSourceNeededRect() or Render().
michael@0 101 * @param aPreFilterDirtyRegion [optional] The pre-filter area of
michael@0 102 * the filtered element that changed, in app units. Only required if you
michael@0 103 * will call ComputePostFilterDirtyRegion().
michael@0 104 * @param aOverridePreFilterVisualOverflowRect [optional] Use a different
michael@0 105 * visual overflow rect for the target element.
michael@0 106 * @param aOverrideBBox [optional] Use a different SVG bbox for the target
michael@0 107 * element.
michael@0 108 * @param aTransformRoot [optional] The transform root frame for painting.
michael@0 109 */
michael@0 110 nsFilterInstance(nsIFrame *aTargetFrame,
michael@0 111 nsSVGFilterPaintCallback *aPaintCallback,
michael@0 112 const nsRegion *aPostFilterDirtyRegion = nullptr,
michael@0 113 const nsRegion *aPreFilterDirtyRegion = nullptr,
michael@0 114 const nsRect *aOverridePreFilterVisualOverflowRect = nullptr,
michael@0 115 const gfxRect *aOverrideBBox = nullptr,
michael@0 116 nsIFrame* aTransformRoot = nullptr);
michael@0 117
michael@0 118 /**
michael@0 119 * Returns true if the filter instance was created successfully.
michael@0 120 */
michael@0 121 bool IsInitialized() const { return mInitialized; }
michael@0 122
michael@0 123 /**
michael@0 124 * Draws the filter output into aContext. The area that
michael@0 125 * needs to be painted must have been specified before calling this method
michael@0 126 * by passing it as the aPostFilterDirtyRegion argument to the
michael@0 127 * nsFilterInstance constructor.
michael@0 128 */
michael@0 129 nsresult Render(gfxContext* aContext);
michael@0 130
michael@0 131 /**
michael@0 132 * Sets the aPostFilterDirtyRegion outparam to the post-filter area in frame
michael@0 133 * space that would be dirtied by mTargetFrame when a given
michael@0 134 * pre-filter area of mTargetFrame is dirtied. The pre-filter area must have
michael@0 135 * been specified before calling this method by passing it as the
michael@0 136 * aPreFilterDirtyRegion argument to the nsFilterInstance constructor.
michael@0 137 */
michael@0 138 nsresult ComputePostFilterDirtyRegion(nsRegion* aPostFilterDirtyRegion);
michael@0 139
michael@0 140 /**
michael@0 141 * Sets the aPostFilterExtents outparam to the post-filter bounds in frame
michael@0 142 * space for the whole filter output. This is not necessarily equivalent to
michael@0 143 * the area that would be dirtied in the result when the entire pre-filter
michael@0 144 * area is dirtied, because some filter primitives can generate output
michael@0 145 * without any input.
michael@0 146 */
michael@0 147 nsresult ComputePostFilterExtents(nsRect* aPostFilterExtents);
michael@0 148
michael@0 149 /**
michael@0 150 * Sets the aDirty outparam to the pre-filter bounds in frame space of the
michael@0 151 * area of mTargetFrame that is needed in order to paint the filtered output
michael@0 152 * for a given post-filter dirtied area. The post-filter area must have been
michael@0 153 * specified before calling this method by passing it as the aPostFilterDirtyRegion
michael@0 154 * argument to the nsFilterInstance constructor.
michael@0 155 */
michael@0 156 nsresult ComputeSourceNeededRect(nsRect* aDirty);
michael@0 157
michael@0 158
michael@0 159 /**
michael@0 160 * Returns the transform from filter space to outer-<svg> device space.
michael@0 161 */
michael@0 162 gfxMatrix GetFilterSpaceToDeviceSpaceTransform() const {
michael@0 163 return mFilterSpaceToDeviceSpaceTransform;
michael@0 164 }
michael@0 165
michael@0 166 private:
michael@0 167 struct SourceInfo {
michael@0 168 // Specifies which parts of the source need to be rendered.
michael@0 169 // Set by ComputeNeededBoxes().
michael@0 170 nsIntRect mNeededBounds;
michael@0 171
michael@0 172 // The surface that contains the input rendering.
michael@0 173 // Set by BuildSourceImage / BuildSourcePaint.
michael@0 174 mozilla::RefPtr<SourceSurface> mSourceSurface;
michael@0 175
michael@0 176 // The position and size of mSourceSurface in filter space.
michael@0 177 // Set by BuildSourceImage / BuildSourcePaint.
michael@0 178 IntRect mSurfaceRect;
michael@0 179 };
michael@0 180
michael@0 181 /**
michael@0 182 * Creates a SourceSurface for either the FillPaint or StrokePaint graph
michael@0 183 * nodes
michael@0 184 */
michael@0 185 nsresult BuildSourcePaint(SourceInfo *aPrimitive,
michael@0 186 gfxASurface* aTargetSurface,
michael@0 187 DrawTarget* aTargetDT);
michael@0 188
michael@0 189 /**
michael@0 190 * Creates a SourceSurface for either the FillPaint and StrokePaint graph
michael@0 191 * nodes, fills its contents and assigns it to mFillPaint.mSourceSurface and
michael@0 192 * mStrokePaint.mSourceSurface respectively.
michael@0 193 */
michael@0 194 nsresult BuildSourcePaints(gfxASurface* aTargetSurface,
michael@0 195 DrawTarget* aTargetDT);
michael@0 196
michael@0 197 /**
michael@0 198 * Creates the SourceSurface for the SourceGraphic graph node, paints its
michael@0 199 * contents, and assigns it to mSourceGraphic.mSourceSurface.
michael@0 200 */
michael@0 201 nsresult BuildSourceImage(gfxASurface* aTargetSurface,
michael@0 202 DrawTarget* aTargetDT);
michael@0 203
michael@0 204 /**
michael@0 205 * Build the list of FilterPrimitiveDescriptions that describes the filter's
michael@0 206 * filter primitives and their connections. This populates
michael@0 207 * mPrimitiveDescriptions and mInputImages.
michael@0 208 */
michael@0 209 nsresult BuildPrimitives();
michael@0 210
michael@0 211 /**
michael@0 212 * Add to the list of FilterPrimitiveDescriptions for a particular SVG
michael@0 213 * reference filter or CSS filter. This populates mPrimitiveDescrs and
michael@0 214 * mInputImages.
michael@0 215 */
michael@0 216 nsresult BuildPrimitivesForFilter(const nsStyleFilter& aFilter);
michael@0 217
michael@0 218 /**
michael@0 219 * Computes the filter space bounds of the areas that we actually *need* from
michael@0 220 * the filter sources, based on the value of mPostFilterDirtyRegion.
michael@0 221 * This sets mNeededBounds on the corresponding SourceInfo structs.
michael@0 222 */
michael@0 223 void ComputeNeededBoxes();
michael@0 224
michael@0 225 /**
michael@0 226 * Compute the scale factors between user space and filter space.
michael@0 227 */
michael@0 228 nsresult ComputeUserSpaceToFilterSpaceScale();
michael@0 229
michael@0 230 /**
michael@0 231 * Transform a rect between user space and filter space.
michael@0 232 */
michael@0 233 gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpace) const;
michael@0 234 gfxRect FilterSpaceToUserSpace(const gfxRect& aFilterSpaceRect) const;
michael@0 235
michael@0 236 /**
michael@0 237 * Converts an nsRect or an nsRegion that is relative to a filtered frame's
michael@0 238 * origin (i.e. the top-left corner of its border box) into filter space,
michael@0 239 * rounding out.
michael@0 240 * Returns the entire filter region if aRect / aRegion is null, or if the
michael@0 241 * result is too large to be stored in an nsIntRect.
michael@0 242 */
michael@0 243 nsIntRect FrameSpaceToFilterSpace(const nsRect* aRect) const;
michael@0 244 nsIntRegion FrameSpaceToFilterSpace(const nsRegion* aRegion) const;
michael@0 245
michael@0 246 /**
michael@0 247 * Converts an nsIntRect or an nsIntRegion from filter space into the space
michael@0 248 * that is relative to a filtered frame's origin (i.e. the top-left corner
michael@0 249 * of its border box) in app units, rounding out.
michael@0 250 */
michael@0 251 nsRect FilterSpaceToFrameSpace(const nsIntRect& aRect) const;
michael@0 252 nsRegion FilterSpaceToFrameSpace(const nsIntRegion& aRegion) const;
michael@0 253
michael@0 254 /**
michael@0 255 * Returns the transform from frame space to the coordinate space that
michael@0 256 * GetCanvasTM transforms to. "Frame space" is the origin of a frame, aka the
michael@0 257 * top-left corner of its border box, aka the top left corner of its mRect.
michael@0 258 */
michael@0 259 gfxMatrix GetUserSpaceToFrameSpaceInCSSPxTransform() const;
michael@0 260
michael@0 261 /**
michael@0 262 * The frame for the element that is currently being filtered.
michael@0 263 */
michael@0 264 nsIFrame* mTargetFrame;
michael@0 265
michael@0 266 nsSVGFilterPaintCallback* mPaintCallback;
michael@0 267
michael@0 268 /**
michael@0 269 * The SVG bbox of the element that is being filtered, in user space.
michael@0 270 */
michael@0 271 gfxRect mTargetBBox;
michael@0 272
michael@0 273 /**
michael@0 274 * The transform from filter space to outer-<svg> device space.
michael@0 275 */
michael@0 276 gfxMatrix mFilterSpaceToDeviceSpaceTransform;
michael@0 277
michael@0 278 /**
michael@0 279 * Transform rects between filter space and frame space in CSS pixels.
michael@0 280 */
michael@0 281 gfxMatrix mFilterSpaceToFrameSpaceInCSSPxTransform;
michael@0 282 gfxMatrix mFrameSpaceInCSSPxToFilterSpaceTransform;
michael@0 283
michael@0 284 /**
michael@0 285 * The "filter region", in the filtered element's user space.
michael@0 286 */
michael@0 287 gfxRect mUserSpaceBounds;
michael@0 288 nsIntRect mFilterSpaceBounds;
michael@0 289
michael@0 290 /**
michael@0 291 * The scale factors between user space and filter space.
michael@0 292 */
michael@0 293 gfxSize mUserSpaceToFilterSpaceScale;
michael@0 294 gfxSize mFilterSpaceToUserSpaceScale;
michael@0 295
michael@0 296 /**
michael@0 297 * Pre-filter paint bounds of the element that is being filtered, in filter
michael@0 298 * space.
michael@0 299 */
michael@0 300 nsIntRect mTargetBounds;
michael@0 301
michael@0 302 /**
michael@0 303 * The dirty area that needs to be repainted, in filter space.
michael@0 304 */
michael@0 305 nsIntRegion mPostFilterDirtyRegion;
michael@0 306
michael@0 307 /**
michael@0 308 * The pre-filter area of the filtered element that changed, in filter space.
michael@0 309 */
michael@0 310 nsIntRegion mPreFilterDirtyRegion;
michael@0 311
michael@0 312 SourceInfo mSourceGraphic;
michael@0 313 SourceInfo mFillPaint;
michael@0 314 SourceInfo mStrokePaint;
michael@0 315 nsIFrame* mTransformRoot;
michael@0 316 nsTArray<mozilla::RefPtr<SourceSurface>> mInputImages;
michael@0 317 nsTArray<FilterPrimitiveDescription> mPrimitiveDescriptions;
michael@0 318 int32_t mAppUnitsPerCSSPx;
michael@0 319 bool mInitialized;
michael@0 320 };
michael@0 321
michael@0 322 #endif

mercurial