content/canvas/src/CanvasRenderingContext2D.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/canvas/src/CanvasRenderingContext2D.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1008 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#ifndef CanvasRenderingContext2D_h
     1.9 +#define CanvasRenderingContext2D_h
    1.10 +
    1.11 +#include "mozilla/Attributes.h"
    1.12 +#include <vector>
    1.13 +#include "nsIDOMCanvasRenderingContext2D.h"
    1.14 +#include "nsICanvasRenderingContextInternal.h"
    1.15 +#include "mozilla/RefPtr.h"
    1.16 +#include "nsColor.h"
    1.17 +#include "mozilla/dom/HTMLCanvasElement.h"
    1.18 +#include "mozilla/dom/HTMLVideoElement.h"
    1.19 +#include "CanvasUtils.h"
    1.20 +#include "gfxFont.h"
    1.21 +#include "mozilla/ErrorResult.h"
    1.22 +#include "mozilla/dom/CanvasGradient.h"
    1.23 +#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
    1.24 +#include "mozilla/dom/CanvasPattern.h"
    1.25 +#include "mozilla/gfx/Rect.h"
    1.26 +#include "mozilla/gfx/2D.h"
    1.27 +#include "gfx2DGlue.h"
    1.28 +#include "imgIEncoder.h"
    1.29 +#include "nsLayoutUtils.h"
    1.30 +#include "mozilla/EnumeratedArray.h"
    1.31 +
    1.32 +class nsGlobalWindow;
    1.33 +class nsXULElement;
    1.34 +
    1.35 +namespace mozilla {
    1.36 +namespace gfx {
    1.37 +class SourceSurface;
    1.38 +class SurfaceStream;
    1.39 +}
    1.40 +
    1.41 +namespace dom {
    1.42 +class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
    1.43 +class ImageData;
    1.44 +class StringOrCanvasGradientOrCanvasPattern;
    1.45 +class OwningStringOrCanvasGradientOrCanvasPattern;
    1.46 +class TextMetrics;
    1.47 +
    1.48 +extern const mozilla::gfx::Float SIGMA_MAX;
    1.49 +
    1.50 +template<typename T> class Optional;
    1.51 +
    1.52 +class CanvasPath MOZ_FINAL :
    1.53 +  public nsWrapperCache
    1.54 +{
    1.55 +public:
    1.56 +  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPath)
    1.57 +  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
    1.58 +
    1.59 +  nsCOMPtr<nsISupports> GetParentObject() { return mParent; }
    1.60 +
    1.61 +  JSObject* WrapObject(JSContext* aCx);
    1.62 +
    1.63 +  static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
    1.64 +                                                  ErrorResult& rv);
    1.65 +  static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
    1.66 +                                                  CanvasPath& aCanvasPath,
    1.67 +                                                  ErrorResult& rv);
    1.68 +  static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
    1.69 +                                                  const nsAString& aPathString,
    1.70 +                                                  ErrorResult& rv);
    1.71 +
    1.72 +  void ClosePath();
    1.73 +  void MoveTo(double x, double y);
    1.74 +  void LineTo(double x, double y);
    1.75 +  void QuadraticCurveTo(double cpx, double cpy, double x, double y);
    1.76 +  void BezierCurveTo(double cp1x, double cp1y,
    1.77 +                     double cp2x, double cp2y,
    1.78 +                     double x, double y);
    1.79 +  void ArcTo(double x1, double y1, double x2, double y2, double radius,
    1.80 +             ErrorResult& error);
    1.81 +  void Rect(double x, double y, double w, double h);
    1.82 +  void Arc(double x, double y, double radius,
    1.83 +           double startAngle, double endAngle, bool anticlockwise,
    1.84 +           ErrorResult& error);
    1.85 +
    1.86 +  void LineTo(const gfx::Point& aPoint);
    1.87 +  void BezierTo(const gfx::Point& aCP1,
    1.88 +                const gfx::Point& aCP2,
    1.89 +                const gfx::Point& aCP3);
    1.90 +
    1.91 +  mozilla::RefPtr<mozilla::gfx::Path> GetPath(const CanvasWindingRule& winding,
    1.92 +                                              const mozilla::RefPtr<mozilla::gfx::DrawTarget>& mTarget) const;
    1.93 +
    1.94 +  explicit CanvasPath(nsISupports* aParent);
    1.95 +  CanvasPath(nsISupports* aParent, RefPtr<gfx::PathBuilder> mPathBuilder);
    1.96 +  virtual ~CanvasPath() {}
    1.97 +
    1.98 +private:
    1.99 +
   1.100 +  nsCOMPtr<nsISupports> mParent;
   1.101 +  static gfx::Float ToFloat(double aValue) { return gfx::Float(aValue); }
   1.102 +
   1.103 +  mutable RefPtr<gfx::Path> mPath;
   1.104 +  mutable RefPtr<gfx::PathBuilder> mPathBuilder;
   1.105 +
   1.106 +  void EnsurePathBuilder() const;
   1.107 +};
   1.108 +
   1.109 +struct CanvasBidiProcessor;
   1.110 +class CanvasRenderingContext2DUserData;
   1.111 +
   1.112 +/**
   1.113 + ** CanvasRenderingContext2D
   1.114 + **/
   1.115 +class CanvasRenderingContext2D :
   1.116 +  public nsICanvasRenderingContextInternal,
   1.117 +  public nsWrapperCache
   1.118 +{
   1.119 +typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
   1.120 +  HTMLImageOrCanvasOrVideoElement;
   1.121 +
   1.122 +public:
   1.123 +  CanvasRenderingContext2D();
   1.124 +  virtual ~CanvasRenderingContext2D();
   1.125 +
   1.126 +  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
   1.127 +
   1.128 +  HTMLCanvasElement* GetCanvas() const
   1.129 +  {
   1.130 +    // corresponds to changes to the old bindings made in bug 745025
   1.131 +    return mCanvasElement->GetOriginalCanvas();
   1.132 +  }
   1.133 +
   1.134 +  void Save();
   1.135 +  void Restore();
   1.136 +  void Scale(double x, double y, mozilla::ErrorResult& error);
   1.137 +  void Rotate(double angle, mozilla::ErrorResult& error);
   1.138 +  void Translate(double x, double y, mozilla::ErrorResult& error);
   1.139 +  void Transform(double m11, double m12, double m21, double m22, double dx,
   1.140 +                 double dy, mozilla::ErrorResult& error);
   1.141 +  void SetTransform(double m11, double m12, double m21, double m22, double dx,
   1.142 +                    double dy, mozilla::ErrorResult& error);
   1.143 +
   1.144 +  double GlobalAlpha()
   1.145 +  {
   1.146 +    return CurrentState().globalAlpha;
   1.147 +  }
   1.148 +
   1.149 +  // Useful for silencing cast warnings
   1.150 +  static mozilla::gfx::Float ToFloat(double aValue) { return mozilla::gfx::Float(aValue); }
   1.151 +
   1.152 +  void SetGlobalAlpha(double globalAlpha)
   1.153 +  {
   1.154 +    if (globalAlpha >= 0.0 && globalAlpha <= 1.0) {
   1.155 +      CurrentState().globalAlpha = ToFloat(globalAlpha);
   1.156 +    }
   1.157 +  }
   1.158 +
   1.159 +  void GetGlobalCompositeOperation(nsAString& op, mozilla::ErrorResult& error);
   1.160 +  void SetGlobalCompositeOperation(const nsAString& op,
   1.161 +                                   mozilla::ErrorResult& error);
   1.162 +
   1.163 +  void GetStrokeStyle(OwningStringOrCanvasGradientOrCanvasPattern& value)
   1.164 +  {
   1.165 +    GetStyleAsUnion(value, Style::STROKE);
   1.166 +  }
   1.167 +
   1.168 +  void SetStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& value)
   1.169 +  {
   1.170 +    SetStyleFromUnion(value, Style::STROKE);
   1.171 +  }
   1.172 +
   1.173 +  void GetFillStyle(OwningStringOrCanvasGradientOrCanvasPattern& value)
   1.174 +  {
   1.175 +    GetStyleAsUnion(value, Style::FILL);
   1.176 +  }
   1.177 +
   1.178 +  void SetFillStyle(const StringOrCanvasGradientOrCanvasPattern& value)
   1.179 +  {
   1.180 +    SetStyleFromUnion(value, Style::FILL);
   1.181 +  }
   1.182 +
   1.183 +  already_AddRefed<CanvasGradient>
   1.184 +    CreateLinearGradient(double x0, double y0, double x1, double y1);
   1.185 +  already_AddRefed<CanvasGradient>
   1.186 +    CreateRadialGradient(double x0, double y0, double r0, double x1, double y1,
   1.187 +                         double r1, ErrorResult& aError);
   1.188 +  already_AddRefed<CanvasPattern>
   1.189 +    CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
   1.190 +                  const nsAString& repeat, ErrorResult& error);
   1.191 +
   1.192 +  double ShadowOffsetX()
   1.193 +  {
   1.194 +    return CurrentState().shadowOffset.x;
   1.195 +  }
   1.196 +
   1.197 +  void SetShadowOffsetX(double shadowOffsetX)
   1.198 +  {
   1.199 +    CurrentState().shadowOffset.x = ToFloat(shadowOffsetX);
   1.200 +  }
   1.201 +
   1.202 +  double ShadowOffsetY()
   1.203 +  {
   1.204 +    return CurrentState().shadowOffset.y;
   1.205 +  }
   1.206 +
   1.207 +  void SetShadowOffsetY(double shadowOffsetY)
   1.208 +  {
   1.209 +    CurrentState().shadowOffset.y = ToFloat(shadowOffsetY);
   1.210 +  }
   1.211 +
   1.212 +  double ShadowBlur()
   1.213 +  {
   1.214 +    return CurrentState().shadowBlur;
   1.215 +  }
   1.216 +
   1.217 +  void SetShadowBlur(double shadowBlur)
   1.218 +  {
   1.219 +    if (shadowBlur >= 0.0) {
   1.220 +      CurrentState().shadowBlur = ToFloat(shadowBlur);
   1.221 +    }
   1.222 +  }
   1.223 +
   1.224 +  void GetShadowColor(nsAString& shadowColor)
   1.225 +  {
   1.226 +    StyleColorToString(CurrentState().shadowColor, shadowColor);
   1.227 +  }
   1.228 +
   1.229 +  void SetShadowColor(const nsAString& shadowColor);
   1.230 +  void ClearRect(double x, double y, double w, double h);
   1.231 +  void FillRect(double x, double y, double w, double h);
   1.232 +  void StrokeRect(double x, double y, double w, double h);
   1.233 +  void BeginPath();
   1.234 +  void Fill(const CanvasWindingRule& winding);
   1.235 +  void Fill(const CanvasPath& path, const CanvasWindingRule& winding);
   1.236 +  void Stroke();
   1.237 +  void Stroke(const CanvasPath& path);
   1.238 +  void DrawFocusIfNeeded(mozilla::dom::Element& element);
   1.239 +  bool DrawCustomFocusRing(mozilla::dom::Element& element);
   1.240 +  void Clip(const CanvasWindingRule& winding);
   1.241 +  void Clip(const CanvasPath& path, const CanvasWindingRule& winding);
   1.242 +  bool IsPointInPath(JSContext* cx, double x, double y,
   1.243 +                     const CanvasWindingRule& winding);
   1.244 +  bool IsPointInPath(JSContext* cx, const CanvasPath& path, double x, double y,
   1.245 +                     const CanvasWindingRule& winding);
   1.246 +  bool IsPointInStroke(JSContext* cx, double x, double y);
   1.247 +  bool IsPointInStroke(JSContext* cx, const CanvasPath& path,
   1.248 +                       double x, double y);
   1.249 +  void FillText(const nsAString& text, double x, double y,
   1.250 +                const Optional<double>& maxWidth,
   1.251 +                mozilla::ErrorResult& error);
   1.252 +  void StrokeText(const nsAString& text, double x, double y,
   1.253 +                  const Optional<double>& maxWidth,
   1.254 +                  mozilla::ErrorResult& error);
   1.255 +  TextMetrics*
   1.256 +    MeasureText(const nsAString& rawText, mozilla::ErrorResult& error);
   1.257 +
   1.258 +  void AddHitRegion(const HitRegionOptions& options, mozilla::ErrorResult& error);
   1.259 +  void RemoveHitRegion(const nsAString& id);
   1.260 +
   1.261 +  void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
   1.262 +                 double dx, double dy, mozilla::ErrorResult& error)
   1.263 +  {
   1.264 +    DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, 0.0, 0.0, 0, error);
   1.265 +  }
   1.266 +
   1.267 +  void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
   1.268 +                 double dx, double dy, double dw, double dh,
   1.269 +                 mozilla::ErrorResult& error)
   1.270 +  {
   1.271 +    DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, dw, dh, 2, error);
   1.272 +  }
   1.273 +
   1.274 +  void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
   1.275 +                 double sx, double sy, double sw, double sh, double dx,
   1.276 +                 double dy, double dw, double dh, mozilla::ErrorResult& error)
   1.277 +  {
   1.278 +    DrawImage(image, sx, sy, sw, sh, dx, dy, dw, dh, 6, error);
   1.279 +  }
   1.280 +
   1.281 +  already_AddRefed<ImageData>
   1.282 +    CreateImageData(JSContext* cx, double sw, double sh,
   1.283 +                    mozilla::ErrorResult& error);
   1.284 +  already_AddRefed<ImageData>
   1.285 +    CreateImageData(JSContext* cx, ImageData& imagedata,
   1.286 +                    mozilla::ErrorResult& error);
   1.287 +  already_AddRefed<ImageData>
   1.288 +    GetImageData(JSContext* cx, double sx, double sy, double sw, double sh,
   1.289 +                 mozilla::ErrorResult& error);
   1.290 +  void PutImageData(ImageData& imageData,
   1.291 +                    double dx, double dy, mozilla::ErrorResult& error);
   1.292 +  void PutImageData(ImageData& imageData,
   1.293 +                    double dx, double dy, double dirtyX, double dirtyY,
   1.294 +                    double dirtyWidth, double dirtyHeight,
   1.295 +                    mozilla::ErrorResult& error);
   1.296 +
   1.297 +  double LineWidth()
   1.298 +  {
   1.299 +    return CurrentState().lineWidth;
   1.300 +  }
   1.301 +
   1.302 +  void SetLineWidth(double width)
   1.303 +  {
   1.304 +    if (width > 0.0) {
   1.305 +      CurrentState().lineWidth = ToFloat(width);
   1.306 +    }
   1.307 +  }
   1.308 +  void GetLineCap(nsAString& linecap);
   1.309 +  void SetLineCap(const nsAString& linecap);
   1.310 +  void GetLineJoin(nsAString& linejoin, mozilla::ErrorResult& error);
   1.311 +  void SetLineJoin(const nsAString& linejoin);
   1.312 +
   1.313 +  double MiterLimit()
   1.314 +  {
   1.315 +    return CurrentState().miterLimit;
   1.316 +  }
   1.317 +
   1.318 +  void SetMiterLimit(double miter)
   1.319 +  {
   1.320 +    if (miter > 0.0) {
   1.321 +      CurrentState().miterLimit = ToFloat(miter);
   1.322 +    }
   1.323 +  }
   1.324 +
   1.325 +  void GetFont(nsAString& font)
   1.326 +  {
   1.327 +    font = GetFont();
   1.328 +  }
   1.329 +
   1.330 +  void SetFont(const nsAString& font, mozilla::ErrorResult& error);
   1.331 +  void GetTextAlign(nsAString& textAlign);
   1.332 +  void SetTextAlign(const nsAString& textAlign);
   1.333 +  void GetTextBaseline(nsAString& textBaseline);
   1.334 +  void SetTextBaseline(const nsAString& textBaseline);
   1.335 +
   1.336 +  void ClosePath()
   1.337 +  {
   1.338 +    EnsureWritablePath();
   1.339 +
   1.340 +    if (mPathBuilder) {
   1.341 +      mPathBuilder->Close();
   1.342 +    } else {
   1.343 +      mDSPathBuilder->Close();
   1.344 +    }
   1.345 +  }
   1.346 +
   1.347 +  void MoveTo(double x, double y)
   1.348 +  {
   1.349 +    EnsureWritablePath();
   1.350 +
   1.351 +    if (mPathBuilder) {
   1.352 +      mPathBuilder->MoveTo(mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
   1.353 +    } else {
   1.354 +      mDSPathBuilder->MoveTo(mTarget->GetTransform() *
   1.355 +                             mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
   1.356 +    }
   1.357 +  }
   1.358 +
   1.359 +  void LineTo(double x, double y)
   1.360 +  {
   1.361 +    EnsureWritablePath();
   1.362 +
   1.363 +    LineTo(mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
   1.364 +  }
   1.365 +
   1.366 +  void QuadraticCurveTo(double cpx, double cpy, double x, double y)
   1.367 +  {
   1.368 +    EnsureWritablePath();
   1.369 +
   1.370 +    if (mPathBuilder) {
   1.371 +      mPathBuilder->QuadraticBezierTo(mozilla::gfx::Point(ToFloat(cpx), ToFloat(cpy)),
   1.372 +                                      mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
   1.373 +    } else {
   1.374 +      mozilla::gfx::Matrix transform = mTarget->GetTransform();
   1.375 +      mDSPathBuilder->QuadraticBezierTo(transform *
   1.376 +                                        mozilla::gfx::Point(ToFloat(cpx), ToFloat(cpy)),
   1.377 +                                        transform *
   1.378 +                                        mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
   1.379 +    }
   1.380 +  }
   1.381 +
   1.382 +  void BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y)
   1.383 +  {
   1.384 +    EnsureWritablePath();
   1.385 +
   1.386 +    BezierTo(mozilla::gfx::Point(ToFloat(cp1x), ToFloat(cp1y)),
   1.387 +             mozilla::gfx::Point(ToFloat(cp2x), ToFloat(cp2y)),
   1.388 +             mozilla::gfx::Point(ToFloat(x), ToFloat(y)));
   1.389 +  }
   1.390 +
   1.391 +  void ArcTo(double x1, double y1, double x2, double y2, double radius,
   1.392 +             mozilla::ErrorResult& error);
   1.393 +  void Rect(double x, double y, double w, double h);
   1.394 +  void Arc(double x, double y, double radius, double startAngle,
   1.395 +           double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
   1.396 +
   1.397 +  void GetMozCurrentTransform(JSContext* cx,
   1.398 +			      JS::MutableHandle<JSObject*> result,
   1.399 +			      mozilla::ErrorResult& error) const;
   1.400 +  void SetMozCurrentTransform(JSContext* cx,
   1.401 +                              JS::Handle<JSObject*> currentTransform,
   1.402 +                              mozilla::ErrorResult& error);
   1.403 +  void GetMozCurrentTransformInverse(JSContext* cx,
   1.404 +				     JS::MutableHandle<JSObject*> result,
   1.405 +				     mozilla::ErrorResult& error) const;
   1.406 +  void SetMozCurrentTransformInverse(JSContext* cx,
   1.407 +                                     JS::Handle<JSObject*> currentTransform,
   1.408 +                                     mozilla::ErrorResult& error);
   1.409 +  void GetFillRule(nsAString& fillRule);
   1.410 +  void SetFillRule(const nsAString& fillRule);
   1.411 +  void GetMozDash(JSContext* cx, JS::MutableHandle<JS::Value> retval,
   1.412 +		  mozilla::ErrorResult& error);
   1.413 +  void SetMozDash(JSContext* cx, const JS::Value& mozDash,
   1.414 +                  mozilla::ErrorResult& error);
   1.415 +
   1.416 +  void SetLineDash(const Sequence<double>& mSegments);
   1.417 +  void GetLineDash(nsTArray<double>& mSegments) const;
   1.418 +
   1.419 +  void SetLineDashOffset(double mOffset);
   1.420 +  double LineDashOffset() const;
   1.421 +
   1.422 +  double MozDashOffset()
   1.423 +  {
   1.424 +    return CurrentState().dashOffset;
   1.425 +  }
   1.426 +  void SetMozDashOffset(double mozDashOffset);
   1.427 +
   1.428 +  void GetMozTextStyle(nsAString& mozTextStyle)
   1.429 +  {
   1.430 +    GetFont(mozTextStyle);
   1.431 +  }
   1.432 +
   1.433 +  void SetMozTextStyle(const nsAString& mozTextStyle,
   1.434 +                       mozilla::ErrorResult& error)
   1.435 +  {
   1.436 +    SetFont(mozTextStyle, error);
   1.437 +  }
   1.438 +
   1.439 +  bool ImageSmoothingEnabled()
   1.440 +  {
   1.441 +    return CurrentState().imageSmoothingEnabled;
   1.442 +  }
   1.443 +
   1.444 +  void SetImageSmoothingEnabled(bool imageSmoothingEnabled)
   1.445 +  {
   1.446 +    if (imageSmoothingEnabled != CurrentState().imageSmoothingEnabled) {
   1.447 +      CurrentState().imageSmoothingEnabled = imageSmoothingEnabled;
   1.448 +    }
   1.449 +  }
   1.450 +
   1.451 +  void DrawWindow(nsGlobalWindow& window, double x, double y, double w, double h,
   1.452 +                  const nsAString& bgColor, uint32_t flags,
   1.453 +                  mozilla::ErrorResult& error);
   1.454 +  void AsyncDrawXULElement(nsXULElement& elem, double x, double y, double w,
   1.455 +                           double h, const nsAString& bgColor, uint32_t flags,
   1.456 +                           mozilla::ErrorResult& error);
   1.457 +
   1.458 +  void Demote();
   1.459 +
   1.460 +  nsresult Redraw();
   1.461 +
   1.462 +#ifdef DEBUG
   1.463 +    virtual int32_t GetWidth() const MOZ_OVERRIDE;
   1.464 +    virtual int32_t GetHeight() const MOZ_OVERRIDE;
   1.465 +#endif
   1.466 +  // nsICanvasRenderingContextInternal
   1.467 +  NS_IMETHOD SetDimensions(int32_t width, int32_t height) MOZ_OVERRIDE;
   1.468 +  NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE;
   1.469 +
   1.470 +  NS_IMETHOD GetInputStream(const char* aMimeType,
   1.471 +                            const char16_t* aEncoderOptions,
   1.472 +                            nsIInputStream **aStream) MOZ_OVERRIDE;
   1.473 +
   1.474 +  mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) MOZ_OVERRIDE
   1.475 +  {
   1.476 +    EnsureTarget();
   1.477 +    if (aPremultAlpha) {
   1.478 +      *aPremultAlpha = true;
   1.479 +    }
   1.480 +    return mTarget->Snapshot();
   1.481 +  }
   1.482 +
   1.483 +  NS_IMETHOD SetIsOpaque(bool isOpaque) MOZ_OVERRIDE;
   1.484 +  bool GetIsOpaque() MOZ_OVERRIDE { return mOpaque; }
   1.485 +  NS_IMETHOD Reset() MOZ_OVERRIDE;
   1.486 +  already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
   1.487 +                                               CanvasLayer *aOldLayer,
   1.488 +                                               LayerManager *aManager) MOZ_OVERRIDE;
   1.489 +  virtual bool ShouldForceInactiveLayer(LayerManager *aManager) MOZ_OVERRIDE;
   1.490 +  void MarkContextClean() MOZ_OVERRIDE;
   1.491 +  NS_IMETHOD SetIsIPC(bool isIPC) MOZ_OVERRIDE;
   1.492 +  // this rect is in canvas device space
   1.493 +  void Redraw(const mozilla::gfx::Rect &r);
   1.494 +  NS_IMETHOD Redraw(const gfxRect &r) MOZ_OVERRIDE { Redraw(ToRect(r)); return NS_OK; }
   1.495 +  NS_IMETHOD SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions) MOZ_OVERRIDE;
   1.496 +
   1.497 +  // this rect is in mTarget's current user space
   1.498 +  void RedrawUser(const gfxRect &r);
   1.499 +
   1.500 +  // nsISupports interface + CC
   1.501 +  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   1.502 +
   1.503 +  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(CanvasRenderingContext2D)
   1.504 +
   1.505 +  MOZ_BEGIN_NESTED_ENUM_CLASS(CanvasMultiGetterType, uint8_t)
   1.506 +    STRING = 0,
   1.507 +    PATTERN = 1,
   1.508 +    GRADIENT = 2
   1.509 +  MOZ_END_NESTED_ENUM_CLASS(CanvasMultiGetterType)
   1.510 +
   1.511 +  MOZ_BEGIN_NESTED_ENUM_CLASS(Style, uint8_t)
   1.512 +    STROKE = 0,
   1.513 +    FILL,
   1.514 +    MAX
   1.515 +  MOZ_END_NESTED_ENUM_CLASS(Style)
   1.516 +
   1.517 +  nsINode* GetParentObject()
   1.518 +  {
   1.519 +    return mCanvasElement;
   1.520 +  }
   1.521 +
   1.522 +  void LineTo(const mozilla::gfx::Point& aPoint)
   1.523 +  {
   1.524 +    if (mPathBuilder) {
   1.525 +      mPathBuilder->LineTo(aPoint);
   1.526 +    } else {
   1.527 +      mDSPathBuilder->LineTo(mTarget->GetTransform() * aPoint);
   1.528 +    }
   1.529 +  }
   1.530 +
   1.531 +  void BezierTo(const mozilla::gfx::Point& aCP1,
   1.532 +                const mozilla::gfx::Point& aCP2,
   1.533 +                const mozilla::gfx::Point& aCP3)
   1.534 +  {
   1.535 +    if (mPathBuilder) {
   1.536 +      mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
   1.537 +    } else {
   1.538 +      mozilla::gfx::Matrix transform = mTarget->GetTransform();
   1.539 +      mDSPathBuilder->BezierTo(transform * aCP1,
   1.540 +                                transform * aCP2,
   1.541 +                                transform * aCP3);
   1.542 +    }
   1.543 +  }
   1.544 +
   1.545 +  friend class CanvasRenderingContext2DUserData;
   1.546 +
   1.547 +  virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
   1.548 +
   1.549 +protected:
   1.550 +  nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
   1.551 +                             uint32_t aWidth, uint32_t aHeight,
   1.552 +                             JSObject** aRetval);
   1.553 +
   1.554 +  nsresult PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h,
   1.555 +                                 dom::Uint8ClampedArray* aArray,
   1.556 +                                 bool hasDirtyRect, int32_t dirtyX, int32_t dirtyY,
   1.557 +                                 int32_t dirtyWidth, int32_t dirtyHeight);
   1.558 +
   1.559 +  /**
   1.560 +   * Internal method to complete initialisation, expects mTarget to have been set
   1.561 +   */
   1.562 +  nsresult Initialize(int32_t width, int32_t height);
   1.563 +
   1.564 +  nsresult InitializeWithTarget(mozilla::gfx::DrawTarget *surface,
   1.565 +                                int32_t width, int32_t height);
   1.566 +
   1.567 +  /**
   1.568 +    * The number of living nsCanvasRenderingContexts.  When this goes down to
   1.569 +    * 0, we free the premultiply and unpremultiply tables, if they exist.
   1.570 +    */
   1.571 +  static uint32_t sNumLivingContexts;
   1.572 +
   1.573 +  /**
   1.574 +    * Lookup table used to speed up GetImageData().
   1.575 +    */
   1.576 +  static uint8_t (*sUnpremultiplyTable)[256];
   1.577 +
   1.578 +  /**
   1.579 +    * Lookup table used to speed up PutImageData().
   1.580 +    */
   1.581 +  static uint8_t (*sPremultiplyTable)[256];
   1.582 +
   1.583 +  static mozilla::gfx::DrawTarget* sErrorTarget;
   1.584 +
   1.585 +  // Some helpers.  Doesn't modify a color on failure.
   1.586 +  void SetStyleFromUnion(const StringOrCanvasGradientOrCanvasPattern& value,
   1.587 +                         Style whichStyle);
   1.588 +  void SetStyleFromString(const nsAString& str, Style whichStyle);
   1.589 +
   1.590 +  void SetStyleFromGradient(CanvasGradient& gradient, Style whichStyle)
   1.591 +  {
   1.592 +    CurrentState().SetGradientStyle(whichStyle, &gradient);
   1.593 +  }
   1.594 +
   1.595 +  void SetStyleFromPattern(CanvasPattern& pattern, Style whichStyle)
   1.596 +  {
   1.597 +    CurrentState().SetPatternStyle(whichStyle, &pattern);
   1.598 +  }
   1.599 +
   1.600 +  void GetStyleAsUnion(OwningStringOrCanvasGradientOrCanvasPattern& aValue,
   1.601 +                       Style aWhichStyle);
   1.602 +
   1.603 +  // Returns whether a color was successfully parsed.
   1.604 +  bool ParseColor(const nsAString& aString, nscolor* aColor);
   1.605 +
   1.606 +  static void StyleColorToString(const nscolor& aColor, nsAString& aStr);
   1.607 +
   1.608 +  /**
   1.609 +   * Creates the error target, if it doesn't exist
   1.610 +   */
   1.611 +  static void EnsureErrorTarget();
   1.612 +
   1.613 +  /* This function ensures there is a writable pathbuilder available, this
   1.614 +   * pathbuilder may be working in user space or in device space or
   1.615 +   * device space.
   1.616 +   * After calling this function mPathTransformWillUpdate will be false
   1.617 +   */
   1.618 +  void EnsureWritablePath();
   1.619 +
   1.620 +  // Ensures a path in UserSpace is available.
   1.621 +  void EnsureUserSpacePath(const CanvasWindingRule& winding = CanvasWindingRule::Nonzero);
   1.622 +
   1.623 +  /**
   1.624 +   * Needs to be called before updating the transform. This makes a call to
   1.625 +   * EnsureTarget() so you don't have to.
   1.626 +   */
   1.627 +  void TransformWillUpdate();
   1.628 +
   1.629 +  // Report the fillRule has changed.
   1.630 +  void FillRuleChanged();
   1.631 +
   1.632 +   /**
   1.633 +   * Create the backing surfacing, if it doesn't exist. If there is an error
   1.634 +   * in creating the target then it will put sErrorTarget in place. If there
   1.635 +   * is in turn an error in creating the sErrorTarget then they would both
   1.636 +   * be null so IsTargetValid() would still return null.
   1.637 +   */
   1.638 +  void EnsureTarget();
   1.639 +
   1.640 +  /*
   1.641 +   * Disposes an old target and prepares to lazily create a new target.
   1.642 +   */
   1.643 +  void ClearTarget();
   1.644 +
   1.645 +  /**
   1.646 +   * Check if the target is valid after calling EnsureTarget.
   1.647 +   */
   1.648 +  bool IsTargetValid() { return mTarget != sErrorTarget && mTarget != nullptr; }
   1.649 +
   1.650 +  /**
   1.651 +    * Returns the surface format this canvas should be allocated using. Takes
   1.652 +    * into account mOpaque, platform requirements, etc.
   1.653 +    */
   1.654 +  mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
   1.655 +
   1.656 +  void DrawImage(const HTMLImageOrCanvasOrVideoElement &imgElt,
   1.657 +                 double sx, double sy, double sw, double sh,
   1.658 +                 double dx, double dy, double dw, double dh, 
   1.659 +                 uint8_t optional_argc, mozilla::ErrorResult& error);
   1.660 +
   1.661 +  void DrawDirectlyToCanvas(const nsLayoutUtils::DirectDrawInfo& image,
   1.662 +                            mozilla::gfx::Rect* bounds, double dx, double dy,
   1.663 +                            double dw, double dh, double sx, double sy,
   1.664 +                            double sw, double sh, gfxIntSize imgSize);
   1.665 +
   1.666 +  nsString& GetFont()
   1.667 +  {
   1.668 +    /* will initilize the value if not set, else does nothing */
   1.669 +    GetCurrentFontStyle();
   1.670 +
   1.671 +    return CurrentState().font;
   1.672 +  }
   1.673 +
   1.674 +  static std::vector<CanvasRenderingContext2D*>& DemotableContexts();
   1.675 +  static void DemoteOldestContextIfNecessary();
   1.676 +
   1.677 +  static void AddDemotableContext(CanvasRenderingContext2D* context);
   1.678 +  static void RemoveDemotableContext(CanvasRenderingContext2D* context);
   1.679 +
   1.680 +  // Do not use GL
   1.681 +  bool mForceSoftware;
   1.682 +
   1.683 +  // Member vars
   1.684 +  int32_t mWidth, mHeight;
   1.685 +
   1.686 +  // This is true when the canvas is valid, but of zero size, this requires
   1.687 +  // specific behavior on some operations.
   1.688 +  bool mZero;
   1.689 +
   1.690 +  bool mOpaque;
   1.691 +
   1.692 +  // This is true when the next time our layer is retrieved we need to
   1.693 +  // recreate it (i.e. our backing surface changed)
   1.694 +  bool mResetLayer;
   1.695 +  // This is needed for drawing in drawAsyncXULElement
   1.696 +  bool mIPC;
   1.697 +
   1.698 +  nsTArray<CanvasRenderingContext2DUserData*> mUserDatas;
   1.699 +
   1.700 +  // If mCanvasElement is not provided, then a docshell is
   1.701 +  nsCOMPtr<nsIDocShell> mDocShell;
   1.702 +
   1.703 +  // This is created lazily so it is necessary to call EnsureTarget before
   1.704 +  // accessing it. In the event of an error it will be equal to
   1.705 +  // sErrorTarget.
   1.706 +  mozilla::RefPtr<mozilla::gfx::DrawTarget> mTarget;
   1.707 +
   1.708 +  RefPtr<gfx::SurfaceStream> mStream;
   1.709 +
   1.710 +  /**
   1.711 +    * Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
   1.712 +    * Redraw is called, reset to false when Render is called.
   1.713 +    */
   1.714 +  bool mIsEntireFrameInvalid;
   1.715 +  /**
   1.716 +    * When this is set, the first call to Redraw(gfxRect) should set
   1.717 +    * mIsEntireFrameInvalid since we expect it will be followed by
   1.718 +    * many more Redraw calls.
   1.719 +    */
   1.720 +  bool mPredictManyRedrawCalls;
   1.721 +
   1.722 +  // This is stored after GetThebesSurface has been called once to avoid
   1.723 +  // excessive ThebesSurface initialization overhead.
   1.724 +  nsRefPtr<gfxASurface> mThebesSurface;
   1.725 +
   1.726 +  /**
   1.727 +    * We also have a device space pathbuilder. The reason for this is as
   1.728 +    * follows, when a path is being built, but the transform changes, we
   1.729 +    * can no longer keep a single path in userspace, considering there's
   1.730 +    * several 'user spaces' now. We therefore transform the current path
   1.731 +    * into device space, and add all operations to this path in device
   1.732 +    * space.
   1.733 +    *
   1.734 +    * When then finally executing a render, the Azure drawing API expects
   1.735 +    * the path to be in userspace. We could then set an identity transform
   1.736 +    * on the DrawTarget and do all drawing in device space. This is
   1.737 +    * undesirable because it requires transforming patterns, gradients,
   1.738 +    * clips, etc. into device space and it would not work for stroking.
   1.739 +    * What we do instead is convert the path back to user space when it is
   1.740 +    * drawn, and draw it with the current transform. This makes all drawing
   1.741 +    * occur correctly.
   1.742 +    *
   1.743 +    * There's never both a device space path builder and a user space path
   1.744 +    * builder present at the same time. There is also never a path and a
   1.745 +    * path builder present at the same time. When writing proceeds on an
   1.746 +    * existing path the Path is cleared and a new builder is created.
   1.747 +    *
   1.748 +    * mPath is always in user-space.
   1.749 +    */
   1.750 +  mozilla::RefPtr<mozilla::gfx::Path> mPath;
   1.751 +  mozilla::RefPtr<mozilla::gfx::PathBuilder> mDSPathBuilder;
   1.752 +  mozilla::RefPtr<mozilla::gfx::PathBuilder> mPathBuilder;
   1.753 +  bool mPathTransformWillUpdate;
   1.754 +  mozilla::gfx::Matrix mPathToDS;
   1.755 +
   1.756 +  /**
   1.757 +    * Number of times we've invalidated before calling redraw
   1.758 +    */
   1.759 +  uint32_t mInvalidateCount;
   1.760 +  static const uint32_t kCanvasMaxInvalidateCount = 100;
   1.761 +
   1.762 +  /**
   1.763 +    * State information for hit regions
   1.764 +    */
   1.765 +
   1.766 +  struct RegionInfo : public nsStringHashKey
   1.767 +  {
   1.768 +    RegionInfo(const nsAString& aKey) :
   1.769 +      nsStringHashKey(&aKey)
   1.770 +    {
   1.771 +    }
   1.772 +    RegionInfo(const nsAString *aKey) :
   1.773 +      nsStringHashKey(aKey)
   1.774 +    {
   1.775 +    }
   1.776 +
   1.777 +    nsRefPtr<Element> mElement;
   1.778 +  };
   1.779 +
   1.780 +#ifdef ACCESSIBILITY
   1.781 +  static PLDHashOperator RemoveHitRegionProperty(RegionInfo* aEntry, void* aData);
   1.782 +#endif
   1.783 +  nsTHashtable<RegionInfo> mHitRegionsOptions;
   1.784 +
   1.785 +  /**
   1.786 +    * Returns true if a shadow should be drawn along with a
   1.787 +    * drawing operation.
   1.788 +    */
   1.789 +  bool NeedToDrawShadow()
   1.790 +  {
   1.791 +    const ContextState& state = CurrentState();
   1.792 +
   1.793 +    // The spec says we should not draw shadows if the operator is OVER.
   1.794 +    // If it's over and the alpha value is zero, nothing needs to be drawn.
   1.795 +    return NS_GET_A(state.shadowColor) != 0 && 
   1.796 +      (state.shadowBlur != 0 || state.shadowOffset.x != 0 || state.shadowOffset.y != 0);
   1.797 +  }
   1.798 +
   1.799 +  mozilla::gfx::CompositionOp UsedOperation()
   1.800 +  {
   1.801 +    if (NeedToDrawShadow()) {
   1.802 +      // In this case the shadow rendering will use the operator.
   1.803 +      return mozilla::gfx::CompositionOp::OP_OVER;
   1.804 +    }
   1.805 +
   1.806 +    return CurrentState().op;
   1.807 +  }
   1.808 +
   1.809 +  /**
   1.810 +    * Gets the pres shell from either the canvas element or the doc shell
   1.811 +    */
   1.812 +  nsIPresShell *GetPresShell() {
   1.813 +    if (mCanvasElement) {
   1.814 +      return mCanvasElement->OwnerDoc()->GetShell();
   1.815 +    }
   1.816 +    if (mDocShell) {
   1.817 +      return mDocShell->GetPresShell();
   1.818 +    }
   1.819 +    return nullptr;
   1.820 +  }
   1.821 +
   1.822 +  // text
   1.823 +
   1.824 +public: // These enums are public only to accomodate non-C++11 legacy path of
   1.825 +        // MOZ_FINISH_NESTED_ENUM_CLASS. Can move back to protected as soon
   1.826 +        // as that legacy path is dropped.
   1.827 +  MOZ_BEGIN_NESTED_ENUM_CLASS(TextAlign, uint8_t)
   1.828 +    START,
   1.829 +    END,
   1.830 +    LEFT,
   1.831 +    RIGHT,
   1.832 +    CENTER
   1.833 +  MOZ_END_NESTED_ENUM_CLASS(TextAlign)
   1.834 +
   1.835 +  MOZ_BEGIN_NESTED_ENUM_CLASS(TextBaseline, uint8_t)
   1.836 +    TOP,
   1.837 +    HANGING,
   1.838 +    MIDDLE,
   1.839 +    ALPHABETIC,
   1.840 +    IDEOGRAPHIC,
   1.841 +    BOTTOM
   1.842 +  MOZ_END_NESTED_ENUM_CLASS(TextBaseline)
   1.843 +
   1.844 +  MOZ_BEGIN_NESTED_ENUM_CLASS(TextDrawOperation, uint8_t)
   1.845 +    FILL,
   1.846 +    STROKE,
   1.847 +    MEASURE
   1.848 +  MOZ_END_NESTED_ENUM_CLASS(TextDrawOperation)
   1.849 +
   1.850 +protected:
   1.851 +  gfxFontGroup *GetCurrentFontStyle();
   1.852 +
   1.853 +  /*
   1.854 +    * Implementation of the fillText, strokeText, and measure functions with
   1.855 +    * the operation abstracted to a flag.
   1.856 +    */
   1.857 +  nsresult DrawOrMeasureText(const nsAString& text,
   1.858 +                             float x,
   1.859 +                             float y,
   1.860 +                             const Optional<double>& maxWidth,
   1.861 +                             TextDrawOperation op,
   1.862 +                             float* aWidth);
   1.863 +
   1.864 +  // state stack handling
   1.865 +  class ContextState {
   1.866 +  public:
   1.867 +    ContextState() : textAlign(TextAlign::START),
   1.868 +                     textBaseline(TextBaseline::ALPHABETIC),
   1.869 +                     lineWidth(1.0f),
   1.870 +                     miterLimit(10.0f),
   1.871 +                     globalAlpha(1.0f),
   1.872 +                     shadowBlur(0.0),
   1.873 +                     dashOffset(0.0f),
   1.874 +                     op(mozilla::gfx::CompositionOp::OP_OVER),
   1.875 +                     fillRule(mozilla::gfx::FillRule::FILL_WINDING),
   1.876 +                     lineCap(mozilla::gfx::CapStyle::BUTT),
   1.877 +                     lineJoin(mozilla::gfx::JoinStyle::MITER_OR_BEVEL),
   1.878 +                     imageSmoothingEnabled(true)
   1.879 +    { }
   1.880 +
   1.881 +    ContextState(const ContextState& other)
   1.882 +        : fontGroup(other.fontGroup),
   1.883 +          gradientStyles(other.gradientStyles),
   1.884 +          patternStyles(other.patternStyles),
   1.885 +          colorStyles(other.colorStyles),
   1.886 +          font(other.font),
   1.887 +          textAlign(other.textAlign),
   1.888 +          textBaseline(other.textBaseline),
   1.889 +          shadowColor(other.shadowColor),
   1.890 +          transform(other.transform),
   1.891 +          shadowOffset(other.shadowOffset),
   1.892 +          lineWidth(other.lineWidth),
   1.893 +          miterLimit(other.miterLimit),
   1.894 +          globalAlpha(other.globalAlpha),
   1.895 +          shadowBlur(other.shadowBlur),
   1.896 +          dash(other.dash),
   1.897 +          dashOffset(other.dashOffset),
   1.898 +          op(other.op),
   1.899 +          fillRule(other.fillRule),
   1.900 +          lineCap(other.lineCap),
   1.901 +          lineJoin(other.lineJoin),
   1.902 +          imageSmoothingEnabled(other.imageSmoothingEnabled)
   1.903 +    { }
   1.904 +
   1.905 +    void SetColorStyle(Style whichStyle, nscolor color)
   1.906 +    {
   1.907 +      colorStyles[whichStyle] = color;
   1.908 +      gradientStyles[whichStyle] = nullptr;
   1.909 +      patternStyles[whichStyle] = nullptr;
   1.910 +    }
   1.911 +
   1.912 +    void SetPatternStyle(Style whichStyle, CanvasPattern* pat)
   1.913 +    {
   1.914 +      gradientStyles[whichStyle] = nullptr;
   1.915 +      patternStyles[whichStyle] = pat;
   1.916 +    }
   1.917 +
   1.918 +    void SetGradientStyle(Style whichStyle, CanvasGradient* grad)
   1.919 +    {
   1.920 +      gradientStyles[whichStyle] = grad;
   1.921 +      patternStyles[whichStyle] = nullptr;
   1.922 +    }
   1.923 +
   1.924 +    /**
   1.925 +      * returns true iff the given style is a solid color.
   1.926 +      */
   1.927 +    bool StyleIsColor(Style whichStyle) const
   1.928 +    {
   1.929 +      return !(patternStyles[whichStyle] || gradientStyles[whichStyle]);
   1.930 +    }
   1.931 +
   1.932 +
   1.933 +    std::vector<mozilla::RefPtr<mozilla::gfx::Path> > clipsPushed;
   1.934 +
   1.935 +    nsRefPtr<gfxFontGroup> fontGroup;
   1.936 +    EnumeratedArray<Style, Style::MAX, nsRefPtr<CanvasGradient>> gradientStyles;
   1.937 +    EnumeratedArray<Style, Style::MAX, nsRefPtr<CanvasPattern>> patternStyles;
   1.938 +    EnumeratedArray<Style, Style::MAX, nscolor> colorStyles;
   1.939 +
   1.940 +    nsString font;
   1.941 +    TextAlign textAlign;
   1.942 +    TextBaseline textBaseline;
   1.943 +
   1.944 +    nscolor shadowColor;
   1.945 +
   1.946 +    mozilla::gfx::Matrix transform;
   1.947 +    mozilla::gfx::Point shadowOffset;
   1.948 +    mozilla::gfx::Float lineWidth;
   1.949 +    mozilla::gfx::Float miterLimit;
   1.950 +    mozilla::gfx::Float globalAlpha;
   1.951 +    mozilla::gfx::Float shadowBlur;
   1.952 +    FallibleTArray<mozilla::gfx::Float> dash;
   1.953 +    mozilla::gfx::Float dashOffset;
   1.954 +
   1.955 +    mozilla::gfx::CompositionOp op;
   1.956 +    mozilla::gfx::FillRule fillRule;
   1.957 +    mozilla::gfx::CapStyle lineCap;
   1.958 +    mozilla::gfx::JoinStyle lineJoin;
   1.959 +
   1.960 +    bool imageSmoothingEnabled;
   1.961 +  };
   1.962 +
   1.963 +  nsAutoTArray<ContextState, 3> mStyleStack;
   1.964 +
   1.965 +  inline ContextState& CurrentState() {
   1.966 +    return mStyleStack[mStyleStack.Length() - 1];
   1.967 +  }
   1.968 +
   1.969 +  inline const ContextState& CurrentState() const {
   1.970 +    return mStyleStack[mStyleStack.Length() - 1];
   1.971 +  }
   1.972 +
   1.973 +  friend class CanvasGeneralPattern;
   1.974 +  friend class AdjustedTarget;
   1.975 +
   1.976 +  // other helpers
   1.977 +  void GetAppUnitsValues(int32_t *perDevPixel, int32_t *perCSSPixel)
   1.978 +  {
   1.979 +    // If we don't have a canvas element, we just return something generic.
   1.980 +    int32_t devPixel = 60;
   1.981 +    int32_t cssPixel = 60;
   1.982 +
   1.983 +    nsIPresShell *ps = GetPresShell();
   1.984 +    nsPresContext *pc;
   1.985 +
   1.986 +    if (!ps) goto FINISH;
   1.987 +    pc = ps->GetPresContext();
   1.988 +    if (!pc) goto FINISH;
   1.989 +    devPixel = pc->AppUnitsPerDevPixel();
   1.990 +    cssPixel = pc->AppUnitsPerCSSPixel();
   1.991 +
   1.992 +  FINISH:
   1.993 +    if (perDevPixel)
   1.994 +      *perDevPixel = devPixel;
   1.995 +    if (perCSSPixel)
   1.996 +      *perCSSPixel = cssPixel;
   1.997 +  }
   1.998 +
   1.999 +  friend struct CanvasBidiProcessor;
  1.1000 +};
  1.1001 +
  1.1002 +MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::CanvasMultiGetterType)
  1.1003 +MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::Style)
  1.1004 +MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::TextAlign)
  1.1005 +MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::TextBaseline)
  1.1006 +MOZ_FINISH_NESTED_ENUM_CLASS(CanvasRenderingContext2D::TextDrawOperation)
  1.1007 +
  1.1008 +}
  1.1009 +}
  1.1010 +
  1.1011 +#endif /* CanvasRenderingContext2D_h */

mercurial