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

Generated by: LCOV version 1.13