LCOV - code coverage report
Current view: top level - dom/canvas - CanvasRenderingContext2D.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 244 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 78 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       3             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #ifndef CanvasRenderingContext2D_h
       6             : #define CanvasRenderingContext2D_h
       7             : 
       8             : #include "mozilla/Attributes.h"
       9             : #include <vector>
      10             : #include "nsIDOMCanvasRenderingContext2D.h"
      11             : #include "nsICanvasRenderingContextInternal.h"
      12             : #include "mozilla/RefPtr.h"
      13             : #include "nsColor.h"
      14             : #include "mozilla/dom/HTMLCanvasElement.h"
      15             : #include "mozilla/dom/HTMLVideoElement.h"
      16             : #include "gfxTextRun.h"
      17             : #include "mozilla/ErrorResult.h"
      18             : #include "mozilla/dom/BasicRenderingContext2D.h"
      19             : #include "mozilla/dom/CanvasGradient.h"
      20             : #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
      21             : #include "mozilla/dom/CanvasPattern.h"
      22             : #include "mozilla/gfx/Rect.h"
      23             : #include "mozilla/gfx/2D.h"
      24             : #include "mozilla/UniquePtr.h"
      25             : #include "gfx2DGlue.h"
      26             : #include "imgIEncoder.h"
      27             : #include "nsLayoutUtils.h"
      28             : #include "mozilla/EnumeratedArray.h"
      29             : #include "FilterSupport.h"
      30             : #include "nsSVGEffects.h"
      31             : #include "Layers.h"
      32             : #include "nsBidi.h"
      33             : 
      34             : class nsGlobalWindow;
      35             : class nsXULElement;
      36             : 
      37             : namespace mozilla {
      38             : namespace gl {
      39             : class SourceSurface;
      40             : } // namespace gl
      41             : 
      42             : namespace dom {
      43             : class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap;
      44             : typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap CanvasImageSource;
      45             : class ImageData;
      46             : class StringOrCanvasGradientOrCanvasPattern;
      47             : class OwningStringOrCanvasGradientOrCanvasPattern;
      48             : class TextMetrics;
      49             : class CanvasFilterChainObserver;
      50             : class CanvasPath;
      51             : 
      52             : extern const mozilla::gfx::Float SIGMA_MAX;
      53             : 
      54             : template<typename T> class Optional;
      55             : 
      56             : struct CanvasBidiProcessor;
      57             : class CanvasRenderingContext2DUserData;
      58             : class CanvasDrawObserver;
      59             : class CanvasShutdownObserver;
      60             : 
      61             : /**
      62             :  ** CanvasRenderingContext2D
      63             :  **/
      64             : class CanvasRenderingContext2D final :
      65             :   public nsICanvasRenderingContextInternal,
      66             :   public nsWrapperCache,
      67             :   public BasicRenderingContext2D
      68             : {
      69             :   virtual ~CanvasRenderingContext2D();
      70             : 
      71             : public:
      72             :   explicit CanvasRenderingContext2D(layers::LayersBackend aCompositorBackend);
      73             : 
      74             :   virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
      75             : 
      76           0 :   HTMLCanvasElement* GetCanvas() const
      77             :   {
      78           0 :     if (!mCanvasElement || mCanvasElement->IsInNativeAnonymousSubtree()) {
      79           0 :       return nullptr;
      80             :     }
      81             : 
      82             :     // corresponds to changes to the old bindings made in bug 745025
      83           0 :     return mCanvasElement->GetOriginalCanvas();
      84             :   }
      85             : 
      86             :   void Save() override;
      87             :   void Restore() override;
      88             :   void Scale(double aX, double aY, mozilla::ErrorResult& aError) override;
      89             :   void Rotate(double aAngle, mozilla::ErrorResult& aError) override;
      90             :   void Translate(double aX, double aY, mozilla::ErrorResult& aError) override;
      91             :   void Transform(double aM11, double aM12, double aM21, double aM22,
      92             :                  double aDx, double aDy, mozilla::ErrorResult& aError) override;
      93             :   void SetTransform(double aM11, double aM12, double aM21, double aM22,
      94             :                     double aDx, double aDy, mozilla::ErrorResult& aError) override;
      95             :   void ResetTransform(mozilla::ErrorResult& aError) override;
      96             : 
      97           0 :   double GlobalAlpha() override
      98             :   {
      99           0 :     return CurrentState().globalAlpha;
     100             :   }
     101             : 
     102             :   // Useful for silencing cast warnings
     103           0 :   static mozilla::gfx::Float ToFloat(double aValue) { return mozilla::gfx::Float(aValue); }
     104             : 
     105           0 :   void SetGlobalAlpha(double aGlobalAlpha) override
     106             :   {
     107           0 :     if (aGlobalAlpha >= 0.0 && aGlobalAlpha <= 1.0) {
     108           0 :       CurrentState().globalAlpha = ToFloat(aGlobalAlpha);
     109             :     }
     110           0 :   }
     111             : 
     112             :   void GetGlobalCompositeOperation(nsAString& aOp,
     113             :                                    mozilla::ErrorResult& aError) override;
     114             :   void SetGlobalCompositeOperation(const nsAString& aOp,
     115             :                                    mozilla::ErrorResult& aError) override;
     116             : 
     117             :   void
     118           0 :   GetStrokeStyle(OwningStringOrCanvasGradientOrCanvasPattern& aValue) override
     119             :   {
     120           0 :     GetStyleAsUnion(aValue, Style::STROKE);
     121           0 :   }
     122             : 
     123             :   void
     124           0 :   SetStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& aValue) override
     125             :   {
     126           0 :     SetStyleFromUnion(aValue, Style::STROKE);
     127           0 :   }
     128             : 
     129             :   void
     130           0 :   GetFillStyle(OwningStringOrCanvasGradientOrCanvasPattern& aValue) override
     131             :   {
     132           0 :     GetStyleAsUnion(aValue, Style::FILL);
     133           0 :   }
     134             : 
     135             :   void
     136           0 :   SetFillStyle(const StringOrCanvasGradientOrCanvasPattern& aValue) override
     137             :   {
     138           0 :     SetStyleFromUnion(aValue, Style::FILL);
     139           0 :   }
     140             : 
     141             :   already_AddRefed<CanvasGradient>
     142             :     CreateLinearGradient(double aX0, double aY0, double aX1, double aY1) override;
     143             :   already_AddRefed<CanvasGradient>
     144             :     CreateRadialGradient(double aX0, double aY0, double aR0,
     145             :                          double aX1, double aY1, double aR1,
     146             :                          ErrorResult& aError) override;
     147             :   already_AddRefed<CanvasPattern>
     148             :     CreatePattern(const CanvasImageSource& aElement,
     149             :                   const nsAString& aRepeat, ErrorResult& aError) override;
     150             : 
     151           0 :   double ShadowOffsetX() override
     152             :   {
     153           0 :     return CurrentState().shadowOffset.x;
     154             :   }
     155             : 
     156           0 :   void SetShadowOffsetX(double aShadowOffsetX) override
     157             :   {
     158           0 :     CurrentState().shadowOffset.x = ToFloat(aShadowOffsetX);
     159           0 :   }
     160             : 
     161           0 :   double ShadowOffsetY() override
     162             :   {
     163           0 :     return CurrentState().shadowOffset.y;
     164             :   }
     165             : 
     166           0 :   void SetShadowOffsetY(double aShadowOffsetY) override
     167             :   {
     168           0 :     CurrentState().shadowOffset.y = ToFloat(aShadowOffsetY);
     169           0 :   }
     170             : 
     171           0 :   double ShadowBlur() override
     172             :   {
     173           0 :     return CurrentState().shadowBlur;
     174             :   }
     175             : 
     176           0 :   void SetShadowBlur(double aShadowBlur) override
     177             :   {
     178           0 :     if (aShadowBlur >= 0.0) {
     179           0 :       CurrentState().shadowBlur = ToFloat(aShadowBlur);
     180             :     }
     181           0 :   }
     182             : 
     183           0 :   void GetShadowColor(nsAString& aShadowColor) override
     184             :   {
     185           0 :     StyleColorToString(CurrentState().shadowColor, aShadowColor);
     186           0 :   }
     187             : 
     188           0 :   void GetFilter(nsAString& aFilter)
     189             :   {
     190           0 :     aFilter = CurrentState().filterString;
     191           0 :   }
     192             : 
     193             :   void SetShadowColor(const nsAString& aShadowColor) override;
     194             :   void SetFilter(const nsAString& aFilter, mozilla::ErrorResult& aError);
     195             :   void ClearRect(double aX, double aY, double aW, double aH) override;
     196             :   void FillRect(double aX, double aY, double aW, double aH) override;
     197             :   void StrokeRect(double aX, double aY, double aW, double aH) override;
     198             :   void BeginPath();
     199             :   void Fill(const CanvasWindingRule& aWinding);
     200             :   void Fill(const CanvasPath& aPath, const CanvasWindingRule& aWinding);
     201             :   void Stroke();
     202             :   void Stroke(const CanvasPath& aPath);
     203             :   void DrawFocusIfNeeded(mozilla::dom::Element& aElement, ErrorResult& aRv);
     204             :   bool DrawCustomFocusRing(mozilla::dom::Element& aElement);
     205             :   void Clip(const CanvasWindingRule& aWinding);
     206             :   void Clip(const CanvasPath& aPath, const CanvasWindingRule& aWinding);
     207             :   bool IsPointInPath(double aX, double aY, const CanvasWindingRule& aWinding);
     208             :   bool IsPointInPath(const CanvasPath& aPath, double aX, double aY, const CanvasWindingRule& aWinding);
     209             :   bool IsPointInStroke(double aX, double aY);
     210             :   bool IsPointInStroke(const CanvasPath& aPath, double aX, double aY);
     211             :   void FillText(const nsAString& aText, double aX, double aY,
     212             :                 const Optional<double>& aMaxWidth,
     213             :                 mozilla::ErrorResult& aError);
     214             :   void StrokeText(const nsAString& aText, double aX, double aY,
     215             :                   const Optional<double>& aMaxWidth,
     216             :                   mozilla::ErrorResult& aError);
     217             :   TextMetrics*
     218             :     MeasureText(const nsAString& aRawText, mozilla::ErrorResult& aError);
     219             : 
     220             :   void AddHitRegion(const HitRegionOptions& aOptions, mozilla::ErrorResult& aError);
     221             :   void RemoveHitRegion(const nsAString& aId);
     222             :   void ClearHitRegions();
     223             : 
     224           0 :   void DrawImage(const CanvasImageSource& aImage, double aDx, double aDy,
     225             :                  mozilla::ErrorResult& aError) override
     226             :   {
     227           0 :     DrawImage(aImage, 0.0, 0.0, 0.0, 0.0, aDx, aDy, 0.0, 0.0, 0, aError);
     228           0 :   }
     229             : 
     230           0 :   void DrawImage(const CanvasImageSource& aImage, double aDx, double aDy,
     231             :                  double aDw, double aDh, mozilla::ErrorResult& aError) override
     232             :   {
     233           0 :     DrawImage(aImage, 0.0, 0.0, 0.0, 0.0, aDx, aDy, aDw, aDh, 2, aError);
     234           0 :   }
     235             : 
     236           0 :   void DrawImage(const CanvasImageSource& aImage,
     237             :                  double aSx, double aSy, double aSw, double aSh,
     238             :                  double aDx, double aDy, double aDw, double aDh,
     239             :                  mozilla::ErrorResult& aError) override
     240             :   {
     241           0 :     DrawImage(aImage, aSx, aSy, aSw, aSh, aDx, aDy, aDw, aDh, 6, aError);
     242           0 :   }
     243             : 
     244             :   already_AddRefed<ImageData>
     245             :     CreateImageData(JSContext* aCx, double aSw, double aSh,
     246             :                     mozilla::ErrorResult& aError);
     247             :   already_AddRefed<ImageData>
     248             :     CreateImageData(JSContext* aCx, ImageData& aImagedata,
     249             :                     mozilla::ErrorResult& aError);
     250             :   already_AddRefed<ImageData>
     251             :     GetImageData(JSContext* aCx, double aSx, double aSy, double aSw, double aSh,
     252             :                  mozilla::ErrorResult& aError);
     253             :   void PutImageData(ImageData& aImageData,
     254             :                     double aDx, double aDy, mozilla::ErrorResult& aError);
     255             :   void PutImageData(ImageData& aImageData,
     256             :                     double aDx, double aDy, double aDirtyX, double aDirtyY,
     257             :                     double aDirtyWidth, double aDirtyHeight,
     258             :                     mozilla::ErrorResult& aError);
     259             : 
     260           0 :   double LineWidth() override
     261             :   {
     262           0 :     return CurrentState().lineWidth;
     263             :   }
     264             : 
     265           0 :   void SetLineWidth(double aWidth) override
     266             :   {
     267           0 :     if (aWidth > 0.0) {
     268           0 :       CurrentState().lineWidth = ToFloat(aWidth);
     269             :     }
     270           0 :   }
     271             :   void GetLineCap(nsAString& aLinecapStyle) override;
     272             :   void SetLineCap(const nsAString& aLinecapStyle) override;
     273             :   void GetLineJoin(nsAString& aLinejoinStyle,
     274             :                    mozilla::ErrorResult& aError) override;
     275             :   void SetLineJoin(const nsAString& aLinejoinStyle) override;
     276             : 
     277           0 :   double MiterLimit() override
     278             :   {
     279           0 :     return CurrentState().miterLimit;
     280             :   }
     281             : 
     282           0 :   void SetMiterLimit(double aMiter) override
     283             :   {
     284           0 :     if (aMiter > 0.0) {
     285           0 :       CurrentState().miterLimit = ToFloat(aMiter);
     286             :     }
     287           0 :   }
     288             : 
     289           0 :   void GetFont(nsAString& aFont)
     290             :   {
     291           0 :     aFont = GetFont();
     292           0 :   }
     293             : 
     294             :   void SetFont(const nsAString& aFont, mozilla::ErrorResult& aError);
     295             :   void GetTextAlign(nsAString& aTextAlign);
     296             :   void SetTextAlign(const nsAString& aTextAlign);
     297             :   void GetTextBaseline(nsAString& aTextBaseline);
     298             :   void SetTextBaseline(const nsAString& aTextBaseline);
     299             : 
     300           0 :   void ClosePath() override
     301             :   {
     302           0 :     EnsureWritablePath();
     303             : 
     304           0 :     if (mPathBuilder) {
     305           0 :       mPathBuilder->Close();
     306             :     } else {
     307           0 :       mDSPathBuilder->Close();
     308             :     }
     309           0 :   }
     310             : 
     311           0 :   void MoveTo(double aX, double aY) override
     312             :   {
     313           0 :     EnsureWritablePath();
     314             : 
     315           0 :     if (mPathBuilder) {
     316           0 :       mPathBuilder->MoveTo(mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)));
     317             :     } else {
     318           0 :       mDSPathBuilder->MoveTo(mTarget->GetTransform().TransformPoint(
     319           0 :                              mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))));
     320             :     }
     321           0 :   }
     322             : 
     323           0 :   void LineTo(double aX, double aY) override
     324             :   {
     325           0 :     EnsureWritablePath();
     326             : 
     327           0 :     LineTo(mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)));
     328           0 :   }
     329             : 
     330           0 :   void QuadraticCurveTo(double aCpx, double aCpy, double aX, double aY) override
     331             :   {
     332           0 :     EnsureWritablePath();
     333             : 
     334           0 :     if (mPathBuilder) {
     335           0 :       mPathBuilder->QuadraticBezierTo(mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy)),
     336           0 :                                       mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)));
     337             :     } else {
     338           0 :       mozilla::gfx::Matrix transform = mTarget->GetTransform();
     339           0 :       mDSPathBuilder->QuadraticBezierTo(transform.TransformPoint(
     340           0 :                                           mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy))),
     341           0 :                                         transform.TransformPoint(
     342           0 :                                           mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))));
     343             :     }
     344           0 :   }
     345             : 
     346           0 :   void BezierCurveTo(double aCp1x, double aCp1y, double aCp2x, double aCp2y,
     347             :                      double aX, double aY) override
     348             :   {
     349           0 :     EnsureWritablePath();
     350             : 
     351           0 :     BezierTo(mozilla::gfx::Point(ToFloat(aCp1x), ToFloat(aCp1y)),
     352           0 :              mozilla::gfx::Point(ToFloat(aCp2x), ToFloat(aCp2y)),
     353           0 :              mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)));
     354           0 :   }
     355             : 
     356             :   void ArcTo(double aX1, double aY1, double aX2, double aY2,
     357             :              double aRadius, mozilla::ErrorResult& aError) override;
     358             :   void Rect(double aX, double aY, double aW, double aH) override;
     359             :   void Arc(double aX, double aY, double aRadius, double aStartAngle,
     360             :            double aEndAngle, bool aAnticlockwise,
     361             :            mozilla::ErrorResult& aError) override;
     362             :   void Ellipse(double aX, double aY, double aRadiusX, double aRadiusY,
     363             :                double aRotation, double aStartAngle, double aEndAngle,
     364             :                bool aAnticlockwise, ErrorResult& aError) override;
     365             : 
     366             :   void GetMozCurrentTransform(JSContext* aCx,
     367             :                               JS::MutableHandle<JSObject*> aResult,
     368             :                               mozilla::ErrorResult& aError);
     369             :   void SetMozCurrentTransform(JSContext* aCx,
     370             :                               JS::Handle<JSObject*> aCurrentTransform,
     371             :                               mozilla::ErrorResult& aError);
     372             :   void GetMozCurrentTransformInverse(JSContext* aCx,
     373             :                                      JS::MutableHandle<JSObject*> aResult,
     374             :                                      mozilla::ErrorResult& aError);
     375             :   void SetMozCurrentTransformInverse(JSContext* aCx,
     376             :                                      JS::Handle<JSObject*> aCurrentTransform,
     377             :                                      mozilla::ErrorResult& aError);
     378             :   void GetFillRule(nsAString& aFillRule);
     379             :   void SetFillRule(const nsAString& aFillRule);
     380             : 
     381             :   void SetLineDash(const Sequence<double>& aSegments,
     382             :                    mozilla::ErrorResult& aRv) override;
     383             :   void GetLineDash(nsTArray<double>& aSegments) const override;
     384             : 
     385             :   void SetLineDashOffset(double aOffset) override;
     386             :   double LineDashOffset() const override;
     387             : 
     388           0 :   void GetMozTextStyle(nsAString& aMozTextStyle)
     389             :   {
     390           0 :     GetFont(aMozTextStyle);
     391           0 :   }
     392             : 
     393           0 :   void SetMozTextStyle(const nsAString& aMozTextStyle,
     394             :                        mozilla::ErrorResult& aError)
     395             :   {
     396           0 :     SetFont(aMozTextStyle, aError);
     397           0 :   }
     398             : 
     399           0 :   bool ImageSmoothingEnabled() override
     400             :   {
     401           0 :     return CurrentState().imageSmoothingEnabled;
     402             :   }
     403             : 
     404           0 :   void SetImageSmoothingEnabled(bool aImageSmoothingEnabled) override
     405             :   {
     406           0 :     if (aImageSmoothingEnabled != CurrentState().imageSmoothingEnabled) {
     407           0 :       CurrentState().imageSmoothingEnabled = aImageSmoothingEnabled;
     408             :     }
     409           0 :   }
     410             : 
     411             :   void DrawWindow(nsGlobalWindow& aWindow, double aX, double aY,
     412             :                   double aW, double aH,
     413             :                   const nsAString& aBgColor, uint32_t aFlags,
     414             :                   mozilla::ErrorResult& aError);
     415             : 
     416             :   enum RenderingMode {
     417             :     SoftwareBackendMode,
     418             :     OpenGLBackendMode,
     419             :     DefaultBackendMode
     420             :   };
     421             : 
     422             :   bool SwitchRenderingMode(RenderingMode aRenderingMode);
     423             : 
     424             :   // Eventually this should be deprecated. Keeping for now to keep the binding functional.
     425             :   void Demote();
     426             : 
     427             :   nsresult Redraw();
     428             : 
     429             :   virtual int32_t GetWidth() const override;
     430             :   virtual int32_t GetHeight() const override;
     431           0 :   gfx::IntSize GetSize() const { return gfx::IntSize(mWidth, mHeight); }
     432             : 
     433             :   // nsICanvasRenderingContextInternal
     434             :   /**
     435             :     * Gets the pres shell from either the canvas element or the doc shell
     436             :     */
     437           0 :   virtual nsIPresShell *GetPresShell() override {
     438           0 :     if (mCanvasElement) {
     439           0 :       return mCanvasElement->OwnerDoc()->GetShell();
     440             :     }
     441           0 :     if (mDocShell) {
     442           0 :       return mDocShell->GetPresShell();
     443             :     }
     444           0 :     return nullptr;
     445             :   }
     446             :   NS_IMETHOD SetDimensions(int32_t aWidth, int32_t aHeight) override;
     447             :   NS_IMETHOD InitializeWithDrawTarget(nsIDocShell* aShell,
     448             :                                       NotNull<gfx::DrawTarget*> aTarget) override;
     449             : 
     450             :   NS_IMETHOD GetInputStream(const char* aMimeType,
     451             :                             const char16_t* aEncoderOptions,
     452             :                             nsIInputStream** aStream) override;
     453             : 
     454             :   already_AddRefed<mozilla::gfx::SourceSurface>
     455           0 :   GetSurfaceSnapshot(gfxAlphaType* aOutAlphaType = nullptr) override
     456             :   {
     457           0 :     EnsureTarget();
     458           0 :     if (aOutAlphaType) {
     459           0 :       *aOutAlphaType = (mOpaque ? gfxAlphaType::Opaque : gfxAlphaType::Premult);
     460             :     }
     461           0 :     return mTarget->Snapshot();
     462             :   }
     463             : 
     464             :   virtual void SetIsOpaque(bool aIsOpaque) override;
     465           0 :   bool GetIsOpaque() override { return mOpaque; }
     466             :   NS_IMETHOD Reset() override;
     467             :   already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
     468             :                                          Layer* aOldLayer,
     469             :                                          LayerManager* aManager,
     470             :                                          bool aMirror = false) override;
     471             :   virtual bool ShouldForceInactiveLayer(LayerManager* aManager) override;
     472             :   void MarkContextClean() override;
     473             :   void MarkContextCleanForFrameCapture() override;
     474             :   bool IsContextCleanForFrameCapture() override;
     475             :   NS_IMETHOD SetIsIPC(bool aIsIPC) override;
     476             :   // this rect is in canvas device space
     477             :   void Redraw(const mozilla::gfx::Rect& aR);
     478           0 :   NS_IMETHOD Redraw(const gfxRect& aR) override { Redraw(ToRect(aR)); return NS_OK; }
     479             :   NS_IMETHOD SetContextOptions(JSContext* aCx,
     480             :                                JS::Handle<JS::Value> aOptions,
     481             :                                ErrorResult& aRvForDictionaryInit) override;
     482             : 
     483             :   /**
     484             :    * An abstract base class to be implemented by callers wanting to be notified
     485             :    * that a refresh has occurred. Callers must ensure an observer is removed
     486             :    * before it is destroyed.
     487             :    */
     488             :   virtual void DidRefresh() override;
     489             : 
     490             :   // this rect is in mTarget's current user space
     491             :   void RedrawUser(const gfxRect& aR);
     492             : 
     493             :   // nsISupports interface + CC
     494             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     495             : 
     496           0 :   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(CanvasRenderingContext2D)
     497             : 
     498             :   enum class CanvasMultiGetterType : uint8_t {
     499             :     STRING = 0,
     500             :     PATTERN = 1,
     501             :     GRADIENT = 2
     502             :   };
     503             : 
     504             :   enum class Style : uint8_t {
     505             :     STROKE = 0,
     506             :     FILL,
     507             :     MAX
     508             :   };
     509             : 
     510           0 :   nsINode* GetParentObject()
     511             :   {
     512           0 :     return mCanvasElement;
     513             :   }
     514             : 
     515           0 :   void LineTo(const mozilla::gfx::Point& aPoint)
     516             :   {
     517           0 :     if (mPathBuilder) {
     518           0 :       mPathBuilder->LineTo(aPoint);
     519             :     } else {
     520           0 :       mDSPathBuilder->LineTo(mTarget->GetTransform().TransformPoint(aPoint));
     521             :     }
     522           0 :   }
     523             : 
     524           0 :   void BezierTo(const mozilla::gfx::Point& aCP1,
     525             :                 const mozilla::gfx::Point& aCP2,
     526             :                 const mozilla::gfx::Point& aCP3)
     527             :   {
     528           0 :     if (mPathBuilder) {
     529           0 :       mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
     530             :     } else {
     531           0 :       mozilla::gfx::Matrix transform = mTarget->GetTransform();
     532           0 :       mDSPathBuilder->BezierTo(transform.TransformPoint(aCP1),
     533           0 :                                transform.TransformPoint(aCP2),
     534           0 :                                transform.TransformPoint(aCP3));
     535             :     }
     536           0 :   }
     537             : 
     538             :   friend class CanvasRenderingContext2DUserData;
     539             : 
     540             :   virtual UniquePtr<uint8_t[]> GetImageBuffer(int32_t* aFormat) override;
     541             : 
     542             : 
     543             :   // Given a point, return hit region ID if it exists
     544             :   nsString GetHitRegion(const mozilla::gfx::Point& aPoint) override;
     545             : 
     546             : 
     547             :   // return true and fills in the bound rect if element has a hit region.
     548             :   bool GetHitRegionRect(Element* aElement, nsRect& aRect) override;
     549             : 
     550             :   void OnShutdown();
     551             : 
     552             :   // Check the global setup, as well as the compositor type:
     553             :   bool AllowOpenGLCanvas() const;
     554             : 
     555             : protected:
     556             :   nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
     557             :                              uint32_t aWidth, uint32_t aHeight,
     558             :                              JSObject** aRetval);
     559             : 
     560             :   nsresult PutImageData_explicit(int32_t aX, int32_t aY, uint32_t aW, uint32_t aH,
     561             :                                  dom::Uint8ClampedArray* aArray,
     562             :                                  bool aHasDirtyRect, int32_t aDirtyX, int32_t aDirtyY,
     563             :                                  int32_t aDirtyWidth, int32_t aDirtyHeight);
     564             : 
     565             :   bool CopyBufferProvider(layers::PersistentBufferProvider& aOld,
     566             :                           gfx::DrawTarget& aTarget,
     567             :                           gfx::IntRect aCopyRect);
     568             : 
     569             :   /**
     570             :    * Internal method to complete initialisation, expects mTarget to have been set
     571             :    */
     572             :   nsresult Initialize(int32_t aWidth, int32_t aHeight);
     573             : 
     574             :   nsresult InitializeWithTarget(mozilla::gfx::DrawTarget* aSurface,
     575             :                                 int32_t aWidth, int32_t aHeight);
     576             : 
     577             :   /**
     578             :     * The number of living nsCanvasRenderingContexts.  When this goes down to
     579             :     * 0, we free the premultiply and unpremultiply tables, if they exist.
     580             :     */
     581             :   static uintptr_t sNumLivingContexts;
     582             : 
     583             :   static mozilla::gfx::DrawTarget* sErrorTarget;
     584             : 
     585             :   void SetTransformInternal(const mozilla::gfx::Matrix& aTransform);
     586             : 
     587             :   // Some helpers.  Doesn't modify a color on failure.
     588             :   void SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& aValue,
     589             :                          Style aWhichStyle);
     590             :   void SetStyleFromString(const nsAString& aStr, Style aWhichStyle);
     591             : 
     592           0 :   void SetStyleFromGradient(CanvasGradient& aGradient, Style aWhichStyle)
     593             :   {
     594           0 :     CurrentState().SetGradientStyle(aWhichStyle, &aGradient);
     595           0 :   }
     596             : 
     597           0 :   void SetStyleFromPattern(CanvasPattern& aPattern, Style aWhichStyle)
     598             :   {
     599           0 :     CurrentState().SetPatternStyle(aWhichStyle, &aPattern);
     600           0 :   }
     601             : 
     602             :   void GetStyleAsUnion(OwningStringOrCanvasGradientOrCanvasPattern& aValue,
     603             :                        Style aWhichStyle);
     604             : 
     605             :   // Returns whether a color was successfully parsed.
     606             :   bool ParseColor(const nsAString& aString, nscolor* aColor);
     607             : 
     608             :   static void StyleColorToString(const nscolor& aColor, nsAString& aStr);
     609             : 
     610             :    // Returns whether a filter was successfully parsed.
     611             :   bool ParseFilter(const nsAString& aString,
     612             :                    nsTArray<nsStyleFilter>& aFilterChain,
     613             :                    ErrorResult& aError);
     614             : 
     615             :   // Returns whether the font was successfully updated.
     616             :   bool SetFontInternal(const nsAString& aFont, mozilla::ErrorResult& aError);
     617             : 
     618             : 
     619             :   /**
     620             :    * Creates the error target, if it doesn't exist
     621             :    */
     622             :   static void EnsureErrorTarget();
     623             : 
     624             :   /* This function ensures there is a writable pathbuilder available, this
     625             :    * pathbuilder may be working in user space or in device space or
     626             :    * device space.
     627             :    * After calling this function mPathTransformWillUpdate will be false
     628             :    */
     629             :   void EnsureWritablePath();
     630             : 
     631             :   // Ensures a path in UserSpace is available.
     632             :   void EnsureUserSpacePath(const CanvasWindingRule& aWinding = CanvasWindingRule::Nonzero);
     633             : 
     634             :   /**
     635             :    * Needs to be called before updating the transform. This makes a call to
     636             :    * EnsureTarget() so you don't have to.
     637             :    */
     638             :   void TransformWillUpdate();
     639             : 
     640             :   // Report the fillRule has changed.
     641             :   void FillRuleChanged();
     642             : 
     643             :    /**
     644             :    * Create the backing surfacing, if it doesn't exist. If there is an error
     645             :    * in creating the target then it will put sErrorTarget in place. If there
     646             :    * is in turn an error in creating the sErrorTarget then they would both
     647             :    * be null so IsTargetValid() would still return null.
     648             :    *
     649             :    * Returns the actual rendering mode being used by the created target.
     650             :    */
     651             :   RenderingMode EnsureTarget(const gfx::Rect* aCoveredRect = nullptr,
     652             :                              RenderingMode aRenderMode = RenderingMode::DefaultBackendMode);
     653             : 
     654             :   void RestoreClipsAndTransformToTarget();
     655             : 
     656             :   bool TrySkiaGLTarget(RefPtr<gfx::DrawTarget>& aOutDT,
     657             :                        RefPtr<layers::PersistentBufferProvider>& aOutProvider);
     658             : 
     659             :   bool TrySharedTarget(RefPtr<gfx::DrawTarget>& aOutDT,
     660             :                        RefPtr<layers::PersistentBufferProvider>& aOutProvider);
     661             : 
     662             :   bool TryBasicTarget(RefPtr<gfx::DrawTarget>& aOutDT,
     663             :                       RefPtr<layers::PersistentBufferProvider>& aOutProvider);
     664             : 
     665             :   void RegisterAllocation();
     666             : 
     667             :   void SetInitialState();
     668             : 
     669             :   void SetErrorState();
     670             : 
     671             :   /**
     672             :    * This method is run at the end of the event-loop spin where
     673             :    * ScheduleStableStateCallback was called.
     674             :    *
     675             :    * We use it to unlock resources that need to be locked while drawing.
     676             :    */
     677             :   void OnStableState();
     678             : 
     679             :   /**
     680             :    * Cf. OnStableState.
     681             :    */
     682             :   void ScheduleStableStateCallback();
     683             : 
     684             :   /**
     685             :    * Disposes an old target and prepares to lazily create a new target.
     686             :    */
     687             :   void ClearTarget();
     688             : 
     689             :   /*
     690             :    * Returns the target to the buffer provider. i.e. this will queue a frame for
     691             :    * rendering.
     692             :    */
     693             :   void ReturnTarget(bool aForceReset = false);
     694             : 
     695             :   /**
     696             :    * Check if the target is valid after calling EnsureTarget.
     697             :    */
     698           0 :   bool IsTargetValid() const {
     699           0 :     return !!mTarget && mTarget != sErrorTarget;
     700             :   }
     701             : 
     702             :   /**
     703             :     * Returns the surface format this canvas should be allocated using. Takes
     704             :     * into account mOpaque, platform requirements, etc.
     705             :     */
     706             :   mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
     707             : 
     708             :   /**
     709             :    * Returns true if we know for sure that the pattern for a given style is opaque.
     710             :    * Usefull to know if we can discard the content below in certain situations.
     711             :    */
     712             :   bool PatternIsOpaque(Style aStyle) const;
     713             : 
     714             :   /**
     715             :    * Update CurrentState().filter with the filter description for
     716             :    * CurrentState().filterChain.
     717             :    * Flushes the PresShell, so the world can change if you call this function.
     718             :    */
     719             :   void UpdateFilter();
     720             : 
     721             :   nsLayoutUtils::SurfaceFromElementResult
     722             :     CachedSurfaceFromElement(Element* aElement);
     723             : 
     724             :   void DrawImage(const CanvasImageSource& aImgElt,
     725             :                  double aSx, double aSy, double aSw, double aSh,
     726             :                  double aDx, double aDy, double aDw, double aDh,
     727             :                  uint8_t aOptional_argc, mozilla::ErrorResult& aError);
     728             : 
     729             :   void DrawDirectlyToCanvas(const nsLayoutUtils::DirectDrawInfo& aImage,
     730             :                             mozilla::gfx::Rect* aBounds,
     731             :                             mozilla::gfx::Rect aDest,
     732             :                             mozilla::gfx::Rect aSrc,
     733             :                             gfx::IntSize aImgSize);
     734             : 
     735           0 :   nsString& GetFont()
     736             :   {
     737             :     /* will initilize the value if not set, else does nothing */
     738           0 :     GetCurrentFontStyle();
     739             : 
     740           0 :     return CurrentState().font;
     741             :   }
     742             : 
     743             :   // This function maintains a list of raw pointers to cycle-collected
     744             :   // objects. We need to ensure that no entries persist beyond unlink,
     745             :   // since the objects are logically destructed at that point.
     746             :   static std::vector<CanvasRenderingContext2D*>& DemotableContexts();
     747             :   static void DemoteOldestContextIfNecessary();
     748             : 
     749             :   static void AddDemotableContext(CanvasRenderingContext2D* aContext);
     750             :   static void RemoveDemotableContext(CanvasRenderingContext2D* aContext);
     751             : 
     752             :   RenderingMode mRenderingMode;
     753             : 
     754             :   layers::LayersBackend mCompositorBackend;
     755             : 
     756             :   // Member vars
     757             :   int32_t mWidth, mHeight;
     758             : 
     759             :   // This is true when the canvas is valid, but of zero size, this requires
     760             :   // specific behavior on some operations.
     761             :   bool mZero;
     762             : 
     763             :   bool mOpaque;
     764             : 
     765             :   // This is true when the next time our layer is retrieved we need to
     766             :   // recreate it (i.e. our backing surface changed)
     767             :   bool mResetLayer;
     768             :   // This is needed for drawing in drawAsyncXULElement
     769             :   bool mIPC;
     770             :   // True if the current DrawTarget is using skia-gl, used so we can avoid
     771             :   // requesting the DT from mBufferProvider to check.
     772             :   bool mIsSkiaGL;
     773             : 
     774             :   bool mHasPendingStableStateCallback;
     775             : 
     776             :   nsTArray<CanvasRenderingContext2DUserData*> mUserDatas;
     777             : 
     778             :   // If mCanvasElement is not provided, then a docshell is
     779             :   nsCOMPtr<nsIDocShell> mDocShell;
     780             : 
     781             :   // This is created lazily so it is necessary to call EnsureTarget before
     782             :   // accessing it. In the event of an error it will be equal to
     783             :   // sErrorTarget.
     784             :   RefPtr<mozilla::gfx::DrawTarget> mTarget;
     785             : 
     786             :   RefPtr<mozilla::layers::PersistentBufferProvider> mBufferProvider;
     787             : 
     788             :   uint32_t SkiaGLTex() const;
     789             : 
     790             :   // This observes our draw calls at the beginning of the canvas
     791             :   // lifetime and switches to software or GPU mode depending on
     792             :   // what it thinks is best
     793             :   CanvasDrawObserver* mDrawObserver;
     794             :   void RemoveDrawObserver();
     795             : 
     796             :   RefPtr<CanvasShutdownObserver> mShutdownObserver;
     797             :   void RemoveShutdownObserver();
     798           0 :   bool AlreadyShutDown() const { return !mShutdownObserver; }
     799             : 
     800             :   /**
     801             :     * Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
     802             :     * Redraw is called, reset to false when Render is called.
     803             :     */
     804             :   bool mIsEntireFrameInvalid;
     805             :   /**
     806             :     * When this is set, the first call to Redraw(gfxRect) should set
     807             :     * mIsEntireFrameInvalid since we expect it will be followed by
     808             :     * many more Redraw calls.
     809             :     */
     810             :   bool mPredictManyRedrawCalls;
     811             : 
     812             :   /**
     813             :    * Flag to avoid unnecessary surface copies to FrameCaptureListeners in the
     814             :    * case when the canvas is not currently being drawn into and not rendered
     815             :    * but canvas capturing is still ongoing.
     816             :    */
     817             :   bool mIsCapturedFrameInvalid;
     818             : 
     819             :   /**
     820             :     * We also have a device space pathbuilder. The reason for this is as
     821             :     * follows, when a path is being built, but the transform changes, we
     822             :     * can no longer keep a single path in userspace, considering there's
     823             :     * several 'user spaces' now. We therefore transform the current path
     824             :     * into device space, and add all operations to this path in device
     825             :     * space.
     826             :     *
     827             :     * When then finally executing a render, the Azure drawing API expects
     828             :     * the path to be in userspace. We could then set an identity transform
     829             :     * on the DrawTarget and do all drawing in device space. This is
     830             :     * undesirable because it requires transforming patterns, gradients,
     831             :     * clips, etc. into device space and it would not work for stroking.
     832             :     * What we do instead is convert the path back to user space when it is
     833             :     * drawn, and draw it with the current transform. This makes all drawing
     834             :     * occur correctly.
     835             :     *
     836             :     * There's never both a device space path builder and a user space path
     837             :     * builder present at the same time. There is also never a path and a
     838             :     * path builder present at the same time. When writing proceeds on an
     839             :     * existing path the Path is cleared and a new builder is created.
     840             :     *
     841             :     * mPath is always in user-space.
     842             :     */
     843             :   RefPtr<mozilla::gfx::Path> mPath;
     844             :   RefPtr<mozilla::gfx::PathBuilder> mDSPathBuilder;
     845             :   RefPtr<mozilla::gfx::PathBuilder> mPathBuilder;
     846             :   bool mPathTransformWillUpdate;
     847             :   mozilla::gfx::Matrix mPathToDS;
     848             : 
     849             :   /**
     850             :     * Number of times we've invalidated before calling redraw
     851             :     */
     852             :   uint32_t mInvalidateCount;
     853             :   static const uint32_t kCanvasMaxInvalidateCount = 100;
     854             : 
     855             :   /**
     856             :     * State information for hit regions
     857             :     */
     858           0 :   struct RegionInfo
     859             :   {
     860             :     nsString          mId;
     861             :     // fallback element for a11y
     862             :     RefPtr<Element> mElement;
     863             :     // Path of the hit region in the 2d context coordinate space (not user space)
     864             :     RefPtr<gfx::Path> mPath;
     865             :   };
     866             : 
     867             :   nsTArray<RegionInfo> mHitRegionsOptions;
     868             : 
     869             :   nsBidi mBidiEngine;
     870             : 
     871             :   /**
     872             :     * Returns true if a shadow should be drawn along with a
     873             :     * drawing operation.
     874             :     */
     875           0 :   bool NeedToDrawShadow()
     876             :   {
     877           0 :     const ContextState& state = CurrentState();
     878             : 
     879             :     // The spec says we should not draw shadows if the operator is OVER.
     880             :     // If it's over and the alpha value is zero, nothing needs to be drawn.
     881           0 :     return NS_GET_A(state.shadowColor) != 0 &&
     882           0 :       (state.shadowBlur != 0.f || state.shadowOffset.x != 0.f || state.shadowOffset.y != 0.f);
     883             :   }
     884             : 
     885             :   /**
     886             :     * Returns true if the result of a drawing operation should be
     887             :     * drawn with a filter.
     888             :     */
     889           0 :   bool NeedToApplyFilter()
     890             :   {
     891           0 :     return EnsureUpdatedFilter().mPrimitives.Length() > 0;
     892             :   }
     893             : 
     894             :   /**
     895             :    * Calls UpdateFilter if the canvas's WriteOnly state has changed between the
     896             :    * last call to UpdateFilter and now.
     897             :    */
     898           0 :   const gfx::FilterDescription& EnsureUpdatedFilter() {
     899           0 :     bool isWriteOnly = mCanvasElement && mCanvasElement->IsWriteOnly();
     900           0 :     if (CurrentState().filterSourceGraphicTainted != isWriteOnly) {
     901           0 :       UpdateFilter();
     902           0 :       EnsureTarget();
     903             :     }
     904           0 :     MOZ_ASSERT(CurrentState().filterSourceGraphicTainted == isWriteOnly);
     905           0 :     return CurrentState().filter;
     906             :   }
     907             : 
     908           0 :   bool NeedToCalculateBounds()
     909             :   {
     910           0 :     return NeedToDrawShadow() || NeedToApplyFilter();
     911             :   }
     912             : 
     913           0 :   mozilla::gfx::CompositionOp UsedOperation()
     914             :   {
     915           0 :     if (NeedToDrawShadow() || NeedToApplyFilter()) {
     916             :       // In this case the shadow or filter rendering will use the operator.
     917           0 :       return mozilla::gfx::CompositionOp::OP_OVER;
     918             :     }
     919             : 
     920           0 :     return CurrentState().op;
     921             :   }
     922             : 
     923             :   // text
     924             : 
     925             : protected:
     926             :   enum class TextAlign : uint8_t {
     927             :     START,
     928             :     END,
     929             :     LEFT,
     930             :     RIGHT,
     931             :     CENTER
     932             :   };
     933             : 
     934             :   enum class TextBaseline : uint8_t {
     935             :     TOP,
     936             :     HANGING,
     937             :     MIDDLE,
     938             :     ALPHABETIC,
     939             :     IDEOGRAPHIC,
     940             :     BOTTOM
     941             :   };
     942             : 
     943             :   enum class TextDrawOperation : uint8_t {
     944             :     FILL,
     945             :     STROKE,
     946             :     MEASURE
     947             :   };
     948             : 
     949             : protected:
     950             :   gfxFontGroup *GetCurrentFontStyle();
     951             : 
     952             :   /**
     953             :    * Implementation of the fillText, strokeText, and measure functions with
     954             :    * the operation abstracted to a flag.
     955             :    */
     956             :   nsresult DrawOrMeasureText(const nsAString& aText,
     957             :                              float aX,
     958             :                              float aY,
     959             :                              const Optional<double>& aMaxWidth,
     960             :                              TextDrawOperation aOp,
     961             :                              float* aWidth);
     962             : 
     963             :   bool CheckSizeForSkiaGL(mozilla::gfx::IntSize aSize);
     964             : 
     965             :   // A clip or a transform, recorded and restored in order.
     966           0 :   struct ClipState {
     967           0 :     explicit ClipState(mozilla::gfx::Path* aClip)
     968           0 :       : clip(aClip)
     969           0 :     {}
     970             : 
     971           0 :     explicit ClipState(const mozilla::gfx::Matrix& aTransform)
     972           0 :       : transform(aTransform)
     973           0 :     {}
     974             : 
     975           0 :     bool IsClip() const { return !!clip; }
     976             : 
     977             :     RefPtr<mozilla::gfx::Path> clip;
     978             :     mozilla::gfx::Matrix transform;
     979             :   };
     980             : 
     981             :   // state stack handling
     982           0 :   class ContextState {
     983             :   public:
     984           0 :     ContextState() : textAlign(TextAlign::START),
     985             :                      textBaseline(TextBaseline::ALPHABETIC),
     986             :                      shadowColor(0),
     987             :                      lineWidth(1.0f),
     988             :                      miterLimit(10.0f),
     989             :                      globalAlpha(1.0f),
     990             :                      shadowBlur(0.0),
     991             :                      dashOffset(0.0f),
     992             :                      op(mozilla::gfx::CompositionOp::OP_OVER),
     993             :                      fillRule(mozilla::gfx::FillRule::FILL_WINDING),
     994             :                      lineCap(mozilla::gfx::CapStyle::BUTT),
     995             :                      lineJoin(mozilla::gfx::JoinStyle::MITER_OR_BEVEL),
     996             :                      filterString(u"none"),
     997             :                      filterSourceGraphicTainted(false),
     998             :                      imageSmoothingEnabled(true),
     999           0 :                      fontExplicitLanguage(false)
    1000           0 :     { }
    1001             : 
    1002           0 :     ContextState(const ContextState& aOther)
    1003           0 :         : fontGroup(aOther.fontGroup),
    1004             :           fontLanguage(aOther.fontLanguage),
    1005             :           fontFont(aOther.fontFont),
    1006             :           gradientStyles(aOther.gradientStyles),
    1007             :           patternStyles(aOther.patternStyles),
    1008             :           colorStyles(aOther.colorStyles),
    1009             :           font(aOther.font),
    1010           0 :           textAlign(aOther.textAlign),
    1011           0 :           textBaseline(aOther.textBaseline),
    1012           0 :           shadowColor(aOther.shadowColor),
    1013             :           transform(aOther.transform),
    1014             :           shadowOffset(aOther.shadowOffset),
    1015           0 :           lineWidth(aOther.lineWidth),
    1016           0 :           miterLimit(aOther.miterLimit),
    1017           0 :           globalAlpha(aOther.globalAlpha),
    1018           0 :           shadowBlur(aOther.shadowBlur),
    1019             :           dash(aOther.dash),
    1020           0 :           dashOffset(aOther.dashOffset),
    1021           0 :           op(aOther.op),
    1022           0 :           fillRule(aOther.fillRule),
    1023           0 :           lineCap(aOther.lineCap),
    1024           0 :           lineJoin(aOther.lineJoin),
    1025             :           filterString(aOther.filterString),
    1026             :           filterChain(aOther.filterChain),
    1027             :           filterChainObserver(aOther.filterChainObserver),
    1028             :           filter(aOther.filter),
    1029             :           filterAdditionalImages(aOther.filterAdditionalImages),
    1030           0 :           filterSourceGraphicTainted(aOther.filterSourceGraphicTainted),
    1031           0 :           imageSmoothingEnabled(aOther.imageSmoothingEnabled),
    1032           0 :           fontExplicitLanguage(aOther.fontExplicitLanguage)
    1033           0 :     { }
    1034             : 
    1035           0 :     void SetColorStyle(Style aWhichStyle, nscolor aColor)
    1036             :     {
    1037           0 :       colorStyles[aWhichStyle] = aColor;
    1038           0 :       gradientStyles[aWhichStyle] = nullptr;
    1039           0 :       patternStyles[aWhichStyle] = nullptr;
    1040           0 :     }
    1041             : 
    1042           0 :     void SetPatternStyle(Style aWhichStyle, CanvasPattern* aPat)
    1043             :     {
    1044           0 :       gradientStyles[aWhichStyle] = nullptr;
    1045           0 :       patternStyles[aWhichStyle] = aPat;
    1046           0 :     }
    1047             : 
    1048           0 :     void SetGradientStyle(Style aWhichStyle, CanvasGradient* aGrad)
    1049             :     {
    1050           0 :       gradientStyles[aWhichStyle] = aGrad;
    1051           0 :       patternStyles[aWhichStyle] = nullptr;
    1052           0 :     }
    1053             : 
    1054             :     /**
    1055             :       * returns true iff the given style is a solid color.
    1056             :       */
    1057           0 :     bool StyleIsColor(Style aWhichStyle) const
    1058             :     {
    1059           0 :       return !(patternStyles[aWhichStyle] || gradientStyles[aWhichStyle]);
    1060             :     }
    1061             : 
    1062           0 :     int32_t ShadowBlurRadius() const
    1063             :     {
    1064             :       static const gfxFloat GAUSSIAN_SCALE_FACTOR = (3 * sqrt(2 * M_PI) / 4) * 1.5;
    1065           0 :       return (int32_t)floor(ShadowBlurSigma() * GAUSSIAN_SCALE_FACTOR + 0.5);
    1066             :     }
    1067             : 
    1068           0 :     mozilla::gfx::Float ShadowBlurSigma() const
    1069             :     {
    1070           0 :       return std::min(SIGMA_MAX, shadowBlur / 2.0f);
    1071             :     }
    1072             : 
    1073             :     nsTArray<ClipState> clipsAndTransforms;
    1074             : 
    1075             :     RefPtr<gfxFontGroup> fontGroup;
    1076             :     nsCOMPtr<nsIAtom> fontLanguage;
    1077             :     nsFont fontFont;
    1078             : 
    1079             :     EnumeratedArray<Style, Style::MAX, RefPtr<CanvasGradient>> gradientStyles;
    1080             :     EnumeratedArray<Style, Style::MAX, RefPtr<CanvasPattern>> patternStyles;
    1081             :     EnumeratedArray<Style, Style::MAX, nscolor> colorStyles;
    1082             : 
    1083             :     nsString font;
    1084             :     TextAlign textAlign;
    1085             :     TextBaseline textBaseline;
    1086             : 
    1087             :     nscolor shadowColor;
    1088             : 
    1089             :     mozilla::gfx::Matrix transform;
    1090             :     mozilla::gfx::Point shadowOffset;
    1091             :     mozilla::gfx::Float lineWidth;
    1092             :     mozilla::gfx::Float miterLimit;
    1093             :     mozilla::gfx::Float globalAlpha;
    1094             :     mozilla::gfx::Float shadowBlur;
    1095             :     nsTArray<mozilla::gfx::Float> dash;
    1096             :     mozilla::gfx::Float dashOffset;
    1097             : 
    1098             :     mozilla::gfx::CompositionOp op;
    1099             :     mozilla::gfx::FillRule fillRule;
    1100             :     mozilla::gfx::CapStyle lineCap;
    1101             :     mozilla::gfx::JoinStyle lineJoin;
    1102             : 
    1103             :     nsString filterString;
    1104             :     nsTArray<nsStyleFilter> filterChain;
    1105             :     RefPtr<nsSVGFilterChainObserver> filterChainObserver;
    1106             :     mozilla::gfx::FilterDescription filter;
    1107             :     nsTArray<RefPtr<mozilla::gfx::SourceSurface>> filterAdditionalImages;
    1108             : 
    1109             :     // This keeps track of whether the canvas was "tainted" or not when
    1110             :     // we last used a filter. This is a security measure, whereby the
    1111             :     // canvas is flipped to write-only if a cross-origin image is drawn to it.
    1112             :     // This is to stop bad actors from reading back data they shouldn't have
    1113             :     // access to.
    1114             :     //
    1115             :     // This also limits what filters we can apply to the context; in particular
    1116             :     // feDisplacementMap is restricted.
    1117             :     //
    1118             :     // We keep track of this to ensure that if this gets out of sync with the
    1119             :     // tainted state of the canvas itself, we update our filters accordingly.
    1120             :     bool filterSourceGraphicTainted;
    1121             : 
    1122             :     bool imageSmoothingEnabled;
    1123             :     bool fontExplicitLanguage;
    1124             :   };
    1125             : 
    1126             :   AutoTArray<ContextState, 3> mStyleStack;
    1127             : 
    1128           0 :   inline ContextState& CurrentState() {
    1129           0 :     return mStyleStack[mStyleStack.Length() - 1];
    1130             :   }
    1131             : 
    1132           0 :   inline const ContextState& CurrentState() const {
    1133           0 :     return mStyleStack[mStyleStack.Length() - 1];
    1134             :   }
    1135             : 
    1136             :   friend class CanvasGeneralPattern;
    1137             :   friend class CanvasFilterChainObserver;
    1138             :   friend class AdjustedTarget;
    1139             :   friend class AdjustedTargetForShadow;
    1140             :   friend class AdjustedTargetForFilter;
    1141             : 
    1142             :   // other helpers
    1143           0 :   void GetAppUnitsValues(int32_t* aPerDevPixel, int32_t* aPerCSSPixel)
    1144             :   {
    1145             :     // If we don't have a canvas element, we just return something generic.
    1146           0 :     int32_t devPixel = 60;
    1147           0 :     int32_t cssPixel = 60;
    1148             : 
    1149           0 :     nsIPresShell *ps = GetPresShell();
    1150             :     nsPresContext *pc;
    1151             : 
    1152           0 :     if (!ps) goto FINISH;
    1153           0 :     pc = ps->GetPresContext();
    1154           0 :     if (!pc) goto FINISH;
    1155           0 :     devPixel = pc->AppUnitsPerDevPixel();
    1156           0 :     cssPixel = pc->AppUnitsPerCSSPixel();
    1157             : 
    1158             :   FINISH:
    1159           0 :     if (aPerDevPixel)
    1160           0 :       *aPerDevPixel = devPixel;
    1161           0 :     if (aPerCSSPixel)
    1162           0 :       *aPerCSSPixel = cssPixel;
    1163           0 :   }
    1164             : 
    1165             :   friend struct CanvasBidiProcessor;
    1166             :   friend class CanvasDrawObserver;
    1167             : };
    1168             : 
    1169             : } // namespace dom
    1170             : } // namespace mozilla
    1171             : 
    1172             : #endif /* CanvasRenderingContext2D_h */

Generated by: LCOV version 1.13