LCOV - code coverage report
Current view: top level - layout/painting - nsCSSRendering.h (source / functions) Hit Total Coverage
Test: output.info Lines: 22 49 44.9 %
Date: 2017-07-14 16:53:18 Functions: 12 14 85.7 %
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             : /* utility functions for drawing borders and backgrounds */
       7             : 
       8             : #ifndef nsCSSRendering_h___
       9             : #define nsCSSRendering_h___
      10             : 
      11             : #include "gfxBlur.h"
      12             : #include "gfxContext.h"
      13             : #include "imgIContainer.h"
      14             : #include "mozilla/gfx/PathHelpers.h"
      15             : #include "mozilla/gfx/Rect.h"
      16             : #include "mozilla/TypedEnumBits.h"
      17             : #include "nsLayoutUtils.h"
      18             : #include "nsStyleStruct.h"
      19             : #include "nsIFrame.h"
      20             : #include "nsImageRenderer.h"
      21             : #include "nsCSSRenderingBorders.h"
      22             : 
      23             : class gfxContext;
      24             : class nsStyleContext;
      25             : class nsPresContext;
      26             : 
      27             : namespace mozilla {
      28             : 
      29             : namespace gfx {
      30             : struct Color;
      31             : class DrawTarget;
      32             : } // namespace gfx
      33             : 
      34             : namespace layers {
      35             : class ImageContainer;
      36             : class StackingContextHelper;
      37             : class WebRenderDisplayItemLayer;
      38             : class WebRenderParentCommand;
      39             : class LayerManager;
      40             : } // namespace layers
      41             : 
      42             : namespace wr {
      43             : class DisplayListBuilder;
      44             : } // namespace wr
      45             : 
      46             : enum class PaintBorderFlags : uint8_t
      47             : {
      48             :   SYNC_DECODE_IMAGES = 1 << 0
      49             : };
      50           3 : MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PaintBorderFlags)
      51             : 
      52             : } // namespace mozilla
      53             : 
      54             : /**
      55             :  * A struct representing all the information needed to paint a background
      56             :  * image to some target, taking into account all CSS background-* properties.
      57             :  * See PrepareImageLayer.
      58             :  */
      59         454 : struct nsBackgroundLayerState {
      60             :   typedef mozilla::gfx::CompositionOp CompositionOp;
      61             :   typedef mozilla::nsImageRenderer nsImageRenderer;
      62             : 
      63             :   /**
      64             :    * @param aFlags some combination of nsCSSRendering::PAINTBG_* flags
      65             :    */
      66         454 :   nsBackgroundLayerState(nsIFrame* aForFrame, const nsStyleImage* aImage,
      67             :                          uint32_t aFlags)
      68         454 :     : mImageRenderer(aForFrame, aImage, aFlags)
      69         454 :   {}
      70             : 
      71             :   /**
      72             :    * The nsImageRenderer that will be used to draw the background.
      73             :    */
      74             :   nsImageRenderer mImageRenderer;
      75             :   /**
      76             :    * A rectangle that one copy of the image tile is mapped onto. Same
      77             :    * coordinate system as aBorderArea/aBGClipRect passed into
      78             :    * PrepareImageLayer.
      79             :    */
      80             :   nsRect mDestArea;
      81             :   /**
      82             :    * The actual rectangle that should be filled with (complete or partial)
      83             :    * image tiles. Same coordinate system as aBorderArea/aBGClipRect passed into
      84             :    * PrepareImageLayer.
      85             :    */
      86             :   nsRect mFillArea;
      87             :   /**
      88             :    * The anchor point that should be snapped to a pixel corner. Same
      89             :    * coordinate system as aBorderArea/aBGClipRect passed into
      90             :    * PrepareImageLayer.
      91             :    */
      92             :   nsPoint mAnchor;
      93             :   /**
      94             :    * The background-repeat property space keyword computes the
      95             :    * repeat size which is image size plus spacing.
      96             :    */
      97             :   nsSize mRepeatSize;
      98             : };
      99             : 
     100             : struct nsCSSRendering {
     101             :   typedef mozilla::gfx::Color Color;
     102             :   typedef mozilla::gfx::CompositionOp CompositionOp;
     103             :   typedef mozilla::gfx::DrawTarget DrawTarget;
     104             :   typedef mozilla::gfx::Float Float;
     105             :   typedef mozilla::gfx::Point Point;
     106             :   typedef mozilla::gfx::Rect Rect;
     107             :   typedef mozilla::gfx::Size Size;
     108             :   typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
     109             :   typedef mozilla::layers::LayerManager LayerManager;
     110             :   typedef mozilla::image::DrawResult DrawResult;
     111             :   typedef nsIFrame::Sides Sides;
     112             : 
     113             :   /**
     114             :    * Initialize any static variables used by nsCSSRendering.
     115             :    */
     116             :   static void Init();
     117             : 
     118             :   /**
     119             :    * Clean up any static variables used by nsCSSRendering.
     120             :    */
     121             :   static void Shutdown();
     122             : 
     123             :   static bool GetShadowInnerRadii(nsIFrame* aFrame,
     124             :                                   const nsRect& aFrameArea,
     125             :                                   RectCornerRadii& aOutInnerRadii);
     126             :   static nsRect GetBoxShadowInnerPaddingRect(nsIFrame* aFrame,
     127             :                                              const nsRect& aFrameArea);
     128             :   static bool ShouldPaintBoxShadowInner(nsIFrame* aFrame);
     129             :   static void PaintBoxShadowInner(nsPresContext* aPresContext,
     130             :                                   gfxContext& aRenderingContext,
     131             :                                   nsIFrame* aForFrame,
     132             :                                   const nsRect& aFrameArea);
     133             : 
     134             :   static bool GetBorderRadii(const nsRect& aFrameRect,
     135             :                              const nsRect& aBorderRect,
     136             :                              nsIFrame* aFrame,
     137             :                              RectCornerRadii& aOutRadii);
     138             :   static nsRect GetShadowRect(const nsRect aFrameArea,
     139             :                               bool aNativeTheme,
     140             :                               nsIFrame* aForFrame);
     141             :   static mozilla::gfx::Color GetShadowColor(nsCSSShadowItem* aShadow,
     142             :                                    nsIFrame* aFrame,
     143             :                                    float aOpacity);
     144             :   // Returns if the frame has a themed frame.
     145             :   // aMaybeHasBorderRadius will return false if we can early detect
     146             :   // that we don't have a border radius.
     147             :   static bool HasBoxShadowNativeTheme(nsIFrame* aFrame,
     148             :                                       bool& aMaybeHasBorderRadius);
     149             :   static void PaintBoxShadowOuter(nsPresContext* aPresContext,
     150             :                                   gfxContext& aRenderingContext,
     151             :                                   nsIFrame* aForFrame,
     152             :                                   const nsRect& aFrameArea,
     153             :                                   const nsRect& aDirtyRect,
     154             :                                   float aOpacity = 1.0);
     155             : 
     156             :   static void ComputePixelRadii(const nscoord *aAppUnitsRadii,
     157             :                                 nscoord aAppUnitsPerPixel,
     158             :                                 RectCornerRadii *oBorderRadii);
     159             : 
     160             :   /**
     161             :    * Render the border for an element using css rendering rules
     162             :    * for borders. aSkipSides says which sides to skip
     163             :    * when rendering, the default is to skip none.
     164             :    */
     165             :   static DrawResult PaintBorder(nsPresContext* aPresContext,
     166             :                                 gfxContext& aRenderingContext,
     167             :                                 nsIFrame* aForFrame,
     168             :                                 const nsRect& aDirtyRect,
     169             :                                 const nsRect& aBorderArea,
     170             :                                 nsStyleContext* aStyleContext,
     171             :                                 mozilla::PaintBorderFlags aFlags,
     172             :                                 Sides aSkipSides = Sides());
     173             : 
     174             :   /**
     175             :    * Like PaintBorder, but taking an nsStyleBorder argument instead of
     176             :    * getting it from aStyleContext. aSkipSides says which sides to skip
     177             :    * when rendering, the default is to skip none.
     178             :    */
     179             :   static DrawResult PaintBorderWithStyleBorder(nsPresContext* aPresContext,
     180             :                                                gfxContext& aRenderingContext,
     181             :                                                nsIFrame* aForFrame,
     182             :                                                const nsRect& aDirtyRect,
     183             :                                                const nsRect& aBorderArea,
     184             :                                                const nsStyleBorder& aBorderStyle,
     185             :                                                nsStyleContext* aStyleContext,
     186             :                                                mozilla::PaintBorderFlags aFlags,
     187             :                                                Sides aSkipSides = Sides());
     188             : 
     189             :   static mozilla::Maybe<nsCSSBorderRenderer>
     190             :   CreateBorderRenderer(nsPresContext* aPresContext,
     191             :                        DrawTarget* aDrawTarget,
     192             :                        nsIFrame* aForFrame,
     193             :                        const nsRect& aDirtyRect,
     194             :                        const nsRect& aBorderArea,
     195             :                        nsStyleContext* aStyleContext,
     196             :                        Sides aSkipSides = Sides());
     197             : 
     198             :   static mozilla::Maybe<nsCSSBorderRenderer>
     199             :   CreateBorderRendererWithStyleBorder(nsPresContext* aPresContext,
     200             :                                       DrawTarget* aDrawTarget,
     201             :                                       nsIFrame* aForFrame,
     202             :                                       const nsRect& aDirtyRect,
     203             :                                       const nsRect& aBorderArea,
     204             :                                       const nsStyleBorder& aBorderStyle,
     205             :                                       nsStyleContext* aStyleContext,
     206             :                                       Sides aSkipSides = Sides());
     207             : 
     208             :   static mozilla::Maybe<nsCSSBorderRenderer>
     209             :   CreateBorderRendererForOutline(nsPresContext* aPresContext,
     210             :                                  gfxContext* aRenderingContext,
     211             :                                  nsIFrame* aForFrame,
     212             :                                  const nsRect& aDirtyRect,
     213             :                                  const nsRect& aBorderArea,
     214             :                                  nsStyleContext* aStyleContext);
     215             : 
     216             :   /**
     217             :    * Render the outline for an element using css rendering rules
     218             :    * for borders.
     219             :    */
     220             :   static void PaintOutline(nsPresContext* aPresContext,
     221             :                           gfxContext& aRenderingContext,
     222             :                           nsIFrame* aForFrame,
     223             :                           const nsRect& aDirtyRect,
     224             :                           const nsRect& aBorderArea,
     225             :                           nsStyleContext* aStyleContext);
     226             : 
     227             :   /**
     228             :    * Render keyboard focus on an element.
     229             :    * |aFocusRect| is the outer rectangle of the focused element.
     230             :    * Uses a fixed style equivalent to "1px dotted |aColor|".
     231             :    * Not used for controls, because the native theme may differ.
     232             :    */
     233             :   static void PaintFocus(nsPresContext* aPresContext,
     234             :                          DrawTarget* aDrawTarget,
     235             :                          const nsRect& aFocusRect,
     236             :                          nscolor aColor);
     237             : 
     238             :   /**
     239             :    * Render a gradient for an element.
     240             :    * aDest is the rect for a single tile of the gradient on the destination.
     241             :    * aFill is the rect on the destination to be covered by repeated tiling of
     242             :    * the gradient.
     243             :    * aSrc is the part of the gradient to be rendered into a tile (aDest), if
     244             :    * aSrc and aDest are different sizes, the image will be scaled to map aSrc
     245             :    * onto aDest.
     246             :    * aIntrinsicSize is the size of the source gradient.
     247             :    */
     248             :   static void PaintGradient(nsPresContext* aPresContext,
     249             :                             gfxContext& aContext,
     250             :                             nsStyleGradient* aGradient,
     251             :                             const nsRect& aDirtyRect,
     252             :                             const nsRect& aDest,
     253             :                             const nsRect& aFill,
     254             :                             const nsSize& aRepeatSize,
     255             :                             const mozilla::CSSIntRect& aSrc,
     256             :                             const nsSize& aIntrinsiceSize,
     257             :                             float aOpacity = 1.0);
     258             : 
     259             :   /**
     260             :    * Find the frame whose background style should be used to draw the
     261             :    * canvas background. aForFrame must be the frame for the root element
     262             :    * whose background style should be used. This function will return
     263             :    * aForFrame unless the <body> background should be propagated, in
     264             :    * which case we return the frame associated with the <body>'s background.
     265             :    */
     266             :   static nsIFrame* FindBackgroundStyleFrame(nsIFrame* aForFrame);
     267             : 
     268             :   /**
     269             :    * @return true if |aFrame| is a canvas frame, in the CSS sense.
     270             :    */
     271             :   static bool IsCanvasFrame(nsIFrame* aFrame);
     272             : 
     273             :   /**
     274             :    * Fill in an aBackgroundSC to be used to paint the background
     275             :    * for an element.  This applies the rules for propagating
     276             :    * backgrounds between BODY, the root element, and the canvas.
     277             :    * @return true if there is some meaningful background.
     278             :    */
     279             :   static bool FindBackground(nsIFrame* aForFrame,
     280             :                              nsStyleContext** aBackgroundSC);
     281             : 
     282             :   /**
     283             :    * As FindBackground, but the passed-in frame is known to be a root frame
     284             :    * (returned from nsCSSFrameConstructor::GetRootElementStyleFrame())
     285             :    * and there is always some meaningful background returned.
     286             :    */
     287             :   static nsStyleContext* FindRootFrameBackground(nsIFrame* aForFrame);
     288             : 
     289             :   /**
     290             :    * Returns background style information for the canvas.
     291             :    *
     292             :    * @param aForFrame
     293             :    *   the frame used to represent the canvas, in the CSS sense (i.e.
     294             :    *   nsCSSRendering::IsCanvasFrame(aForFrame) must be true)
     295             :    * @param aRootElementFrame
     296             :    *   the frame representing the root element of the document
     297             :    * @param aBackground
     298             :    *   contains background style information for the canvas on return
     299             :    */
     300             :   static nsStyleContext*
     301          53 :   FindCanvasBackground(nsIFrame* aForFrame, nsIFrame* aRootElementFrame)
     302             :   {
     303          53 :     MOZ_ASSERT(IsCanvasFrame(aForFrame), "not a canvas frame");
     304          53 :     if (aRootElementFrame)
     305          53 :       return FindRootFrameBackground(aRootElementFrame);
     306             : 
     307             :     // This should always give transparent, so we'll fill it in with the
     308             :     // default color if needed.  This seems to happen a bit while a page is
     309             :     // being loaded.
     310           0 :     return aForFrame->StyleContext();
     311             :   }
     312             : 
     313             :   /**
     314             :    * Find a frame which draws a non-transparent background,
     315             :    * for various table-related and HR-related backwards-compatibility hacks.
     316             :    * This function will also stop if it finds themed frame which might draw
     317             :    * background.
     318             :    *
     319             :    * Be very hesitant if you're considering calling this function -- it's
     320             :    * usually not what you want.
     321             :    */
     322             :   static nsIFrame*
     323             :   FindNonTransparentBackgroundFrame(nsIFrame* aFrame,
     324             :                                     bool aStartAtParent = false);
     325             : 
     326             :   /**
     327             :    * Determine the background color to draw taking into account print settings.
     328             :    */
     329             :   static nscolor
     330             :   DetermineBackgroundColor(nsPresContext* aPresContext,
     331             :                            nsStyleContext* aStyleContext,
     332             :                            nsIFrame* aFrame,
     333             :                            bool& aDrawBackgroundImage,
     334             :                            bool& aDrawBackgroundColor);
     335             : 
     336             :   static nsRect
     337             :   ComputeImageLayerPositioningArea(nsPresContext* aPresContext,
     338             :                                    nsIFrame* aForFrame,
     339             :                                    const nsRect& aBorderArea,
     340             :                                    const nsStyleImageLayers::Layer& aLayer,
     341             :                                    nsIFrame** aAttachedToFrame,
     342             :                                    bool* aOutTransformedFixed);
     343             : 
     344             :   // Implementation of the formula for computation of background-repeat round
     345             :   // See http://dev.w3.org/csswg/css3-background/#the-background-size
     346             :   // This function returns the adjusted size of the background image.
     347             :   static nscoord
     348             :   ComputeRoundedSize(nscoord aCurrentSize, nscoord aPositioningSize);
     349             : 
     350             :   /* ComputeBorderSpacedRepeatSize
     351             :   * aImageDimension: the image width/height
     352             :   * aAvailableSpace: the background positioning area width/height
     353             :   * aSpace: the space between each image
     354             :   * Returns the image size plus gap size of app units for use as spacing
     355             :   */
     356             :   static nscoord
     357             :   ComputeBorderSpacedRepeatSize(nscoord aImageDimension,
     358             :                                 nscoord aAvailableSpace,
     359             :                                 nscoord& aSpace);
     360             : 
     361             :   static nsBackgroundLayerState
     362             :   PrepareImageLayer(nsPresContext* aPresContext,
     363             :                     nsIFrame* aForFrame,
     364             :                     uint32_t aFlags,
     365             :                     const nsRect& aBorderArea,
     366             :                     const nsRect& aBGClipRect,
     367             :                     const nsStyleImageLayers::Layer& aLayer,
     368             :                     bool* aOutIsTransformedFixed = nullptr);
     369             : 
     370         413 :   struct ImageLayerClipState {
     371             :     nsRect mBGClipArea;            // Affected by mClippedRadii
     372             :     nsRect mAdditionalBGClipArea;  // Not affected by mClippedRadii
     373             :     nsRect mDirtyRectInAppUnits;
     374             :     gfxRect mDirtyRectInDevPx;
     375             : 
     376             :     nscoord mRadii[8];
     377             :     RectCornerRadii mClippedRadii;
     378             :     bool mHasRoundedCorners;
     379             :     bool mHasAdditionalBGClipArea;
     380             : 
     381             :     // Whether we are being asked to draw with a caller provided background
     382             :     // clipping area. If this is true we also disable rounded corners.
     383             :     bool mCustomClip;
     384             : 
     385         413 :     ImageLayerClipState()
     386         413 :      : mHasRoundedCorners(false),
     387             :        mHasAdditionalBGClipArea(false),
     388         413 :        mCustomClip(false)
     389             :     {
     390         413 :       memset(mRadii, 0, sizeof(nscoord) * 8);
     391         413 :     }
     392             : 
     393             :     bool IsValid() const;
     394             :   };
     395             : 
     396             :   static void
     397             :   GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
     398             :                     nsIFrame* aForFrame, const nsStyleBorder& aBorder,
     399             :                     const nsRect& aBorderArea, const nsRect& aCallerDirtyRect,
     400             :                     bool aWillPaintBorder, nscoord aAppUnitsPerPixel,
     401             :                     /* out */ ImageLayerClipState* aClipState);
     402             : 
     403             :   /**
     404             :    * Render the background for an element using css rendering rules
     405             :    * for backgrounds or mask.
     406             :    */
     407             :   enum {
     408             :     /**
     409             :      * When this flag is passed, the element's nsDisplayBorder will be
     410             :      * painted immediately on top of this background.
     411             :      */
     412             :     PAINTBG_WILL_PAINT_BORDER = 0x01,
     413             :     /**
     414             :      * When this flag is passed, images are synchronously decoded.
     415             :      */
     416             :     PAINTBG_SYNC_DECODE_IMAGES = 0x02,
     417             :     /**
     418             :      * When this flag is passed, painting will go to the screen so we can
     419             :      * take advantage of the fact that it will be clipped to the viewport.
     420             :      */
     421             :     PAINTBG_TO_WINDOW = 0x04,
     422             :     /**
     423             :      * When this flag is passed, painting will read properties of mask-image
     424             :      * style, instead of background-image.
     425             :      */
     426             :     PAINTBG_MASK_IMAGE = 0x08
     427             :   };
     428             : 
     429          59 :   struct PaintBGParams {
     430             :     nsPresContext& presCtx;
     431             :     nsRect dirtyRect;
     432             :     nsRect borderArea;
     433             :     nsIFrame* frame;
     434             :     uint32_t paintFlags;
     435             :     nsRect* bgClipRect = nullptr;
     436             :     int32_t layer;                  // -1 means painting all layers; other
     437             :                                     // value means painting one specific
     438             :                                     // layer only.
     439             :     CompositionOp compositionOp;
     440             :     float opacity;
     441             : 
     442             :     static PaintBGParams ForAllLayers(nsPresContext& aPresCtx,
     443             :                                       const nsRect& aDirtyRect,
     444             :                                       const nsRect& aBorderArea,
     445             :                                       nsIFrame *aFrame,
     446             :                                       uint32_t aPaintFlags,
     447             :                                       float aOpacity = 1.0);
     448             :     static PaintBGParams ForSingleLayer(nsPresContext& aPresCtx,
     449             :                                         const nsRect& aDirtyRect,
     450             :                                         const nsRect& aBorderArea,
     451             :                                         nsIFrame *aFrame,
     452             :                                         uint32_t aPaintFlags,
     453             :                                         int32_t aLayer,
     454             :                                         CompositionOp aCompositionOp  = CompositionOp::OP_OVER,
     455             :                                         float aOpacity = 1.0);
     456             : 
     457             :   private:
     458          59 :     PaintBGParams(nsPresContext& aPresCtx,
     459             :                   const nsRect& aDirtyRect,
     460             :                   const nsRect& aBorderArea,
     461             :                   nsIFrame* aFrame,
     462             :                   uint32_t aPaintFlags,
     463             :                   int32_t aLayer,
     464             :                   CompositionOp aCompositionOp,
     465             :                   float aOpacity)
     466          59 :      : presCtx(aPresCtx),
     467             :        dirtyRect(aDirtyRect),
     468             :        borderArea(aBorderArea),
     469             :        frame(aFrame),
     470             :        paintFlags(aPaintFlags),
     471             :        layer(aLayer),
     472             :        compositionOp(aCompositionOp),
     473          59 :        opacity(aOpacity) {}
     474             :   };
     475             : 
     476             :   static DrawResult PaintStyleImageLayer(const PaintBGParams& aParams,
     477             :                                          gfxContext& aRenderingCtx);
     478             : 
     479             :   /**
     480             :    * Same as |PaintStyleImageLayer|, except using the provided style structs.
     481             :    * This short-circuits the code that ensures that the root element's
     482             :    * {background|mask} is drawn on the canvas.
     483             :    * The aLayer parameter allows you to paint a single layer of the
     484             :    * {background|mask}.
     485             :    * The default value for aLayer, -1, means that all layers will be painted.
     486             :    * The background color will only be painted if the back-most layer is also
     487             :    * being painted and (aParams.paintFlags & PAINTBG_MASK_IMAGE) is false.
     488             :    * aCompositionOp is only respected if a single layer is specified (aLayer != -1).
     489             :    * If all layers are painted, the image layer's blend mode (or the mask
     490             :    * layer's composition mode) will be used.
     491             :    */
     492             :   static DrawResult PaintStyleImageLayerWithSC(const PaintBGParams& aParams,
     493             :                                                gfxContext& aRenderingCtx,
     494             :                                                nsStyleContext *mBackgroundSC,
     495             :                                                const nsStyleBorder& aBorder);
     496             : 
     497             :   static bool CanBuildWebRenderDisplayItemsForStyleImageLayer(LayerManager* aManager,
     498             :                                                               nsPresContext& aPresCtx,
     499             :                                                               nsIFrame *aFrame,
     500             :                                                               const nsStyleBackground* aBackgroundStyle,
     501             :                                                               int32_t aLayer);
     502             :   static DrawResult BuildWebRenderDisplayItemsForStyleImageLayer(const PaintBGParams& aParams,
     503             :                                                                  mozilla::wr::DisplayListBuilder& aBuilder,
     504             :                                                                  const mozilla::layers::StackingContextHelper& aSc,
     505             :                                                                  nsTArray<mozilla::layers::WebRenderParentCommand>& aParentCommands,
     506             :                                                                  mozilla::layers::WebRenderDisplayItemLayer* aLayer,
     507             :                                                                  mozilla::layers::WebRenderLayerManager* aManager,
     508             :                                                                  nsDisplayItem* aItem);
     509             : 
     510             :   static DrawResult BuildWebRenderDisplayItemsForStyleImageLayerWithSC(const PaintBGParams& aParams,
     511             :                                                                        mozilla::wr::DisplayListBuilder& aBuilder,
     512             :                                                                        const mozilla::layers::StackingContextHelper& aSc,
     513             :                                                                        nsTArray<mozilla::layers::WebRenderParentCommand>& aParentCommands,
     514             :                                                                        mozilla::layers::WebRenderDisplayItemLayer* aLayer,
     515             :                                                                        mozilla::layers::WebRenderLayerManager* aManager,
     516             :                                                                        nsDisplayItem* aItem,
     517             :                                                                        nsStyleContext *mBackgroundSC,
     518             :                                                                        const nsStyleBorder& aBorder);
     519             : 
     520             :   /**
     521             :    * Returns the rectangle covered by the given background layer image, taking
     522             :    * into account background positioning, sizing, and repetition, but not
     523             :    * clipping.
     524             :    */
     525             :   static nsRect GetBackgroundLayerRect(nsPresContext* aPresContext,
     526             :                                        nsIFrame* aForFrame,
     527             :                                        const nsRect& aBorderArea,
     528             :                                        const nsRect& aClipRect,
     529             :                                        const nsStyleImageLayers::Layer& aLayer,
     530             :                                        uint32_t aFlags);
     531             : 
     532             :   /**
     533             :    * Called when we start creating a display list. The frame tree will not
     534             :    * change until a matching EndFrameTreeLocked is called.
     535             :    */
     536             :   static void BeginFrameTreesLocked();
     537             :   /**
     538             :    * Called when we've finished using a display list. When all
     539             :    * BeginFrameTreeLocked calls have been balanced by an EndFrameTreeLocked,
     540             :    * the frame tree may start changing again.
     541             :    */
     542             :   static void EndFrameTreesLocked();
     543             : 
     544             :   // Draw a border segment in the table collapsing border model without
     545             :   // beveling corners
     546             :   static void DrawTableBorderSegment(DrawTarget&   aDrawTarget,
     547             :                                      uint8_t       aBorderStyle,
     548             :                                      nscolor       aBorderColor,
     549             :                                      nscolor       aBGColor,
     550             :                                      const nsRect& aBorderRect,
     551             :                                      int32_t       aAppUnitsPerDevPixel,
     552             :                                      int32_t       aAppUnitsPerCSSPixel,
     553             :                                      uint8_t       aStartBevelSide = 0,
     554             :                                      nscoord       aStartBevelOffset = 0,
     555             :                                      uint8_t       aEndBevelSide = 0,
     556             :                                      nscoord       aEndBevelOffset = 0);
     557             : 
     558             :   // NOTE: pt, dirtyRect, lineSize, ascent, offset in the following
     559             :   //       structs are non-rounded device pixels, not app units.
     560           3 :   struct DecorationRectParams
     561             :   {
     562             :     // The width [length] and the height [thickness] of the decoration
     563             :     // line. This is a "logical" size in textRun orientation, so that
     564             :     // for a vertical textrun, width will actually be a physical height;
     565             :     // and conversely, height will be a physical width.
     566             :     Size lineSize;
     567             :     // The ascent of the text.
     568             :     Float ascent = 0.0f;
     569             :     // The offset of the decoration line from the baseline of the text
     570             :     // (if the value is positive, the line is lifted up).
     571             :     Float offset = 0.0f;
     572             :     // If descentLimit is zero or larger and the underline overflows
     573             :     // from the descent space, the underline should be lifted up as far
     574             :     // as possible.  Note that this does not mean the underline never
     575             :     // overflows from this limitation, because if the underline is
     576             :     // positioned to the baseline or upper, it causes unreadability.
     577             :     // Note that if this is zero or larger, the underline rect may be
     578             :     // shrunken if it's possible.  Therefore, this value is used for
     579             :     // strikeout line and overline too.
     580             :     Float descentLimit = -1.0f;
     581             :     // Which line will be painted. The value can be
     582             :     // NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE or
     583             :     // NS_STYLE_TEXT_DECORATION_LINE_OVERLINE or
     584             :     // NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH.
     585             :     uint8_t decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
     586             :     // The style of the decoration line such as
     587             :     // NS_STYLE_TEXT_DECORATION_STYLE_*.
     588             :     uint8_t style = NS_STYLE_TEXT_DECORATION_STYLE_NONE;
     589             :     bool vertical = false;
     590             :   };
     591           3 :   struct PaintDecorationLineParams : DecorationRectParams
     592             :   {
     593             :     // No need to paint outside this rect.
     594             :     Rect dirtyRect;
     595             :     // The top/left edge of the text.
     596             :     Point pt;
     597             :     // The color of the decoration line.
     598             :     nscolor color = NS_RGBA(0, 0, 0, 0);
     599             :     // The distance between the left edge of the given frame and the
     600             :     // position of the text as positioned without offset of the shadow.
     601             :     Float icoordInFrame = 0.0f;
     602             :   };
     603             : 
     604             :   /**
     605             :    * Function for painting the decoration lines for the text.
     606             :    *
     607             :    *   input:
     608             :    *     @param aFrame            the frame which needs the decoration line
     609             :    *     @param aGfxContext
     610             :    */
     611             :   static void PaintDecorationLine(nsIFrame* aFrame, DrawTarget& aDrawTarget,
     612             :                                   const PaintDecorationLineParams& aParams);
     613             : 
     614             :   /**
     615             :    * Returns a Rect corresponding to the outline of the decoration line for the
     616             :    * given text metrics.  Arguments have the same meaning as for
     617             :    * PaintDecorationLine.  Currently this only works for solid
     618             :    * decorations; for other decoration styles the returned Rect will be empty.
     619             :    */
     620             :   static Rect DecorationLineToPath(const PaintDecorationLineParams& aParams);
     621             : 
     622             :   /**
     623             :    * Function for getting the decoration line rect for the text.
     624             :    * NOTE: aLineSize, aAscent and aOffset are non-rounded device pixels,
     625             :    *       not app units.
     626             :    *   input:
     627             :    *     @param aPresContext
     628             :    *   output:
     629             :    *     @return                  the decoration line rect for the input,
     630             :    *                              the each values are app units.
     631             :    */
     632             :   static nsRect GetTextDecorationRect(nsPresContext* aPresContext,
     633             :                                       const DecorationRectParams& aParams);
     634             : 
     635           0 :   static CompositionOp GetGFXBlendMode(uint8_t mBlendMode) {
     636           0 :     switch (mBlendMode) {
     637           0 :       case NS_STYLE_BLEND_NORMAL:      return CompositionOp::OP_OVER;
     638           0 :       case NS_STYLE_BLEND_MULTIPLY:    return CompositionOp::OP_MULTIPLY;
     639           0 :       case NS_STYLE_BLEND_SCREEN:      return CompositionOp::OP_SCREEN;
     640           0 :       case NS_STYLE_BLEND_OVERLAY:     return CompositionOp::OP_OVERLAY;
     641           0 :       case NS_STYLE_BLEND_DARKEN:      return CompositionOp::OP_DARKEN;
     642           0 :       case NS_STYLE_BLEND_LIGHTEN:     return CompositionOp::OP_LIGHTEN;
     643           0 :       case NS_STYLE_BLEND_COLOR_DODGE: return CompositionOp::OP_COLOR_DODGE;
     644           0 :       case NS_STYLE_BLEND_COLOR_BURN:  return CompositionOp::OP_COLOR_BURN;
     645           0 :       case NS_STYLE_BLEND_HARD_LIGHT:  return CompositionOp::OP_HARD_LIGHT;
     646           0 :       case NS_STYLE_BLEND_SOFT_LIGHT:  return CompositionOp::OP_SOFT_LIGHT;
     647           0 :       case NS_STYLE_BLEND_DIFFERENCE:  return CompositionOp::OP_DIFFERENCE;
     648           0 :       case NS_STYLE_BLEND_EXCLUSION:   return CompositionOp::OP_EXCLUSION;
     649           0 :       case NS_STYLE_BLEND_HUE:         return CompositionOp::OP_HUE;
     650           0 :       case NS_STYLE_BLEND_SATURATION:  return CompositionOp::OP_SATURATION;
     651           0 :       case NS_STYLE_BLEND_COLOR:       return CompositionOp::OP_COLOR;
     652           0 :       case NS_STYLE_BLEND_LUMINOSITY:  return CompositionOp::OP_LUMINOSITY;
     653           0 :       default:      MOZ_ASSERT(false); return CompositionOp::OP_OVER;
     654             :     }
     655             :   }
     656             : 
     657           0 :   static CompositionOp GetGFXCompositeMode(uint8_t aCompositeMode) {
     658           0 :     switch (aCompositeMode) {
     659           0 :       case NS_STYLE_MASK_COMPOSITE_ADD:       return CompositionOp::OP_OVER;
     660           0 :       case NS_STYLE_MASK_COMPOSITE_SUBTRACT:  return CompositionOp::OP_OUT;
     661           0 :       case NS_STYLE_MASK_COMPOSITE_INTERSECT: return CompositionOp::OP_IN;
     662           0 :       case NS_STYLE_MASK_COMPOSITE_EXCLUDE:   return CompositionOp::OP_XOR;
     663           0 :       default: MOZ_ASSERT(false);             return CompositionOp::OP_OVER;
     664             :     }
     665             :   }
     666             : protected:
     667             :   static gfxRect GetTextDecorationRectInternal(
     668             :       const Point& aPt, const DecorationRectParams& aParams);
     669             : 
     670             :   /**
     671             :    * Returns inflated rect for painting a decoration line.
     672             :    * Complex style decoration lines should be painted from leftmost of nearest
     673             :    * ancestor block box because that makes better look of connection of lines
     674             :    * for different nodes.  ExpandPaintingRectForDecorationLine() returns
     675             :    * a rect for actual painting rect for the clipped rect.
     676             :    *
     677             :    * input:
     678             :    *     @param aFrame            the frame which needs the decoration line.
     679             :    *     @param aStyle            the style of the complex decoration line
     680             :    *                              NS_STYLE_TEXT_DECORATION_STYLE_DOTTED or
     681             :    *                              NS_STYLE_TEXT_DECORATION_STYLE_DASHED or
     682             :    *                              NS_STYLE_TEXT_DECORATION_STYLE_WAVY.
     683             :    *     @param aClippedRect      the clipped rect for the decoration line.
     684             :    *                              in other words, visible area of the line.
     685             :    *     @param aICoordInFrame  the distance between inline-start edge of aFrame
     686             :    *                              and aClippedRect.pos.
     687             :    *     @param aCycleLength      the width of one cycle of the line style.
     688             :    */
     689             :   static Rect ExpandPaintingRectForDecorationLine(
     690             :                    nsIFrame* aFrame,
     691             :                    const uint8_t aStyle,
     692             :                    const Rect &aClippedRect,
     693             :                    const Float aICoordInFrame,
     694             :                    const Float aCycleLength,
     695             :                    bool aVertical);
     696             : };
     697             : 
     698             : /*
     699             :  * nsContextBoxBlur
     700             :  * Creates an 8-bit alpha channel context for callers to draw in, blurs the
     701             :  * contents of that context and applies it as a 1-color mask on a
     702             :  * different existing context. Uses gfxAlphaBoxBlur as its back end.
     703             :  *
     704             :  * You must call Init() first to create a suitable temporary surface to draw
     705             :  * on.  You must then draw any desired content onto the given context, then
     706             :  * call DoPaint() to apply the blurred content as a single-color mask. You
     707             :  * can only call Init() once, so objects cannot be reused.
     708             :  *
     709             :  * This is very useful for creating drop shadows or silhouettes.
     710             :  */
     711          20 : class nsContextBoxBlur {
     712             :   typedef mozilla::gfx::Color Color;
     713             :   typedef mozilla::gfx::DrawTarget DrawTarget;
     714             :   typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
     715             : 
     716             : public:
     717             :   enum {
     718             :     FORCE_MASK = 0x01
     719             :   };
     720             :   /**
     721             :    * Prepares a gfxContext to draw on. Do not call this twice; if you want
     722             :    * to get the gfxContext again use GetContext().
     723             :    *
     724             :    * @param aRect                The coordinates of the surface to create.
     725             :    *                             All coordinates must be in app units.
     726             :    *                             This must not include the blur radius, pass
     727             :    *                             it as the second parameter and everything
     728             :    *                             is taken care of.
     729             :    *
     730             :    * @param aBlurRadius          The blur radius in app units.
     731             :    *
     732             :    * @param aAppUnitsPerDevPixel The number of app units in a device pixel,
     733             :    *                             for conversion.  Most of the time you'll
     734             :    *                             pass this from the current PresContext if
     735             :    *                             available.
     736             :    *
     737             :    * @param aDestinationCtx      The graphics context to apply the blurred
     738             :    *                             mask to when you call DoPaint(). Make sure
     739             :    *                             it is not destroyed before you call
     740             :    *                             DoPaint(). To set the color of the
     741             :    *                             resulting blurred graphic mask, you must
     742             :    *                             set the color on this context before
     743             :    *                             calling Init().
     744             :    *
     745             :    * @param aDirtyRect           The absolute dirty rect in app units. Used to
     746             :    *                             optimize the temporary surface size and speed up blur.
     747             :    *
     748             :    * @param aSkipRect            An area in device pixels (NOT app units!) to avoid
     749             :    *                             blurring over, to prevent unnecessary work.
     750             :    *
     751             :    * @param aFlags               FORCE_MASK to ensure that the content drawn to the
     752             :    *                             returned gfxContext is used as a mask, and not
     753             :    *                             drawn directly to aDestinationCtx.
     754             :    *
     755             :    * @return            A blank 8-bit alpha-channel-only graphics context to
     756             :    *                    draw on, or null on error. Must not be freed. The
     757             :    *                    context has a device offset applied to it given by
     758             :    *                    aRect. This means you can use coordinates as if it
     759             :    *                    were at the desired position at aRect and you don't
     760             :    *                    need to worry about translating any coordinates to
     761             :    *                    draw on this temporary surface.
     762             :    *
     763             :    * If aBlurRadius is 0, the returned context is aDestinationCtx and
     764             :    * DoPaint() does nothing, because no blurring is required. Therefore, you
     765             :    * should prepare the destination context as if you were going to draw
     766             :    * directly on it instead of any temporary surface created in this class.
     767             :    */
     768             :   gfxContext* Init(const nsRect& aRect, nscoord aSpreadRadius,
     769             :                    nscoord aBlurRadius,
     770             :                    int32_t aAppUnitsPerDevPixel, gfxContext* aDestinationCtx,
     771             :                    const nsRect& aDirtyRect, const gfxRect* aSkipRect,
     772             :                    uint32_t aFlags = 0);
     773             : 
     774             :   /**
     775             :    * Does the actual blurring and mask applying. Users of this object *must*
     776             :    * have called Init() first, then have drawn whatever they want to be
     777             :    * blurred onto the internal gfxContext before calling this.
     778             :    */
     779             :   void DoPaint();
     780             : 
     781             :   /**
     782             :    * Gets the internal gfxContext at any time. Must not be freed. Avoid
     783             :    * calling this before calling Init() since the context would not be
     784             :    * constructed at that point.
     785             :    */
     786             :   gfxContext* GetContext();
     787             : 
     788             : 
     789             :   /**
     790             :    * Get the margin associated with the given blur radius, i.e., the
     791             :    * additional area that might be painted as a result of it.  (The
     792             :    * margin for a spread radius is itself, on all sides.)
     793             :    */
     794             :   static nsMargin GetBlurRadiusMargin(nscoord aBlurRadius,
     795             :                                       int32_t aAppUnitsPerDevPixel);
     796             : 
     797             :   /**
     798             :    * Blurs a coloured rectangle onto aDestinationCtx. This is equivalent
     799             :    * to calling Init(), drawing a rectangle onto the returned surface
     800             :    * and then calling DoPaint, but may let us optimize better in the
     801             :    * backend.
     802             :    *
     803             :    * @param aDestinationCtx      The destination to blur to.
     804             :    * @param aRect                The rectangle to blur in app units.
     805             :    * @param aAppUnitsPerDevPixel The number of app units in a device pixel,
     806             :    *                             for conversion.  Most of the time you'll
     807             :    *                             pass this from the current PresContext if
     808             :    *                             available.
     809             :    * @param aCornerRadii         Corner radii for aRect, if it is a rounded
     810             :    *                             rectangle.
     811             :    * @param aBlurRadius          The blur radius in app units.
     812             :    * @param aShadowColor         The color to draw the blurred shadow.
     813             :    * @param aDirtyRect           The absolute dirty rect in app units. Used to
     814             :    *                             optimize the temporary surface size and speed up blur.
     815             :    * @param aSkipRect            An area in device pixels (NOT app units!) to avoid
     816             :    *                             blurring over, to prevent unnecessary work.
     817             :    */
     818             :   static void BlurRectangle(gfxContext* aDestinationCtx,
     819             :                             const nsRect& aRect,
     820             :                             int32_t aAppUnitsPerDevPixel,
     821             :                             RectCornerRadii* aCornerRadii,
     822             :                             nscoord aBlurRadius,
     823             :                             const Color& aShadowColor,
     824             :                             const nsRect& aDirtyRect,
     825             :                             const gfxRect& aSkipRect);
     826             : 
     827             :   /**
     828             :    * Draws a blurred inset box shadow shape onto the destination surface.
     829             :    * Like BlurRectangle, this is equivalent to calling Init(),
     830             :    * drawing a rectangle onto the returned surface
     831             :    * and then calling DoPaint, but may let us optimize better in the
     832             :    * backend.
     833             :    *
     834             :    * @param aDestinationCtx      The destination to blur to.
     835             :    * @param aDestinationRect     The rectangle to blur in app units.
     836             :    * @param aShadowClipRect      The inside clip rect that creates the path.
     837             :    * @param aShadowColor         The color of the blur
     838             :    * @param aBlurRadiusAppUnits  The blur radius in app units
     839             :    * @param aSpreadRadiusAppUnits The spread radius in app units.
     840             :    * @param aAppUnitsPerDevPixel The number of app units in a device pixel,
     841             :    *                             for conversion.  Most of the time you'll
     842             :    *                             pass this from the current PresContext if
     843             :    *                             available.
     844             :    * @param aHasBorderRadius     If this inset box blur has a border radius
     845             :    * @param aInnerClipRectRadii  The clip rect radii used for the inside rect's path.
     846             :    * @param aSkipRect            An area in device pixels (NOT app units!) to avoid
     847             :    *                             blurring over, to prevent unnecessary work.
     848             :    */
     849             :   bool InsetBoxBlur(gfxContext* aDestinationCtx,
     850             :                     mozilla::gfx::Rect aDestinationRect,
     851             :                     mozilla::gfx::Rect aShadowClipRect,
     852             :                     mozilla::gfx::Color& aShadowColor,
     853             :                     nscoord aBlurRadiusAppUnits,
     854             :                     nscoord aSpreadRadiusAppUnits,
     855             :                     int32_t aAppUnitsPerDevPixel,
     856             :                     bool aHasBorderRadius,
     857             :                     RectCornerRadii& aInnerClipRectRadii,
     858             :                     mozilla::gfx::Rect aSkipRect,
     859             :                     mozilla::gfx::Point aShadowOffset);
     860             : 
     861             : protected:
     862             :   static void GetBlurAndSpreadRadius(DrawTarget* aDestDrawTarget,
     863             :                                      int32_t aAppUnitsPerDevPixel,
     864             :                                      nscoord aBlurRadius,
     865             :                                      nscoord aSpreadRadius,
     866             :                                      mozilla::gfx::IntSize& aOutBlurRadius,
     867             :                                      mozilla::gfx::IntSize& aOutSpreadRadius,
     868             :                                      bool aConstrainSpreadRadius = true);
     869             : 
     870             :   gfxAlphaBoxBlur mAlphaBoxBlur;
     871             :   RefPtr<gfxContext> mContext;
     872             :   gfxContext* mDestinationCtx;
     873             : 
     874             :   /* This is true if the blur already has it's content transformed
     875             :    * by mDestinationCtx's transform */
     876             :   bool mPreTransformed;
     877             : };
     878             : 
     879             : #endif /* nsCSSRendering_h___ */

Generated by: LCOV version 1.13