--- a/dom/canvas/BasicRenderingContext2D.cpp
+++ b/dom/canvas/BasicRenderingContext2D.cpp
@@ -1,30 +1,103 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/BasicRenderingContext2D.h"
+#include "mozilla/dom/HTMLCanvasElement.h"
+#include "mozilla/dom/HTMLImageElement.h"
+#include "mozilla/dom/HTMLVideoElement.h"
+#include "mozilla/dom/ImageBitmap.h"
+#include "nsContentUtils.h"
+#include "nsICanvasRenderingContextInternal.h"
+#include "nsPrintfCString.h"
+#include "nsStyleUtil.h"
+
+using mozilla::gfx::SourceSurface;
namespace mozilla {
namespace dom{
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasGradient, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasGradient, Release)
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasGradient, mContext)
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPattern, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPattern, Release)
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasPattern, mContext)
+
+
// Cap sigma to avoid overly large temp surfaces.
const mozilla::gfx::Float SIGMA_MAX = 100;
const size_t MAX_STYLE_STACK_SIZE = 1024;
/**
** BasicRenderingContext2D impl
**/
+void
+BasicRenderingContext2D::GetStyleAsUnion(OwningStringOrCanvasGradientOrCanvasPattern& aValue,
+ Style aWhichStyle)
+{
+ const ContextState &state = CurrentState();
+ if (state.patternStyles[aWhichStyle]) {
+ aValue.SetAsCanvasPattern() = state.patternStyles[aWhichStyle];
+ } else if (state.gradientStyles[aWhichStyle]) {
+ aValue.SetAsCanvasGradient() = state.gradientStyles[aWhichStyle];
+ } else {
+ StyleColorToString(state.colorStyles[aWhichStyle], aValue.SetAsString());
+ }
+}
+
+void
+BasicRenderingContext2D::SetStyleFromString(const nsAString& aStr,
+ Style aWhichStyle)
+{
+ MOZ_ASSERT(!aStr.IsVoid());
+
+ nscolor color;
+ if (!ParseColor(aStr, &color)) {
+ return;
+ }
+
+ CurrentState().SetColorStyle(aWhichStyle, color);
+}
+
+// static
+void
+BasicRenderingContext2D::StyleColorToString(const nscolor& aColor, nsAString& aStr)
+{
+ // We can't reuse the normal CSS color stringification code,
+ // because the spec calls for a different algorithm for canvas.
+ if (NS_GET_A(aColor) == 255) {
+ CopyUTF8toUTF16(nsPrintfCString("#%02x%02x%02x",
+ NS_GET_R(aColor),
+ NS_GET_G(aColor),
+ NS_GET_B(aColor)),
+ aStr);
+ } else {
+ CopyUTF8toUTF16(nsPrintfCString("rgba(%d, %d, %d, ",
+ NS_GET_R(aColor),
+ NS_GET_G(aColor),
+ NS_GET_B(aColor)),
+ aStr);
+ aStr.AppendFloat(nsStyleUtil::ColorComponentToFloat(NS_GET_A(aColor)));
+ aStr.Append(')');
+ }
+}
+
//
// state
//
+
void
BasicRenderingContext2D::Save()
{
EnsureTarget();
mStyleStack[mStyleStack.Length() - 1].transform = mTarget->GetTransform();
mStyleStack.SetCapacity(mStyleStack.Length() + 1);
mStyleStack.AppendElement(CurrentState());
@@ -245,18 +318,184 @@ BasicRenderingContext2D::GetGlobalCompos
else {
aError.Throw(NS_ERROR_FAILURE);
}
#undef CANVAS_OP_TO_GFX_OP
}
//
+// gradients and patterns
+//
+
+already_AddRefed<CanvasGradient>
+BasicRenderingContext2D::CreateLinearGradient(double aX0, double aY0, double aX1, double aY1)
+{
+ RefPtr<CanvasGradient> grad =
+ new CanvasLinearGradient(this, Point(aX0, aY0), Point(aX1, aY1));
+
+ return grad.forget();
+}
+
+already_AddRefed<CanvasGradient>
+BasicRenderingContext2D::CreateRadialGradient(double aX0, double aY0, double aR0,
+ double aX1, double aY1, double aR1,
+ ErrorResult& aError)
+{
+ if (aR0 < 0.0 || aR1 < 0.0) {
+ aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+ return nullptr;
+ }
+
+ RefPtr<CanvasGradient> grad =
+ new CanvasRadialGradient(this, Point(aX0, aY0), aR0, Point(aX1, aY1), aR1);
+
+ return grad.forget();
+}
+
+already_AddRefed<CanvasPattern>
+BasicRenderingContext2D::CreatePattern(const CanvasImageSource& aSource,
+ const nsAString& aRepeat,
+ ErrorResult& aError)
+{
+ CanvasPattern::RepeatMode repeatMode =
+ CanvasPattern::RepeatMode::NOREPEAT;
+
+ if (aRepeat.IsEmpty() || aRepeat.EqualsLiteral("repeat")) {
+ repeatMode = CanvasPattern::RepeatMode::REPEAT;
+ } else if (aRepeat.EqualsLiteral("repeat-x")) {
+ repeatMode = CanvasPattern::RepeatMode::REPEATX;
+ } else if (aRepeat.EqualsLiteral("repeat-y")) {
+ repeatMode = CanvasPattern::RepeatMode::REPEATY;
+ } else if (aRepeat.EqualsLiteral("no-repeat")) {
+ repeatMode = CanvasPattern::RepeatMode::NOREPEAT;
+ } else {
+ aError.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+ return nullptr;
+ }
+
+ Element* htmlElement;
+ if (aSource.IsHTMLCanvasElement()) {
+ HTMLCanvasElement* canvas = &aSource.GetAsHTMLCanvasElement();
+ htmlElement = canvas;
+
+ nsIntSize size = canvas->GetSize();
+ if (size.width == 0 || size.height == 0) {
+ aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+ return nullptr;
+ }
+
+ // Special case for Canvas, which could be an Azure canvas!
+ nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
+ if (srcCanvas) {
+ // This might not be an Azure canvas!
+ RefPtr<SourceSurface> srcSurf = srcCanvas->GetSurfaceSnapshot();
+ if (!srcSurf) {
+ JSContext* context = nsContentUtils::GetCurrentJSContext();
+ if (context) {
+ JS_ReportWarningASCII(context,
+ "CanvasRenderingContext2D.createPattern()"
+ " failed to snapshot source canvas.");
+ }
+ aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+ return nullptr;
+ }
+
+ RefPtr<CanvasPattern> pat =
+ new CanvasPattern(this, srcSurf, repeatMode,
+ htmlElement->NodePrincipal(),
+ canvas->IsWriteOnly(), false);
+
+ return pat.forget();
+ }
+ } else if (aSource.IsHTMLImageElement()) {
+ HTMLImageElement* img = &aSource.GetAsHTMLImageElement();
+ if (img->IntrinsicState().HasState(NS_EVENT_STATE_BROKEN)) {
+ aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+ return nullptr;
+ }
+
+ htmlElement = img;
+ } else if (aSource.IsHTMLVideoElement()) {
+ auto& video = aSource.GetAsHTMLVideoElement();
+ video.MarkAsContentSource(mozilla::dom::HTMLVideoElement::CallerAPI::CREATE_PATTERN);
+ htmlElement = &video;
+ } else {
+ // Special case for ImageBitmap
+ ImageBitmap& imgBitmap = aSource.GetAsImageBitmap();
+ EnsureTarget();
+ RefPtr<SourceSurface> srcSurf = imgBitmap.PrepareForDrawTarget(mTarget);
+ if (!srcSurf) {
+ JSContext* context = nsContentUtils::GetCurrentJSContext();
+ if (context) {
+ JS_ReportWarningASCII(context,
+ "CanvasRenderingContext2D.createPattern()"
+ " failed to prepare source ImageBitmap.");
+ }
+ aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+ return nullptr;
+ }
+
+ // An ImageBitmap never taints others so we set principalForSecurityCheck to
+ // nullptr and set CORSUsed to true for passing the security check in
+ // CanvasUtils::DoDrawImageSecurityCheck().
+ RefPtr<CanvasPattern> pat =
+ new CanvasPattern(this, srcSurf, repeatMode, nullptr, false, true);
+
+ return pat.forget();
+ }
+
+ EnsureTarget();
+
+ // The canvas spec says that createPattern should use the first frame
+ // of animated images
+ nsLayoutUtils::SurfaceFromElementResult res =
+ nsLayoutUtils::SurfaceFromElement(htmlElement,
+ nsLayoutUtils::SFE_WANT_FIRST_FRAME, mTarget);
+
+ if (!res.GetSourceSurface()) {
+ return nullptr;
+ }
+
+ RefPtr<CanvasPattern> pat = new CanvasPattern(this, res.GetSourceSurface(), repeatMode,
+ res.mPrincipal, res.mIsWriteOnly,
+ res.mCORSUsed);
+ return pat.forget();
+}
+
+//
+// colors
+//
+
+void
+BasicRenderingContext2D::SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& aValue,
+ Style aWhichStyle)
+{
+ if (aValue.IsString()) {
+ SetStyleFromString(aValue.GetAsString(), aWhichStyle);
+ return;
+ }
+
+ if (aValue.IsCanvasGradient()) {
+ SetStyleFromGradient(aValue.GetAsCanvasGradient(), aWhichStyle);
+ return;
+ }
+
+ if (aValue.IsCanvasPattern()) {
+ SetStyleFromPattern(aValue.GetAsCanvasPattern(), aWhichStyle);
+ return;
+ }
+
+ MOZ_ASSERT_UNREACHABLE("Invalid union value");
+}
+
+//
// path bits
//
+
void
BasicRenderingContext2D::TransformWillUpdate()
{
EnsureTarget();
// Store the matrix that would transform the current path to device
// space.
if (mPath || mPathBuilder) {
--- a/dom/canvas/BasicRenderingContext2D.h
+++ b/dom/canvas/BasicRenderingContext2D.h
@@ -1,51 +1,61 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BasicRenderingContext2D_h
#define BasicRenderingContext2D_h
#include "FilterSupport.h"
+#include "gfxTextRun.h"
+#include "mozilla/dom/CanvasGradient.h"
+#include "mozilla/dom/CanvasPattern.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
#include "mozilla/gfx/2D.h"
#include "nsStyleStruct.h"
#include "nsSVGEffects.h"
using mozilla::gfx::CompositionOp;
using mozilla::gfx::FilterDescription;
using mozilla::gfx::Matrix;
namespace mozilla {
namespace dom {
+ #define NS_BASICRENDERINGCONTEXT2D_IID \
+ { 0xbd7f3f74, 0x5ed8, 0x4451, \
+ { 0x89, 0x95, 0x1c, 0x6a, 0x82, 0xeb, 0xef, 0x9f} }
+
class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap;
typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap
CanvasImageSource;
extern const mozilla::gfx::Float SIGMA_MAX;
/*
* BasicRenderingContext2D
*/
-class BasicRenderingContext2D
+class BasicRenderingContext2D : public nsISupports
{
public:
enum RenderingMode {
SoftwareBackendMode,
OpenGLBackendMode,
DefaultBackendMode
};
// This is created lazily so it is necessary to call EnsureTarget before
// accessing it. In the event of an error it will be equal to
// sErrorTarget.
RefPtr<mozilla::gfx::DrawTarget> mTarget;
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_BASICRENDERINGCONTEXT2D_IID)
+protected:
+ ~BasicRenderingContext2D(){}
public:
explicit BasicRenderingContext2D(layers::LayersBackend aCompositorBackend)
: mPathTransformWillUpdate(false){};
//
// CanvasState
//
void Save();
void Restore();
@@ -98,40 +108,50 @@ public:
CurrentState().imageSmoothingEnabled = aImageSmoothingEnabled;
}
}
//
// CanvasFillStrokeStyles
//
- virtual void GetStrokeStyle(
- OwningStringOrCanvasGradientOrCanvasPattern& aValue) = 0;
- virtual void SetStrokeStyle(
- const StringOrCanvasGradientOrCanvasPattern& aValue) = 0;
- virtual void GetFillStyle(
- OwningStringOrCanvasGradientOrCanvasPattern& aValue) = 0;
- virtual void SetFillStyle(
- const StringOrCanvasGradientOrCanvasPattern& aValue) = 0;
- virtual already_AddRefed<CanvasGradient> CreateLinearGradient(double aX0,
- double aY0,
- double aX1,
- double aY1) = 0;
- virtual already_AddRefed<CanvasGradient> CreateRadialGradient(
- double aX0,
- double aY0,
- double aR0,
- double aX1,
- double aY1,
- double aR1,
- ErrorResult& aError) = 0;
- virtual already_AddRefed<CanvasPattern> CreatePattern(
- const CanvasImageSource& aElement,
- const nsAString& aRepeat,
- ErrorResult& aError) = 0;
+ void
+ GetStrokeStyle(OwningStringOrCanvasGradientOrCanvasPattern& aValue)
+ {
+ GetStyleAsUnion(aValue, Style::STROKE);
+ }
+
+ void
+ SetStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& aValue)
+ {
+ SetStyleFromUnion(aValue, Style::STROKE);
+ }
+
+ void
+ GetFillStyle(OwningStringOrCanvasGradientOrCanvasPattern& aValue)
+ {
+ GetStyleAsUnion(aValue, Style::FILL);
+ }
+
+ void
+ SetFillStyle(const StringOrCanvasGradientOrCanvasPattern& aValue)
+ {
+ SetStyleFromUnion(aValue, Style::FILL);
+ }
+
+ already_AddRefed<CanvasGradient> CreateLinearGradient(double aX0, double aY0,
+ double aX1, double aY1);
+ already_AddRefed<CanvasGradient> CreateRadialGradient(double aX0, double aY0,
+ double aR0, double aX1,
+ double aY1, double aR1,
+ ErrorResult& aError);
+ already_AddRefed<CanvasPattern> CreatePattern(const CanvasImageSource& aElement,
+ const nsAString& aRepeat,
+ ErrorResult& aError);
+
//
// CanvasShadowStyles
//
virtual double ShadowOffsetX() = 0;
virtual void SetShadowOffsetX(double aShadowOffsetX) = 0;
virtual double ShadowOffsetY() = 0;
virtual void SetShadowOffsetY(double aShadowOffsetY) = 0;
virtual double ShadowBlur() = 0;
@@ -473,14 +493,40 @@ protected:
/**
* Needs to be called before updating the transform. This makes a call to
* EnsureTarget() so you don't have to.
*/
void TransformWillUpdate();
void SetTransformInternal(const Matrix& aTransform);
+
+ // Some helpers. Doesn't modify a color on failure.
+ void SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& aValue,
+ Style aWhichStyle);
+ void SetStyleFromString(const nsAString& aStr, Style aWhichStyle);
+
+ void SetStyleFromGradient(CanvasGradient& aGradient, Style aWhichStyle)
+ {
+ CurrentState().SetGradientStyle(aWhichStyle, &aGradient);
+ }
+
+ void SetStyleFromPattern(CanvasPattern& aPattern, Style aWhichStyle)
+ {
+ CurrentState().SetPatternStyle(aWhichStyle, &aPattern);
+ }
+
+ // Returns whether a color was successfully parsed.
+ virtual bool ParseColor(const nsAString& aString, nscolor* aColor) = 0;
+
+ static void StyleColorToString(const nscolor& aColor, nsAString& aStr);
+
+ void GetStyleAsUnion(OwningStringOrCanvasGradientOrCanvasPattern& aValue,
+ Style aWhichStyle);
};
+ NS_DEFINE_STATIC_IID_ACCESSOR(BasicRenderingContext2D,
+ NS_BASICRENDERINGCONTEXT2D_IID)
+
} // namespace dom
} // namespace mozilla
#endif /* BasicRenderingContext2D_h */
new file mode 100644
--- /dev/null
+++ b/dom/canvas/CanvasGradient.cpp
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "CanvasGradient.h"
+
+#include "mozilla/gfx/Types.h"
+#include "mozilla/dom/CanvasRenderingContext2D.h"
+#include "nsCSSParser.h"
+
+namespace mozilla {
+namespace dom {
+
+using mozilla::gfx::Color;
+using mozilla::gfx::GradientStop;
+using mozilla::gfx::GradientStops;
+
+void
+CanvasGradient::AddColorStop(float aOffset, const nsAString& aColorstr, ErrorResult& aRv)
+{
+ if (aOffset < 0.0 || aOffset > 1.0) {
+ aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+ return;
+ }
+
+ nsCSSValue value;
+ nsCSSParser parser;
+ if (!parser.ParseColorString(aColorstr, nullptr, 0, value)) {
+ aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+ return;
+ }
+
+ nscolor color;
+ nsCOMPtr<nsIPresShell> presShell =
+ mContext ? static_cast<CanvasRenderingContext2D*>(mContext.get())->GetPresShell() : nullptr;
+ if (!nsRuleNode::ComputeColor(value, presShell ? presShell->GetPresContext() : nullptr,
+ nullptr, color)) {
+ aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+ return;
+ }
+
+ mStops = nullptr;
+
+ GradientStop newStop;
+
+ newStop.offset = aOffset;
+ newStop.color = Color::FromABGR(color);
+
+ mRawStops.AppendElement(newStop);
+}
+
+mozilla::gfx::GradientStops *
+CanvasGradient::GetGradientStopsForTarget(mozilla::gfx::DrawTarget *aRT)
+{
+ if (mStops && mStops->GetBackendType() == aRT->GetBackendType()) {
+ return mStops;
+ }
+
+ mStops =
+ gfx::gfxGradientCache::GetOrCreateGradientStops(aRT,
+ mRawStops,
+ gfx::ExtendMode::CLAMP);
+
+ return mStops;
+}
+
+} // namespace dom
+} // namespace mozilla
\ No newline at end of file
--- a/dom/canvas/CanvasGradient.h
+++ b/dom/canvas/CanvasGradient.h
@@ -4,24 +4,29 @@
#ifndef mozilla_dom_CanvasGradient_h
#define mozilla_dom_CanvasGradient_h
#include "mozilla/Attributes.h"
#include "nsTArray.h"
#include "mozilla/RefPtr.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
-#include "mozilla/dom/CanvasRenderingContext2D.h"
+#include "mozilla/dom/BasicRenderingContext2D.h"
#include "mozilla/gfx/2D.h"
#include "nsWrapperCache.h"
#include "gfxGradientCache.h"
+using mozilla::gfx::Float;
+using mozilla::gfx::Point;
+
namespace mozilla {
namespace dom {
+class BasicRenderingContext2D;
+
class CanvasGradient : public nsWrapperCache
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasGradient)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasGradient)
enum class Type : uint8_t {
LINEAR = 0,
@@ -29,55 +34,84 @@ public:
};
Type GetType()
{
return mType;
}
mozilla::gfx::GradientStops *
- GetGradientStopsForTarget(mozilla::gfx::DrawTarget *aRT)
- {
- if (mStops && mStops->GetBackendType() == aRT->GetBackendType()) {
- return mStops;
- }
-
- mStops =
- gfx::gfxGradientCache::GetOrCreateGradientStops(aRT,
- mRawStops,
- gfx::ExtendMode::CLAMP);
-
- return mStops;
- }
+ GetGradientStopsForTarget(mozilla::gfx::DrawTarget *aRT);
// WebIDL
void AddColorStop(float offset, const nsAString& colorstr, ErrorResult& rv);
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
{
return CanvasGradientBinding::Wrap(aCx, this, aGivenProto);
}
- CanvasRenderingContext2D* GetParentObject()
+ BasicRenderingContext2D* GetParentObject()
{
return mContext;
}
protected:
friend struct CanvasBidiProcessor;
- CanvasGradient(CanvasRenderingContext2D* aContext, Type aType)
+ CanvasGradient(BasicRenderingContext2D* aContext, Type aType)
: mContext(aContext)
, mType(aType)
{
}
- RefPtr<CanvasRenderingContext2D> mContext;
+ RefPtr<BasicRenderingContext2D> mContext;
nsTArray<mozilla::gfx::GradientStop> mRawStops;
RefPtr<mozilla::gfx::GradientStops> mStops;
Type mType;
virtual ~CanvasGradient() {}
};
+class CanvasRadialGradient : public CanvasGradient
+{
+public:
+ CanvasRadialGradient(BasicRenderingContext2D* aContext,
+ const Point& aBeginOrigin, Float aBeginRadius,
+ const Point& aEndOrigin, Float aEndRadius)
+ : CanvasGradient(aContext, Type::RADIAL)
+ , mCenter1(aBeginOrigin)
+ , mCenter2(aEndOrigin)
+ , mRadius1(aBeginRadius)
+ , mRadius2(aEndRadius)
+ {
+ }
+
+ Point mCenter1;
+ Point mCenter2;
+ Float mRadius1;
+ Float mRadius2;
+};
+
+class CanvasLinearGradient : public CanvasGradient
+{
+public:
+ CanvasLinearGradient(BasicRenderingContext2D* aContext,
+ const Point& aBegin, const Point& aEnd)
+ : CanvasGradient(aContext, Type::LINEAR)
+ , mBegin(aBegin)
+ , mEnd(aEnd)
+ {
+ }
+
+protected:
+ friend struct CanvasBidiProcessor;
+ friend class CanvasGeneralPattern;
+
+ // Beginning of linear gradient.
+ Point mBegin;
+ // End of linear gradient.
+ Point mEnd;
+};
+
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_CanvasGradient_h
new file mode 100644
--- /dev/null
+++ b/dom/canvas/CanvasPattern.cpp
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "CanvasPattern.h"
+
+#include "gfx2DGlue.h"
+#include "mozilla/dom/SVGMatrix.h"
+
+namespace mozilla {
+namespace dom {
+
+using mozilla::gfx::ToMatrix;
+
+void
+CanvasPattern::SetTransform(SVGMatrix& aMatrix)
+{
+ mTransform = ToMatrix(aMatrix.GetMatrix());
+}
+
+} // namespace dom
+} // namespace mozilla
\ No newline at end of file
--- a/dom/canvas/CanvasPattern.h
+++ b/dom/canvas/CanvasPattern.h
@@ -2,46 +2,47 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_CanvasPattern_h
#define mozilla_dom_CanvasPattern_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
-#include "mozilla/dom/CanvasRenderingContext2D.h"
+#include "mozilla/dom/BasicRenderingContext2D.h"
#include "mozilla/RefPtr.h"
#include "nsISupports.h"
#include "nsWrapperCache.h"
class nsIPrincipal;
namespace mozilla {
namespace gfx {
class SourceSurface;
} // namespace gfx
namespace dom {
+class BasicRenderingContext2D;
class SVGMatrix;
class CanvasPattern final : public nsWrapperCache
{
~CanvasPattern() {}
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPattern)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPattern)
enum class RepeatMode : uint8_t {
REPEAT,
REPEATX,
REPEATY,
NOREPEAT
};
- CanvasPattern(CanvasRenderingContext2D* aContext,
+ CanvasPattern(BasicRenderingContext2D* aContext,
gfx::SourceSurface* aSurface,
RepeatMode aRepeat,
nsIPrincipal* principalForSecurityCheck,
bool forceWriteOnly,
bool CORSUsed)
: mContext(aContext)
, mSurface(aSurface)
, mPrincipal(principalForSecurityCheck)
@@ -52,25 +53,25 @@ public:
{
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
{
return CanvasPatternBinding::Wrap(aCx, this, aGivenProto);
}
- CanvasRenderingContext2D* GetParentObject()
+ BasicRenderingContext2D* GetParentObject()
{
return mContext;
}
// WebIDL
- void SetTransform(SVGMatrix& matrix);
+ void SetTransform(SVGMatrix& aMatrix);
- RefPtr<CanvasRenderingContext2D> mContext;
+ RefPtr<BasicRenderingContext2D> mContext;
RefPtr<gfx::SourceSurface> mSurface;
nsCOMPtr<nsIPrincipal> mPrincipal;
mozilla::gfx::Matrix mTransform;
const bool mForceWriteOnly;
const bool mCORSUsed;
const RepeatMode mRepeat;
};
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -26,18 +26,16 @@
#include "nsError.h"
#include "nsCSSParser.h"
#include "mozilla/css/StyleRule.h"
#include "mozilla/css/Declaration.h"
#include "nsComputedDOMStyle.h"
#include "nsStyleSet.h"
-#include "nsPrintfCString.h"
-
#include "nsReadableUtils.h"
#include "nsColor.h"
#include "nsGfxCIID.h"
#include "nsIDocShell.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "nsDisplayList.h"
@@ -58,17 +56,16 @@
#include "nsFrameLoader.h"
#include "nsBidi.h"
#include "nsBidiPresUtils.h"
#include "Layers.h"
#include "LayerUserData.h"
#include "CanvasUtils.h"
#include "nsIMemoryReporter.h"
-#include "nsStyleUtil.h"
#include "CanvasImageCache.h"
#include <algorithm>
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/Conversions.h"
#include "js/HeapAPI.h"
@@ -181,57 +178,16 @@ public:
"(width * height * 4) bytes.");
return NS_OK;
}
};
NS_IMPL_ISUPPORTS(Canvas2dPixelsReporter, nsIMemoryReporter)
-class CanvasRadialGradient : public CanvasGradient
-{
-public:
- CanvasRadialGradient(CanvasRenderingContext2D* aContext,
- const Point& aBeginOrigin, Float aBeginRadius,
- const Point& aEndOrigin, Float aEndRadius)
- : CanvasGradient(aContext, Type::RADIAL)
- , mCenter1(aBeginOrigin)
- , mCenter2(aEndOrigin)
- , mRadius1(aBeginRadius)
- , mRadius2(aEndRadius)
- {
- }
-
- Point mCenter1;
- Point mCenter2;
- Float mRadius1;
- Float mRadius2;
-};
-
-class CanvasLinearGradient : public CanvasGradient
-{
-public:
- CanvasLinearGradient(CanvasRenderingContext2D* aContext,
- const Point& aBegin, const Point& aEnd)
- : CanvasGradient(aContext, Type::LINEAR)
- , mBegin(aBegin)
- , mEnd(aEnd)
- {
- }
-
-protected:
- friend struct CanvasBidiProcessor;
- friend class CanvasGeneralPattern;
-
- // Beginning of linear gradient.
- Point mBegin;
- // End of linear gradient.
- Point mEnd;
-};
-
bool
CanvasRenderingContext2D::PatternIsOpaque(CanvasRenderingContext2D::Style aStyle) const
{
const ContextState& state = CurrentState();
if (state.globalAlpha < 1.0) {
return false;
}
@@ -698,65 +654,16 @@ private:
return gfx::Rect(extents.GetBounds());
}
RefPtr<DrawTarget> mTarget;
UniquePtr<AdjustedTargetForShadow> mShadowTarget;
UniquePtr<AdjustedTargetForFilter> mFilterTarget;
};
-void
-CanvasPattern::SetTransform(SVGMatrix& aMatrix)
-{
- mTransform = ToMatrix(aMatrix.GetMatrix());
-}
-
-void
-CanvasGradient::AddColorStop(float aOffset, const nsAString& aColorstr, ErrorResult& aRv)
-{
- if (aOffset < 0.0 || aOffset > 1.0) {
- aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
- return;
- }
-
- nsCSSValue value;
- nsCSSParser parser;
- if (!parser.ParseColorString(aColorstr, nullptr, 0, value)) {
- aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
- return;
- }
-
- nscolor color;
- nsCOMPtr<nsIPresShell> presShell = mContext ? mContext->GetPresShell() : nullptr;
- if (!nsRuleNode::ComputeColor(value, presShell ? presShell->GetPresContext() : nullptr,
- nullptr, color)) {
- aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
- return;
- }
-
- mStops = nullptr;
-
- GradientStop newStop;
-
- newStop.offset = aOffset;
- newStop.color = Color::FromABGR(color);
-
- mRawStops.AppendElement(newStop);
-}
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasGradient, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasGradient, Release)
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasGradient, mContext)
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPattern, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPattern, Release)
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasPattern, mContext)
-
class CanvasShutdownObserver final : public nsIObserver
{
public:
explicit CanvasShutdownObserver(CanvasRenderingContext2D* aCanvas)
: mCanvas(aCanvas)
{}
NS_DECL_ISUPPORTS
@@ -1036,19 +943,20 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_
return nsCCUncollectableMarker::sGeneration && tmp->HasKnownLiveWrapper();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(CanvasRenderingContext2D)
return nsCCUncollectableMarker::sGeneration && tmp->HasKnownLiveWrapper();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CanvasRenderingContext2D)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextInternal)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
- NS_INTERFACE_MAP_ENTRY(nsISupports)
+ NS_INTERFACE_MAP_ENTRY(BasicRenderingContext2D)
NS_INTERFACE_MAP_END
/**
** CanvasRenderingContext2D impl
**/
// Initialize our static variables.
@@ -1201,67 +1109,17 @@ void
CanvasRenderingContext2D::RemoveShutdownObserver()
{
if (mShutdownObserver) {
nsContentUtils::UnregisterShutdownObserver(mShutdownObserver);
mShutdownObserver = nullptr;
}
}
-void
-CanvasRenderingContext2D::SetStyleFromString(const nsAString& aStr,
- Style aWhichStyle)
-{
- MOZ_ASSERT(!aStr.IsVoid());
-
- nscolor color;
- if (!ParseColor(aStr, &color)) {
- return;
- }
-
- CurrentState().SetColorStyle(aWhichStyle, color);
-}
-
-void
-CanvasRenderingContext2D::GetStyleAsUnion(OwningStringOrCanvasGradientOrCanvasPattern& aValue,
- Style aWhichStyle)
-{
- const ContextState &state = CurrentState();
- if (state.patternStyles[aWhichStyle]) {
- aValue.SetAsCanvasPattern() = state.patternStyles[aWhichStyle];
- } else if (state.gradientStyles[aWhichStyle]) {
- aValue.SetAsCanvasGradient() = state.gradientStyles[aWhichStyle];
- } else {
- StyleColorToString(state.colorStyles[aWhichStyle], aValue.SetAsString());
- }
-}
-
// static
-void
-CanvasRenderingContext2D::StyleColorToString(const nscolor& aColor, nsAString& aStr)
-{
- // We can't reuse the normal CSS color stringification code,
- // because the spec calls for a different algorithm for canvas.
- if (NS_GET_A(aColor) == 255) {
- CopyUTF8toUTF16(nsPrintfCString("#%02x%02x%02x",
- NS_GET_R(aColor),
- NS_GET_G(aColor),
- NS_GET_B(aColor)),
- aStr);
- } else {
- CopyUTF8toUTF16(nsPrintfCString("rgba(%d, %d, %d, ",
- NS_GET_R(aColor),
- NS_GET_G(aColor),
- NS_GET_B(aColor)),
- aStr);
- aStr.AppendFloat(nsStyleUtil::ColorComponentToFloat(NS_GET_A(aColor)));
- aStr.Append(')');
- }
-}
-
nsresult
CanvasRenderingContext2D::Redraw()
{
mIsCapturedFrameInvalid = true;
if (mIsEntireFrameInvalid) {
return NS_OK;
}
@@ -2245,39 +2103,16 @@ CanvasRenderingContext2D::GetMozCurrentT
}
MatrixToJSObject(aCx, ctm, aResult, aError);
}
//
// colors
//
-
-void
-CanvasRenderingContext2D::SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& aValue,
- Style aWhichStyle)
-{
- if (aValue.IsString()) {
- SetStyleFromString(aValue.GetAsString(), aWhichStyle);
- return;
- }
-
- if (aValue.IsCanvasGradient()) {
- SetStyleFromGradient(aValue.GetAsCanvasGradient(), aWhichStyle);
- return;
- }
-
- if (aValue.IsCanvasPattern()) {
- SetStyleFromPattern(aValue.GetAsCanvasPattern(), aWhichStyle);
- return;
- }
-
- MOZ_ASSERT_UNREACHABLE("Invalid union value");
-}
-
void
CanvasRenderingContext2D::SetFillRule(const nsAString& aString)
{
FillRule rule;
if (aString.EqualsLiteral("evenodd"))
rule = FillRule::FILL_EVEN_ODD;
else if (aString.EqualsLiteral("nonzero"))
@@ -2293,151 +2128,16 @@ CanvasRenderingContext2D::GetFillRule(ns
{
switch (CurrentState().fillRule) {
case FillRule::FILL_WINDING:
aString.AssignLiteral("nonzero"); break;
case FillRule::FILL_EVEN_ODD:
aString.AssignLiteral("evenodd"); break;
}
}
-//
-// gradients and patterns
-//
-already_AddRefed<CanvasGradient>
-CanvasRenderingContext2D::CreateLinearGradient(double aX0, double aY0, double aX1, double aY1)
-{
- RefPtr<CanvasGradient> grad =
- new CanvasLinearGradient(this, Point(aX0, aY0), Point(aX1, aY1));
-
- return grad.forget();
-}
-
-already_AddRefed<CanvasGradient>
-CanvasRenderingContext2D::CreateRadialGradient(double aX0, double aY0, double aR0,
- double aX1, double aY1, double aR1,
- ErrorResult& aError)
-{
- if (aR0 < 0.0 || aR1 < 0.0) {
- aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
- return nullptr;
- }
-
- RefPtr<CanvasGradient> grad =
- new CanvasRadialGradient(this, Point(aX0, aY0), aR0, Point(aX1, aY1), aR1);
-
- return grad.forget();
-}
-
-already_AddRefed<CanvasPattern>
-CanvasRenderingContext2D::CreatePattern(const CanvasImageSource& aSource,
- const nsAString& aRepeat,
- ErrorResult& aError)
-{
- CanvasPattern::RepeatMode repeatMode =
- CanvasPattern::RepeatMode::NOREPEAT;
-
- if (aRepeat.IsEmpty() || aRepeat.EqualsLiteral("repeat")) {
- repeatMode = CanvasPattern::RepeatMode::REPEAT;
- } else if (aRepeat.EqualsLiteral("repeat-x")) {
- repeatMode = CanvasPattern::RepeatMode::REPEATX;
- } else if (aRepeat.EqualsLiteral("repeat-y")) {
- repeatMode = CanvasPattern::RepeatMode::REPEATY;
- } else if (aRepeat.EqualsLiteral("no-repeat")) {
- repeatMode = CanvasPattern::RepeatMode::NOREPEAT;
- } else {
- aError.Throw(NS_ERROR_DOM_SYNTAX_ERR);
- return nullptr;
- }
-
- Element* htmlElement;
- if (aSource.IsHTMLCanvasElement()) {
- HTMLCanvasElement* canvas = &aSource.GetAsHTMLCanvasElement();
- htmlElement = canvas;
-
- nsIntSize size = canvas->GetSize();
- if (size.width == 0 || size.height == 0) {
- aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
- return nullptr;
- }
-
- // Special case for Canvas, which could be an Azure canvas!
- nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
- if (srcCanvas) {
- // This might not be an Azure canvas!
- RefPtr<SourceSurface> srcSurf = srcCanvas->GetSurfaceSnapshot();
- if (!srcSurf) {
- JSContext* context = nsContentUtils::GetCurrentJSContext();
- if (context) {
- JS_ReportWarningASCII(context,
- "CanvasRenderingContext2D.createPattern()"
- " failed to snapshot source canvas.");
- }
- aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
- return nullptr;
- }
-
- RefPtr<CanvasPattern> pat =
- new CanvasPattern(this, srcSurf, repeatMode, htmlElement->NodePrincipal(), canvas->IsWriteOnly(), false);
-
- return pat.forget();
- }
- } else if (aSource.IsHTMLImageElement()) {
- HTMLImageElement* img = &aSource.GetAsHTMLImageElement();
- if (img->IntrinsicState().HasState(NS_EVENT_STATE_BROKEN)) {
- aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
- return nullptr;
- }
-
- htmlElement = img;
- } else if (aSource.IsHTMLVideoElement()) {
- auto& video = aSource.GetAsHTMLVideoElement();
- video.MarkAsContentSource(mozilla::dom::HTMLVideoElement::CallerAPI::CREATE_PATTERN);
- htmlElement = &video;
- } else {
- // Special case for ImageBitmap
- ImageBitmap& imgBitmap = aSource.GetAsImageBitmap();
- EnsureTarget();
- RefPtr<SourceSurface> srcSurf = imgBitmap.PrepareForDrawTarget(mTarget);
- if (!srcSurf) {
- JSContext* context = nsContentUtils::GetCurrentJSContext();
- if (context) {
- JS_ReportWarningASCII(context,
- "CanvasRenderingContext2D.createPattern()"
- " failed to prepare source ImageBitmap.");
- }
- aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
- return nullptr;
- }
-
- // An ImageBitmap never taints others so we set principalForSecurityCheck to
- // nullptr and set CORSUsed to true for passing the security check in
- // CanvasUtils::DoDrawImageSecurityCheck().
- RefPtr<CanvasPattern> pat =
- new CanvasPattern(this, srcSurf, repeatMode, nullptr, false, true);
-
- return pat.forget();
- }
-
- EnsureTarget();
-
- // The canvas spec says that createPattern should use the first frame
- // of animated images
- nsLayoutUtils::SurfaceFromElementResult res =
- nsLayoutUtils::SurfaceFromElement(htmlElement,
- nsLayoutUtils::SFE_WANT_FIRST_FRAME, mTarget);
-
- if (!res.GetSourceSurface()) {
- return nullptr;
- }
-
- RefPtr<CanvasPattern> pat = new CanvasPattern(this, res.GetSourceSurface(), repeatMode,
- res.mPrincipal, res.mIsWriteOnly,
- res.mCORSUsed);
- return pat.forget();
-}
//
// shadows
//
void
CanvasRenderingContext2D::SetShadowColor(const nsAString& aShadowColor)
{
nscolor color;
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -11,17 +11,16 @@
#include "nsICanvasRenderingContextInternal.h"
#include "mozilla/RefPtr.h"
#include "nsColor.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "gfxTextRun.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BasicRenderingContext2D.h"
-#include "mozilla/dom/CanvasGradient.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
#include "mozilla/dom/CanvasPattern.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/UniquePtr.h"
#include "gfx2DGlue.h"
#include "imgIEncoder.h"
#include "nsLayoutUtils.h"
#include "mozilla/EnumeratedArray.h"
@@ -50,18 +49,18 @@ class CanvasRenderingContext2DUserData;
class CanvasDrawObserver;
class CanvasShutdownObserver;
/**
** CanvasRenderingContext2D
**/
class CanvasRenderingContext2D final :
public nsICanvasRenderingContextInternal,
- public nsWrapperCache,
- public BasicRenderingContext2D
+ public BasicRenderingContext2D,
+ public nsWrapperCache
{
virtual ~CanvasRenderingContext2D();
public:
explicit CanvasRenderingContext2D(layers::LayersBackend aCompositorBackend);
virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
@@ -70,50 +69,16 @@ public:
if (!mCanvasElement || mCanvasElement->IsInNativeAnonymousSubtree()) {
return nullptr;
}
// corresponds to changes to the old bindings made in bug 745025
return mCanvasElement->GetOriginalCanvas();
}
- void
- GetStrokeStyle(OwningStringOrCanvasGradientOrCanvasPattern& aValue) override
- {
- GetStyleAsUnion(aValue, Style::STROKE);
- }
-
- void
- SetStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& aValue) override
- {
- SetStyleFromUnion(aValue, Style::STROKE);
- }
-
- void
- GetFillStyle(OwningStringOrCanvasGradientOrCanvasPattern& aValue) override
- {
- GetStyleAsUnion(aValue, Style::FILL);
- }
-
- void
- SetFillStyle(const StringOrCanvasGradientOrCanvasPattern& aValue) override
- {
- SetStyleFromUnion(aValue, Style::FILL);
- }
-
- already_AddRefed<CanvasGradient>
- CreateLinearGradient(double aX0, double aY0, double aX1, double aY1) override;
- already_AddRefed<CanvasGradient>
- CreateRadialGradient(double aX0, double aY0, double aR0,
- double aX1, double aY1, double aR1,
- ErrorResult& aError) override;
- already_AddRefed<CanvasPattern>
- CreatePattern(const CanvasImageSource& aElement,
- const nsAString& aRepeat, ErrorResult& aError) override;
-
double ShadowOffsetX() override
{
return CurrentState().shadowOffset.x;
}
void SetShadowOffsetX(double aShadowOffsetX) override
{
CurrentState().shadowOffset.x = ToFloat(aShadowOffsetX);
@@ -429,17 +394,18 @@ public:
*/
virtual void DidRefresh() override;
// this rect is in mTarget's current user space
void RedrawUser(const gfxRect& aR);
// nsISupports interface + CC
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(CanvasRenderingContext2D)
+ NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(CanvasRenderingContext2D,
+ nsICanvasRenderingContextInternal)
enum class CanvasMultiGetterType : uint8_t {
STRING = 0,
PATTERN = 1,
GRADIENT = 2
};
nsINode* GetParentObject()
@@ -513,37 +479,21 @@ protected:
* The number of living nsCanvasRenderingContexts. When this goes down to
* 0, we free the premultiply and unpremultiply tables, if they exist.
*/
static uint32_t sNumLivingContexts;
static mozilla::gfx::DrawTarget* sErrorTarget;
// Some helpers. Doesn't modify a color on failure.
- void SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& aValue,
- Style aWhichStyle);
- void SetStyleFromString(const nsAString& aStr, Style aWhichStyle);
-
- void SetStyleFromGradient(CanvasGradient& aGradient, Style aWhichStyle)
- {
- CurrentState().SetGradientStyle(aWhichStyle, &aGradient);
- }
-
- void SetStyleFromPattern(CanvasPattern& aPattern, Style aWhichStyle)
- {
- CurrentState().SetPatternStyle(aWhichStyle, &aPattern);
- }
-
void GetStyleAsUnion(OwningStringOrCanvasGradientOrCanvasPattern& aValue,
Style aWhichStyle);
// Returns whether a color was successfully parsed.
- bool ParseColor(const nsAString& aString, nscolor* aColor);
-
- static void StyleColorToString(const nscolor& aColor, nsAString& aStr);
+ virtual bool ParseColor(const nsAString& aString, nscolor* aColor) override;
// Returns whether a filter was successfully parsed.
bool ParseFilter(const nsAString& aString,
nsTArray<nsStyleFilter>& aFilterChain,
ErrorResult& aError);
// Returns whether the font was successfully updated.
bool SetFontInternal(const nsAString& aFont, mozilla::ErrorResult& aError);
--- a/dom/canvas/moz.build
+++ b/dom/canvas/moz.build
@@ -69,17 +69,19 @@ EXPORTS.mozilla.dom += [
'OffscreenCanvas.h',
'TextMetrics.h',
'WebGLVertexArrayObject.h',
]
# Canvas 2D and common sources
UNIFIED_SOURCES += [
'BasicRenderingContext2D.cpp',
+ 'CanvasGradient.cpp',
'CanvasImageCache.cpp',
+ 'CanvasPattern.cpp',
'CanvasRenderingContext2D.cpp',
'CanvasRenderingContextHelper.cpp',
'CanvasUtils.cpp',
'DocumentRendererChild.cpp',
'DocumentRendererParent.cpp',
'ImageBitmap.cpp',
'ImageBitmapColorUtils.cpp',
'ImageBitmapRenderingContext.cpp',
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -565,17 +565,18 @@ HTMLCanvasElement::CopyInnerTo(Element*
NS_ENSURE_SUCCESS(rv, rv);
if (aDest->OwnerDoc()->IsStaticDocument()) {
HTMLCanvasElement* dest = static_cast<HTMLCanvasElement*>(aDest);
dest->mOriginalCanvas = this;
nsCOMPtr<nsISupports> cxt;
dest->GetContext(NS_LITERAL_STRING("2d"), getter_AddRefs(cxt));
RefPtr<CanvasRenderingContext2D> context2d =
- static_cast<CanvasRenderingContext2D*>(cxt.get());
+ static_cast<CanvasRenderingContext2D*>(
+ static_cast<nsICanvasRenderingContextInternal*>(cxt.get()));
if (context2d && !mPrintCallback) {
CanvasImageSource source;
source.SetAsHTMLCanvasElement() = this;
ErrorResult err;
context2d->DrawImage(source,
0.0, 0.0, err);
rv = err.StealNSResult();
}