2012-06-13 08:14:15 -07:00
|
|
|
/* 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/. */
|
|
|
|
|
2012-10-12 02:42:52 -07:00
|
|
|
#ifndef CanvasRenderingContext2D_h
|
|
|
|
#define CanvasRenderingContext2D_h
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2013-05-29 13:43:41 -07:00
|
|
|
#include "mozilla/Attributes.h"
|
2012-06-13 08:14:15 -07:00
|
|
|
#include <vector>
|
|
|
|
#include "nsIDOMCanvasRenderingContext2D.h"
|
|
|
|
#include "nsICanvasRenderingContextInternal.h"
|
|
|
|
#include "mozilla/RefPtr.h"
|
|
|
|
#include "nsColor.h"
|
2013-01-03 21:16:14 -08:00
|
|
|
#include "mozilla/dom/HTMLCanvasElement.h"
|
2013-03-19 05:27:35 -07:00
|
|
|
#include "mozilla/dom/HTMLVideoElement.h"
|
2012-11-13 16:35:36 -08:00
|
|
|
#include "CanvasUtils.h"
|
2012-06-13 08:14:15 -07:00
|
|
|
#include "gfxFont.h"
|
|
|
|
#include "mozilla/ErrorResult.h"
|
2013-04-26 07:55:37 -07:00
|
|
|
#include "mozilla/dom/CanvasGradient.h"
|
2013-01-16 18:55:43 -08:00
|
|
|
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
|
2013-04-19 01:49:22 -07:00
|
|
|
#include "mozilla/dom/CanvasPattern.h"
|
2013-05-29 06:32:30 -07:00
|
|
|
#include "mozilla/gfx/Rect.h"
|
2013-10-07 16:15:59 -07:00
|
|
|
#include "mozilla/gfx/2D.h"
|
|
|
|
#include "gfx2DGlue.h"
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2013-01-29 09:51:55 -08:00
|
|
|
class nsXULElement;
|
2012-11-13 16:35:36 -08:00
|
|
|
|
2012-06-13 08:14:15 -07:00
|
|
|
namespace mozilla {
|
|
|
|
namespace gfx {
|
|
|
|
class SourceSurface;
|
|
|
|
}
|
|
|
|
|
2012-10-12 02:42:52 -07:00
|
|
|
namespace dom {
|
2013-07-26 11:25:54 -07:00
|
|
|
class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
|
2013-08-22 22:17:11 -07:00
|
|
|
class ImageData;
|
2013-07-26 11:25:54 -07:00
|
|
|
class StringOrCanvasGradientOrCanvasPattern;
|
2013-09-17 08:16:02 -07:00
|
|
|
class OwningStringOrCanvasGradientOrCanvasPattern;
|
2013-04-19 01:49:22 -07:00
|
|
|
class TextMetrics;
|
|
|
|
|
2012-06-13 08:14:15 -07:00
|
|
|
extern const mozilla::gfx::Float SIGMA_MAX;
|
|
|
|
|
2012-10-12 02:42:52 -07:00
|
|
|
template<typename T> class Optional;
|
|
|
|
|
|
|
|
struct CanvasBidiProcessor;
|
|
|
|
class CanvasRenderingContext2DUserData;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
/**
|
2012-10-12 02:42:52 -07:00
|
|
|
** CanvasRenderingContext2D
|
2012-06-13 08:14:15 -07:00
|
|
|
**/
|
2012-10-12 02:42:52 -07:00
|
|
|
class CanvasRenderingContext2D :
|
2012-06-13 08:14:15 -07:00
|
|
|
public nsICanvasRenderingContextInternal,
|
|
|
|
public nsWrapperCache
|
|
|
|
{
|
2013-07-26 11:25:54 -07:00
|
|
|
typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
|
2012-06-13 08:14:15 -07:00
|
|
|
HTMLImageOrCanvasOrVideoElement;
|
|
|
|
|
|
|
|
public:
|
2012-10-12 02:42:52 -07:00
|
|
|
CanvasRenderingContext2D();
|
|
|
|
virtual ~CanvasRenderingContext2D();
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2013-04-25 09:29:54 -07:00
|
|
|
virtual JSObject* WrapObject(JSContext *cx,
|
|
|
|
JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
|
2012-05-21 14:30:07 -07:00
|
|
|
|
2013-01-03 21:16:14 -08:00
|
|
|
HTMLCanvasElement* GetCanvas() const
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
2012-11-21 13:55:36 -08:00
|
|
|
// corresponds to changes to the old bindings made in bug 745025
|
|
|
|
return mCanvasElement->GetOriginalCanvas();
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Save();
|
|
|
|
void Restore();
|
|
|
|
void Scale(double x, double y, mozilla::ErrorResult& error);
|
|
|
|
void Rotate(double angle, mozilla::ErrorResult& error);
|
|
|
|
void Translate(double x, double y, mozilla::ErrorResult& error);
|
|
|
|
void Transform(double m11, double m12, double m21, double m22, double dx,
|
|
|
|
double dy, mozilla::ErrorResult& error);
|
|
|
|
void SetTransform(double m11, double m12, double m21, double m22, double dx,
|
|
|
|
double dy, mozilla::ErrorResult& error);
|
|
|
|
|
2012-09-11 12:08:24 -07:00
|
|
|
double GlobalAlpha()
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
|
|
|
return CurrentState().globalAlpha;
|
|
|
|
}
|
|
|
|
|
2013-01-28 17:39:47 -08:00
|
|
|
// Useful for silencing cast warnings
|
|
|
|
static mozilla::gfx::Float ToFloat(double aValue) { return mozilla::gfx::Float(aValue); }
|
|
|
|
|
2012-06-13 08:14:15 -07:00
|
|
|
void SetGlobalAlpha(double globalAlpha)
|
|
|
|
{
|
2012-11-27 12:32:05 -08:00
|
|
|
if (globalAlpha >= 0.0 && globalAlpha <= 1.0) {
|
2013-01-28 17:39:47 -08:00
|
|
|
CurrentState().globalAlpha = ToFloat(globalAlpha);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GetGlobalCompositeOperation(nsAString& op, mozilla::ErrorResult& error);
|
|
|
|
void SetGlobalCompositeOperation(const nsAString& op,
|
|
|
|
mozilla::ErrorResult& error);
|
|
|
|
|
2013-09-17 08:16:02 -07:00
|
|
|
void GetStrokeStyle(OwningStringOrCanvasGradientOrCanvasPattern& value)
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
2013-07-26 11:25:54 -07:00
|
|
|
GetStyleAsUnion(value, STYLE_STROKE);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
2013-07-26 11:25:54 -07:00
|
|
|
void SetStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& value)
|
|
|
|
{
|
|
|
|
SetStyleFromUnion(value, STYLE_STROKE);
|
|
|
|
}
|
|
|
|
|
2013-09-17 08:16:02 -07:00
|
|
|
void GetFillStyle(OwningStringOrCanvasGradientOrCanvasPattern& value)
|
2013-07-26 11:25:54 -07:00
|
|
|
{
|
|
|
|
GetStyleAsUnion(value, STYLE_FILL);
|
|
|
|
}
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2013-07-26 11:25:54 -07:00
|
|
|
void SetFillStyle(const StringOrCanvasGradientOrCanvasPattern& value)
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
2013-07-26 11:25:54 -07:00
|
|
|
SetStyleFromUnion(value, STYLE_FILL);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
2013-04-26 07:55:54 -07:00
|
|
|
already_AddRefed<CanvasGradient>
|
|
|
|
CreateLinearGradient(double x0, double y0, double x1, double y1);
|
|
|
|
already_AddRefed<CanvasGradient>
|
2012-06-13 08:14:15 -07:00
|
|
|
CreateRadialGradient(double x0, double y0, double r0, double x1, double y1,
|
2013-04-26 07:55:54 -07:00
|
|
|
double r1, ErrorResult& aError);
|
2013-04-19 01:49:22 -07:00
|
|
|
already_AddRefed<CanvasPattern>
|
2012-06-13 08:14:15 -07:00
|
|
|
CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
|
2013-04-26 07:55:54 -07:00
|
|
|
const nsAString& repeat, ErrorResult& error);
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-09-11 12:08:24 -07:00
|
|
|
double ShadowOffsetX()
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
|
|
|
return CurrentState().shadowOffset.x;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetShadowOffsetX(double shadowOffsetX)
|
|
|
|
{
|
2013-01-28 17:39:47 -08:00
|
|
|
CurrentState().shadowOffset.x = ToFloat(shadowOffsetX);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
2012-09-11 12:08:24 -07:00
|
|
|
double ShadowOffsetY()
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
|
|
|
return CurrentState().shadowOffset.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetShadowOffsetY(double shadowOffsetY)
|
|
|
|
{
|
2013-01-28 17:39:47 -08:00
|
|
|
CurrentState().shadowOffset.y = ToFloat(shadowOffsetY);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
2012-09-11 12:08:24 -07:00
|
|
|
double ShadowBlur()
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
|
|
|
return CurrentState().shadowBlur;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetShadowBlur(double shadowBlur)
|
|
|
|
{
|
2012-11-27 12:32:05 -08:00
|
|
|
if (shadowBlur >= 0.0) {
|
2013-01-28 17:39:47 -08:00
|
|
|
CurrentState().shadowBlur = ToFloat(shadowBlur);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GetShadowColor(nsAString& shadowColor)
|
|
|
|
{
|
|
|
|
StyleColorToString(CurrentState().shadowColor, shadowColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetShadowColor(const nsAString& shadowColor);
|
|
|
|
void ClearRect(double x, double y, double w, double h);
|
|
|
|
void FillRect(double x, double y, double w, double h);
|
|
|
|
void StrokeRect(double x, double y, double w, double h);
|
|
|
|
void BeginPath();
|
2013-01-16 18:55:43 -08:00
|
|
|
void Fill(const CanvasWindingRule& winding);
|
2012-06-13 08:14:15 -07:00
|
|
|
void Stroke();
|
2013-01-16 18:55:43 -08:00
|
|
|
void Clip(const CanvasWindingRule& winding);
|
|
|
|
bool IsPointInPath(double x, double y, const CanvasWindingRule& winding);
|
2012-11-22 05:37:42 -08:00
|
|
|
bool IsPointInStroke(double x, double y);
|
2012-06-13 08:14:15 -07:00
|
|
|
void FillText(const nsAString& text, double x, double y,
|
2013-07-26 11:25:54 -07:00
|
|
|
const Optional<double>& maxWidth,
|
2012-06-13 08:14:15 -07:00
|
|
|
mozilla::ErrorResult& error);
|
|
|
|
void StrokeText(const nsAString& text, double x, double y,
|
2013-07-26 11:25:54 -07:00
|
|
|
const Optional<double>& maxWidth,
|
2012-06-13 08:14:15 -07:00
|
|
|
mozilla::ErrorResult& error);
|
2013-04-19 01:49:22 -07:00
|
|
|
TextMetrics*
|
2012-06-13 08:14:15 -07:00
|
|
|
MeasureText(const nsAString& rawText, mozilla::ErrorResult& error);
|
|
|
|
|
|
|
|
void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
|
|
|
|
double dx, double dy, mozilla::ErrorResult& error)
|
|
|
|
{
|
|
|
|
DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, 0.0, 0.0, 0, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
|
|
|
|
double dx, double dy, double dw, double dh,
|
|
|
|
mozilla::ErrorResult& error)
|
|
|
|
{
|
|
|
|
DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, dw, dh, 2, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
|
|
|
|
double sx, double sy, double sw, double sh, double dx,
|
|
|
|
double dy, double dw, double dh, mozilla::ErrorResult& error)
|
|
|
|
{
|
|
|
|
DrawImage(image, sx, sy, sw, sh, dx, dy, dw, dh, 6, error);
|
|
|
|
}
|
|
|
|
|
2013-07-26 11:25:54 -07:00
|
|
|
already_AddRefed<ImageData>
|
2012-06-13 08:14:15 -07:00
|
|
|
CreateImageData(JSContext* cx, double sw, double sh,
|
|
|
|
mozilla::ErrorResult& error);
|
2013-07-26 11:25:54 -07:00
|
|
|
already_AddRefed<ImageData>
|
|
|
|
CreateImageData(JSContext* cx, ImageData& imagedata,
|
2012-06-13 08:14:15 -07:00
|
|
|
mozilla::ErrorResult& error);
|
2013-07-26 11:25:54 -07:00
|
|
|
already_AddRefed<ImageData>
|
2012-06-13 08:14:15 -07:00
|
|
|
GetImageData(JSContext* cx, double sx, double sy, double sw, double sh,
|
|
|
|
mozilla::ErrorResult& error);
|
2013-07-26 11:25:54 -07:00
|
|
|
void PutImageData(ImageData& imageData,
|
2012-06-13 08:14:15 -07:00
|
|
|
double dx, double dy, mozilla::ErrorResult& error);
|
2013-07-26 11:25:54 -07:00
|
|
|
void PutImageData(ImageData& imageData,
|
2012-06-13 08:14:15 -07:00
|
|
|
double dx, double dy, double dirtyX, double dirtyY,
|
|
|
|
double dirtyWidth, double dirtyHeight,
|
|
|
|
mozilla::ErrorResult& error);
|
|
|
|
|
2012-09-11 12:08:24 -07:00
|
|
|
double LineWidth()
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
|
|
|
return CurrentState().lineWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetLineWidth(double width)
|
|
|
|
{
|
2012-11-27 12:32:05 -08:00
|
|
|
if (width > 0.0) {
|
2013-01-28 17:39:47 -08:00
|
|
|
CurrentState().lineWidth = ToFloat(width);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
void GetLineCap(nsAString& linecap);
|
|
|
|
void SetLineCap(const nsAString& linecap);
|
|
|
|
void GetLineJoin(nsAString& linejoin, mozilla::ErrorResult& error);
|
|
|
|
void SetLineJoin(const nsAString& linejoin);
|
|
|
|
|
2012-09-11 12:08:24 -07:00
|
|
|
double MiterLimit()
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
|
|
|
return CurrentState().miterLimit;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetMiterLimit(double miter)
|
|
|
|
{
|
2012-11-27 12:32:05 -08:00
|
|
|
if (miter > 0.0) {
|
2013-01-28 17:39:47 -08:00
|
|
|
CurrentState().miterLimit = ToFloat(miter);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GetFont(nsAString& font)
|
|
|
|
{
|
|
|
|
font = GetFont();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetFont(const nsAString& font, mozilla::ErrorResult& error);
|
|
|
|
void GetTextAlign(nsAString& textAlign);
|
|
|
|
void SetTextAlign(const nsAString& textAlign);
|
|
|
|
void GetTextBaseline(nsAString& textBaseline);
|
|
|
|
void SetTextBaseline(const nsAString& textBaseline);
|
|
|
|
|
|
|
|
void ClosePath()
|
|
|
|
{
|
|
|
|
EnsureWritablePath();
|
|
|
|
|
|
|
|
if (mPathBuilder) {
|
|
|
|
mPathBuilder->Close();
|
|
|
|
} else {
|
|
|
|
mDSPathBuilder->Close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MoveTo(double x, double y)
|
|
|
|
{
|
2012-11-27 12:32:05 -08:00
|
|
|
EnsureWritablePath();
|
|
|
|
|
|
|
|
if (mPathBuilder) {
|
2013-01-28 17:39:47 -08:00
|
|
|
mPathBuilder->MoveTo(mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
|
2012-11-27 12:32:05 -08:00
|
|
|
} else {
|
|
|
|
mDSPathBuilder->MoveTo(mTarget->GetTransform() *
|
2013-01-28 17:39:47 -08:00
|
|
|
mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LineTo(double x, double y)
|
|
|
|
{
|
2012-11-27 12:32:05 -08:00
|
|
|
EnsureWritablePath();
|
2013-07-26 11:25:54 -07:00
|
|
|
|
2013-01-28 17:39:47 -08:00
|
|
|
LineTo(mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void QuadraticCurveTo(double cpx, double cpy, double x, double y)
|
|
|
|
{
|
2012-11-27 12:32:05 -08:00
|
|
|
EnsureWritablePath();
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-11-27 12:32:05 -08:00
|
|
|
if (mPathBuilder) {
|
2013-01-28 17:39:47 -08:00
|
|
|
mPathBuilder->QuadraticBezierTo(mozilla::gfx::Point(ToFloat(cpx), ToFloat(cpy)),
|
|
|
|
mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
|
2012-11-27 12:32:05 -08:00
|
|
|
} else {
|
|
|
|
mozilla::gfx::Matrix transform = mTarget->GetTransform();
|
|
|
|
mDSPathBuilder->QuadraticBezierTo(transform *
|
2013-01-28 17:39:47 -08:00
|
|
|
mozilla::gfx::Point(ToFloat(cpx), ToFloat(cpy)),
|
2012-11-27 12:32:05 -08:00
|
|
|
transform *
|
2013-01-28 17:39:47 -08:00
|
|
|
mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y)
|
|
|
|
{
|
2012-11-27 12:32:05 -08:00
|
|
|
EnsureWritablePath();
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2013-01-28 17:39:47 -08:00
|
|
|
BezierTo(mozilla::gfx::Point(ToFloat(cp1x), ToFloat(cp1y)),
|
|
|
|
mozilla::gfx::Point(ToFloat(cp2x), ToFloat(cp2y)),
|
|
|
|
mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void ArcTo(double x1, double y1, double x2, double y2, double radius,
|
|
|
|
mozilla::ErrorResult& error);
|
|
|
|
void Rect(double x, double y, double w, double h);
|
|
|
|
void Arc(double x, double y, double radius, double startAngle,
|
|
|
|
double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
|
|
|
|
|
|
|
|
JSObject* GetMozCurrentTransform(JSContext* cx,
|
|
|
|
mozilla::ErrorResult& error) const;
|
2013-05-16 09:36:55 -07:00
|
|
|
void SetMozCurrentTransform(JSContext* cx,
|
|
|
|
JS::Handle<JSObject*> currentTransform,
|
2012-06-13 08:14:15 -07:00
|
|
|
mozilla::ErrorResult& error);
|
|
|
|
JSObject* GetMozCurrentTransformInverse(JSContext* cx,
|
|
|
|
mozilla::ErrorResult& error) const;
|
2013-05-16 09:36:55 -07:00
|
|
|
void SetMozCurrentTransformInverse(JSContext* cx,
|
|
|
|
JS::Handle<JSObject*> currentTransform,
|
2012-06-13 08:14:15 -07:00
|
|
|
mozilla::ErrorResult& error);
|
|
|
|
void GetFillRule(nsAString& fillRule);
|
|
|
|
void SetFillRule(const nsAString& fillRule);
|
|
|
|
JS::Value GetMozDash(JSContext* cx, mozilla::ErrorResult& error);
|
|
|
|
void SetMozDash(JSContext* cx, const JS::Value& mozDash,
|
|
|
|
mozilla::ErrorResult& error);
|
|
|
|
|
2012-09-11 12:08:24 -07:00
|
|
|
double MozDashOffset()
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
|
|
|
return CurrentState().dashOffset;
|
|
|
|
}
|
2012-11-13 16:35:36 -08:00
|
|
|
void SetMozDashOffset(double mozDashOffset);
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
void GetMozTextStyle(nsAString& mozTextStyle)
|
|
|
|
{
|
|
|
|
GetFont(mozTextStyle);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetMozTextStyle(const nsAString& mozTextStyle,
|
|
|
|
mozilla::ErrorResult& error)
|
|
|
|
{
|
|
|
|
SetFont(mozTextStyle, error);
|
|
|
|
}
|
|
|
|
|
2012-09-11 12:08:24 -07:00
|
|
|
bool ImageSmoothingEnabled()
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
|
|
|
return CurrentState().imageSmoothingEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetImageSmoothingEnabled(bool imageSmoothingEnabled)
|
|
|
|
{
|
|
|
|
if (imageSmoothingEnabled != CurrentState().imageSmoothingEnabled) {
|
|
|
|
CurrentState().imageSmoothingEnabled = imageSmoothingEnabled;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DrawWindow(nsIDOMWindow* window, double x, double y, double w, double h,
|
|
|
|
const nsAString& bgColor, uint32_t flags,
|
|
|
|
mozilla::ErrorResult& error);
|
2013-01-29 09:51:55 -08:00
|
|
|
void AsyncDrawXULElement(nsXULElement& elem, double x, double y, double w,
|
2012-06-13 08:14:15 -07:00
|
|
|
double h, const nsAString& bgColor, uint32_t flags,
|
|
|
|
mozilla::ErrorResult& error);
|
|
|
|
|
2013-08-23 06:52:32 -07:00
|
|
|
void Demote();
|
|
|
|
|
2012-06-13 08:14:15 -07:00
|
|
|
nsresult Redraw();
|
|
|
|
|
2013-09-30 14:02:40 -07:00
|
|
|
#ifdef DEBUG
|
|
|
|
virtual int32_t GetWidth() const MOZ_OVERRIDE;
|
|
|
|
virtual int32_t GetHeight() const MOZ_OVERRIDE;
|
|
|
|
#endif
|
2012-06-13 08:14:15 -07:00
|
|
|
// nsICanvasRenderingContextInternal
|
2013-05-29 13:43:41 -07:00
|
|
|
NS_IMETHOD SetDimensions(int32_t width, int32_t height) MOZ_OVERRIDE;
|
|
|
|
NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
NS_IMETHOD Render(gfxContext *ctx,
|
2013-10-01 14:01:19 -07:00
|
|
|
GraphicsFilter aFilter,
|
2013-05-29 13:43:41 -07:00
|
|
|
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
|
2012-06-13 08:14:15 -07:00
|
|
|
NS_IMETHOD GetInputStream(const char* aMimeType,
|
|
|
|
const PRUnichar* aEncoderOptions,
|
2013-05-29 13:43:41 -07:00
|
|
|
nsIInputStream **aStream) MOZ_OVERRIDE;
|
|
|
|
NS_IMETHOD GetThebesSurface(gfxASurface **surface) MOZ_OVERRIDE;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2013-05-29 13:43:41 -07:00
|
|
|
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE
|
2012-09-29 09:32:57 -07:00
|
|
|
{ EnsureTarget(); return mTarget->Snapshot(); }
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2013-05-29 13:43:41 -07:00
|
|
|
NS_IMETHOD SetIsOpaque(bool isOpaque) MOZ_OVERRIDE;
|
|
|
|
NS_IMETHOD Reset() MOZ_OVERRIDE;
|
2012-06-13 08:14:15 -07:00
|
|
|
already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
2012-10-12 02:42:53 -07:00
|
|
|
CanvasLayer *aOldLayer,
|
2013-05-29 13:43:41 -07:00
|
|
|
LayerManager *aManager) MOZ_OVERRIDE;
|
|
|
|
virtual bool ShouldForceInactiveLayer(LayerManager *aManager) MOZ_OVERRIDE;
|
|
|
|
void MarkContextClean() MOZ_OVERRIDE;
|
|
|
|
NS_IMETHOD SetIsIPC(bool isIPC) MOZ_OVERRIDE;
|
2012-06-13 08:14:15 -07:00
|
|
|
// this rect is in canvas device space
|
|
|
|
void Redraw(const mozilla::gfx::Rect &r);
|
2013-05-29 13:43:41 -07:00
|
|
|
NS_IMETHOD Redraw(const gfxRect &r) MOZ_OVERRIDE { Redraw(ToRect(r)); return NS_OK; }
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
// this rect is in mTarget's current user space
|
|
|
|
void RedrawUser(const gfxRect &r);
|
|
|
|
|
|
|
|
// nsISupports interface + CC
|
|
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
|
|
|
2012-11-13 16:35:36 -08:00
|
|
|
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(CanvasRenderingContext2D)
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2013-02-19 13:46:27 -08:00
|
|
|
enum CanvasMultiGetterType {
|
|
|
|
CMG_STYLE_STRING = 0,
|
|
|
|
CMG_STYLE_PATTERN = 1,
|
|
|
|
CMG_STYLE_GRADIENT = 2
|
2012-11-13 16:35:36 -08:00
|
|
|
};
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
enum Style {
|
|
|
|
STYLE_STROKE = 0,
|
|
|
|
STYLE_FILL,
|
|
|
|
STYLE_MAX
|
|
|
|
};
|
|
|
|
|
|
|
|
nsINode* GetParentObject()
|
|
|
|
{
|
|
|
|
return mCanvasElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LineTo(const mozilla::gfx::Point& aPoint)
|
|
|
|
{
|
|
|
|
if (mPathBuilder) {
|
|
|
|
mPathBuilder->LineTo(aPoint);
|
|
|
|
} else {
|
|
|
|
mDSPathBuilder->LineTo(mTarget->GetTransform() * aPoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BezierTo(const mozilla::gfx::Point& aCP1,
|
|
|
|
const mozilla::gfx::Point& aCP2,
|
|
|
|
const mozilla::gfx::Point& aCP3)
|
|
|
|
{
|
|
|
|
if (mPathBuilder) {
|
|
|
|
mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
|
|
|
|
} else {
|
|
|
|
mozilla::gfx::Matrix transform = mTarget->GetTransform();
|
|
|
|
mDSPathBuilder->BezierTo(transform * aCP1,
|
|
|
|
transform * aCP2,
|
|
|
|
transform * aCP3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-12 02:42:52 -07:00
|
|
|
friend class CanvasRenderingContext2DUserData;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
protected:
|
|
|
|
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
|
|
|
|
uint32_t aWidth, uint32_t aHeight,
|
|
|
|
JSObject** aRetval);
|
|
|
|
|
2012-11-13 16:35:36 -08:00
|
|
|
nsresult PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h,
|
|
|
|
unsigned char *aData, uint32_t aDataLen,
|
|
|
|
bool hasDirtyRect, int32_t dirtyX, int32_t dirtyY,
|
|
|
|
int32_t dirtyWidth, int32_t dirtyHeight);
|
|
|
|
|
2012-07-24 03:18:39 -07:00
|
|
|
/**
|
|
|
|
* Internal method to complete initialisation, expects mTarget to have been set
|
|
|
|
*/
|
2012-08-22 08:56:38 -07:00
|
|
|
nsresult Initialize(int32_t width, int32_t height);
|
2012-07-24 03:18:39 -07:00
|
|
|
|
2012-06-13 08:14:15 -07:00
|
|
|
nsresult InitializeWithTarget(mozilla::gfx::DrawTarget *surface,
|
2012-08-22 08:56:38 -07:00
|
|
|
int32_t width, int32_t height);
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The number of living nsCanvasRenderingContexts. When this goes down to
|
|
|
|
* 0, we free the premultiply and unpremultiply tables, if they exist.
|
|
|
|
*/
|
2012-08-22 08:56:38 -07:00
|
|
|
static uint32_t sNumLivingContexts;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Lookup table used to speed up GetImageData().
|
|
|
|
*/
|
2012-08-22 08:56:38 -07:00
|
|
|
static uint8_t (*sUnpremultiplyTable)[256];
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Lookup table used to speed up PutImageData().
|
|
|
|
*/
|
2012-08-22 08:56:38 -07:00
|
|
|
static uint8_t (*sPremultiplyTable)[256];
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-05-30 17:47:27 -07:00
|
|
|
static mozilla::gfx::DrawTarget* sErrorTarget;
|
|
|
|
|
2012-06-13 08:14:15 -07:00
|
|
|
// Some helpers. Doesn't modify a color on failure.
|
2013-07-26 11:25:54 -07:00
|
|
|
void SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& value,
|
|
|
|
Style whichStyle);
|
2012-06-13 08:14:15 -07:00
|
|
|
void SetStyleFromString(const nsAString& str, Style whichStyle);
|
|
|
|
|
2013-07-26 11:25:54 -07:00
|
|
|
void SetStyleFromGradient(CanvasGradient& gradient, Style whichStyle)
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
2013-07-26 11:25:54 -07:00
|
|
|
CurrentState().SetGradientStyle(whichStyle, &gradient);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
2013-07-26 11:25:54 -07:00
|
|
|
void SetStyleFromPattern(CanvasPattern& pattern, Style whichStyle)
|
2012-06-13 08:14:15 -07:00
|
|
|
{
|
2013-07-26 11:25:54 -07:00
|
|
|
CurrentState().SetPatternStyle(whichStyle, &pattern);
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
2013-09-17 08:16:02 -07:00
|
|
|
void GetStyleAsUnion(OwningStringOrCanvasGradientOrCanvasPattern& aValue,
|
2013-07-26 11:25:54 -07:00
|
|
|
Style aWhichStyle);
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
// Returns whether a color was successfully parsed.
|
|
|
|
bool ParseColor(const nsAString& aString, nscolor* aColor);
|
|
|
|
|
|
|
|
static void StyleColorToString(const nscolor& aColor, nsAString& aStr);
|
|
|
|
|
2012-05-30 17:47:27 -07:00
|
|
|
/**
|
|
|
|
* Creates the error target, if it doesn't exist
|
|
|
|
*/
|
|
|
|
static void EnsureErrorTarget();
|
|
|
|
|
2012-06-13 08:14:15 -07:00
|
|
|
/* This function ensures there is a writable pathbuilder available, this
|
|
|
|
* pathbuilder may be working in user space or in device space or
|
|
|
|
* device space.
|
2012-07-24 03:18:38 -07:00
|
|
|
* After calling this function mPathTransformWillUpdate will be false
|
2012-06-13 08:14:15 -07:00
|
|
|
*/
|
|
|
|
void EnsureWritablePath();
|
|
|
|
|
|
|
|
// Ensures a path in UserSpace is available.
|
2013-05-06 12:28:13 -07:00
|
|
|
void EnsureUserSpacePath(const CanvasWindingRule& winding = CanvasWindingRule::Nonzero);
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-05-30 17:47:27 -07:00
|
|
|
/**
|
|
|
|
* Needs to be called before updating the transform. This makes a call to
|
|
|
|
* EnsureTarget() so you don't have to.
|
|
|
|
*/
|
2012-06-13 08:14:15 -07:00
|
|
|
void TransformWillUpdate();
|
|
|
|
|
|
|
|
// Report the fillRule has changed.
|
|
|
|
void FillRuleChanged();
|
|
|
|
|
2012-05-30 17:47:27 -07:00
|
|
|
/**
|
|
|
|
* Create the backing surfacing, if it doesn't exist. If there is an error
|
|
|
|
* in creating the target then it will put sErrorTarget in place. If there
|
|
|
|
* is in turn an error in creating the sErrorTarget then they would both
|
|
|
|
* be null so IsTargetValid() would still return null.
|
|
|
|
*/
|
|
|
|
void EnsureTarget();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Disposes an old target and prepares to lazily create a new target.
|
|
|
|
*/
|
|
|
|
void ClearTarget();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the target is valid after calling EnsureTarget.
|
|
|
|
*/
|
2013-07-31 14:10:16 -07:00
|
|
|
bool IsTargetValid() { return mTarget != sErrorTarget && mTarget != nullptr; }
|
2012-05-30 17:47:27 -07:00
|
|
|
|
2012-06-13 08:14:15 -07:00
|
|
|
/**
|
|
|
|
* Returns the surface format this canvas should be allocated using. Takes
|
|
|
|
* into account mOpaque, platform requirements, etc.
|
|
|
|
*/
|
|
|
|
mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
|
|
|
|
|
|
|
|
void DrawImage(const HTMLImageOrCanvasOrVideoElement &imgElt,
|
|
|
|
double sx, double sy, double sw, double sh,
|
|
|
|
double dx, double dy, double dw, double dh,
|
2012-08-22 08:56:38 -07:00
|
|
|
uint8_t optional_argc, mozilla::ErrorResult& error);
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
nsString& GetFont()
|
|
|
|
{
|
|
|
|
/* will initilize the value if not set, else does nothing */
|
|
|
|
GetCurrentFontStyle();
|
|
|
|
|
|
|
|
return CurrentState().font;
|
|
|
|
}
|
|
|
|
|
2013-06-28 19:58:40 -07:00
|
|
|
#if USE_SKIA_GPU
|
|
|
|
static std::vector<CanvasRenderingContext2D*>& DemotableContexts();
|
|
|
|
static void DemoteOldestContextIfNecessary();
|
2013-08-23 06:52:32 -07:00
|
|
|
|
2013-06-28 19:58:40 -07:00
|
|
|
static void AddDemotableContext(CanvasRenderingContext2D* context);
|
2013-08-23 06:52:32 -07:00
|
|
|
static void RemoveDemotableContext(CanvasRenderingContext2D* context);
|
2013-06-28 19:58:40 -07:00
|
|
|
|
|
|
|
// Do not use GL
|
|
|
|
bool mForceSoftware;
|
|
|
|
#endif
|
|
|
|
|
2012-06-13 08:14:15 -07:00
|
|
|
// Member vars
|
2012-08-22 08:56:38 -07:00
|
|
|
int32_t mWidth, mHeight;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
// This is true when the canvas is valid, but of zero size, this requires
|
|
|
|
// specific behavior on some operations.
|
|
|
|
bool mZero;
|
|
|
|
|
|
|
|
bool mOpaque;
|
|
|
|
|
|
|
|
// This is true when the next time our layer is retrieved we need to
|
|
|
|
// recreate it (i.e. our backing surface changed)
|
|
|
|
bool mResetLayer;
|
|
|
|
// This is needed for drawing in drawAsyncXULElement
|
|
|
|
bool mIPC;
|
|
|
|
|
2012-10-12 02:42:52 -07:00
|
|
|
nsTArray<CanvasRenderingContext2DUserData*> mUserDatas;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
// If mCanvasElement is not provided, then a docshell is
|
|
|
|
nsCOMPtr<nsIDocShell> mDocShell;
|
|
|
|
|
2012-05-30 17:47:27 -07:00
|
|
|
// 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.
|
2012-06-13 08:14:15 -07:00
|
|
|
mozilla::RefPtr<mozilla::gfx::DrawTarget> mTarget;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
|
|
|
|
* Redraw is called, reset to false when Render is called.
|
|
|
|
*/
|
|
|
|
bool mIsEntireFrameInvalid;
|
|
|
|
/**
|
|
|
|
* When this is set, the first call to Redraw(gfxRect) should set
|
|
|
|
* mIsEntireFrameInvalid since we expect it will be followed by
|
|
|
|
* many more Redraw calls.
|
|
|
|
*/
|
|
|
|
bool mPredictManyRedrawCalls;
|
|
|
|
|
|
|
|
// This is stored after GetThebesSurface has been called once to avoid
|
|
|
|
// excessive ThebesSurface initialization overhead.
|
|
|
|
nsRefPtr<gfxASurface> mThebesSurface;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* We also have a device space pathbuilder. The reason for this is as
|
|
|
|
* follows, when a path is being built, but the transform changes, we
|
|
|
|
* can no longer keep a single path in userspace, considering there's
|
|
|
|
* several 'user spaces' now. We therefore transform the current path
|
|
|
|
* into device space, and add all operations to this path in device
|
|
|
|
* space.
|
|
|
|
*
|
|
|
|
* When then finally executing a render, the Azure drawing API expects
|
|
|
|
* the path to be in userspace. We could then set an identity transform
|
|
|
|
* on the DrawTarget and do all drawing in device space. This is
|
|
|
|
* undesirable because it requires transforming patterns, gradients,
|
|
|
|
* clips, etc. into device space and it would not work for stroking.
|
|
|
|
* What we do instead is convert the path back to user space when it is
|
|
|
|
* drawn, and draw it with the current transform. This makes all drawing
|
|
|
|
* occur correctly.
|
|
|
|
*
|
|
|
|
* There's never both a device space path builder and a user space path
|
|
|
|
* builder present at the same time. There is also never a path and a
|
|
|
|
* path builder present at the same time. When writing proceeds on an
|
|
|
|
* existing path the Path is cleared and a new builder is created.
|
|
|
|
*
|
|
|
|
* mPath is always in user-space.
|
|
|
|
*/
|
|
|
|
mozilla::RefPtr<mozilla::gfx::Path> mPath;
|
|
|
|
mozilla::RefPtr<mozilla::gfx::PathBuilder> mDSPathBuilder;
|
|
|
|
mozilla::RefPtr<mozilla::gfx::PathBuilder> mPathBuilder;
|
|
|
|
bool mPathTransformWillUpdate;
|
|
|
|
mozilla::gfx::Matrix mPathToDS;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Number of times we've invalidated before calling redraw
|
|
|
|
*/
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t mInvalidateCount;
|
|
|
|
static const uint32_t kCanvasMaxInvalidateCount = 100;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if a shadow should be drawn along with a
|
|
|
|
* drawing operation.
|
|
|
|
*/
|
|
|
|
bool NeedToDrawShadow()
|
|
|
|
{
|
|
|
|
const ContextState& state = CurrentState();
|
|
|
|
|
|
|
|
// The spec says we should not draw shadows if the operator is OVER.
|
|
|
|
// If it's over and the alpha value is zero, nothing needs to be drawn.
|
|
|
|
return NS_GET_A(state.shadowColor) != 0 &&
|
|
|
|
(state.shadowBlur != 0 || state.shadowOffset.x != 0 || state.shadowOffset.y != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::gfx::CompositionOp UsedOperation()
|
|
|
|
{
|
|
|
|
if (NeedToDrawShadow()) {
|
|
|
|
// In this case the shadow rendering will use the operator.
|
|
|
|
return mozilla::gfx::OP_OVER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CurrentState().op;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the pres shell from either the canvas element or the doc shell
|
|
|
|
*/
|
|
|
|
nsIPresShell *GetPresShell() {
|
|
|
|
if (mCanvasElement) {
|
|
|
|
return mCanvasElement->OwnerDoc()->GetShell();
|
|
|
|
}
|
|
|
|
if (mDocShell) {
|
2012-12-28 17:56:42 -08:00
|
|
|
return mDocShell->GetPresShell();
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
2012-07-30 07:20:58 -07:00
|
|
|
return nullptr;
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// text
|
|
|
|
enum TextAlign {
|
|
|
|
TEXT_ALIGN_START,
|
|
|
|
TEXT_ALIGN_END,
|
|
|
|
TEXT_ALIGN_LEFT,
|
|
|
|
TEXT_ALIGN_RIGHT,
|
|
|
|
TEXT_ALIGN_CENTER
|
|
|
|
};
|
|
|
|
|
|
|
|
enum TextBaseline {
|
|
|
|
TEXT_BASELINE_TOP,
|
|
|
|
TEXT_BASELINE_HANGING,
|
|
|
|
TEXT_BASELINE_MIDDLE,
|
|
|
|
TEXT_BASELINE_ALPHABETIC,
|
|
|
|
TEXT_BASELINE_IDEOGRAPHIC,
|
|
|
|
TEXT_BASELINE_BOTTOM
|
|
|
|
};
|
|
|
|
|
|
|
|
gfxFontGroup *GetCurrentFontStyle();
|
|
|
|
|
|
|
|
enum TextDrawOperation {
|
|
|
|
TEXT_DRAW_OPERATION_FILL,
|
|
|
|
TEXT_DRAW_OPERATION_STROKE,
|
|
|
|
TEXT_DRAW_OPERATION_MEASURE
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Implementation of the fillText, strokeText, and measure functions with
|
|
|
|
* the operation abstracted to a flag.
|
|
|
|
*/
|
|
|
|
nsresult DrawOrMeasureText(const nsAString& text,
|
2012-10-12 02:42:53 -07:00
|
|
|
float x,
|
|
|
|
float y,
|
2013-07-26 11:25:54 -07:00
|
|
|
const Optional<double>& maxWidth,
|
2012-10-12 02:42:53 -07:00
|
|
|
TextDrawOperation op,
|
|
|
|
float* aWidth);
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
// state stack handling
|
|
|
|
class ContextState {
|
|
|
|
public:
|
2012-10-12 02:42:53 -07:00
|
|
|
ContextState() : textAlign(TEXT_ALIGN_START),
|
|
|
|
textBaseline(TEXT_BASELINE_ALPHABETIC),
|
|
|
|
lineWidth(1.0f),
|
|
|
|
miterLimit(10.0f),
|
|
|
|
globalAlpha(1.0f),
|
|
|
|
shadowBlur(0.0),
|
|
|
|
dashOffset(0.0f),
|
|
|
|
op(mozilla::gfx::OP_OVER),
|
|
|
|
fillRule(mozilla::gfx::FILL_WINDING),
|
|
|
|
lineCap(mozilla::gfx::CAP_BUTT),
|
|
|
|
lineJoin(mozilla::gfx::JOIN_MITER_OR_BEVEL),
|
|
|
|
imageSmoothingEnabled(true)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
ContextState(const ContextState& other)
|
|
|
|
: fontGroup(other.fontGroup),
|
|
|
|
font(other.font),
|
|
|
|
textAlign(other.textAlign),
|
|
|
|
textBaseline(other.textBaseline),
|
|
|
|
shadowColor(other.shadowColor),
|
|
|
|
transform(other.transform),
|
|
|
|
shadowOffset(other.shadowOffset),
|
|
|
|
lineWidth(other.lineWidth),
|
|
|
|
miterLimit(other.miterLimit),
|
|
|
|
globalAlpha(other.globalAlpha),
|
|
|
|
shadowBlur(other.shadowBlur),
|
|
|
|
dash(other.dash),
|
|
|
|
dashOffset(other.dashOffset),
|
|
|
|
op(other.op),
|
|
|
|
fillRule(other.fillRule),
|
|
|
|
lineCap(other.lineCap),
|
|
|
|
lineJoin(other.lineJoin),
|
|
|
|
imageSmoothingEnabled(other.imageSmoothingEnabled)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < STYLE_MAX; i++) {
|
|
|
|
colorStyles[i] = other.colorStyles[i];
|
|
|
|
gradientStyles[i] = other.gradientStyles[i];
|
|
|
|
patternStyles[i] = other.patternStyles[i];
|
2012-06-13 08:14:15 -07:00
|
|
|
}
|
2012-10-12 02:42:53 -07:00
|
|
|
}
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
void SetColorStyle(Style whichStyle, nscolor color)
|
|
|
|
{
|
|
|
|
colorStyles[whichStyle] = color;
|
|
|
|
gradientStyles[whichStyle] = nullptr;
|
|
|
|
patternStyles[whichStyle] = nullptr;
|
|
|
|
}
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
void SetPatternStyle(Style whichStyle, CanvasPattern* pat)
|
|
|
|
{
|
|
|
|
gradientStyles[whichStyle] = nullptr;
|
|
|
|
patternStyles[whichStyle] = pat;
|
|
|
|
}
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
void SetGradientStyle(Style whichStyle, CanvasGradient* grad)
|
|
|
|
{
|
|
|
|
gradientStyles[whichStyle] = grad;
|
|
|
|
patternStyles[whichStyle] = nullptr;
|
|
|
|
}
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
/**
|
|
|
|
* returns true iff the given style is a solid color.
|
|
|
|
*/
|
|
|
|
bool StyleIsColor(Style whichStyle) const
|
|
|
|
{
|
|
|
|
return !(patternStyles[whichStyle] || gradientStyles[whichStyle]);
|
|
|
|
}
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
std::vector<mozilla::RefPtr<mozilla::gfx::Path> > clipsPushed;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
nsRefPtr<gfxFontGroup> fontGroup;
|
|
|
|
nsRefPtr<CanvasGradient> gradientStyles[STYLE_MAX];
|
|
|
|
nsRefPtr<CanvasPattern> patternStyles[STYLE_MAX];
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
nsString font;
|
|
|
|
TextAlign textAlign;
|
|
|
|
TextBaseline textBaseline;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
nscolor colorStyles[STYLE_MAX];
|
|
|
|
nscolor shadowColor;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
mozilla::gfx::Matrix transform;
|
|
|
|
mozilla::gfx::Point shadowOffset;
|
|
|
|
mozilla::gfx::Float lineWidth;
|
|
|
|
mozilla::gfx::Float miterLimit;
|
|
|
|
mozilla::gfx::Float globalAlpha;
|
|
|
|
mozilla::gfx::Float shadowBlur;
|
|
|
|
FallibleTArray<mozilla::gfx::Float> dash;
|
|
|
|
mozilla::gfx::Float dashOffset;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
mozilla::gfx::CompositionOp op;
|
|
|
|
mozilla::gfx::FillRule fillRule;
|
|
|
|
mozilla::gfx::CapStyle lineCap;
|
|
|
|
mozilla::gfx::JoinStyle lineJoin;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
2012-10-12 02:42:53 -07:00
|
|
|
bool imageSmoothingEnabled;
|
2012-06-13 08:14:15 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
nsAutoTArray<ContextState, 3> mStyleStack;
|
|
|
|
|
|
|
|
inline ContextState& CurrentState() {
|
|
|
|
return mStyleStack[mStyleStack.Length() - 1];
|
|
|
|
}
|
|
|
|
|
2012-06-29 11:20:13 -07:00
|
|
|
friend class CanvasGeneralPattern;
|
2012-06-13 08:14:15 -07:00
|
|
|
friend class AdjustedTarget;
|
|
|
|
|
|
|
|
// other helpers
|
2013-02-19 13:46:27 -08:00
|
|
|
void GetAppUnitsValues(int32_t *perDevPixel, int32_t *perCSSPixel)
|
2012-10-12 02:42:53 -07:00
|
|
|
{
|
2012-06-13 08:14:15 -07:00
|
|
|
// If we don't have a canvas element, we just return something generic.
|
2013-02-19 13:46:27 -08:00
|
|
|
int32_t devPixel = 60;
|
|
|
|
int32_t cssPixel = 60;
|
2012-06-13 08:14:15 -07:00
|
|
|
|
|
|
|
nsIPresShell *ps = GetPresShell();
|
|
|
|
nsPresContext *pc;
|
|
|
|
|
|
|
|
if (!ps) goto FINISH;
|
|
|
|
pc = ps->GetPresContext();
|
|
|
|
if (!pc) goto FINISH;
|
|
|
|
devPixel = pc->AppUnitsPerDevPixel();
|
|
|
|
cssPixel = pc->AppUnitsPerCSSPixel();
|
|
|
|
|
|
|
|
FINISH:
|
|
|
|
if (perDevPixel)
|
|
|
|
*perDevPixel = devPixel;
|
|
|
|
if (perCSSPixel)
|
|
|
|
*perCSSPixel = cssPixel;
|
|
|
|
}
|
|
|
|
|
2012-10-12 02:42:52 -07:00
|
|
|
friend struct CanvasBidiProcessor;
|
2012-06-13 08:14:15 -07:00
|
|
|
};
|
|
|
|
|
2012-10-12 02:42:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* CanvasRenderingContext2D_h */
|