tor-browser

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

nsImageRenderer.h (12103B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef nsImageRenderer_h__
      8 #define nsImageRenderer_h__
      9 
     10 #include "Units.h"
     11 #include "mozilla/AspectRatio.h"
     12 #include "mozilla/SurfaceFromElementResult.h"
     13 #include "nsStyleStruct.h"
     14 
     15 class gfxDrawable;
     16 
     17 namespace mozilla {
     18 class nsDisplayItem;
     19 
     20 namespace layers {
     21 class StackingContextHelper;
     22 class WebRenderParentCommand;
     23 class RenderRootStateManager;
     24 }  // namespace layers
     25 
     26 namespace wr {
     27 class DisplayListBuilder;
     28 class IpcResourceUpdateQueue;
     29 }  // namespace wr
     30 
     31 // A CSSSizeOrRatio represents a (possibly partially specified) size for use
     32 // in computing image sizes. Either or both of the width and height might be
     33 // given. A ratio of width to height may also be given. If we at least two
     34 // of these then we can compute a concrete size, that is a width and height.
     35 struct CSSSizeOrRatio {
     36  CSSSizeOrRatio()
     37      : mWidth(0), mHeight(0), mHasWidth(false), mHasHeight(false) {}
     38 
     39  bool CanComputeConcreteSize() const {
     40    return mHasWidth + mHasHeight + HasRatio() >= 2;
     41  }
     42  bool IsConcrete() const { return mHasWidth && mHasHeight; }
     43  bool HasRatio() const { return !!mRatio; }
     44  bool IsEmpty() const {
     45    return (mHasWidth && mWidth <= 0) || (mHasHeight && mHeight <= 0) ||
     46           !mRatio;
     47  }
     48 
     49  // CanComputeConcreteSize must return true when ComputeConcreteSize is
     50  // called.
     51  nsSize ComputeConcreteSize() const;
     52 
     53  void SetWidth(nscoord aWidth) {
     54    mWidth = aWidth;
     55    mHasWidth = true;
     56    if (mHasHeight) {
     57      mRatio = AspectRatio::FromSize(mWidth, mHeight);
     58    }
     59  }
     60  void SetHeight(nscoord aHeight) {
     61    mHeight = aHeight;
     62    mHasHeight = true;
     63    if (mHasWidth) {
     64      mRatio = AspectRatio::FromSize(mWidth, mHeight);
     65    }
     66  }
     67  void SetSize(const nsSize& aSize) {
     68    mWidth = aSize.width;
     69    mHeight = aSize.height;
     70    mHasWidth = true;
     71    mHasHeight = true;
     72    mRatio = AspectRatio::FromSize(mWidth, mHeight);
     73  }
     74  void SetRatio(const AspectRatio& aRatio) {
     75    MOZ_ASSERT(
     76        !mHasWidth || !mHasHeight,
     77        "Probably shouldn't be setting a ratio if we have a concrete size");
     78    mRatio = aRatio;
     79  }
     80 
     81  AspectRatio mRatio;
     82  nscoord mWidth;
     83  nscoord mHeight;
     84  bool mHasWidth;
     85  bool mHasHeight;
     86 };
     87 
     88 /**
     89 * This is a small wrapper class to encapsulate image drawing that can draw an
     90 * StyleImage image, which may internally be a real image, a sub image, or a CSS
     91 * gradient, etc...
     92 *
     93 * @note Always call the member functions in the order of PrepareImage(),
     94 * SetSize(), and Draw*().
     95 */
     96 class nsImageRenderer {
     97 public:
     98  typedef mozilla::image::ImgDrawResult ImgDrawResult;
     99  typedef mozilla::layers::ImageContainer ImageContainer;
    100 
    101  enum {
    102    FLAG_SYNC_DECODE_IMAGES = 0x01,
    103    FLAG_PAINTING_TO_WINDOW = 0x02,
    104    FLAG_HIGH_QUALITY_SCALING = 0x04,
    105    FLAG_DRAW_PARTIAL_FRAMES = 0x08
    106  };
    107  enum FitType { CONTAIN, COVER };
    108 
    109  nsImageRenderer(nsIFrame* aForFrame, const mozilla::StyleImage* aImage,
    110                  uint32_t aFlags);
    111  ~nsImageRenderer() = default;
    112  /**
    113   * Populates member variables to get ready for rendering.
    114   * @return true iff the image is ready, and there is at least a pixel to
    115   * draw.
    116   */
    117  bool PrepareImage();
    118 
    119  /**
    120   * The three Compute*Size functions correspond to the sizing algorthms and
    121   * definitions from the CSS Image Values and Replaced Content spec. See
    122   * http://dev.w3.org/csswg/css-images-3/#sizing .
    123   */
    124 
    125  /**
    126   * Compute the intrinsic size of the image as defined in the CSS Image Values
    127   * spec. The intrinsic size is the unscaled size which the image would ideally
    128   * like to be in app units.
    129   */
    130  mozilla::CSSSizeOrRatio ComputeIntrinsicSize();
    131 
    132  /**
    133   * Computes the placement for a background image, or for the image data
    134   * inside of a replaced element.
    135   *
    136   * @param aPos The CSS <position> value that specifies the image's position.
    137   * @param aOriginBounds The box to which the tiling position should be
    138   *          relative. For background images, this should correspond to
    139   *          'background-origin' for the frame, except when painting on the
    140   *          canvas, in which case the origin bounds should be the bounds
    141   *          of the root element's frame. For a replaced element, this should
    142   *          be the element's content-box.
    143   * @param aTopLeft [out] The top-left corner where an image tile should be
    144   *          drawn.
    145   * @param aAnchorPoint [out] A point which should be pixel-aligned by
    146   *          nsLayoutUtils::DrawImage. This is the same as aTopLeft, unless
    147   *          CSS specifies a percentage (including 'right' or 'bottom'), in
    148   *          which case it's that percentage within of aOriginBounds. So
    149   *          'right' would set aAnchorPoint.x to aOriginBounds.XMost().
    150   *
    151   * Points are returned relative to aOriginBounds.
    152   */
    153  static void ComputeObjectAnchorPoint(const mozilla::Position& aPos,
    154                                       const nsSize& aOriginBounds,
    155                                       const nsSize& aImageSize,
    156                                       nsPoint* aTopLeft,
    157                                       nsPoint* aAnchorPoint);
    158 
    159  /**
    160   * Compute the size of the rendered image using either the 'cover' or
    161   * 'contain' constraints (aFitType).
    162   */
    163  static nsSize ComputeConstrainedSize(
    164      const nsSize& aConstrainingSize,
    165      const mozilla::AspectRatio& aIntrinsicRatio, FitType aFitType);
    166  /**
    167   * Compute the size of the rendered image (the concrete size) where no cover/
    168   * contain constraints are given. The 'default algorithm' from the CSS Image
    169   * Values spec.
    170   */
    171  static nsSize ComputeConcreteSize(
    172      const mozilla::CSSSizeOrRatio& aSpecifiedSize,
    173      const mozilla::CSSSizeOrRatio& aIntrinsicSize,
    174      const nsSize& aDefaultSize);
    175 
    176  /**
    177   * Set this image's preferred size. This will be its intrinsic size where
    178   * specified and the default size where it is not. Used as the unscaled size
    179   * when rendering the image.
    180   */
    181  void SetPreferredSize(const mozilla::CSSSizeOrRatio& aIntrinsicSize,
    182                        const nsSize& aDefaultSize);
    183 
    184  /**
    185   * Draws the image to the target rendering context using
    186   * {background|mask}-specific arguments.
    187   * @see nsLayoutUtils::DrawImage() for parameters.
    188   */
    189  ImgDrawResult DrawLayer(nsPresContext* aPresContext,
    190                          gfxContext& aRenderingContext, const nsRect& aDest,
    191                          const nsRect& aFill, const nsPoint& aAnchor,
    192                          const nsRect& aDirty, const nsSize& aRepeatSize,
    193                          float aOpacity);
    194 
    195  /**
    196   * Builds WebRender DisplayItems for an image using
    197   * {background|mask}-specific arguments.
    198   * @see nsLayoutUtils::DrawImage() for parameters.
    199   */
    200  ImgDrawResult BuildWebRenderDisplayItemsForLayer(
    201      nsPresContext* aPresContext, mozilla::wr::DisplayListBuilder& aBuilder,
    202      mozilla::wr::IpcResourceUpdateQueue& aResource,
    203      const mozilla::layers::StackingContextHelper& aSc,
    204      mozilla::layers::RenderRootStateManager* aManager, nsDisplayItem* aItem,
    205      const nsRect& aDest, const nsRect& aFill, const nsPoint& aAnchor,
    206      const nsRect& aDirty, const nsSize& aRepeatSize, float aOpacity);
    207 
    208  /**
    209   * Draw the image to a single component of a border-image style rendering.
    210   * aFill The destination rect to be drawn into
    211   * aSrc is the part of the image to be rendered into a tile (aUnitSize in
    212   * aFill), if aSrc and the dest tile are different sizes, the image will be
    213   * scaled to map aSrc onto the dest tile.
    214   * aHFill and aVFill are the repeat patterns for the component -
    215   * NS_STYLE_BORDER_IMAGE_REPEAT_*
    216   * aUnitSize The scaled size of a single source rect (in destination coords)
    217   * aIndex identifies the component: 0 1 2
    218   *                                  3 4 5
    219   *                                  6 7 8
    220   * aSVGViewportSize The image size evaluated by default sizing algorithm.
    221   * Pass Nothing() if we can read a valid viewport size or aspect-ratio from
    222   * the drawing image directly, otherwise, pass Some() with viewport size
    223   * evaluated from default sizing algorithm.
    224   * aHasIntrinsicRatio is used to record if the source image has fixed
    225   * intrinsic ratio.
    226   */
    227  ImgDrawResult DrawBorderImageComponent(
    228      nsPresContext* aPresContext, gfxContext& aRenderingContext,
    229      const nsRect& aDirtyRect, const nsRect& aFill,
    230      const mozilla::CSSIntRect& aSrc,
    231      mozilla::StyleBorderImageRepeatKeyword aHFill,
    232      mozilla::StyleBorderImageRepeatKeyword aVFill, const nsSize& aUnitSize,
    233      uint8_t aIndex, const mozilla::Maybe<nsSize>& aSVGViewportSize,
    234      const bool aHasIntrinsicRatio);
    235 
    236  /**
    237   * Draw the image to aRenderingContext which can be used to define the
    238   * float area in the presence of "shape-outside: <image>".
    239   */
    240  ImgDrawResult DrawShapeImage(nsPresContext* aPresContext,
    241                               gfxContext& aRenderingContext);
    242 
    243  bool IsRasterImage() const;
    244 
    245  /// Retrieves the image associated with this nsImageRenderer, if there is one.
    246  already_AddRefed<imgIContainer> GetImage();
    247 
    248  bool IsReady() const { return mPrepareResult == ImgDrawResult::SUCCESS; }
    249  ImgDrawResult PrepareResult() const { return mPrepareResult; }
    250  void SetExtendMode(mozilla::gfx::ExtendMode aMode) { mExtendMode = aMode; }
    251  void SetMaskOp(mozilla::StyleMaskMode aMaskOp) { mMaskOp = aMaskOp; }
    252  const nsSize& GetSize() const { return mSize; }
    253  mozilla::StyleImage::Tag GetType() const { return mType; }
    254  const mozilla::StyleGradient* GetGradientData() const {
    255    return mGradientData;
    256  }
    257 
    258 private:
    259  /**
    260   * Draws the image to the target rendering context.
    261   * aSrc is a rect on the source image which will be mapped to aDest; it's
    262   * currently only used for gradients.
    263   *
    264   * @see nsLayoutUtils::DrawImage() for other parameters.
    265   */
    266  ImgDrawResult Draw(nsPresContext* aPresContext, gfxContext& aRenderingContext,
    267                     const nsRect& aDirtyRect, const nsRect& aDest,
    268                     const nsRect& aFill, const nsPoint& aAnchor,
    269                     const nsSize& aRepeatSize, const mozilla::CSSIntRect& aSrc,
    270                     float aOpacity = 1.0);
    271 
    272  /**
    273   * Builds WebRender DisplayItems for the image.
    274   * aSrc is a rect on the source image which will be mapped to aDest; it's
    275   * currently only used for gradients.
    276   *
    277   * @see nsLayoutUtils::DrawImage() for other parameters.
    278   */
    279  ImgDrawResult BuildWebRenderDisplayItems(
    280      nsPresContext* aPresContext, mozilla::wr::DisplayListBuilder& aBuilder,
    281      mozilla::wr::IpcResourceUpdateQueue& aResources,
    282      const mozilla::layers::StackingContextHelper& aSc,
    283      mozilla::layers::RenderRootStateManager* aManager, nsDisplayItem* aItem,
    284      const nsRect& aDirtyRect, const nsRect& aDest, const nsRect& aFill,
    285      const nsPoint& aAnchor, const nsSize& aRepeatSize,
    286      const mozilla::CSSIntRect& aSrc, float aOpacity = 1.0);
    287 
    288  /**
    289   * Helper method for creating a gfxDrawable from mPaintServerFrame or
    290   * mImageElementSurface.
    291   * Requires mType to be Element.
    292   * Returns null if we cannot create the drawable.
    293   */
    294  already_AddRefed<gfxDrawable> DrawableForElement(const nsRect& aImageRect,
    295                                                   gfxContext& aContext);
    296 
    297  nsIFrame* mForFrame;
    298  const mozilla::StyleImage* mImage;
    299  ImageResolution mImageResolution;
    300  mozilla::StyleImage::Tag mType;
    301  nsCOMPtr<imgIContainer> mImageContainer;
    302  const mozilla::StyleGradient* mGradientData;
    303  nsIFrame* mPaintServerFrame;
    304  SurfaceFromElementResult mImageElementSurface;
    305  ImgDrawResult mPrepareResult;
    306  nsSize mSize;  // unscaled size of the image, in app units
    307  uint32_t mFlags;
    308  mozilla::gfx::ExtendMode mExtendMode;
    309  mozilla::StyleMaskMode mMaskOp;
    310 };
    311 
    312 }  // namespace mozilla
    313 
    314 #endif /* nsImageRenderer_h__ */