content/canvas/src/CanvasRenderingContext2D.h

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #ifndef CanvasRenderingContext2D_h
michael@0 6 #define CanvasRenderingContext2D_h
michael@0 7
michael@0 8 #include "mozilla/Attributes.h"
michael@0 9 #include <vector>
michael@0 10 #include "nsIDOMCanvasRenderingContext2D.h"
michael@0 11 #include "nsICanvasRenderingContextInternal.h"
michael@0 12 #include "mozilla/RefPtr.h"
michael@0 13 #include "nsColor.h"
michael@0 14 #include "mozilla/dom/HTMLCanvasElement.h"
michael@0 15 #include "mozilla/dom/HTMLVideoElement.h"
michael@0 16 #include "CanvasUtils.h"
michael@0 17 #include "gfxFont.h"
michael@0 18 #include "mozilla/ErrorResult.h"
michael@0 19 #include "mozilla/dom/CanvasGradient.h"
michael@0 20 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
michael@0 21 #include "mozilla/dom/CanvasPattern.h"
michael@0 22 #include "mozilla/gfx/Rect.h"
michael@0 23 #include "mozilla/gfx/2D.h"
michael@0 24 #include "gfx2DGlue.h"
michael@0 25 #include "imgIEncoder.h"
michael@0 26 #include "nsLayoutUtils.h"
michael@0 27 #include "mozilla/EnumeratedArray.h"
michael@0 28
michael@0 29 class nsGlobalWindow;
michael@0 30 class nsXULElement;
michael@0 31
michael@0 32 namespace mozilla {
michael@0 33 namespace gfx {
michael@0 34 class SourceSurface;
michael@0 35 class SurfaceStream;
michael@0 36 }
michael@0 37
michael@0 38 namespace dom {
michael@0 39 class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
michael@0 40 class ImageData;
michael@0 41 class StringOrCanvasGradientOrCanvasPattern;
michael@0 42 class OwningStringOrCanvasGradientOrCanvasPattern;
michael@0 43 class TextMetrics;
michael@0 44
michael@0 45 extern const mozilla::gfx::Float SIGMA_MAX;
michael@0 46
michael@0 47 template<typename T> class Optional;
michael@0 48
michael@0 49 class CanvasPath MOZ_FINAL :
michael@0 50 public nsWrapperCache
michael@0 51 {
michael@0 52 public:
michael@0 53 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPath)
michael@0 54 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
michael@0 55
michael@0 56 nsCOMPtr<nsISupports> GetParentObject() { return mParent; }
michael@0 57
michael@0 58 JSObject* WrapObject(JSContext* aCx);
michael@0 59
michael@0 60 static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
michael@0 61 ErrorResult& rv);
michael@0 62 static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
michael@0 63 CanvasPath& aCanvasPath,
michael@0 64 ErrorResult& rv);
michael@0 65 static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
michael@0 66 const nsAString& aPathString,
michael@0 67 ErrorResult& rv);
michael@0 68
michael@0 69 void ClosePath();
michael@0 70 void MoveTo(double x, double y);
michael@0 71 void LineTo(double x, double y);
michael@0 72 void QuadraticCurveTo(double cpx, double cpy, double x, double y);
michael@0 73 void BezierCurveTo(double cp1x, double cp1y,
michael@0 74 double cp2x, double cp2y,
michael@0 75 double x, double y);
michael@0 76 void ArcTo(double x1, double y1, double x2, double y2, double radius,
michael@0 77 ErrorResult& error);
michael@0 78 void Rect(double x, double y, double w, double h);
michael@0 79 void Arc(double x, double y, double radius,
michael@0 80 double startAngle, double endAngle, bool anticlockwise,
michael@0 81 ErrorResult& error);
michael@0 82
michael@0 83 void LineTo(const gfx::Point& aPoint);
michael@0 84 void BezierTo(const gfx::Point& aCP1,
michael@0 85 const gfx::Point& aCP2,
michael@0 86 const gfx::Point& aCP3);
michael@0 87
michael@0 88 mozilla::RefPtr<mozilla::gfx::Path> GetPath(const CanvasWindingRule& winding,
michael@0 89 const mozilla::RefPtr<mozilla::gfx::DrawTarget>& mTarget) const;
michael@0 90
michael@0 91 explicit CanvasPath(nsISupports* aParent);
michael@0 92 CanvasPath(nsISupports* aParent, RefPtr<gfx::PathBuilder> mPathBuilder);
michael@0 93 virtual ~CanvasPath() {}
michael@0 94
michael@0 95 private:
michael@0 96
michael@0 97 nsCOMPtr<nsISupports> mParent;
michael@0 98 static gfx::Float ToFloat(double aValue) { return gfx::Float(aValue); }
michael@0 99
michael@0 100 mutable RefPtr<gfx::Path> mPath;
michael@0 101 mutable RefPtr<gfx::PathBuilder> mPathBuilder;
michael@0 102
michael@0 103 void EnsurePathBuilder() const;
michael@0 104 };
michael@0 105
michael@0 106 struct CanvasBidiProcessor;
michael@0 107 class CanvasRenderingContext2DUserData;
michael@0 108
michael@0 109 /**
michael@0 110 ** CanvasRenderingContext2D
michael@0 111 **/
michael@0 112 class CanvasRenderingContext2D :
michael@0 113 public nsICanvasRenderingContextInternal,
michael@0 114 public nsWrapperCache
michael@0 115 {
michael@0 116 typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
michael@0 117 HTMLImageOrCanvasOrVideoElement;
michael@0 118
michael@0 119 public:
michael@0 120 CanvasRenderingContext2D();
michael@0 121 virtual ~CanvasRenderingContext2D();
michael@0 122
michael@0 123 virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
michael@0 124
michael@0 125 HTMLCanvasElement* GetCanvas() const
michael@0 126 {
michael@0 127 // corresponds to changes to the old bindings made in bug 745025
michael@0 128 return mCanvasElement->GetOriginalCanvas();
michael@0 129 }
michael@0 130
michael@0 131 void Save();
michael@0 132 void Restore();
michael@0 133 void Scale(double x, double y, mozilla::ErrorResult& error);
michael@0 134 void Rotate(double angle, mozilla::ErrorResult& error);
michael@0 135 void Translate(double x, double y, mozilla::ErrorResult& error);
michael@0 136 void Transform(double m11, double m12, double m21, double m22, double dx,
michael@0 137 double dy, mozilla::ErrorResult& error);
michael@0 138 void SetTransform(double m11, double m12, double m21, double m22, double dx,
michael@0 139 double dy, mozilla::ErrorResult& error);
michael@0 140
michael@0 141 double GlobalAlpha()
michael@0 142 {
michael@0 143 return CurrentState().globalAlpha;
michael@0 144 }
michael@0 145
michael@0 146 // Useful for silencing cast warnings
michael@0 147 static mozilla::gfx::Float ToFloat(double aValue) { return mozilla::gfx::Float(aValue); }
michael@0 148
michael@0 149 void SetGlobalAlpha(double globalAlpha)
michael@0 150 {
michael@0 151 if (globalAlpha >= 0.0 && globalAlpha <= 1.0) {
michael@0 152 CurrentState().globalAlpha = ToFloat(globalAlpha);
michael@0 153 }
michael@0 154 }
michael@0 155
michael@0 156 void GetGlobalCompositeOperation(nsAString& op, mozilla::ErrorResult& error);
michael@0 157 void SetGlobalCompositeOperation(const nsAString& op,
michael@0 158 mozilla::ErrorResult& error);
michael@0 159
michael@0 160 void GetStrokeStyle(OwningStringOrCanvasGradientOrCanvasPattern& value)
michael@0 161 {
michael@0 162 GetStyleAsUnion(value, Style::STROKE);
michael@0 163 }
michael@0 164
michael@0 165 void SetStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& value)
michael@0 166 {
michael@0 167 SetStyleFromUnion(value, Style::STROKE);
michael@0 168 }
michael@0 169
michael@0 170 void GetFillStyle(OwningStringOrCanvasGradientOrCanvasPattern& value)
michael@0 171 {
michael@0 172 GetStyleAsUnion(value, Style::FILL);
michael@0 173 }
michael@0 174
michael@0 175 void SetFillStyle(const StringOrCanvasGradientOrCanvasPattern& value)
michael@0 176 {
michael@0 177 SetStyleFromUnion(value, Style::FILL);
michael@0 178 }
michael@0 179
michael@0 180 already_AddRefed<CanvasGradient>
michael@0 181 CreateLinearGradient(double x0, double y0, double x1, double y1);
michael@0 182 already_AddRefed<CanvasGradient>
michael@0 183 CreateRadialGradient(double x0, double y0, double r0, double x1, double y1,
michael@0 184 double r1, ErrorResult& aError);
michael@0 185 already_AddRefed<CanvasPattern>
michael@0 186 CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
michael@0 187 const nsAString& repeat, ErrorResult& error);
michael@0 188
michael@0 189 double ShadowOffsetX()
michael@0 190 {
michael@0 191 return CurrentState().shadowOffset.x;
michael@0 192 }
michael@0 193
michael@0 194 void SetShadowOffsetX(double shadowOffsetX)
michael@0 195 {
michael@0 196 CurrentState().shadowOffset.x = ToFloat(shadowOffsetX);
michael@0 197 }
michael@0 198
michael@0 199 double ShadowOffsetY()
michael@0 200 {
michael@0 201 return CurrentState().shadowOffset.y;
michael@0 202 }
michael@0 203
michael@0 204 void SetShadowOffsetY(double shadowOffsetY)
michael@0 205 {
michael@0 206 CurrentState().shadowOffset.y = ToFloat(shadowOffsetY);
michael@0 207 }
michael@0 208
michael@0 209 double ShadowBlur()
michael@0 210 {
michael@0 211 return CurrentState().shadowBlur;
michael@0 212 }
michael@0 213
michael@0 214 void SetShadowBlur(double shadowBlur)
michael@0 215 {
michael@0 216 if (shadowBlur >= 0.0) {
michael@0 217 CurrentState().shadowBlur = ToFloat(shadowBlur);
michael@0 218 }
michael@0 219 }
michael@0 220
michael@0 221 void GetShadowColor(nsAString& shadowColor)
michael@0 222 {
michael@0 223 StyleColorToString(CurrentState().shadowColor, shadowColor);
michael@0 224 }
michael@0 225
michael@0 226 void SetShadowColor(const nsAString& shadowColor);
michael@0 227 void ClearRect(double x, double y, double w, double h);
michael@0 228 void FillRect(double x, double y, double w, double h);
michael@0 229 void StrokeRect(double x, double y, double w, double h);
michael@0 230 void BeginPath();
michael@0 231 void Fill(const CanvasWindingRule& winding);
michael@0 232 void Fill(const CanvasPath& path, const CanvasWindingRule& winding);
michael@0 233 void Stroke();
michael@0 234 void Stroke(const CanvasPath& path);
michael@0 235 void DrawFocusIfNeeded(mozilla::dom::Element& element);
michael@0 236 bool DrawCustomFocusRing(mozilla::dom::Element& element);
michael@0 237 void Clip(const CanvasWindingRule& winding);
michael@0 238 void Clip(const CanvasPath& path, const CanvasWindingRule& winding);
michael@0 239 bool IsPointInPath(JSContext* cx, double x, double y,
michael@0 240 const CanvasWindingRule& winding);
michael@0 241 bool IsPointInPath(JSContext* cx, const CanvasPath& path, double x, double y,
michael@0 242 const CanvasWindingRule& winding);
michael@0 243 bool IsPointInStroke(JSContext* cx, double x, double y);
michael@0 244 bool IsPointInStroke(JSContext* cx, const CanvasPath& path,
michael@0 245 double x, double y);
michael@0 246 void FillText(const nsAString& text, double x, double y,
michael@0 247 const Optional<double>& maxWidth,
michael@0 248 mozilla::ErrorResult& error);
michael@0 249 void StrokeText(const nsAString& text, double x, double y,
michael@0 250 const Optional<double>& maxWidth,
michael@0 251 mozilla::ErrorResult& error);
michael@0 252 TextMetrics*
michael@0 253 MeasureText(const nsAString& rawText, mozilla::ErrorResult& error);
michael@0 254
michael@0 255 void AddHitRegion(const HitRegionOptions& options, mozilla::ErrorResult& error);
michael@0 256 void RemoveHitRegion(const nsAString& id);
michael@0 257
michael@0 258 void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
michael@0 259 double dx, double dy, mozilla::ErrorResult& error)
michael@0 260 {
michael@0 261 DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, 0.0, 0.0, 0, error);
michael@0 262 }
michael@0 263
michael@0 264 void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
michael@0 265 double dx, double dy, double dw, double dh,
michael@0 266 mozilla::ErrorResult& error)
michael@0 267 {
michael@0 268 DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, dw, dh, 2, error);
michael@0 269 }
michael@0 270
michael@0 271 void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
michael@0 272 double sx, double sy, double sw, double sh, double dx,
michael@0 273 double dy, double dw, double dh, mozilla::ErrorResult& error)
michael@0 274 {
michael@0 275 DrawImage(image, sx, sy, sw, sh, dx, dy, dw, dh, 6, error);
michael@0 276 }
michael@0 277
michael@0 278 already_AddRefed<ImageData>
michael@0 279 CreateImageData(JSContext* cx, double sw, double sh,
michael@0 280 mozilla::ErrorResult& error);
michael@0 281 already_AddRefed<ImageData>
michael@0 282 CreateImageData(JSContext* cx, ImageData& imagedata,
michael@0 283 mozilla::ErrorResult& error);
michael@0 284 already_AddRefed<ImageData>
michael@0 285 GetImageData(JSContext* cx, double sx, double sy, double sw, double sh,
michael@0 286 mozilla::ErrorResult& error);
michael@0 287 void PutImageData(ImageData& imageData,
michael@0 288 double dx, double dy, mozilla::ErrorResult& error);
michael@0 289 void PutImageData(ImageData& imageData,
michael@0 290 double dx, double dy, double dirtyX, double dirtyY,
michael@0 291 double dirtyWidth, double dirtyHeight,
michael@0 292 mozilla::ErrorResult& error);
michael@0 293
michael@0 294 double LineWidth()
michael@0 295 {
michael@0 296 return CurrentState().lineWidth;
michael@0 297 }
michael@0 298
michael@0 299 void SetLineWidth(double width)
michael@0 300 {
michael@0 301 if (width > 0.0) {
michael@0 302 CurrentState().lineWidth = ToFloat(width);
michael@0 303 }
michael@0 304 }
michael@0 305 void GetLineCap(nsAString& linecap);
michael@0 306 void SetLineCap(const nsAString& linecap);
michael@0 307 void GetLineJoin(nsAString& linejoin, mozilla::ErrorResult& error);
michael@0 308 void SetLineJoin(const nsAString& linejoin);
michael@0 309
michael@0 310 double MiterLimit()
michael@0 311 {
michael@0 312 return CurrentState().miterLimit;
michael@0 313 }
michael@0 314
michael@0 315 void SetMiterLimit(double miter)
michael@0 316 {
michael@0 317 if (miter > 0.0) {
michael@0 318 CurrentState().miterLimit = ToFloat(miter);
michael@0 319 }
michael@0 320 }
michael@0 321
michael@0 322 void GetFont(nsAString& font)
michael@0 323 {
michael@0 324 font = GetFont();
michael@0 325 }
michael@0 326
michael@0 327 void SetFont(const nsAString& font, mozilla::ErrorResult& error);
michael@0 328 void GetTextAlign(nsAString& textAlign);
michael@0 329 void SetTextAlign(const nsAString& textAlign);
michael@0 330 void GetTextBaseline(nsAString& textBaseline);
michael@0 331 void SetTextBaseline(const nsAString& textBaseline);
michael@0 332
michael@0 333 void ClosePath()
michael@0 334 {
michael@0 335 EnsureWritablePath();
michael@0 336
michael@0 337 if (mPathBuilder) {
michael@0 338 mPathBuilder->Close();
michael@0 339 } else {
michael@0 340 mDSPathBuilder->Close();
michael@0 341 }
michael@0 342 }
michael@0 343
michael@0 344 void MoveTo(double x, double y)
michael@0 345 {
michael@0 346 EnsureWritablePath();
michael@0 347
michael@0 348 if (mPathBuilder) {
michael@0 349 mPathBuilder->MoveTo(mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
michael@0 350 } else {
michael@0 351 mDSPathBuilder->MoveTo(mTarget->GetTransform() *
michael@0 352 mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
michael@0 353 }
michael@0 354 }
michael@0 355
michael@0 356 void LineTo(double x, double y)
michael@0 357 {
michael@0 358 EnsureWritablePath();
michael@0 359
michael@0 360 LineTo(mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
michael@0 361 }
michael@0 362
michael@0 363 void QuadraticCurveTo(double cpx, double cpy, double x, double y)
michael@0 364 {
michael@0 365 EnsureWritablePath();
michael@0 366
michael@0 367 if (mPathBuilder) {
michael@0 368 mPathBuilder->QuadraticBezierTo(mozilla::gfx::Point(ToFloat(cpx), ToFloat(cpy)),
michael@0 369 mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
michael@0 370 } else {
michael@0 371 mozilla::gfx::Matrix transform = mTarget->GetTransform();
michael@0 372 mDSPathBuilder->QuadraticBezierTo(transform *
michael@0 373 mozilla::gfx::Point(ToFloat(cpx), ToFloat(cpy)),
michael@0 374 transform *
michael@0 375 mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
michael@0 376 }
michael@0 377 }
michael@0 378
michael@0 379 void BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y)
michael@0 380 {
michael@0 381 EnsureWritablePath();
michael@0 382
michael@0 383 BezierTo(mozilla::gfx::Point(ToFloat(cp1x), ToFloat(cp1y)),
michael@0 384 mozilla::gfx::Point(ToFloat(cp2x), ToFloat(cp2y)),
michael@0 385 mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
michael@0 386 }
michael@0 387
michael@0 388 void ArcTo(double x1, double y1, double x2, double y2, double radius,
michael@0 389 mozilla::ErrorResult& error);
michael@0 390 void Rect(double x, double y, double w, double h);
michael@0 391 void Arc(double x, double y, double radius, double startAngle,
michael@0 392 double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
michael@0 393
michael@0 394 void GetMozCurrentTransform(JSContext* cx,
michael@0 395 JS::MutableHandle<JSObject*> result,
michael@0 396 mozilla::ErrorResult& error) const;
michael@0 397 void SetMozCurrentTransform(JSContext* cx,
michael@0 398 JS::Handle<JSObject*> currentTransform,
michael@0 399 mozilla::ErrorResult& error);
michael@0 400 void GetMozCurrentTransformInverse(JSContext* cx,
michael@0 401 JS::MutableHandle<JSObject*> result,
michael@0 402 mozilla::ErrorResult& error) const;
michael@0 403 void SetMozCurrentTransformInverse(JSContext* cx,
michael@0 404 JS::Handle<JSObject*> currentTransform,
michael@0 405 mozilla::ErrorResult& error);
michael@0 406 void GetFillRule(nsAString& fillRule);
michael@0 407 void SetFillRule(const nsAString& fillRule);
michael@0 408 void GetMozDash(JSContext* cx, JS::MutableHandle<JS::Value> retval,
michael@0 409 mozilla::ErrorResult& error);
michael@0 410 void SetMozDash(JSContext* cx, const JS::Value& mozDash,
michael@0 411 mozilla::ErrorResult& error);
michael@0 412
michael@0 413 void SetLineDash(const Sequence<double>& mSegments);
michael@0 414 void GetLineDash(nsTArray<double>& mSegments) const;
michael@0 415
michael@0 416 void SetLineDashOffset(double mOffset);
michael@0 417 double LineDashOffset() const;
michael@0 418
michael@0 419 double MozDashOffset()
michael@0 420 {
michael@0 421 return CurrentState().dashOffset;
michael@0 422 }
michael@0 423 void SetMozDashOffset(double mozDashOffset);
michael@0 424
michael@0 425 void GetMozTextStyle(nsAString& mozTextStyle)
michael@0 426 {
michael@0 427 GetFont(mozTextStyle);
michael@0 428 }
michael@0 429
michael@0 430 void SetMozTextStyle(const nsAString& mozTextStyle,
michael@0 431 mozilla::ErrorResult& error)
michael@0 432 {
michael@0 433 SetFont(mozTextStyle, error);
michael@0 434 }
michael@0 435
michael@0 436 bool ImageSmoothingEnabled()
michael@0 437 {
michael@0 438 return CurrentState().imageSmoothingEnabled;
michael@0 439 }
michael@0 440
michael@0 441 void SetImageSmoothingEnabled(bool imageSmoothingEnabled)
michael@0 442 {
michael@0 443 if (imageSmoothingEnabled != CurrentState().imageSmoothingEnabled) {
michael@0 444 CurrentState().imageSmoothingEnabled = imageSmoothingEnabled;
michael@0 445 }
michael@0 446 }
michael@0 447
michael@0 448 void DrawWindow(nsGlobalWindow& window, double x, double y, double w, double h,
michael@0 449 const nsAString& bgColor, uint32_t flags,
michael@0 450 mozilla::ErrorResult& error);
michael@0 451 void AsyncDrawXULElement(nsXULElement& elem, double x, double y, double w,
michael@0 452 double h, const nsAString& bgColor, uint32_t flags,
michael@0 453 mozilla::ErrorResult& error);
michael@0 454
michael@0 455 void Demote();
michael@0 456
michael@0 457 nsresult Redraw();
michael@0 458
michael@0 459 #ifdef DEBUG
michael@0 460 virtual int32_t GetWidth() const MOZ_OVERRIDE;
michael@0 461 virtual int32_t GetHeight() const MOZ_OVERRIDE;
michael@0 462 #endif
michael@0 463 // nsICanvasRenderingContextInternal
michael@0 464 NS_IMETHOD SetDimensions(int32_t width, int32_t height) MOZ_OVERRIDE;
michael@0 465 NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE;
michael@0 466
michael@0 467 NS_IMETHOD GetInputStream(const char* aMimeType,
michael@0 468 const char16_t* aEncoderOptions,
michael@0 469 nsIInputStream **aStream) MOZ_OVERRIDE;
michael@0 470
michael@0 471 mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) MOZ_OVERRIDE
michael@0 472 {
michael@0 473 EnsureTarget();
michael@0 474 if (aPremultAlpha) {
michael@0 475 *aPremultAlpha = true;
michael@0 476 }
michael@0 477 return mTarget->Snapshot();
michael@0 478 }
michael@0 479
michael@0 480 NS_IMETHOD SetIsOpaque(bool isOpaque) MOZ_OVERRIDE;
michael@0 481 bool GetIsOpaque() MOZ_OVERRIDE { return mOpaque; }
michael@0 482 NS_IMETHOD Reset() MOZ_OVERRIDE;
michael@0 483 already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
michael@0 484 CanvasLayer *aOldLayer,
michael@0 485 LayerManager *aManager) MOZ_OVERRIDE;
michael@0 486 virtual bool ShouldForceInactiveLayer(LayerManager *aManager) MOZ_OVERRIDE;
michael@0 487 void MarkContextClean() MOZ_OVERRIDE;
michael@0 488 NS_IMETHOD SetIsIPC(bool isIPC) MOZ_OVERRIDE;
michael@0 489 // this rect is in canvas device space
michael@0 490 void Redraw(const mozilla::gfx::Rect &r);
michael@0 491 NS_IMETHOD Redraw(const gfxRect &r) MOZ_OVERRIDE { Redraw(ToRect(r)); return NS_OK; }
michael@0 492 NS_IMETHOD SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions) MOZ_OVERRIDE;
michael@0 493
michael@0 494 // this rect is in mTarget's current user space
michael@0 495 void RedrawUser(const gfxRect &r);
michael@0 496
michael@0 497 // nsISupports interface + CC
michael@0 498 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
michael@0 499
michael@0 500 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(CanvasRenderingContext2D)
michael@0 501
michael@0 502 MOZ_BEGIN_NESTED_ENUM_CLASS(CanvasMultiGetterType, uint8_t)
michael@0 503 STRING = 0,
michael@0 504 PATTERN = 1,
michael@0 505 GRADIENT = 2
michael@0 506 MOZ_END_NESTED_ENUM_CLASS(CanvasMultiGetterType)
michael@0 507
michael@0 508 MOZ_BEGIN_NESTED_ENUM_CLASS(Style, uint8_t)
michael@0 509 STROKE = 0,
michael@0 510 FILL,
michael@0 511 MAX
michael@0 512 MOZ_END_NESTED_ENUM_CLASS(Style)
michael@0 513
michael@0 514 nsINode* GetParentObject()
michael@0 515 {
michael@0 516 return mCanvasElement;
michael@0 517 }
michael@0 518
michael@0 519 void LineTo(const mozilla::gfx::Point& aPoint)
michael@0 520 {
michael@0 521 if (mPathBuilder) {
michael@0 522 mPathBuilder->LineTo(aPoint);
michael@0 523 } else {
michael@0 524 mDSPathBuilder->LineTo(mTarget->GetTransform() * aPoint);
michael@0 525 }
michael@0 526 }
michael@0 527
michael@0 528 void BezierTo(const mozilla::gfx::Point& aCP1,
michael@0 529 const mozilla::gfx::Point& aCP2,
michael@0 530 const mozilla::gfx::Point& aCP3)
michael@0 531 {
michael@0 532 if (mPathBuilder) {
michael@0 533 mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
michael@0 534 } else {
michael@0 535 mozilla::gfx::Matrix transform = mTarget->GetTransform();
michael@0 536 mDSPathBuilder->BezierTo(transform * aCP1,
michael@0 537 transform * aCP2,
michael@0 538 transform * aCP3);
michael@0 539 }
michael@0 540 }
michael@0 541
michael@0 542 friend class CanvasRenderingContext2DUserData;
michael@0 543
michael@0 544 virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
michael@0 545
michael@0 546 protected:
michael@0 547 nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
michael@0 548 uint32_t aWidth, uint32_t aHeight,
michael@0 549 JSObject** aRetval);
michael@0 550
michael@0 551 nsresult PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h,
michael@0 552 dom::Uint8ClampedArray* aArray,
michael@0 553 bool hasDirtyRect, int32_t dirtyX, int32_t dirtyY,
michael@0 554 int32_t dirtyWidth, int32_t dirtyHeight);
michael@0 555
michael@0 556 /**
michael@0 557 * Internal method to complete initialisation, expects mTarget to have been set
michael@0 558 */
michael@0 559 nsresult Initialize(int32_t width, int32_t height);
michael@0 560
michael@0 561 nsresult InitializeWithTarget(mozilla::gfx::DrawTarget *surface,
michael@0 562 int32_t width, int32_t height);
michael@0 563
michael@0 564 /**
michael@0 565 * The number of living nsCanvasRenderingContexts. When this goes down to
michael@0 566 * 0, we free the premultiply and unpremultiply tables, if they exist.
michael@0 567 */
michael@0 568 static uint32_t sNumLivingContexts;
michael@0 569
michael@0 570 /**
michael@0 571 * Lookup table used to speed up GetImageData().
michael@0 572 */
michael@0 573 static uint8_t (*sUnpremultiplyTable)[256];
michael@0 574
michael@0 575 /**
michael@0 576 * Lookup table used to speed up PutImageData().
michael@0 577 */
michael@0 578 static uint8_t (*sPremultiplyTable)[256];
michael@0 579
michael@0 580 static mozilla::gfx::DrawTarget* sErrorTarget;
michael@0 581
michael@0 582 // Some helpers. Doesn't modify a color on failure.
michael@0 583 void SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& value,
michael@0 584 Style whichStyle);
michael@0 585 void SetStyleFromString(const nsAString& str, Style whichStyle);
michael@0 586
michael@0 587 void SetStyleFromGradient(CanvasGradient& gradient, Style whichStyle)
michael@0 588 {
michael@0 589 CurrentState().SetGradientStyle(whichStyle, &gradient);
michael@0 590 }
michael@0 591
michael@0 592 void SetStyleFromPattern(CanvasPattern& pattern, Style whichStyle)
michael@0 593 {
michael@0 594 CurrentState().SetPatternStyle(whichStyle, &pattern);
michael@0 595 }
michael@0 596
michael@0 597 void GetStyleAsUnion(OwningStringOrCanvasGradientOrCanvasPattern& aValue,
michael@0 598 Style aWhichStyle);
michael@0 599
michael@0 600 // Returns whether a color was successfully parsed.
michael@0 601 bool ParseColor(const nsAString& aString, nscolor* aColor);
michael@0 602
michael@0 603 static void StyleColorToString(const nscolor& aColor, nsAString& aStr);
michael@0 604
michael@0 605 /**
michael@0 606 * Creates the error target, if it doesn't exist
michael@0 607 */
michael@0 608 static void EnsureErrorTarget();
michael@0 609
michael@0 610 /* This function ensures there is a writable pathbuilder available, this
michael@0 611 * pathbuilder may be working in user space or in device space or
michael@0 612 * device space.
michael@0 613 * After calling this function mPathTransformWillUpdate will be false
michael@0 614 */
michael@0 615 void EnsureWritablePath();
michael@0 616
michael@0 617 // Ensures a path in UserSpace is available.
michael@0 618 void EnsureUserSpacePath(const CanvasWindingRule& winding = CanvasWindingRule::Nonzero);
michael@0 619
michael@0 620 /**
michael@0 621 * Needs to be called before updating the transform. This makes a call to
michael@0 622 * EnsureTarget() so you don't have to.
michael@0 623 */
michael@0 624 void TransformWillUpdate();
michael@0 625
michael@0 626 // Report the fillRule has changed.
michael@0 627 void FillRuleChanged();
michael@0 628
michael@0 629 /**
michael@0 630 * Create the backing surfacing, if it doesn't exist. If there is an error
michael@0 631 * in creating the target then it will put sErrorTarget in place. If there
michael@0 632 * is in turn an error in creating the sErrorTarget then they would both
michael@0 633 * be null so IsTargetValid() would still return null.
michael@0 634 */
michael@0 635 void EnsureTarget();
michael@0 636
michael@0 637 /*
michael@0 638 * Disposes an old target and prepares to lazily create a new target.
michael@0 639 */
michael@0 640 void ClearTarget();
michael@0 641
michael@0 642 /**
michael@0 643 * Check if the target is valid after calling EnsureTarget.
michael@0 644 */
michael@0 645 bool IsTargetValid() { return mTarget != sErrorTarget && mTarget != nullptr; }
michael@0 646
michael@0 647 /**
michael@0 648 * Returns the surface format this canvas should be allocated using. Takes
michael@0 649 * into account mOpaque, platform requirements, etc.
michael@0 650 */
michael@0 651 mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
michael@0 652
michael@0 653 void DrawImage(const HTMLImageOrCanvasOrVideoElement &imgElt,
michael@0 654 double sx, double sy, double sw, double sh,
michael@0 655 double dx, double dy, double dw, double dh,
michael@0 656 uint8_t optional_argc, mozilla::ErrorResult& error);
michael@0 657
michael@0 658 void DrawDirectlyToCanvas(const nsLayoutUtils::DirectDrawInfo& image,
michael@0 659 mozilla::gfx::Rect* bounds, double dx, double dy,
michael@0 660 double dw, double dh, double sx, double sy,
michael@0 661 double sw, double sh, gfxIntSize imgSize);
michael@0 662
michael@0 663 nsString& GetFont()
michael@0 664 {
michael@0 665 /* will initilize the value if not set, else does nothing */
michael@0 666 GetCurrentFontStyle();
michael@0 667
michael@0 668 return CurrentState().font;
michael@0 669 }
michael@0 670
michael@0 671 static std::vector<CanvasRenderingContext2D*>& DemotableContexts();
michael@0 672 static void DemoteOldestContextIfNecessary();
michael@0 673
michael@0 674 static void AddDemotableContext(CanvasRenderingContext2D* context);
michael@0 675 static void RemoveDemotableContext(CanvasRenderingContext2D* context);
michael@0 676
michael@0 677 // Do not use GL
michael@0 678 bool mForceSoftware;
michael@0 679
michael@0 680 // Member vars
michael@0 681 int32_t mWidth, mHeight;
michael@0 682
michael@0 683 // This is true when the canvas is valid, but of zero size, this requires
michael@0 684 // specific behavior on some operations.
michael@0 685 bool mZero;
michael@0 686
michael@0 687 bool mOpaque;
michael@0 688
michael@0 689 // This is true when the next time our layer is retrieved we need to
michael@0 690 // recreate it (i.e. our backing surface changed)
michael@0 691 bool mResetLayer;
michael@0 692 // This is needed for drawing in drawAsyncXULElement
michael@0 693 bool mIPC;
michael@0 694
michael@0 695 nsTArray<CanvasRenderingContext2DUserData*> mUserDatas;
michael@0 696
michael@0 697 // If mCanvasElement is not provided, then a docshell is
michael@0 698 nsCOMPtr<nsIDocShell> mDocShell;
michael@0 699
michael@0 700 // This is created lazily so it is necessary to call EnsureTarget before
michael@0 701 // accessing it. In the event of an error it will be equal to
michael@0 702 // sErrorTarget.
michael@0 703 mozilla::RefPtr<mozilla::gfx::DrawTarget> mTarget;
michael@0 704
michael@0 705 RefPtr<gfx::SurfaceStream> mStream;
michael@0 706
michael@0 707 /**
michael@0 708 * Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
michael@0 709 * Redraw is called, reset to false when Render is called.
michael@0 710 */
michael@0 711 bool mIsEntireFrameInvalid;
michael@0 712 /**
michael@0 713 * When this is set, the first call to Redraw(gfxRect) should set
michael@0 714 * mIsEntireFrameInvalid since we expect it will be followed by
michael@0 715 * many more Redraw calls.
michael@0 716 */
michael@0 717 bool mPredictManyRedrawCalls;
michael@0 718
michael@0 719 // This is stored after GetThebesSurface has been called once to avoid
michael@0 720 // excessive ThebesSurface initialization overhead.
michael@0 721 nsRefPtr<gfxASurface> mThebesSurface;
michael@0 722
michael@0 723 /**
michael@0 724 * We also have a device space pathbuilder. The reason for this is as
michael@0 725 * follows, when a path is being built, but the transform changes, we
michael@0 726 * can no longer keep a single path in userspace, considering there's
michael@0 727 * several 'user spaces' now. We therefore transform the current path
michael@0 728 * into device space, and add all operations to this path in device
michael@0 729 * space.
michael@0 730 *
michael@0 731 * When then finally executing a render, the Azure drawing API expects
michael@0 732 * the path to be in userspace. We could then set an identity transform
michael@0 733 * on the DrawTarget and do all drawing in device space. This is
michael@0 734 * undesirable because it requires transforming patterns, gradients,
michael@0 735 * clips, etc. into device space and it would not work for stroking.
michael@0 736 * What we do instead is convert the path back to user space when it is
michael@0 737 * drawn, and draw it with the current transform. This makes all drawing
michael@0 738 * occur correctly.
michael@0 739 *
michael@0 740 * There's never both a device space path builder and a user space path
michael@0 741 * builder present at the same time. There is also never a path and a
michael@0 742 * path builder present at the same time. When writing proceeds on an
michael@0 743 * existing path the Path is cleared and a new builder is created.
michael@0 744 *
michael@0 745 * mPath is always in user-space.
michael@0 746 */
michael@0 747 mozilla::RefPtr<mozilla::gfx::Path> mPath;
michael@0 748 mozilla::RefPtr<mozilla::gfx::PathBuilder> mDSPathBuilder;
michael@0 749 mozilla::RefPtr<mozilla::gfx::PathBuilder> mPathBuilder;
michael@0 750 bool mPathTransformWillUpdate;
michael@0 751 mozilla::gfx::Matrix mPathToDS;
michael@0 752
michael@0 753 /**
michael@0 754 * Number of times we've invalidated before calling redraw
michael@0 755 */
michael@0 756 uint32_t mInvalidateCount;
michael@0 757 static const uint32_t kCanvasMaxInvalidateCount = 100;
michael@0 758
michael@0 759 /**
michael@0 760 * State information for hit regions
michael@0 761 */
michael@0 762
michael@0 763 struct RegionInfo : public nsStringHashKey
michael@0 764 {
michael@0 765 RegionInfo(const nsAString& aKey) :
michael@0 766 nsStringHashKey(&aKey)
michael@0 767 {
michael@0 768 }
michael@0 769 RegionInfo(const nsAString *aKey) :
michael@0 770 nsStringHashKey(aKey)
michael@0 771 {
michael@0 772 }
michael@0 773
michael@0 774 nsRefPtr<Element> mElement;
michael@0 775 };
michael@0 776
michael@0 777 #ifdef ACCESSIBILITY
michael@0 778 static PLDHashOperator RemoveHitRegionProperty(RegionInfo* aEntry, void* aData);
michael@0 779 #endif
michael@0 780 nsTHashtable<RegionInfo> mHitRegionsOptions;
michael@0 781
michael@0 782 /**
michael@0 783 * Returns true if a shadow should be drawn along with a
michael@0 784 * drawing operation.
michael@0 785 */
michael@0 786 bool NeedToDrawShadow()
michael@0 787 {
michael@0 788 const ContextState& state = CurrentState();
michael@0 789
michael@0 790 // The spec says we should not draw shadows if the operator is OVER.
michael@0 791 // If it's over and the alpha value is zero, nothing needs to be drawn.
michael@0 792 return NS_GET_A(state.shadowColor) != 0 &&
michael@0 793 (state.shadowBlur != 0 || state.shadowOffset.x != 0 || state.shadowOffset.y != 0);
michael@0 794 }
michael@0 795
michael@0 796 mozilla::gfx::CompositionOp UsedOperation()
michael@0 797 {
michael@0 798 if (NeedToDrawShadow()) {
michael@0 799 // In this case the shadow rendering will use the operator.
michael@0 800 return mozilla::gfx::CompositionOp::OP_OVER;
michael@0 801 }
michael@0 802
michael@0 803 return CurrentState().op;
michael@0 804 }
michael@0 805
michael@0 806 /**
michael@0 807 * Gets the pres shell from either the canvas element or the doc shell
michael@0 808 */
michael@0 809 nsIPresShell *GetPresShell() {
michael@0 810 if (mCanvasElement) {
michael@0 811 return mCanvasElement->OwnerDoc()->GetShell();
michael@0 812 }
michael@0 813 if (mDocShell) {
michael@0 814 return mDocShell->GetPresShell();
michael@0 815 }
michael@0 816 return nullptr;
michael@0 817 }
michael@0 818
michael@0 819 // text
michael@0 820
michael@0 821 public: // These enums are public only to accomodate non-C++11 legacy path of
michael@0 822 // MOZ_FINISH_NESTED_ENUM_CLASS. Can move back to protected as soon
michael@0 823 // as that legacy path is dropped.
michael@0 824 MOZ_BEGIN_NESTED_ENUM_CLASS(TextAlign, uint8_t)
michael@0 825 START,
michael@0 826 END,
michael@0 827 LEFT,
michael@0 828 RIGHT,
michael@0 829 CENTER
michael@0 830 MOZ_END_NESTED_ENUM_CLASS(TextAlign)
michael@0 831
michael@0 832 MOZ_BEGIN_NESTED_ENUM_CLASS(TextBaseline, uint8_t)
michael@0 833 TOP,
michael@0 834 HANGING,
michael@0 835 MIDDLE,
michael@0 836 ALPHABETIC,
michael@0 837 IDEOGRAPHIC,
michael@0 838 BOTTOM
michael@0 839 MOZ_END_NESTED_ENUM_CLASS(TextBaseline)
michael@0 840
michael@0 841 MOZ_BEGIN_NESTED_ENUM_CLASS(TextDrawOperation, uint8_t)
michael@0 842 FILL,
michael@0 843 STROKE,
michael@0 844 MEASURE
michael@0 845 MOZ_END_NESTED_ENUM_CLASS(TextDrawOperation)
michael@0 846
michael@0 847 protected:
michael@0 848 gfxFontGroup *GetCurrentFontStyle();
michael@0 849
michael@0 850 /*
michael@0 851 * Implementation of the fillText, strokeText, and measure functions with
michael@0 852 * the operation abstracted to a flag.
michael@0 853 */
michael@0 854 nsresult DrawOrMeasureText(const nsAString& text,
michael@0 855 float x,
michael@0 856 float y,
michael@0 857 const Optional<double>& maxWidth,
michael@0 858 TextDrawOperation op,
michael@0 859 float* aWidth);
michael@0 860
michael@0 861 // state stack handling
michael@0 862 class ContextState {
michael@0 863 public:
michael@0 864 ContextState() : textAlign(TextAlign::START),
michael@0 865 textBaseline(TextBaseline::ALPHABETIC),
michael@0 866 lineWidth(1.0f),
michael@0 867 miterLimit(10.0f),
michael@0 868 globalAlpha(1.0f),
michael@0 869 shadowBlur(0.0),
michael@0 870 dashOffset(0.0f),
michael@0 871 op(mozilla::gfx::CompositionOp::OP_OVER),
michael@0 872 fillRule(mozilla::gfx::FillRule::FILL_WINDING),
michael@0 873 lineCap(mozilla::gfx::CapStyle::BUTT),
michael@0 874 lineJoin(mozilla::gfx::JoinStyle::MITER_OR_BEVEL),
michael@0 875 imageSmoothingEnabled(true)
michael@0 876 { }
michael@0 877
michael@0 878 ContextState(const ContextState& other)
michael@0 879 : fontGroup(other.fontGroup),
michael@0 880 gradientStyles(other.gradientStyles),
michael@0 881 patternStyles(other.patternStyles),
michael@0 882 colorStyles(other.colorStyles),
michael@0 883 font(other.font),
michael@0 884 textAlign(other.textAlign),
michael@0 885 textBaseline(other.textBaseline),
michael@0 886 shadowColor(other.shadowColor),
michael@0 887 transform(other.transform),
michael@0 888 shadowOffset(other.shadowOffset),
michael@0 889 lineWidth(other.lineWidth),
michael@0 890 miterLimit(other.miterLimit),
michael@0 891 globalAlpha(other.globalAlpha),
michael@0 892 shadowBlur(other.shadowBlur),
michael@0 893 dash(other.dash),
michael@0 894 dashOffset(other.dashOffset),
michael@0 895 op(other.op),
michael@0 896 fillRule(other.fillRule),
michael@0 897 lineCap(other.lineCap),
michael@0 898 lineJoin(other.lineJoin),
michael@0 899 imageSmoothingEnabled(other.imageSmoothingEnabled)
michael@0 900 { }
michael@0 901
michael@0 902 void SetColorStyle(Style whichStyle, nscolor color)
michael@0 903 {
michael@0 904 colorStyles[whichStyle] = color;
michael@0 905 gradientStyles[whichStyle] = nullptr;
michael@0 906 patternStyles[whichStyle] = nullptr;
michael@0 907 }
michael@0 908
michael@0 909 void SetPatternStyle(Style whichStyle, CanvasPattern* pat)
michael@0 910 {
michael@0 911 gradientStyles[whichStyle] = nullptr;
michael@0 912 patternStyles[whichStyle] = pat;
michael@0 913 }
michael@0 914
michael@0 915 void SetGradientStyle(Style whichStyle, CanvasGradient* grad)
michael@0 916 {
michael@0 917 gradientStyles[whichStyle] = grad;
michael@0 918 patternStyles[whichStyle] = nullptr;
michael@0 919 }
michael@0 920
michael@0 921 /**
michael@0 922 * returns true iff the given style is a solid color.
michael@0 923 */
michael@0 924 bool StyleIsColor(Style whichStyle) const
michael@0 925 {
michael@0 926 return !(patternStyles[whichStyle] || gradientStyles[whichStyle]);
michael@0 927 }
michael@0 928
michael@0 929
michael@0 930 std::vector<mozilla::RefPtr<mozilla::gfx::Path> > clipsPushed;
michael@0 931
michael@0 932 nsRefPtr<gfxFontGroup> fontGroup;
michael@0 933 EnumeratedArray<Style, Style::MAX, nsRefPtr<CanvasGradient>> gradientStyles;
michael@0 934 EnumeratedArray<Style, Style::MAX, nsRefPtr<CanvasPattern>> patternStyles;
michael@0 935 EnumeratedArray<Style, Style::MAX, nscolor> colorStyles;
michael@0 936
michael@0 937 nsString font;
michael@0 938 TextAlign textAlign;
michael@0 939 TextBaseline textBaseline;
michael@0 940
michael@0 941 nscolor shadowColor;
michael@0 942
michael@0 943 mozilla::gfx::Matrix transform;
michael@0 944 mozilla::gfx::Point shadowOffset;
michael@0 945 mozilla::gfx::Float lineWidth;
michael@0 946 mozilla::gfx::Float miterLimit;
michael@0 947 mozilla::gfx::Float globalAlpha;
michael@0 948 mozilla::gfx::Float shadowBlur;
michael@0 949 FallibleTArray<mozilla::gfx::Float> dash;
michael@0 950 mozilla::gfx::Float dashOffset;
michael@0 951
michael@0 952 mozilla::gfx::CompositionOp op;
michael@0 953 mozilla::gfx::FillRule fillRule;
michael@0 954 mozilla::gfx::CapStyle lineCap;
michael@0 955 mozilla::gfx::JoinStyle lineJoin;
michael@0 956
michael@0 957 bool imageSmoothingEnabled;
michael@0 958 };
michael@0 959
michael@0 960 nsAutoTArray<ContextState, 3> mStyleStack;
michael@0 961
michael@0 962 inline ContextState& CurrentState() {
michael@0 963 return mStyleStack[mStyleStack.Length() - 1];
michael@0 964 }
michael@0 965
michael@0 966 inline const ContextState& CurrentState() const {
michael@0 967 return mStyleStack[mStyleStack.Length() - 1];
michael@0 968 }
michael@0 969
michael@0 970 friend class CanvasGeneralPattern;
michael@0 971 friend class AdjustedTarget;
michael@0 972
michael@0 973 // other helpers
michael@0 974 void GetAppUnitsValues(int32_t *perDevPixel, int32_t *perCSSPixel)
michael@0 975 {
michael@0 976 // If we don't have a canvas element, we just return something generic.
michael@0 977 int32_t devPixel = 60;
michael@0 978 int32_t cssPixel = 60;
michael@0 979
michael@0 980 nsIPresShell *ps = GetPresShell();
michael@0 981 nsPresContext *pc;
michael@0 982
michael@0 983 if (!ps) goto FINISH;
michael@0 984 pc = ps->GetPresContext();
michael@0 985 if (!pc) goto FINISH;
michael@0 986 devPixel = pc->AppUnitsPerDevPixel();
michael@0 987 cssPixel = pc->AppUnitsPerCSSPixel();
michael@0 988
michael@0 989 FINISH:
michael@0 990 if (perDevPixel)
michael@0 991 *perDevPixel = devPixel;
michael@0 992 if (perCSSPixel)
michael@0 993 *perCSSPixel = cssPixel;
michael@0 994 }
michael@0 995
michael@0 996 friend struct CanvasBidiProcessor;
michael@0 997 };
michael@0 998
michael@0 999 MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::CanvasMultiGetterType)
michael@0 1000 MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::Style)
michael@0 1001 MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::TextAlign)
michael@0 1002 MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::TextBaseline)
michael@0 1003 MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::TextDrawOperation)
michael@0 1004
michael@0 1005 }
michael@0 1006 }
michael@0 1007
michael@0 1008 #endif /* CanvasRenderingContext2D_h */

mercurial