tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gfxBlur.h (7715B)


      1 /* -*- Mode: C++; tab-width: 4; 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 GFX_BLUR_H
      7 #define GFX_BLUR_H
      8 
      9 #include "gfxTypes.h"
     10 #include "gfxRect.h"
     11 #include "nsSize.h"
     12 #include "gfxPoint.h"
     13 #include "mozilla/RefPtr.h"
     14 #include "mozilla/gfx/Blur.h"
     15 
     16 class gfxContext;
     17 
     18 namespace mozilla {
     19 namespace gfx {
     20 struct sRGBColor;
     21 struct RectCornerRadii;
     22 class SourceSurface;
     23 class DrawTarget;
     24 }  // namespace gfx
     25 }  // namespace mozilla
     26 
     27 /**
     28 * Implementation of a Gaussian blur.
     29 *
     30 * A Gaussian blur is good for blurring because, when done independently
     31 * in the horizontal and vertical directions, it matches the result that
     32 * would be obtained using a different (rotated) set of axes.
     33 *
     34 * Creates an 8-bit alpha channel context for callers to draw in,
     35 * spreads the contents of that context, blurs the contents, and applies
     36 * it as an alpha mask on a different existing context.
     37 *
     38 * A spread N makes each output pixel the maximum value of all source
     39 * pixels within a square of side length 2N+1 centered on the output pixel.
     40 *
     41 * A temporary surface is created in the Init function. The caller then draws
     42 * any desired content onto the context acquired through GetContext, and lastly
     43 * calls Paint to apply the blurred content as an alpha mask.
     44 */
     45 class gfxGaussianBlur final {
     46  typedef mozilla::gfx::sRGBColor sRGBColor;
     47  typedef mozilla::gfx::DrawTarget DrawTarget;
     48  typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
     49 
     50 public:
     51  gfxGaussianBlur() = default;
     52 
     53  ~gfxGaussianBlur();
     54 
     55  /**
     56   * Constructs a gaussian blur and initializes the temporary surface.
     57   *
     58   * @param aDestinationCtx The destination to blur to.
     59   *
     60   * @param aRect The coordinates of the surface to create in device units.
     61   *
     62   * @param aBlurSigma The blur sigma.
     63   *
     64   * @param aDirtyRect A pointer to a dirty rect, measured in device units,
     65   *  if available. This will be used for optimizing the blur operation. It
     66   *  is safe to pass nullptr here.
     67   *
     68   * @param aSkipRect A pointer to a rect, measured in device units, that
     69   *  represents an area where blurring is unnecessary and shouldn't be done
     70   *  for speed reasons. It is safe to pass nullptr here.
     71   *
     72   * @param aClamp Whether clamping at border pixels is required.
     73   */
     74  mozilla::UniquePtr<gfxContext> Init(
     75      gfxContext* aDestinationCtx, const gfxRect& aRect,
     76      const mozilla::gfx::IntSize& aSpreadRadius,
     77      const mozilla::gfx::Point& aBlurSigma, const gfxRect* aDirtyRect,
     78      const gfxRect* aSkipRect, bool aClamp = false);
     79 
     80  mozilla::UniquePtr<gfxContext> Init(
     81      gfxContext* aDestinationCtx, const gfxRect& aRect,
     82      const mozilla::gfx::IntSize& aSpreadRadius,
     83      const mozilla::gfx::IntSize& aBlurRadius, const gfxRect* aDirtyRect,
     84      const gfxRect* aSkipRect, bool aClamp = false);
     85 
     86  already_AddRefed<DrawTarget> InitDrawTarget(
     87      const mozilla::gfx::DrawTarget* aReferenceDT,
     88      const mozilla::gfx::Rect& aRect,
     89      const mozilla::gfx::IntSize& aSpreadRadius,
     90      const mozilla::gfx::Point& aBlurSigma,
     91      const mozilla::gfx::Rect* aDirtyRect = nullptr,
     92      const mozilla::gfx::Rect* aSkipRect = nullptr, bool aClamp = false);
     93 
     94  /**
     95   * Performs the blur and optionally colors the result if aShadowColor is not
     96   * null.
     97   */
     98  already_AddRefed<mozilla::gfx::SourceSurface> DoBlur(
     99      const mozilla::gfx::sRGBColor* aShadowColor = nullptr,
    100      mozilla::gfx::IntPoint* aOutTopLeft = nullptr);
    101 
    102  /**
    103   * Does the actual blurring/spreading and mask applying. Users of this
    104   * object must have drawn whatever they want to be blurred onto the internal
    105   * gfxContext returned by GetContext before calling this.
    106   *
    107   * @param aDestinationCtx The graphics context on which to apply the
    108   *  blurred mask.
    109   */
    110  void Paint(gfxContext* aDestinationCtx);
    111 
    112  /**
    113   * Calculates a blur radius that, when used with box blur, approximates
    114   * a Gaussian blur with the given standard deviation.  The result of
    115   * this function should be used as the aBlurRadius parameter to Init,
    116   * above.
    117   */
    118  static mozilla::gfx::IntSize CalculateBlurRadius(
    119      const gfxPoint& aStandardDeviation);
    120  static mozilla::gfx::Point CalculateBlurSigma(
    121      const mozilla::gfx::IntSize& aBlurRadius);
    122 
    123  /**
    124   * Blurs a coloured rectangle onto aDestinationCtx. This is equivalent
    125   * to calling Init(), drawing a rectangle onto the returned surface
    126   * and then calling Paint, but may let us optimize better in the
    127   * backend.
    128   *
    129   * @param aDestinationCtx      The destination to blur to.
    130   * @param aRect                The rectangle to blur in device pixels.
    131   * @param aCornerRadii         Corner radii for aRect, if it is a rounded
    132   *                             rectangle.
    133   * @param aBlurRadius          The standard deviation of the blur.
    134   * @param aShadowColor         The color to draw the blurred shadow.
    135   * @param aDirtyRect           An area in device pixels that is dirty and
    136   * needs to be redrawn.
    137   * @param aSkipRect            An area in device pixels to avoid blurring
    138   * over, to prevent unnecessary work.
    139   */
    140  static void BlurRectangle(gfxContext* aDestinationCtx, const gfxRect& aRect,
    141                            const RectCornerRadii* aCornerRadii,
    142                            const gfxPoint& aBlurStdDev,
    143                            const sRGBColor& aShadowColor,
    144                            const gfxRect& aDirtyRect,
    145                            const gfxRect& aSkipRect);
    146 
    147  static void ShutdownBlurCache();
    148 
    149  /***
    150   * Blurs an inset box shadow according to a given path.
    151   * This is equivalent to calling Init(), drawing the inset path,
    152   * and calling paint. Do not call Init() if using this method.
    153   *
    154   * @param aDestinationCtx     The destination to blur to.
    155   * @param aDestinationRect    The destination rect in device pixels
    156   * @param aShadowClipRect     The destiniation inner rect of the
    157   *                            inset path in device pixels.
    158   * @param aBlurRadius         The standard deviation of the blur.
    159   * @param aShadowColor        The color of the blur.
    160   * @param aInnerClipRadii     Corner radii for the inside rect if it is a
    161   *                            rounded rect.
    162   * @param aSkipRect           An area in device pixels we don't have to
    163   *                            paint in.
    164   */
    165  void BlurInsetBox(gfxContext* aDestinationCtx,
    166                    const mozilla::gfx::Rect& aDestinationRect,
    167                    const mozilla::gfx::Rect& aShadowClipRect,
    168                    const mozilla::gfx::IntSize& aBlurRadius,
    169                    const mozilla::gfx::sRGBColor& aShadowColor,
    170                    const RectCornerRadii* aInnerClipRadii,
    171                    const mozilla::gfx::Rect& aSkipRect,
    172                    const mozilla::gfx::Point& aShadowOffset);
    173 
    174 protected:
    175  already_AddRefed<mozilla::gfx::SourceSurface> GetInsetBlur(
    176      const mozilla::gfx::Rect& aOuterRect,
    177      const mozilla::gfx::Rect& aWhitespaceRect, bool aIsDestRect,
    178      const mozilla::gfx::sRGBColor& aShadowColor,
    179      const mozilla::gfx::IntSize& aBlurRadius,
    180      const RectCornerRadii* aInnerClipRadii, DrawTarget* aDestDrawTarget,
    181      bool aMirrorCorners);
    182 
    183  /**
    184   * The DrawTarget of the temporary alpha surface.
    185   */
    186  RefPtr<DrawTarget> mDrawTarget;
    187 
    188  /**
    189   * The temporary alpha surface.
    190   */
    191  uint8_t* mData = nullptr;
    192 
    193  /**
    194   * The object that actually does the blurring for us.
    195   */
    196  mozilla::gfx::GaussianBlur mBlur;
    197 };
    198 
    199 #endif /* GFX_BLUR_H */