Back out 438c192e561b and d6f341e77b68 (bug 762652, bug 762654) on suspicion of breaking Windows PGO tests
authorMatt Brubeck <mbrubeck@mozilla.com>
Wed, 27 Jun 2012 16:24:53 -0700
changeset 100531 9a2cc88619ba31dfbfc1369c84f1a25c53ac28bf
parent 100530 18f7e51126e0ef8b65318ae3d4013c00e25a76d2
child 100532 784b7a971022bb1d7df85a398214b5a4fe1eb234
push id1729
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 20:02:43 +0000
treeherdermozilla-aurora@f4e75e148951 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs762652, 762654
milestone16.0a1
backs out438c192e561bfe8abea50f7c7dc3ccd2730b438e
Back out 438c192e561b and d6f341e77b68 (bug 762652, bug 762654) on suspicion of breaking Windows PGO tests
content/canvas/public/nsICanvasRenderingContextInternal.h
content/canvas/src/ImageData.cpp
content/canvas/src/ImageData.h
content/canvas/src/Makefile.in
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.h
content/canvas/test/test_canvas.html
content/html/content/src/nsHTMLCanvasElement.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsJSEnvironment.cpp
dom/bindings/BindingUtils.h
dom/bindings/Bindings.conf
dom/bindings/Makefile.in
dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
dom/webidl/CanvasRenderingContext2D.webidl
dom/webidl/WebIDL.mk
--- a/content/canvas/public/nsICanvasRenderingContextInternal.h
+++ b/content/canvas/public/nsICanvasRenderingContextInternal.h
@@ -124,20 +124,12 @@ public:
   // anything into this canvas before changing the shmem state, it will be
   // lost.
   NS_IMETHOD SetIsIPC(bool isIPC) = 0;
 
 protected:
   nsRefPtr<nsHTMLCanvasElement> mCanvasElement;
 };
 
-namespace mozilla {
-namespace dom {
-
-extern bool AzureCanvasEnabled();
-
-}
-}
-
 NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal,
                               NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
 
 #endif /* nsICanvasRenderingContextInternal_h___ */
--- a/content/canvas/src/ImageData.cpp
+++ b/content/canvas/src/ImageData.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/ImageData.h"
 
 #include "nsDOMClassInfoID.h"
 #include "nsContentUtils.h"
-#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #include "jsapi.h"
 
 DOMCI_DATA(ImageData, mozilla::dom::ImageData)
 
 namespace mozilla {
 namespace dom {
 
--- a/content/canvas/src/ImageData.h
+++ b/content/canvas/src/ImageData.h
@@ -46,20 +46,16 @@ public:
   uint32_t GetWidth()
   {
     return mWidth;
   }
   uint32_t GetHeight()
   {
     return mHeight;
   }
-  JSObject* GetData(JSContext* cx)
-  {
-    return GetDataObject();
-  }
   JSObject* GetDataObject()
   {
     xpc_UnmarkGrayObject(mData);
     return mData;
   }
 
 private:
   void HoldData();
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -72,13 +72,12 @@ include $(topsrcdir)/ipc/chromium/chromi
 CXXFLAGS	+= $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
 
 INCLUDES	+= \
 		-I$(srcdir)/../../../layout/xul/base/src \
 		-I$(srcdir)/../../../layout/style \
 		-I$(srcdir)/../../../layout/generic \
 		-I$(srcdir)/../../base/src \
 		-I$(srcdir)/../../html/content/src \
-		-I$(srcdir)/../../../js/xpconnect/src \
 		-I$(srcdir)/../../../dom/base \
 		$(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -1417,30 +1417,30 @@ nsCanvasRenderingContext2D::GetCanvas(ns
     return NS_OK;
 }
 
 //
 // state
 //
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::MozSave()
+nsCanvasRenderingContext2D::Save()
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     ContextState state = CurrentState();
     mStyleStack.AppendElement(state);
     mThebes->Save();
     mSaveCount++;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::MozRestore()
+nsCanvasRenderingContext2D::Restore()
 {
     if (!EnsureSurface()) 
         return NS_ERROR_FAILURE;
 
     if (mSaveCount == 0)
         return NS_OK;
 
     mStyleStack.RemoveElementAt(mSaveCount);
@@ -1946,32 +1946,32 @@ nsCanvasRenderingContext2D::SetShadowBlu
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetShadowBlur(float *blur)
 {
     *blur = CurrentState().shadowBlur;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D:: SetMozShadowColor(const nsAString& aColor)
+nsCanvasRenderingContext2D::SetShadowColor(const nsAString& aColor)
 {
     nscolor color;
     if (!ParseColor(aColor, &color)) {
         return NS_OK;
     }
 
     CurrentState().SetColorStyle(STYLE_SHADOW, color);
 
     mDirtyStyle[STYLE_SHADOW] = true;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetMozShadowColor(nsAString& color)
+nsCanvasRenderingContext2D::GetShadowColor(nsAString& color)
 {
     StyleColorToString(CurrentState().colorStyles[STYLE_SHADOW], color);
 
     return NS_OK;
 }
 
 static const gfxFloat SIGMA_MAX = 100;
 
@@ -2212,58 +2212,58 @@ nsCanvasRenderingContext2D::StrokeRect(f
     return DrawRect(gfxRect(x, y, w, h), STYLE_STROKE);
 }
 
 //
 // path bits
 //
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::MozBeginPath()
+nsCanvasRenderingContext2D::BeginPath()
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     mHasPath = false;
     mThebes->NewPath();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::MozClosePath()
+nsCanvasRenderingContext2D::ClosePath()
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     mThebes->ClosePath();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::MozFill()
+nsCanvasRenderingContext2D::Fill()
 {
     gfxRect dirty;
     nsresult rv = DrawPath(STYLE_FILL, &dirty);
     if (NS_FAILED(rv))
         return rv;
     return RedrawUser(dirty);
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::MozStroke()
+nsCanvasRenderingContext2D::Stroke()
 {
     gfxRect dirty;
     nsresult rv = DrawPath(STYLE_STROKE, &dirty);
     if (NS_FAILED(rv))
         return rv;
     return RedrawUser(dirty);
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::MozClip()
+nsCanvasRenderingContext2D::Clip()
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     mThebes->Clip();
     return NS_OK;
 }
 
@@ -2482,17 +2482,17 @@ CreateFontStyleRule(const nsAString& aFo
 
     rule->RuleMatched();
 
     rule.forget(aResult);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetMozFont(const nsAString& font)
+nsCanvasRenderingContext2D::SetFont(const nsAString& font)
 {
     nsresult rv;
 
     /*
      * If font is defined with relative units (e.g. ems) and the parent
      * style context changes in between calls, setting the font to the
      * same value as previous could result in a different computed value,
      * so we cannot have the optimization where we check if the new font
@@ -2611,44 +2611,44 @@ nsCanvasRenderingContext2D::SetMozFont(c
     // the spec required font sizes be converted to pixels, but that no
     // longer seems to be required.)
     declaration->GetValue(eCSSProperty_font, CurrentState().font);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetMozFont(nsAString& font)
+nsCanvasRenderingContext2D::GetFont(nsAString& font)
 {
     /* will initilize the value if not set, else does nothing */
     GetCurrentFontStyle();
 
     font = CurrentState().font;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetMozTextAlign(const nsAString& ta)
+nsCanvasRenderingContext2D::SetTextAlign(const nsAString& ta)
 {
     if (ta.EqualsLiteral("start"))
         CurrentState().textAlign = TEXT_ALIGN_START;
     else if (ta.EqualsLiteral("end"))
         CurrentState().textAlign = TEXT_ALIGN_END;
     else if (ta.EqualsLiteral("left"))
         CurrentState().textAlign = TEXT_ALIGN_LEFT;
     else if (ta.EqualsLiteral("right"))
         CurrentState().textAlign = TEXT_ALIGN_RIGHT;
     else if (ta.EqualsLiteral("center"))
         CurrentState().textAlign = TEXT_ALIGN_CENTER;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetMozTextAlign(nsAString& ta)
+nsCanvasRenderingContext2D::GetTextAlign(nsAString& ta)
 {
     switch (CurrentState().textAlign)
     {
     case TEXT_ALIGN_START:
         ta.AssignLiteral("start");
         break;
     case TEXT_ALIGN_END:
         ta.AssignLiteral("end");
@@ -2663,17 +2663,17 @@ nsCanvasRenderingContext2D::GetMozTextAl
         ta.AssignLiteral("center");
         break;
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetMozTextBaseline(const nsAString& tb)
+nsCanvasRenderingContext2D::SetTextBaseline(const nsAString& tb)
 {
     if (tb.EqualsLiteral("top"))
         CurrentState().textBaseline = TEXT_BASELINE_TOP;
     else if (tb.EqualsLiteral("hanging"))
         CurrentState().textBaseline = TEXT_BASELINE_HANGING;
     else if (tb.EqualsLiteral("middle"))
         CurrentState().textBaseline = TEXT_BASELINE_MIDDLE;
     else if (tb.EqualsLiteral("alphabetic"))
@@ -2682,17 +2682,17 @@ nsCanvasRenderingContext2D::SetMozTextBa
         CurrentState().textBaseline = TEXT_BASELINE_IDEOGRAPHIC;
     else if (tb.EqualsLiteral("bottom"))
         CurrentState().textBaseline = TEXT_BASELINE_BOTTOM;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetMozTextBaseline(nsAString& tb)
+nsCanvasRenderingContext2D::GetTextBaseline(nsAString& tb)
 {
     switch (CurrentState().textBaseline)
     {
     case TEXT_BASELINE_TOP:
         tb.AssignLiteral("top");
         break;
     case TEXT_BASELINE_HANGING:
         tb.AssignLiteral("hanging");
@@ -3109,35 +3109,35 @@ nsCanvasRenderingContext2D::DrawOrMeasur
 
     if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_FILL && !doDrawShadow)
         return RedrawUser(boundingBox);
 
     return Redraw();
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetTextStyle(const nsAString& textStyle)
+nsCanvasRenderingContext2D::SetMozTextStyle(const nsAString& textStyle)
 {
     // font and mozTextStyle are the same value
-    return SetMozFont(textStyle);
+    return SetFont(textStyle);
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetTextStyle(nsAString& textStyle)
+nsCanvasRenderingContext2D::GetMozTextStyle(nsAString& textStyle)
 {
     // font and mozTextStyle are the same value
-    return GetMozFont(textStyle);
+    return GetFont(textStyle);
 }
 
 gfxFontGroup*
 nsCanvasRenderingContext2D::GetCurrentFontStyle()
 {
     // use lazy initilization for the font group since it's rather expensive
     if(!CurrentState().fontGroup) {
-        nsresult rv = SetTextStyle(kDefaultFontStyle);
+        nsresult rv = SetMozTextStyle(kDefaultFontStyle);
         if (NS_FAILED(rv)) {
             gfxFontStyle style;
             style.size = kDefaultFontSize;
             CurrentState().fontGroup =
                 gfxPlatform::GetPlatform()->CreateFontGroup(kDefaultFontName,
                                                             &style,
                                                             nsnull);
             if (CurrentState().fontGroup) {
@@ -3192,17 +3192,17 @@ nsCanvasRenderingContext2D::GetLineWidth
         return NS_ERROR_FAILURE;
  
     gfxFloat d = mThebes->CurrentLineWidth();
     *width = static_cast<float>(d);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetMozLineCap(const nsAString& capstyle)
+nsCanvasRenderingContext2D::SetLineCap(const nsAString& capstyle)
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     gfxContext::GraphicsLineCap cap;
 
     if (capstyle.EqualsLiteral("butt"))
         cap = gfxContext::LINE_CAP_BUTT;
@@ -3214,17 +3214,17 @@ nsCanvasRenderingContext2D::SetMozLineCa
         // XXX ERRMSG we need to report an error to developers here! (bug 329026)
         return NS_OK;
 
     mThebes->SetLineCap(cap);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetMozLineCap(nsAString& capstyle)
+nsCanvasRenderingContext2D::GetLineCap(nsAString& capstyle)
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     gfxContext::GraphicsLineCap cap = mThebes->CurrentLineCap();
 
     if (cap == gfxContext::LINE_CAP_BUTT)
         capstyle.AssignLiteral("butt");
@@ -3234,17 +3234,17 @@ nsCanvasRenderingContext2D::GetMozLineCa
         capstyle.AssignLiteral("square");
     else
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetMozLineJoin(const nsAString& joinstyle)
+nsCanvasRenderingContext2D::SetLineJoin(const nsAString& joinstyle)
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     gfxContext::GraphicsLineJoin j;
 
     if (joinstyle.EqualsLiteral("round"))
         j = gfxContext::LINE_JOIN_ROUND;
@@ -3256,17 +3256,17 @@ nsCanvasRenderingContext2D::SetMozLineJo
         // XXX ERRMSG we need to report an error to developers here! (bug 329026)
         return NS_OK;
 
     mThebes->SetLineJoin(j);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetMozLineJoin(nsAString& joinstyle)
+nsCanvasRenderingContext2D::GetLineJoin(nsAString& joinstyle)
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     gfxContext::GraphicsLineJoin j = mThebes->CurrentLineJoin();
 
     if (j == gfxContext::LINE_JOIN_ROUND)
         joinstyle.AssignLiteral("round");
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -1,28 +1,29 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/basictypes.h"
-#include "nsCanvasRenderingContext2DAzure.h"
 
 #include "nsIDOMXULElement.h"
 
 #include "prmem.h"
 #include "prenv.h"
 
 #include "nsIServiceManager.h"
 #include "nsMathUtils.h"
 
 #include "nsContentUtils.h"
 
 #include "nsIDOMDocument.h"
 #include "nsIDocument.h"
+#include "nsIDOMCanvasRenderingContext2D.h"
+#include "nsICanvasRenderingContextInternal.h"
 #include "nsHTMLCanvasElement.h"
 #include "nsSVGEffects.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIVariant.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFrame.h"
@@ -85,22 +86,16 @@
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/ipc/PDocumentRendererParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/unused.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsWrapperCacheInlines.h"
-#include "nsJSUtils.h"
-#include "XPCQuickStubs.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "nsHTMLImageElement.h"
-#include "nsHTMLVideoElement.h"
-#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
 #endif
 
 // windows.h (included by chromium code) defines this, in its infinite wisdom
 #undef DrawText
 
@@ -132,16 +127,92 @@ static PRInt64 GetCanvasAzureMemoryUsed(
 NS_MEMORY_REPORTER_IMPLEMENT(CanvasAzureMemory,
   "canvas-2d-pixel-bytes",
   KIND_OTHER,
   UNITS_BYTES,
   GetCanvasAzureMemoryUsed,
   "Memory used by 2D canvases. Each canvas requires (width * height * 4) "
   "bytes.")
 
+/**
+ ** nsCanvasGradientAzure
+ **/
+#define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
+    {0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
+class nsCanvasGradientAzure : public nsIDOMCanvasGradient
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENTAZURE_PRIVATE_IID)
+
+  enum Type
+  {
+    LINEAR = 0,
+    RADIAL
+  };
+
+  Type GetType()
+  {
+    return mType;
+  }
+
+
+  GradientStops *GetGradientStopsForTarget(DrawTarget *aRT)
+  {
+    if (mStops && mStops->GetBackendType() == aRT->GetType()) {
+      return mStops;
+    }
+
+    mStops = aRT->CreateGradientStops(mRawStops.Elements(), mRawStops.Length());
+
+    return mStops;
+  }
+
+  NS_DECL_ISUPPORTS
+
+  /* nsIDOMCanvasGradient */
+  NS_IMETHOD AddColorStop (float offset,
+                            const nsAString& colorstr)
+  {
+    if (!FloatValidate(offset) || offset < 0.0 || offset > 1.0) {
+      return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    }
+
+    nsCSSValue value;
+    nsCSSParser parser;
+    if (!parser.ParseColorString(colorstr, nsnull, 0, value)) {
+      return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    nscolor color;
+    if (!nsRuleNode::ComputeColor(value, nsnull, nsnull, color)) {
+      return NS_ERROR_DOM_SYNTAX_ERR;
+    }
+
+    mStops = nsnull;
+
+    GradientStop newStop;
+
+    newStop.offset = offset;
+    newStop.color = Color::FromABGR(color);
+
+    mRawStops.AppendElement(newStop);
+
+    return NS_OK;
+  }
+
+protected:
+  nsCanvasGradientAzure(Type aType) : mType(aType)
+  {}
+
+  nsTArray<GradientStop> mRawStops;
+  RefPtr<GradientStops> mStops;
+  Type mType;
+  virtual ~nsCanvasGradientAzure() {}
+};
+
 class nsCanvasRadialGradientAzure : public nsCanvasGradientAzure
 {
 public:
   nsCanvasRadialGradientAzure(const Point &aBeginOrigin, Float aBeginRadius,
                               const Point &aEndOrigin, Float aEndRadius)
     : nsCanvasGradientAzure(RADIAL)
     , mCenter1(aBeginOrigin)
     , mCenter2(aEndOrigin)
@@ -162,240 +233,79 @@ public:
   nsCanvasLinearGradientAzure(const Point &aBegin, const Point &aEnd)
     : nsCanvasGradientAzure(LINEAR)
     , mBegin(aBegin)
     , mEnd(aEnd)
   {
   }
 
 protected:
-  friend class GeneralPattern;
+  friend class nsCanvasRenderingContext2DAzure;
 
   // Beginning of linear gradient.
   Point mBegin;
   // End of linear gradient.
   Point mEnd;
 };
 
-class GeneralPattern
-{
-public:
-  typedef nsCanvasRenderingContext2DAzure::Style Style;
-  typedef nsCanvasRenderingContext2DAzure::ContextState ContextState;
-
-  GeneralPattern() : mPattern(nsnull) {}
-  ~GeneralPattern()
-  {
-    if (mPattern) {
-      mPattern->~Pattern();
-    }
-  }
-
-  Pattern& ForStyle(nsCanvasRenderingContext2DAzure *aCtx,
-                    Style aStyle,
-                    DrawTarget *aRT)
-  {
-    // This should only be called once or the mPattern destructor will
-    // not be executed.
-    NS_ASSERTION(!mPattern, "ForStyle() should only be called once on GeneralPattern!");
-
-    const ContextState &state = aCtx->CurrentState();
-
-    if (state.StyleIsColor(aStyle)) {
-      mPattern = new (mColorPattern.addr()) ColorPattern(Color::FromABGR(state.colorStyles[aStyle]));
-    } else if (state.gradientStyles[aStyle] &&
-               state.gradientStyles[aStyle]->GetType() == nsCanvasGradientAzure::LINEAR) {
-      nsCanvasLinearGradientAzure *gradient =
-        static_cast<nsCanvasLinearGradientAzure*>(state.gradientStyles[aStyle].get());
-
-      mPattern = new (mLinearGradientPattern.addr())
-        LinearGradientPattern(gradient->mBegin, gradient->mEnd,
-                              gradient->GetGradientStopsForTarget(aRT));
-    } else if (state.gradientStyles[aStyle] &&
-               state.gradientStyles[aStyle]->GetType() == nsCanvasGradientAzure::RADIAL) {
-      nsCanvasRadialGradientAzure *gradient =
-        static_cast<nsCanvasRadialGradientAzure*>(state.gradientStyles[aStyle].get());
-
-      mPattern = new (mRadialGradientPattern.addr())
-        RadialGradientPattern(gradient->mCenter1, gradient->mCenter2, gradient->mRadius1,
-                              gradient->mRadius2, gradient->GetGradientStopsForTarget(aRT));
-    } else if (state.patternStyles[aStyle]) {
-      if (aCtx->mCanvasElement) {
-        CanvasUtils::DoDrawImageSecurityCheck(aCtx->mCanvasElement,
-                                              state.patternStyles[aStyle]->mPrincipal,
-                                              state.patternStyles[aStyle]->mForceWriteOnly,
-                                              state.patternStyles[aStyle]->mCORSUsed);
-      }
-
-      ExtendMode mode;
-      if (state.patternStyles[aStyle]->mRepeat == nsCanvasPatternAzure::NOREPEAT) {
-        mode = EXTEND_CLAMP;
-      } else {
-        mode = EXTEND_REPEAT;
-      }
-      mPattern = new (mSurfacePattern.addr())
-        SurfacePattern(state.patternStyles[aStyle]->mSurface, mode);
-    }
-
-    return *mPattern;
-  }
-
-  union {
-    AlignedStorage2<ColorPattern> mColorPattern;
-    AlignedStorage2<LinearGradientPattern> mLinearGradientPattern;
-    AlignedStorage2<RadialGradientPattern> mRadialGradientPattern;
-    AlignedStorage2<SurfacePattern> mSurfacePattern;
-  };
-  Pattern *mPattern;
-};
-
-/* This is an RAII based class that can be used as a drawtarget for
- * operations that need a shadow drawn. It will automatically provide a
- * temporary target when needed, and if so blend it back with a shadow.
- *
- * aBounds specifies the bounds of the drawing operation that will be
- * drawn to the target, it is given in device space! This function will
- * change aBounds to incorporate shadow bounds. If this is NULL the drawing
- * operation will be assumed to cover an infinite rect.
- */
-class AdjustedTarget
-{
-public:
-  typedef nsCanvasRenderingContext2DAzure::ContextState ContextState;
-
-  AdjustedTarget(nsCanvasRenderingContext2DAzure *ctx,
-                 mgfx::Rect *aBounds = nsnull)
-    : mCtx(nsnull)
-  {
-    if (!ctx->NeedToDrawShadow()) {
-      mTarget = ctx->mTarget;
-      return;
-    }
-    mCtx = ctx;
-
-    const ContextState &state = mCtx->CurrentState();
-
-    mSigma = state.shadowBlur / 2.0f;
-
-    if (mSigma > SIGMA_MAX) {
-      mSigma = SIGMA_MAX;
-    }
-      
-    Matrix transform = mCtx->mTarget->GetTransform();
-
-    mTempRect = mgfx::Rect(0, 0, ctx->mWidth, ctx->mHeight);
-
-    Float blurRadius = mSigma * 3;
-
-    // We need to enlarge and possibly offset our temporary surface
-    // so that things outside of the canvas may cast shadows.
-    mTempRect.Inflate(Margin(blurRadius + NS_MAX<Float>(state.shadowOffset.x, 0),
-                             blurRadius + NS_MAX<Float>(state.shadowOffset.y, 0),
-                             blurRadius + NS_MAX<Float>(-state.shadowOffset.x, 0),
-                             blurRadius + NS_MAX<Float>(-state.shadowOffset.y, 0)));
-
-    if (aBounds) {
-      // We actually include the bounds of the shadow blur, this makes it
-      // easier to execute the actual blur on hardware, and shouldn't affect
-      // the amount of pixels that need to be touched.
-      aBounds->Inflate(Margin(blurRadius, blurRadius,
-                              blurRadius, blurRadius));
-      mTempRect = mTempRect.Intersect(*aBounds);
-    }
-
-    mTempRect.ScaleRoundOut(1.0f);
-
-    transform._31 -= mTempRect.x;
-    transform._32 -= mTempRect.y;
-      
-    mTarget =
-      mCtx->mTarget->CreateSimilarDrawTarget(IntSize(int32_t(mTempRect.width), int32_t(mTempRect.height)),
-                                             FORMAT_B8G8R8A8);
-
-    if (!mTarget) {
-      // XXX - Deal with the situation where our temp size is too big to
-      // fit in a texture.
-      mTarget = ctx->mTarget;
-      mCtx = nsnull;
-    } else {
-      mTarget->SetTransform(transform);
-    }
-  }
-
-  ~AdjustedTarget()
-  {
-    if (!mCtx) {
-      return;
-    }
-
-    RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
-    
-    mCtx->mTarget->DrawSurfaceWithShadow(snapshot, mTempRect.TopLeft(),
-                                         Color::FromABGR(mCtx->CurrentState().shadowColor),
-                                         mCtx->CurrentState().shadowOffset, mSigma,
-                                         mCtx->CurrentState().op);
-  }
-
-  DrawTarget* operator->()
-  {
-    return mTarget;
-  }
-
-private:
-  RefPtr<DrawTarget> mTarget;
-  nsCanvasRenderingContext2DAzure *mCtx;
-  Float mSigma;
-  mgfx::Rect mTempRect;
-};
-
-NS_IMETHODIMP
-nsCanvasGradientAzure::AddColorStop(float offset, const nsAString& colorstr)
-{
-  if (!FloatValidate(offset) || offset < 0.0 || offset > 1.0) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-
-  nsCSSValue value;
-  nsCSSParser parser;
-  if (!parser.ParseColorString(colorstr, nsnull, 0, value)) {
-    return NS_ERROR_DOM_SYNTAX_ERR;
-  }
-
-  nscolor color;
-  if (!nsRuleNode::ComputeColor(value, nsnull, nsnull, color)) {
-    return NS_ERROR_DOM_SYNTAX_ERR;
-  }
-
-  mStops = nsnull;
-
-  GradientStop newStop;
-
-  newStop.offset = offset;
-  newStop.color = Color::FromABGR(color);
-
-  mRawStops.AppendElement(newStop);
-
-  return NS_OK;
-}
-
 NS_DEFINE_STATIC_IID_ACCESSOR(nsCanvasGradientAzure, NS_CANVASGRADIENTAZURE_PRIVATE_IID)
 
 NS_IMPL_ADDREF(nsCanvasGradientAzure)
 NS_IMPL_RELEASE(nsCanvasGradientAzure)
 
 // XXX
 // DOMCI_DATA(CanvasGradient, nsCanvasGradientAzure)
 
 NS_INTERFACE_MAP_BEGIN(nsCanvasGradientAzure)
   NS_INTERFACE_MAP_ENTRY(nsCanvasGradientAzure)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCanvasGradient)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CanvasGradient)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
+/**
+ ** nsCanvasPatternAzure
+ **/
+#define NS_CANVASPATTERNAZURE_PRIVATE_IID \
+    {0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
+class nsCanvasPatternAzure MOZ_FINAL : public nsIDOMCanvasPattern
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERNAZURE_PRIVATE_IID)
+
+  enum RepeatMode
+  {
+    REPEAT,
+    REPEATX,
+    REPEATY,
+    NOREPEAT
+  };
+
+  nsCanvasPatternAzure(SourceSurface* aSurface,
+                       RepeatMode aRepeat,
+                       nsIPrincipal* principalForSecurityCheck,
+                       bool forceWriteOnly,
+                       bool CORSUsed)
+    : mSurface(aSurface)
+    , mRepeat(aRepeat)
+    , mPrincipal(principalForSecurityCheck)
+    , mForceWriteOnly(forceWriteOnly)
+    , mCORSUsed(CORSUsed)
+  {
+  }
+
+  NS_DECL_ISUPPORTS
+
+  RefPtr<SourceSurface> mSurface;
+  const RepeatMode mRepeat;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
+  const bool mForceWriteOnly;
+  const bool mCORSUsed;
+};
+
 NS_DEFINE_STATIC_IID_ACCESSOR(nsCanvasPatternAzure, NS_CANVASPATTERNAZURE_PRIVATE_IID)
 
 NS_IMPL_ADDREF(nsCanvasPatternAzure)
 NS_IMPL_RELEASE(nsCanvasPatternAzure)
 
 // XXX
 // DOMCI_DATA(CanvasPattern, nsCanvasPatternAzure)
 
@@ -441,18 +351,599 @@ NS_IMPL_RELEASE(nsTextMetricsAzure)
 
 NS_INTERFACE_MAP_BEGIN(nsTextMetricsAzure)
   NS_INTERFACE_MAP_ENTRY(nsTextMetricsAzure)
   NS_INTERFACE_MAP_ENTRY(nsIDOMTextMetrics)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TextMetrics)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
+struct nsCanvasBidiProcessorAzure;
+class CanvasRenderingContext2DUserDataAzure;
+
 // Cap sigma to avoid overly large temp surfaces.
-const Float SIGMA_MAX = 100;
+static const Float SIGMA_MAX = 100;
+
+/**
+ ** nsCanvasRenderingContext2DAzure
+ **/
+class nsCanvasRenderingContext2DAzure :
+  public nsIDOMCanvasRenderingContext2D,
+  public nsICanvasRenderingContextInternal,
+  public nsWrapperCache
+{
+public:
+  nsCanvasRenderingContext2DAzure();
+  virtual ~nsCanvasRenderingContext2DAzure();
+
+  nsresult Redraw();
+
+  // nsICanvasRenderingContextInternal
+  NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
+  NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, PRInt32 width, PRInt32 height)
+  { return NS_ERROR_NOT_IMPLEMENTED; }
+
+  NS_IMETHOD Render(gfxContext *ctx,
+                    gfxPattern::GraphicsFilter aFilter,
+                    PRUint32 aFlags = RenderFlagPremultAlpha);
+  NS_IMETHOD GetInputStream(const char* aMimeType,
+                            const PRUnichar* aEncoderOptions,
+                            nsIInputStream **aStream);
+  NS_IMETHOD GetThebesSurface(gfxASurface **surface);
+
+  TemporaryRef<SourceSurface> GetSurfaceSnapshot()
+  { return mTarget ? mTarget->Snapshot() : nsnull; }
+
+  NS_IMETHOD SetIsOpaque(bool isOpaque);
+  NS_IMETHOD Reset();
+  already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
+                                                CanvasLayer *aOldLayer,
+                                                LayerManager *aManager);
+  void MarkContextClean();
+  NS_IMETHOD SetIsIPC(bool isIPC);
+  // this rect is in canvas device space
+  void Redraw(const mgfx::Rect &r);
+  NS_IMETHOD Redraw(const gfxRect &r) { Redraw(ToRect(r)); return NS_OK; }
+
+  // this rect is in mTarget's current user space
+  nsresult RedrawUser(const gfxRect &r);
+
+  // nsISupports interface + CC
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+
+  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
+    nsCanvasRenderingContext2DAzure, nsIDOMCanvasRenderingContext2D)
+
+  // nsIDOMCanvasRenderingContext2D interface
+  NS_DECL_NSIDOMCANVASRENDERINGCONTEXT2D
+
+  enum Style {
+    STYLE_STROKE = 0,
+    STYLE_FILL,
+    STYLE_MAX
+  };
+  
+  nsresult LineTo(const Point& aPoint);
+  nsresult BezierTo(const Point& aCP1, const Point& aCP2, const Point& aCP3);
+
+  friend class CanvasRenderingContext2DUserDataAzure;
+
+protected:
+  nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
+                             uint32_t aWidth, uint32_t aHeight,
+                             JSObject** aRetval);
+
+  nsresult InitializeWithTarget(DrawTarget *surface, PRInt32 width, PRInt32 height);
+
+  /**
+    * The number of living nsCanvasRenderingContexts.  When this goes down to
+    * 0, we free the premultiply and unpremultiply tables, if they exist.
+    */
+  static PRUint32 sNumLivingContexts;
+
+  /**
+    * Lookup table used to speed up GetImageData().
+    */
+  static PRUint8 (*sUnpremultiplyTable)[256];
+
+  /**
+    * Lookup table used to speed up PutImageData().
+    */
+  static PRUint8 (*sPremultiplyTable)[256];
+
+  // Some helpers.  Doesn't modify a color on failure.
+  nsresult SetStyleFromStringOrInterface(const nsAString& aStr, nsISupports *aInterface, Style aWhichStyle);
+  nsresult GetStyleAsStringOrInterface(nsAString& aStr, nsISupports **aInterface, PRInt32 *aType, Style aWhichStyle);
+
+  // Returns whether a color was successfully parsed.
+  bool ParseColor(const nsAString& aString, nscolor* aColor);
+
+  void StyleColorToString(const nscolor& aColor, nsAString& aStr);
+
+  /**
+    * Creates the unpremultiply lookup table, if it doesn't exist.
+    */
+  void EnsureUnpremultiplyTable();
+
+  /**
+    * Creates the premultiply lookup table, if it doesn't exist.
+    */
+  void EnsurePremultiplyTable();
+
+  /* This function ensures there is a writable pathbuilder available, this
+   * pathbuilder may be working in user space or in device space or
+   * device space.
+   */
+  void EnsureWritablePath();
+
+  // Ensures a path in UserSpace is available.
+  void EnsureUserSpacePath();
+
+  void TransformWillUpdate();
+
+  // Report the fillRule has changed.
+  void FillRuleChanged();
+
+  /**
+    * Returns the surface format this canvas should be allocated using. Takes
+    * into account mOpaque, platform requirements, etc.
+    */
+  SurfaceFormat GetSurfaceFormat() const;
+
+  // Member vars
+  PRInt32 mWidth, mHeight;
+
+  // This is true when the canvas is valid, false otherwise, this occurs when
+  // for some reason initialization of the drawtarget fails. If the canvas
+  // is invalid certain behavior is expected.
+  bool mValid;
+  // 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;
+
+  nsTArray<CanvasRenderingContext2DUserDataAzure*> mUserDatas;
+
+  // If mCanvasElement is not provided, then a docshell is
+  nsCOMPtr<nsIDocShell> mDocShell;
+
+  // our drawing surfaces, contexts, and layers
+  RefPtr<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.
+    */
+  RefPtr<Path> mPath;
+  RefPtr<PathBuilder> mDSPathBuilder;
+  RefPtr<PathBuilder> mPathBuilder;
+  bool mPathTransformWillUpdate;
+  Matrix mPathToDS;
+
+  /**
+    * Number of times we've invalidated before calling redraw
+    */
+  PRUint32 mInvalidateCount;
+  static const PRUint32 kCanvasMaxInvalidateCount = 100;
+
+  /**
+    * 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);
+  }
+
+  CompositionOp UsedOperation()
+  {
+    if (NeedToDrawShadow()) {
+      // In this case the shadow rendering will use the operator.
+      return 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) {
+      nsCOMPtr<nsIPresShell> shell;
+      mDocShell->GetPresShell(getter_AddRefs(shell));
+      return shell.get();
+    }
+    return nsnull;
+  }
+
+  // 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,
+                              float x,
+                              float y,
+                              float maxWidth,
+                              TextDrawOperation op,
+                              float* aWidth);
+
+  // state stack handling
+  class ContextState {
+  public:
+      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(OP_OVER),
+                       fillRule(FILL_WINDING),
+                       lineCap(CAP_BUTT),
+                       lineJoin(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];
+          }
+      }
+
+      void SetColorStyle(Style whichStyle, nscolor color) {
+          colorStyles[whichStyle] = color;
+          gradientStyles[whichStyle] = nsnull;
+          patternStyles[whichStyle] = nsnull;
+      }
+
+      void SetPatternStyle(Style whichStyle, nsCanvasPatternAzure* pat) {
+          gradientStyles[whichStyle] = nsnull;
+          patternStyles[whichStyle] = pat;
+      }
+
+      void SetGradientStyle(Style whichStyle, nsCanvasGradientAzure* grad) {
+          gradientStyles[whichStyle] = grad;
+          patternStyles[whichStyle] = nsnull;
+      }
+
+      /**
+        * returns true iff the given style is a solid color.
+        */
+      bool StyleIsColor(Style whichStyle) const
+      {
+          return !(patternStyles[whichStyle] ||
+                    gradientStyles[whichStyle]);
+      }
+
+
+      std::vector<RefPtr<Path> > clipsPushed;
+
+      nsRefPtr<gfxFontGroup> fontGroup;
+      nsRefPtr<nsCanvasGradientAzure> gradientStyles[STYLE_MAX];
+      nsRefPtr<nsCanvasPatternAzure> patternStyles[STYLE_MAX];
+
+      nsString font;
+      TextAlign textAlign;
+      TextBaseline textBaseline;
+
+      nscolor colorStyles[STYLE_MAX];
+      nscolor shadowColor;
+
+      Matrix transform;
+      Point shadowOffset;
+      Float lineWidth;
+      Float miterLimit;
+      Float globalAlpha;
+      Float shadowBlur;
+      FallibleTArray<Float> dash;
+      Float dashOffset;
+
+      CompositionOp op;
+      FillRule fillRule;
+      CapStyle lineCap;
+      JoinStyle lineJoin;
+
+      bool imageSmoothingEnabled;
+  };
+
+  class GeneralPattern
+  {
+  public:
+    GeneralPattern() : mPattern(nsnull) {}
+    ~GeneralPattern()
+    {
+      if (mPattern) {
+        mPattern->~Pattern();
+      }
+    }
+
+    Pattern& ForStyle(nsCanvasRenderingContext2DAzure *aCtx,
+                      Style aStyle,
+                      DrawTarget *aRT)
+    {
+      // This should only be called once or the mPattern destructor will
+      // not be executed.
+      NS_ASSERTION(!mPattern, "ForStyle() should only be called once on GeneralPattern!");
+
+      const nsCanvasRenderingContext2DAzure::ContextState &state = aCtx->CurrentState();
+
+      if (state.StyleIsColor(aStyle)) {
+        mPattern = new (mColorPattern.addr()) ColorPattern(Color::FromABGR(state.colorStyles[aStyle]));
+      } else if (state.gradientStyles[aStyle] &&
+                 state.gradientStyles[aStyle]->GetType() == nsCanvasGradientAzure::LINEAR) {
+        nsCanvasLinearGradientAzure *gradient =
+          static_cast<nsCanvasLinearGradientAzure*>(state.gradientStyles[aStyle].get());
+
+        mPattern = new (mLinearGradientPattern.addr())
+          LinearGradientPattern(gradient->mBegin, gradient->mEnd,
+                                gradient->GetGradientStopsForTarget(aRT));
+      } else if (state.gradientStyles[aStyle] &&
+                 state.gradientStyles[aStyle]->GetType() == nsCanvasGradientAzure::RADIAL) {
+        nsCanvasRadialGradientAzure *gradient =
+          static_cast<nsCanvasRadialGradientAzure*>(state.gradientStyles[aStyle].get());
+
+        mPattern = new (mRadialGradientPattern.addr())
+          RadialGradientPattern(gradient->mCenter1, gradient->mCenter2, gradient->mRadius1,
+                                gradient->mRadius2, gradient->GetGradientStopsForTarget(aRT));
+      } else if (state.patternStyles[aStyle]) {
+        if (aCtx->mCanvasElement) {
+          CanvasUtils::DoDrawImageSecurityCheck(aCtx->mCanvasElement,
+                                                state.patternStyles[aStyle]->mPrincipal,
+                                                state.patternStyles[aStyle]->mForceWriteOnly,
+                                                state.patternStyles[aStyle]->mCORSUsed);
+        }
+
+        ExtendMode mode;
+        if (state.patternStyles[aStyle]->mRepeat == nsCanvasPatternAzure::NOREPEAT) {
+          mode = EXTEND_CLAMP;
+        } else {
+          mode = EXTEND_REPEAT;
+        }
+        mPattern = new (mSurfacePattern.addr())
+          SurfacePattern(state.patternStyles[aStyle]->mSurface, mode);
+      }
+
+      return *mPattern;
+    }
+
+    union {
+      AlignedStorage2<ColorPattern> mColorPattern;
+      AlignedStorage2<LinearGradientPattern> mLinearGradientPattern;
+      AlignedStorage2<RadialGradientPattern> mRadialGradientPattern;
+      AlignedStorage2<SurfacePattern> mSurfacePattern;
+    };
+    Pattern *mPattern;
+  };
+
+  /* This is an RAII based class that can be used as a drawtarget for
+   * operations that need a shadow drawn. It will automatically provide a
+   * temporary target when needed, and if so blend it back with a shadow.
+   *
+   * aBounds specifies the bounds of the drawing operation that will be
+   * drawn to the target, it is given in device space! This function will
+   * change aBounds to incorporate shadow bounds. If this is NULL the drawing
+   * operation will be assumed to cover an infinite rect.
+   */
+  class AdjustedTarget
+  {
+  public:
+    AdjustedTarget(nsCanvasRenderingContext2DAzure *ctx,
+                   mgfx::Rect *aBounds = nsnull)
+      : mCtx(nsnull)
+    {
+      if (!ctx->NeedToDrawShadow()) {
+        mTarget = ctx->mTarget;
+        return;
+      }
+      mCtx = ctx;
+
+      const ContextState &state = mCtx->CurrentState();
+
+      mSigma = state.shadowBlur / 2.0f;
+
+      if (mSigma > SIGMA_MAX) {
+        mSigma = SIGMA_MAX;
+      }
+        
+      Matrix transform = mCtx->mTarget->GetTransform();
+
+      mTempRect = mgfx::Rect(0, 0, ctx->mWidth, ctx->mHeight);
+
+      Float blurRadius = mSigma * 3;
+
+      // We need to enlarge and possibly offset our temporary surface
+      // so that things outside of the canvas may cast shadows.
+      mTempRect.Inflate(Margin(blurRadius + NS_MAX<Float>(state.shadowOffset.x, 0),
+                               blurRadius + NS_MAX<Float>(state.shadowOffset.y, 0),
+                               blurRadius + NS_MAX<Float>(-state.shadowOffset.x, 0),
+                               blurRadius + NS_MAX<Float>(-state.shadowOffset.y, 0)));
+
+      if (aBounds) {
+        // We actually include the bounds of the shadow blur, this makes it
+        // easier to execute the actual blur on hardware, and shouldn't affect
+        // the amount of pixels that need to be touched.
+        aBounds->Inflate(Margin(blurRadius, blurRadius,
+                                blurRadius, blurRadius));
+        mTempRect = mTempRect.Intersect(*aBounds);
+      }
+
+      mTempRect.ScaleRoundOut(1.0f);
+
+      transform._31 -= mTempRect.x;
+      transform._32 -= mTempRect.y;
+        
+      mTarget =
+        mCtx->mTarget->CreateSimilarDrawTarget(IntSize(int32_t(mTempRect.width), int32_t(mTempRect.height)),
+                                               FORMAT_B8G8R8A8);
+
+      if (!mTarget) {
+        // XXX - Deal with the situation where our temp size is too big to
+        // fit in a texture.
+        mTarget = ctx->mTarget;
+        mCtx = nsnull;
+      } else {
+        mTarget->SetTransform(transform);
+      }
+    }
+
+    ~AdjustedTarget()
+    {
+      if (!mCtx) {
+        return;
+      }
+
+      RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
+      
+      mCtx->mTarget->DrawSurfaceWithShadow(snapshot, mTempRect.TopLeft(),
+                                           Color::FromABGR(mCtx->CurrentState().shadowColor),
+                                           mCtx->CurrentState().shadowOffset, mSigma,
+                                           mCtx->CurrentState().op);
+    }
+
+    DrawTarget* operator->()
+    {
+      return mTarget;
+    }
+
+  private:
+    RefPtr<DrawTarget> mTarget;
+    nsCanvasRenderingContext2DAzure *mCtx;
+    Float mSigma;
+    mgfx::Rect mTempRect;
+  };
+
+  nsAutoTArray<ContextState, 3> mStyleStack;
+
+  inline ContextState& CurrentState() {
+    return mStyleStack[mStyleStack.Length() - 1];
+  }
+    
+  // other helpers
+  void GetAppUnitsValues(PRUint32 *perDevPixel, PRUint32 *perCSSPixel) {
+    // If we don't have a canvas element, we just return something generic.
+    PRUint32 devPixel = 60;
+    PRUint32 cssPixel = 60;
+
+    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;
+  }
+
+  friend struct nsCanvasBidiProcessorAzure;
+};
 
 class CanvasRenderingContext2DUserDataAzure : public LayerUserData {
 public:
     CanvasRenderingContext2DUserDataAzure(nsCanvasRenderingContext2DAzure *aContext)
     : mContext(aContext)
   {
     aContext->mUserDatas.AppendElement(this);
   }
@@ -537,61 +1028,29 @@ NS_INTERFACE_MAP_END
  **/
 
 
 // Initialize our static variables.
 PRUint32 nsCanvasRenderingContext2DAzure::sNumLivingContexts = 0;
 PRUint8 (*nsCanvasRenderingContext2DAzure::sUnpremultiplyTable)[256] = nsnull;
 PRUint8 (*nsCanvasRenderingContext2DAzure::sPremultiplyTable)[256] = nsnull;
 
-namespace mozilla {
-namespace dom {
-
-static bool
-AzureCanvasEnabledOnPlatform()
-{
-#ifdef XP_WIN
-  if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
-      gfxWindowsPlatform::RENDER_DIRECT2D ||
-      !gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) {
-    static bool checkedPref = false;
-    static bool preferSkia;
-    if (!checkedPref) {
-      preferSkia = Preferences::GetBool("gfx.canvas.azure.prefer-skia", false);
-      checkedPref = true;
-    }
-    return preferSkia;
-  }
-#elif !defined(XP_MACOSX) && !defined(ANDROID) && !defined(LINUX)
-  return false;
-#endif
-  return true;
-}
-
-bool
-AzureCanvasEnabled()
-{
-  static bool checkedPref = false;
-  static bool azureEnabled;
-  if (!checkedPref) {
-    azureEnabled = Preferences::GetBool("gfx.canvas.azure.enabled", false);
-    checkedPref = true;
-  }
-  return azureEnabled && AzureCanvasEnabledOnPlatform();
-}
-
-}
-}
-
 nsresult
 NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
 {
-  if (!AzureCanvasEnabledOnPlatform()) {
+#ifdef XP_WIN
+  if ((gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
+      gfxWindowsPlatform::RENDER_DIRECT2D ||
+      !gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) &&
+      !Preferences::GetBool("gfx.canvas.azure.prefer-skia", false)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
+#elif !defined(XP_MACOSX) && !defined(ANDROID) && !defined(LINUX)
+  return NS_ERROR_NOT_AVAILABLE;
+#endif
 
   nsRefPtr<nsIDOMCanvasRenderingContext2D> ctx = new nsCanvasRenderingContext2DAzure();
   if (!ctx)
     return NS_ERROR_OUT_OF_MEMORY;
 
   *aResult = ctx.forget().get();
   return NS_OK;
 }
@@ -599,17 +1058,16 @@ NS_NewCanvasRenderingContext2DAzure(nsID
 nsCanvasRenderingContext2DAzure::nsCanvasRenderingContext2DAzure()
   : mValid(false), mZero(false), mOpaque(false), mResetLayer(true)
   , mIPC(false)
   , mIsEntireFrameInvalid(false)
   , mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
   , mInvalidateCount(0)
 {
   sNumLivingContexts++;
-  SetIsDOMBinding();
 }
 
 nsCanvasRenderingContext2DAzure::~nsCanvasRenderingContext2DAzure()
 {
   Reset();
   // Drop references from all CanvasRenderingContext2DUserDataAzure to this context
   for (PRUint32 i = 0; i < mUserDatas.Length(); ++i) {
     mUserDatas[i]->Forget();
@@ -618,23 +1076,16 @@ nsCanvasRenderingContext2DAzure::~nsCanv
   if (!sNumLivingContexts) {
     delete[] sUnpremultiplyTable;
     delete[] sPremultiplyTable;
     sUnpremultiplyTable = nsnull;
     sPremultiplyTable = nsnull;
   }
 }
 
-JSObject*
-nsCanvasRenderingContext2DAzure::WrapObject(JSContext *cx, JSObject *scope,
-                                            bool *triedToWrap)
-{
-  return CanvasRenderingContext2DBinding::Wrap(cx, scope, this, triedToWrap);
-}
-
 bool
 nsCanvasRenderingContext2DAzure::ParseColor(const nsAString& aString,
                                             nscolor* aColor)
 {
   nsIDocument* document = mCanvasElement
                           ? mCanvasElement->OwnerDoc()
                           : nsnull;
 
@@ -680,92 +1131,80 @@ nsCanvasRenderingContext2DAzure::Reset()
   mThebesSurface = nsnull;
   mValid = false;
   mIsEntireFrameInvalid = false;
   mPredictManyRedrawCalls = false;
 
   return NS_OK;
 }
 
-static void
-WarnAboutUnexpectedStyle(nsHTMLCanvasElement* canvasElement)
-{
-  nsContentUtils::ReportToConsole(
-    nsIScriptError::warningFlag,
-    "Canvas",
-    canvasElement ? canvasElement->OwnerDoc() : nsnull,
-    nsContentUtils::eDOM_PROPERTIES,
-    "UnexpectedCanvasVariantStyle");
-}
-
-void
-nsCanvasRenderingContext2DAzure::SetStyleFromString(const nsAString& str,
-                                                    Style whichStyle)
-{
-  MOZ_ASSERT(!str.IsVoid());
-
-  nscolor color;
-  if (!ParseColor(str, &color)) {
-    return;
-  }
-
-  CurrentState().SetColorStyle(whichStyle, color);
-}
-
-void
+nsresult
 nsCanvasRenderingContext2DAzure::SetStyleFromStringOrInterface(const nsAString& aStr,
                                                                nsISupports *aInterface,
                                                                Style aWhichStyle)
 {
   if (!aStr.IsVoid()) {
-    SetStyleFromString(aStr, aWhichStyle);
-    return;
+    nscolor color;
+    if (!ParseColor(aStr, &color)) {
+      return NS_OK;
+    }
+
+    CurrentState().SetColorStyle(aWhichStyle, color);
+    return NS_OK;
   }
 
   if (aInterface) {
     nsCOMPtr<nsCanvasGradientAzure> grad(do_QueryInterface(aInterface));
     if (grad) {
-      SetStyleFromGradient(grad, aWhichStyle);
-      return;
+      CurrentState().SetGradientStyle(aWhichStyle, grad);
+      return NS_OK;
     }
 
     nsCOMPtr<nsCanvasPatternAzure> pattern(do_QueryInterface(aInterface));
     if (pattern) {
-      SetStyleFromPattern(pattern, aWhichStyle);
-      return;
+      CurrentState().SetPatternStyle(aWhichStyle, pattern);
+      return NS_OK;
     }
   }
 
-  WarnAboutUnexpectedStyle(mCanvasElement);
+  nsContentUtils::ReportToConsole(
+    nsIScriptError::warningFlag,
+    "Canvas",
+    mCanvasElement ? mCanvasElement->OwnerDoc() : nsnull,
+    nsContentUtils::eDOM_PROPERTIES,
+    "UnexpectedCanvasVariantStyle");
+
+  return NS_OK;
 }
 
-nsISupports*
+nsresult
 nsCanvasRenderingContext2DAzure::GetStyleAsStringOrInterface(nsAString& aStr,
-                                                             CanvasMultiGetterType& aType,
+                                                             nsISupports **aInterface,
+                                                             PRInt32 *aType,
                                                              Style aWhichStyle)
 {
   const ContextState &state = CurrentState();
-  nsISupports* supports;
+
   if (state.patternStyles[aWhichStyle]) {
     aStr.SetIsVoid(true);
-    supports = state.patternStyles[aWhichStyle];
-    aType = CMG_STYLE_PATTERN;
+    NS_ADDREF(*aInterface = state.patternStyles[aWhichStyle]);
+    *aType = CMG_STYLE_PATTERN;
   } else if (state.gradientStyles[aWhichStyle]) {
     aStr.SetIsVoid(true);
-    supports = state.gradientStyles[aWhichStyle];
-    aType = CMG_STYLE_GRADIENT;
+    NS_ADDREF(*aInterface = state.gradientStyles[aWhichStyle]);
+    *aType = CMG_STYLE_GRADIENT;
   } else {
     StyleColorToString(state.colorStyles[aWhichStyle], aStr);
-    supports = nsnull;
-    aType = CMG_STYLE_STRING;
+    *aInterface = nsnull;
+    *aType = CMG_STYLE_STRING;
   }
-  return supports;
+
+  return NS_OK;
 }
 
-// static
 void
 nsCanvasRenderingContext2DAzure::StyleColorToString(const nscolor& aColor, nsAString& aStr)
 {
   // We can't reuse the normal CSS color stringification code,
   // because the spec calls for a different algorithm for canvas.
   if (NS_GET_A(aColor) == 255) {
     CopyUTF8toUTF16(nsPrintfCString("#%02x%02x%02x",
                                     NS_GET_R(aColor),
@@ -837,27 +1276,29 @@ nsCanvasRenderingContext2DAzure::Redraw(
   nsSVGEffects::InvalidateDirectRenderingObservers(mCanvasElement);
 
   gfxRect tmpR = ThebesRect(r);
   mCanvasElement->InvalidateCanvasContent(&tmpR);
 
   return;
 }
 
-void
+nsresult
 nsCanvasRenderingContext2DAzure::RedrawUser(const gfxRect& r)
 {
   if (mIsEntireFrameInvalid) {
     ++mInvalidateCount;
-    return;
+    return NS_OK;
   }
 
   mgfx::Rect newr =
     mTarget->GetTransform().TransformBounds(ToRect(r));
   Redraw(newr);
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetDimensions(PRInt32 width, PRInt32 height)
 {
   RefPtr<DrawTarget> target;
 
   // Zero sized surfaces cause issues, so just go with 1x1.
@@ -1118,452 +1559,238 @@ nsCanvasRenderingContext2DAzure::GetSurf
 
 //
 // nsCanvasRenderingContext2DAzure impl
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetCanvas(nsIDOMHTMLCanvasElement **canvas)
 {
-  NS_IF_ADDREF(*canvas = GetCanvas());
+  NS_IF_ADDREF(*canvas = mCanvasElement);
 
   return NS_OK;
 }
 
 //
 // state
 //
 
-void
+NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::Save()
 {
   mStyleStack[mStyleStack.Length() - 1].transform = mTarget->GetTransform();
   mStyleStack.SetCapacity(mStyleStack.Length() + 1);
   mStyleStack.AppendElement(CurrentState());
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::MozSave()
-{
-  Save();
-  return NS_OK;
-}
-
-void
 nsCanvasRenderingContext2DAzure::Restore()
 {
   if (mStyleStack.Length() - 1 == 0)
-    return;
+    return NS_OK;
 
   for (PRUint32 i = 0; i < CurrentState().clipsPushed.size(); i++) {
     mTarget->PopClip();
   }
 
   mStyleStack.RemoveElementAt(mStyleStack.Length() - 1);
 
   TransformWillUpdate();
 
   mTarget->SetTransform(CurrentState().transform);
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::MozRestore()
-{
-  Restore();
+
   return NS_OK;
 }
 
 //
 // transformations
 //
 
-void
-nsCanvasRenderingContext2DAzure::Scale(double x, double y, ErrorResult& error)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::Scale(float x, float y)
 {
   if (!mTarget) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+    return NS_ERROR_FAILURE;
   }
-
   if (!FloatValidate(x,y)) {
-    return;
+    return NS_OK;
   }
 
   TransformWillUpdate();
 
   Matrix newMatrix = mTarget->GetTransform();
   mTarget->SetTransform(newMatrix.Scale(x, y));
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Scale(float x, float y)
-{
-  ErrorResult rv;
-  Scale((double)x, (double)y, rv);
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::Rotate(double angle, ErrorResult& error)
+nsCanvasRenderingContext2DAzure::Rotate(float angle)
 {
   if (!mTarget) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+    return NS_ERROR_FAILURE;
   }
-
   if (!FloatValidate(angle)) {
-    return;
+    return NS_OK;
   }
 
   TransformWillUpdate();
 
   Matrix rotation = Matrix::Rotation(angle);
   mTarget->SetTransform(rotation * mTarget->GetTransform());
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Rotate(float angle)
-{
-  ErrorResult rv;
-  Rotate((double)angle, rv);
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::Translate(double x, double y, ErrorResult& error)
+nsCanvasRenderingContext2DAzure::Translate(float x, float y)
 {
   if (!mTarget) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+    return NS_ERROR_FAILURE;
   }
-
   if (!FloatValidate(x,y)) {
-    return;
+    return NS_OK;
   }
 
   TransformWillUpdate();
 
   Matrix newMatrix = mTarget->GetTransform();
   mTarget->SetTransform(newMatrix.Translate(x, y));
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Translate(float x, float y)
-{
-  ErrorResult rv;
-  Translate((double)x, (double)y, rv);
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::Transform(double m11, double m12, double m21,
-                                           double m22, double dx, double dy,
-                                           ErrorResult& error)
+nsCanvasRenderingContext2DAzure::Transform(float m11, float m12, float m21, float m22, float dx, float dy)
 {
   if (!mTarget) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+    return NS_ERROR_FAILURE;
   }
-
   if (!FloatValidate(m11,m12,m21,m22,dx,dy)) {
-    return;
+    return NS_OK;
   }
 
   TransformWillUpdate();
 
   Matrix matrix(m11, m12, m21, m22, dx, dy);
   mTarget->SetTransform(matrix * mTarget->GetTransform());
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Transform(float m11, float m12, float m21, float m22, float dx, float dy)
-{
-  ErrorResult rv;
-  Transform((double)m11, (double)m12, (double)m21, (double)m22, (double)dx,
-            (double)dy, rv);
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::SetTransform(double m11, double m12,
-                                              double m21, double m22,
-                                              double dx, double dy,
-                                              ErrorResult& error)
+nsCanvasRenderingContext2DAzure::SetTransform(float m11, float m12, float m21, float m22, float dx, float dy)
 {
   if (!mTarget) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+    return NS_ERROR_FAILURE;
   }
-
   if (!FloatValidate(m11,m12,m21,m22,dx,dy)) {
-    return;
+    return NS_OK;
   }
 
   TransformWillUpdate();
 
   Matrix matrix(m11, m12, m21, m22, dx, dy);
   mTarget->SetTransform(matrix);
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetTransform(float m11, float m12, float m21, float m22, float dx, float dy)
-{
-  ErrorResult rv;
-  SetTransform((double)m11, (double)m12, (double)m21, (double)m22, (double)dx,
-               (double)dy, rv);
-  return rv.ErrorCode();
-}
-
-JSObject*
-MatrixToJSObject(JSContext* cx, const Matrix& matrix, ErrorResult& error)
-{
-  jsval elts[] = {
-      DOUBLE_TO_JSVAL(matrix._11), DOUBLE_TO_JSVAL(matrix._12),
-      DOUBLE_TO_JSVAL(matrix._21), DOUBLE_TO_JSVAL(matrix._22),
-      DOUBLE_TO_JSVAL(matrix._31), DOUBLE_TO_JSVAL(matrix._32)
-  };
-
-  // XXX Should we enter GetWrapper()'s compartment?
-  JSObject* obj = JS_NewArrayObject(cx, 6, elts);
-  if  (!obj) {
-      error.Throw(NS_ERROR_OUT_OF_MEMORY);
-  }
-  return obj;
-}
-
-bool
-ObjectToMatrix(JSContext* cx, JSObject& obj, Matrix& matrix, ErrorResult& error)
-{
-  uint32_t length;
-  if (!JS_GetArrayLength(cx, &obj, &length) || length != 6) {
-    // Not an array-like thing or wrong size
-    error.Throw(NS_ERROR_INVALID_ARG);
-    return false;
-  }
-
-  Float* elts[] = { &matrix._11, &matrix._12, &matrix._21, &matrix._22,
-                    &matrix._31, &matrix._32 };
-  for (PRUint32 i = 0; i < 6; ++i) {
-    jsval elt;
-    double d;
-    if (!JS_GetElement(cx, &obj, i, &elt)) {
-      error.Throw(NS_ERROR_FAILURE);
-      return false;
-    }
-    if (!CoerceDouble(elt, &d)) {
-      error.Throw(NS_ERROR_INVALID_ARG);
-      return false;
-    }
-    if (!FloatValidate(d)) {
-      // This is weird, but it's the behavior of SetTransform()
-      return false;
-    }
-    *elts[i] = Float(d);
-  }
-  return true;
-}
-
-void
-nsCanvasRenderingContext2DAzure::SetMozCurrentTransform(JSContext* cx,
-                                                        JSObject& currentTransform,
-                                                        ErrorResult& error)
-{
-  if (!mTarget) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  Matrix newCTM;
-  if (ObjectToMatrix(cx, currentTransform, newCTM, error)) {
-    mTarget->SetTransform(newCTM);
-  }
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozCurrentTransform(JSContext* cx,
                                                         const jsval& matrix)
 {
-  if (!matrix.isObject()) {
-    return NS_ERROR_INVALID_ARG;
+  if (!mTarget) {
+    return NS_ERROR_FAILURE;
   }
 
-  ErrorResult rv;
-  SetMozCurrentTransform(cx, matrix.toObject(), rv);
-  return rv.ErrorCode();
-}
-
-JSObject*
-nsCanvasRenderingContext2DAzure::GetMozCurrentTransform(JSContext* cx,
-                                                        ErrorResult& error) const
-{
-  if (!mTarget) {
-    error.Throw(NS_ERROR_FAILURE);
-    return NULL;
+  nsresult rv;
+  Matrix newCTM;
+
+  if (!JSValToMatrix(cx, matrix, &newCTM, &rv)) {
+    return rv;
   }
 
-  return MatrixToJSObject(cx, mTarget->GetTransform(), error);
+  mTarget->SetTransform(newCTM);
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozCurrentTransform(JSContext* cx,
                                                         jsval* matrix)
 {
-  ErrorResult rv;
-  JSObject* obj = GetMozCurrentTransform(cx, rv);
-  if (!rv.Failed()) {
-    *matrix = OBJECT_TO_JSVAL(obj);
+  if (!mTarget) {
+    return NS_ERROR_FAILURE;
   }
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::SetMozCurrentTransformInverse(JSContext* cx,
-                                                               JSObject& currentTransform,
-                                                               ErrorResult& error)
-{
-  if (!mTarget) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  Matrix newCTMInverse;
-  if (ObjectToMatrix(cx, currentTransform, newCTMInverse, error)) {
-    // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    if (newCTMInverse.Invert()) {
-      mTarget->SetTransform(newCTMInverse);
-    }
-  }
+
+  return MatrixToJSVal(mTarget->GetTransform(), cx, matrix);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozCurrentTransformInverse(JSContext* cx,
                                                                const jsval& matrix)
 {
-  if (!matrix.isObject()) {
-    return NS_ERROR_INVALID_ARG;
+  if (!mTarget) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsresult rv;
+  Matrix newCTMInverse;
+
+  if (!JSValToMatrix(cx, matrix, &newCTMInverse, &rv)) {
+    return rv;
   }
 
-  ErrorResult rv;
-  SetMozCurrentTransformInverse(cx, matrix.toObject(), rv);
-  return rv.ErrorCode();
+  // XXX ERRMSG we need to report an error to developers here! (bug 329026)
+  if (newCTMInverse.Invert()) {
+    mTarget->SetTransform(newCTMInverse);
+  }
+
+  return NS_OK;
 }
 
-JSObject*
+NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozCurrentTransformInverse(JSContext* cx,
-                                                               ErrorResult& error) const
+                                                               jsval* matrix)
 {
   if (!mTarget) {
-    error.Throw(NS_ERROR_FAILURE);
-    return NULL;
+    return NS_ERROR_FAILURE;
   }
 
   Matrix ctm = mTarget->GetTransform();
 
   if (!ctm.Invert()) {
     double NaN = JSVAL_TO_DOUBLE(JS_GetNaNValue(cx));
     ctm = Matrix(NaN, NaN, NaN, NaN, NaN, NaN);
   }
 
-  return MatrixToJSObject(cx, ctm, error);
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozCurrentTransformInverse(JSContext* cx,
-                                                               jsval* matrix)
-{
-  ErrorResult rv;
-  JSObject* obj = GetMozCurrentTransformInverse(cx, rv);
-  if (!rv.Failed()) {
-    *matrix = OBJECT_TO_JSVAL(obj);
-  }
-  return rv.ErrorCode();
+  return MatrixToJSVal(ctm, cx, matrix);
 }
 
 //
 // colors
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetGlobalAlpha(float aGlobalAlpha)
 {
-  SetGlobalAlpha((double)aGlobalAlpha);
+  if (!FloatValidate(aGlobalAlpha) || aGlobalAlpha < 0.0 || aGlobalAlpha > 1.0) {
+    return NS_OK;
+  }
+
+  CurrentState().globalAlpha = aGlobalAlpha;
+    
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetGlobalAlpha(float *aGlobalAlpha)
 {
-  *aGlobalAlpha = GetGlobalAlpha();
+  *aGlobalAlpha = CurrentState().globalAlpha;
   return NS_OK;
 }
 
-void
-nsCanvasRenderingContext2DAzure::SetStyleFromJSValue(JSContext* cx,
-                                                     JS::Value& value,
-                                                     Style whichStyle)
-{
-  if (value.isString()) {
-    nsDependentJSString strokeStyle;
-    if (strokeStyle.init(cx, value.toString())) {
-      SetStyleFromString(strokeStyle, whichStyle);
-    }
-    return;
-  }
-
-  if (value.isObject()) {
-    nsCOMPtr<nsISupports> holder;
-
-    nsCanvasGradientAzure* gradient;
-    nsresult rv = xpc_qsUnwrapArg<nsCanvasGradientAzure>(cx, value, &gradient,
-                                                         static_cast<nsISupports**>(getter_AddRefs(holder)),
-                                                         &value);
-    if (NS_SUCCEEDED(rv)) {
-      SetStyleFromGradient(gradient, whichStyle);
-      return;
-    }
-
-    nsCanvasPatternAzure* pattern;
-    rv = xpc_qsUnwrapArg<nsCanvasPatternAzure>(cx, value, &pattern,
-                                               static_cast<nsISupports**>(getter_AddRefs(holder)),
-                                               &value);
-    if (NS_SUCCEEDED(rv)) {
-      SetStyleFromPattern(pattern, whichStyle);
-      return;
-    }
-  }
-
-  WarnAboutUnexpectedStyle(mCanvasElement);
-}
-
-static JS::Value
-WrapStyle(JSContext* cx, JSObject* obj,
-          nsIDOMCanvasRenderingContext2D::CanvasMultiGetterType type,
-          nsAString& str, nsISupports* supports, ErrorResult& error)
-{
-  JS::Value v;
-  bool ok;
-  switch (type) {
-    case nsIDOMCanvasRenderingContext2D::CMG_STYLE_STRING:
-    {
-      ok = xpc::StringToJsval(cx, str, &v);
-      break;
-    }
-    case nsIDOMCanvasRenderingContext2D::CMG_STYLE_PATTERN:
-    case nsIDOMCanvasRenderingContext2D::CMG_STYLE_GRADIENT:
-    {
-      ok = dom::WrapObject(cx, obj, supports, &v);
-      break;
-    }
-  }
-  if (!ok) {
-    error.Throw(NS_ERROR_FAILURE);
-  }
-  return v;
-}
-
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetStrokeStyle(nsIVariant *aValue)
 {
   if (!aValue)
       return NS_ERROR_FAILURE;
 
   nsString str;
 
@@ -1588,26 +1815,16 @@ nsCanvasRenderingContext2DAzure::SetStro
   }
 
   rv = aValue->GetAsAString(str);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return SetStrokeStyle_multi(str, nsnull);
 }
 
-JS::Value
-nsCanvasRenderingContext2DAzure::GetStrokeStyle(JSContext* cx,
-                                                ErrorResult& error)
-{
-  nsString str;
-  CanvasMultiGetterType t;
-  nsISupports* supports = GetStyleAsStringOrInterface(str, t, STYLE_STROKE);
-  return WrapStyle(cx, GetWrapper(), t, str, supports, error);
-}
-
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetStrokeStyle(nsIVariant **aResult)
 {
   nsCOMPtr<nsIWritableVariant> wv = do_CreateInstance(NS_VARIANT_CONTRACTID);
 
   nsCOMPtr<nsISupports> sup;
   nsString str;
   PRInt32 t;
@@ -1658,26 +1875,16 @@ nsCanvasRenderingContext2DAzure::SetFill
   }
 
   rv = aValue->GetAsAString(str);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return SetFillStyle_multi(str, nsnull);
 }
 
-JS::Value
-nsCanvasRenderingContext2DAzure::GetFillStyle(JSContext* cx,
-                                              ErrorResult& error)
-{
-  nsString str;
-  CanvasMultiGetterType t;
-  nsISupports* supports = GetStyleAsStringOrInterface(str, t, STYLE_FILL);
-  return WrapStyle(cx, GetWrapper(), t, str, supports, error);
-}
-
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetFillStyle(nsIVariant **aResult)
 {
   nsCOMPtr<nsIWritableVariant> wv = do_CreateInstance(NS_VARIANT_CONTRACTID);
 
   nsCOMPtr<nsISupports> sup;
   nsString str;
   PRInt32 t;
@@ -1697,336 +1904,278 @@ nsCanvasRenderingContext2DAzure::GetFill
     return NS_ERROR_FAILURE;
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_IF_ADDREF(*aResult = wv.get());
   return NS_OK;
 }
 
-void
-nsCanvasRenderingContext2DAzure::SetFillRule(const nsAString& aString)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::SetMozFillRule(const nsAString& aString)
 {
   FillRule rule;
 
   if (aString.EqualsLiteral("evenodd"))
     rule = FILL_EVEN_ODD;
   else if (aString.EqualsLiteral("nonzero"))
     rule = FILL_WINDING;
   else
-    return;
+    return NS_OK;
 
   CurrentState().fillRule = rule;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozFillRule(const nsAString& aString)
-{
-  SetFillRule(aString);
-  return NS_OK;
-}
-
-void
-nsCanvasRenderingContext2DAzure::GetFillRule(nsAString& aString)
+nsCanvasRenderingContext2DAzure::GetMozFillRule(nsAString& aString)
 {
     switch (CurrentState().fillRule) {
     case FILL_WINDING:
         aString.AssignLiteral("nonzero"); break;
     case FILL_EVEN_ODD:
         aString.AssignLiteral("evenodd"); break;
     }
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozFillRule(nsAString& aString)
-{
-  GetFillRule(aString);
-  return NS_OK;
+
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetStrokeStyle_multi(const nsAString& aStr, nsISupports *aInterface)
 {
-  SetStyleFromStringOrInterface(aStr, aInterface, STYLE_STROKE);
-  return NS_OK;
+    return SetStyleFromStringOrInterface(aStr, aInterface, STYLE_STROKE);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetStrokeStyle_multi(nsAString& aStr, nsISupports **aInterface, PRInt32 *aType)
 {
-  CanvasMultiGetterType type;
-  NS_IF_ADDREF(*aInterface = GetStyleAsStringOrInterface(aStr, type, STYLE_STROKE));
-  *aType = type;
-  return NS_OK;
+    return GetStyleAsStringOrInterface(aStr, aInterface, aType, STYLE_STROKE);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetFillStyle_multi(const nsAString& aStr, nsISupports *aInterface)
 {
-  SetStyleFromStringOrInterface(aStr, aInterface, STYLE_FILL);
-  return NS_OK;
+    return SetStyleFromStringOrInterface(aStr, aInterface, STYLE_FILL);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetFillStyle_multi(nsAString& aStr, nsISupports **aInterface, PRInt32 *aType)
 {
-  CanvasMultiGetterType type;
-  NS_IF_ADDREF(*aInterface = GetStyleAsStringOrInterface(aStr, type, STYLE_FILL));
-  *aType = type;
-  return NS_OK;
+    return GetStyleAsStringOrInterface(aStr, aInterface, aType, STYLE_FILL);
 }
 
 //
 // gradients and patterns
 //
-already_AddRefed<nsIDOMCanvasGradient>
-nsCanvasRenderingContext2DAzure::CreateLinearGradient(double x0, double y0, double x1, double y1,
-                                                      ErrorResult& aError)
-{
-  if (!FloatValidate(x0,y0,x1,y1)) {
-    aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-    return nsnull;
-  }
-
-  nsRefPtr<nsIDOMCanvasGradient> grad =
-    new nsCanvasLinearGradientAzure(Point(x0, y0), Point(x1, y1));
-
-  return grad.forget();
-}
-
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::CreateLinearGradient(float x0, float y0, float x1, float y1,
                                                       nsIDOMCanvasGradient **_retval)
 {
-  ErrorResult rv;
-  *_retval = CreateLinearGradient(x0, y0, x1, y1, rv).get();
-  return rv.ErrorCode();
-}
-
-already_AddRefed<nsIDOMCanvasGradient>
-nsCanvasRenderingContext2DAzure::CreateRadialGradient(double x0, double y0, double r0,
-                                                      double x1, double y1, double r1,
-                                                      ErrorResult& aError)
-{
-  if (!FloatValidate(x0,y0,r0,x1,y1,r1)) {
-    aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-    return nsnull;
-  }
-
-  if (r0 < 0.0 || r1 < 0.0) {
-    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return nsnull;
+  if (!FloatValidate(x0,y0,x1,y1)) {
+    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
   }
 
   nsRefPtr<nsIDOMCanvasGradient> grad =
-    new nsCanvasRadialGradientAzure(Point(x0, y0), r0, Point(x1, y1), r1);
-
-  return grad.forget();
+    new nsCanvasLinearGradientAzure(Point(x0, y0), Point(x1, y1));
+
+  *_retval = grad.forget().get();
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::CreateRadialGradient(float x0, float y0, float r0,
                                                       float x1, float y1, float r1,
                                                       nsIDOMCanvasGradient **_retval)
 {
-  ErrorResult rv;
-  *_retval = CreateRadialGradient(x0, y0, r0, x1, y1, r1, rv).get();
-  return rv.ErrorCode();
+  if (!FloatValidate(x0,y0,r0,x1,y1,r1)) {
+    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+  }
+
+  if (r0 < 0.0 || r1 < 0.0) {
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+  }
+
+  nsRefPtr<nsIDOMCanvasGradient> grad =
+    new nsCanvasRadialGradientAzure(Point(x0, y0), r0, Point(x1, y1), r1);
+
+  *_retval = grad.forget().get();
+  return NS_OK;
 }
 
-already_AddRefed<nsIDOMCanvasPattern>
-nsCanvasRenderingContext2DAzure::CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image,
                                                const nsAString& repeat,
-                                               ErrorResult& error)
+                                               nsIDOMCanvasPattern **_retval)
 {
+  nsCOMPtr<nsIContent> content = do_QueryInterface(image);
+  if (!content) {
+    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
+  }
+
   nsCanvasPatternAzure::RepeatMode repeatMode =
     nsCanvasPatternAzure::NOREPEAT;
 
   if (repeat.IsEmpty() || repeat.EqualsLiteral("repeat")) {
     repeatMode = nsCanvasPatternAzure::REPEAT;
   } else if (repeat.EqualsLiteral("repeat-x")) {
     repeatMode = nsCanvasPatternAzure::REPEATX;
   } else if (repeat.EqualsLiteral("repeat-y")) {
     repeatMode = nsCanvasPatternAzure::REPEATY;
   } else if (repeat.EqualsLiteral("no-repeat")) {
     repeatMode = nsCanvasPatternAzure::NOREPEAT;
   } else {
-    error.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return NULL;
+    return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
-  Element* htmlElement;
-  if (element.IsHTMLCanvasElement()) {
-    nsHTMLCanvasElement* canvas = element.GetAsHTMLCanvasElement();
-    htmlElement = canvas;
-
+  nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content);
+  if (canvas) {
     nsIntSize size = canvas->GetSize();
     if (size.width == 0 || size.height == 0) {
-      error.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
-      return NULL;
+      return NS_ERROR_DOM_INVALID_STATE_ERR;
     }
 
     // Special case for Canvas, which could be an Azure canvas!
     nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
     if (srcCanvas) {
       // This might not be an Azure canvas!
       RefPtr<SourceSurface> srcSurf = srcCanvas->GetSurfaceSnapshot();
 
       nsRefPtr<nsCanvasPatternAzure> pat =
-        new nsCanvasPatternAzure(srcSurf, repeatMode, htmlElement->NodePrincipal(), canvas->IsWriteOnly(), false);
-
-      return pat.forget();
+        new nsCanvasPatternAzure(srcSurf, repeatMode, content->NodePrincipal(), canvas->IsWriteOnly(), false);
+
+      *_retval = pat.forget().get();
+      return NS_OK;
     }
-  } else if (element.IsHTMLImageElement()) {
-    htmlElement = element.GetAsHTMLImageElement();
-  } else {
-    htmlElement = element.GetAsHTMLVideoElement();
   }
 
   // The canvas spec says that createPattern should use the first frame
   // of animated images
   nsLayoutUtils::SurfaceFromElementResult res =
-    nsLayoutUtils::SurfaceFromElement(htmlElement,
+    nsLayoutUtils::SurfaceFromElement(content->AsElement(),
       nsLayoutUtils::SFE_WANT_FIRST_FRAME | nsLayoutUtils::SFE_WANT_NEW_SURFACE);
 
   if (!res.mSurface) {
-    error.Throw(NS_ERROR_NOT_AVAILABLE);
-    return NULL;
+    return NS_ERROR_NOT_AVAILABLE;
   }
 
   // Ignore nsnull cairo surfaces! See bug 666312.
   if (!res.mSurface->CairoSurface() || res.mSurface->CairoStatus()) {
-    return NULL;
+    return NS_OK;
   }
 
   RefPtr<SourceSurface> srcSurf =
     gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, res.mSurface);
 
   nsRefPtr<nsCanvasPatternAzure> pat =
     new nsCanvasPatternAzure(srcSurf, repeatMode, res.mPrincipal,
                              res.mIsWriteOnly, res.mCORSUsed);
 
-  return pat.forget();
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image,
-                                               const nsAString& repeat,
-                                               nsIDOMCanvasPattern **_retval)
-{
-  HTMLImageOrCanvasOrVideoElement element;
-  if (!ToHTMLImageOrCanvasOrVideoElement(image, element)) {
-    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
-  }
-
-  ErrorResult rv;
-  *_retval = CreatePattern(element, repeat, rv).get();
-  return rv.ErrorCode();
+  *_retval = pat.forget().get();
+  return NS_OK;
 }
 
 //
 // shadows
 //
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetShadowOffsetX(float x)
 {
-  SetShadowOffsetX((double)x);
+  if (!FloatValidate(x)) {
+    return NS_OK;
+  }
+
+  CurrentState().shadowOffset.x = x;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetShadowOffsetX(float *x)
 {
-  *x = static_cast<float>(GetShadowOffsetX());
+  *x = static_cast<float>(CurrentState().shadowOffset.x);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetShadowOffsetY(float y)
 {
-  SetShadowOffsetY((double)y);
+  if (!FloatValidate(y)) {
+    return NS_OK;
+  }
+
+  CurrentState().shadowOffset.y = y;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetShadowOffsetY(float *y)
 {
-  *y = static_cast<float>(GetShadowOffsetY());
+  *y = static_cast<float>(CurrentState().shadowOffset.y);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetShadowBlur(float blur)
 {
-  SetShadowBlur((double)blur);
+  if (!FloatValidate(blur) || blur < 0.0) {
+    return NS_OK;
+  }
+
+  CurrentState().shadowBlur = blur;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetShadowBlur(float *blur)
 {
-  *blur = GetShadowBlur();
-  return NS_OK;
-}
-
-void
-nsCanvasRenderingContext2DAzure::SetShadowColor(const nsAString& shadowColor)
-{
-  nscolor color;
-  if (!ParseColor(shadowColor, &color)) {
-    return;
-  }
-
-  CurrentState().shadowColor = color;
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozShadowColor(const nsAString& colorstr)
-{
-  SetShadowColor(colorstr);
+  *blur = CurrentState().shadowBlur;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozShadowColor(nsAString& color)
+nsCanvasRenderingContext2DAzure::SetShadowColor(const nsAString& aColor)
 {
-  GetShadowColor(color);
+  nscolor color;
+  if (!ParseColor(aColor, &color)) {
+    return NS_OK;
+  }
+
+  CurrentState().shadowColor = color;
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetShadowColor(nsAString& color)
+{
+  StyleColorToString(CurrentState().shadowColor, color);
+
   return NS_OK;
 }
 
 //
 // rects
 //
 
-void
-nsCanvasRenderingContext2DAzure::ClearRect(double x, double y, double w,
-                                           double h)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::ClearRect(float x, float y, float w, float h)
 {
   if (!FloatValidate(x,y,w,h)) {
-    return;
+    return NS_OK;
   }
  
   mTarget->ClearRect(mgfx::Rect(x, y, w, h));
 
-  RedrawUser(gfxRect(x, y, w, h));
+  return RedrawUser(gfxRect(x, y, w, h));
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::ClearRect(float x, float y, float w, float h)
-{
-  ClearRect((double)x, (double)y, (double)w, (double)h);
-  return NS_OK;
-}
-
-void
-nsCanvasRenderingContext2DAzure::FillRect(double x, double y, double w,
-                                          double h)
+nsCanvasRenderingContext2DAzure::FillRect(float x, float y, float w, float h)
 {
   if (!FloatValidate(x,y,w,h)) {
-    return;
+    return NS_OK;
   }
 
   const ContextState &state = CurrentState();
 
   if (state.patternStyles[STYLE_FILL]) {
     nsCanvasPatternAzure::RepeatMode repeat = 
       state.patternStyles[STYLE_FILL]->mRepeat;
     // In the FillRect case repeat modes are easy to deal with.
@@ -2079,165 +2228,140 @@ nsCanvasRenderingContext2DAzure::FillRec
     bounds = mTarget->GetTransform().TransformBounds(bounds);
   }
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
     FillRect(mgfx::Rect(x, y, w, h),
              GeneralPattern().ForStyle(this, STYLE_FILL, mTarget),
              DrawOptions(state.globalAlpha, UsedOperation()));
 
-  RedrawUser(gfxRect(x, y, w, h));
+  return RedrawUser(gfxRect(x, y, w, h));
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::FillRect(float x, float y, float w, float h)
-{
-  FillRect((double)x, (double)y, (double)w, (double)h);
-  return NS_OK;
-}
-
-void
-nsCanvasRenderingContext2DAzure::StrokeRect(double x, double y, double w,
-                                            double h)
+nsCanvasRenderingContext2DAzure::StrokeRect(float x, float y, float w, float h)
 {
   if (!FloatValidate(x,y,w,h)) {
-    return;
+    return NS_OK;
   }
 
   const ContextState &state = CurrentState();
 
   mgfx::Rect bounds;
   
   if (NeedToDrawShadow()) {
     bounds = mgfx::Rect(x - state.lineWidth / 2.0f, y - state.lineWidth / 2.0f,
                         w + state.lineWidth, h + state.lineWidth);
     bounds = mTarget->GetTransform().TransformBounds(bounds);
   }
 
   if (!w && !h) {
-    return;
-  }
-
-  if (!h) {
+    return NS_OK;
+  } else if (!h) {
     CapStyle cap = CAP_BUTT;
     if (state.lineJoin == JOIN_ROUND) {
       cap = CAP_ROUND;
     }
     AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
       StrokeLine(Point(x, y), Point(x + w, y),
                   GeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
                   StrokeOptions(state.lineWidth, state.lineJoin,
                                 cap, state.miterLimit,
                                 state.dash.Length(),
                                 state.dash.Elements(),
                                 state.dashOffset),
                   DrawOptions(state.globalAlpha, UsedOperation()));
-    return;
-  }
-
-  if (!w) {
+    return NS_OK;
+  } else if (!w) {
     CapStyle cap = CAP_BUTT;
     if (state.lineJoin == JOIN_ROUND) {
       cap = CAP_ROUND;
     }
     AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
       StrokeLine(Point(x, y), Point(x, y + h),
                   GeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
                   StrokeOptions(state.lineWidth, state.lineJoin,
                                 cap, state.miterLimit,
                                 state.dash.Length(),
                                 state.dash.Elements(),
                                 state.dashOffset),
                   DrawOptions(state.globalAlpha, UsedOperation()));
-    return;
+    return NS_OK;
   }
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
     StrokeRect(mgfx::Rect(x, y, w, h),
                 GeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
                 StrokeOptions(state.lineWidth, state.lineJoin,
                               state.lineCap, state.miterLimit,
                               state.dash.Length(),
                               state.dash.Elements(),
                               state.dashOffset),
                 DrawOptions(state.globalAlpha, UsedOperation()));
 
-  Redraw();
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::StrokeRect(float x, float y, float w, float h)
-{
-  StrokeRect((double)x, (double)y, (double)w, (double)h);
-  return NS_OK;
+  return Redraw();
 }
 
 //
 // path bits
 //
 
-void
+NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::BeginPath()
 {
   mPath = nsnull;
   mPathBuilder = nsnull;
   mDSPathBuilder = nsnull;
   mPathTransformWillUpdate = false;
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::MozBeginPath()
-{
-  BeginPath();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::MozClosePath()
+nsCanvasRenderingContext2DAzure::ClosePath()
 {
-  ClosePath();
+  EnsureWritablePath();
+
+  if (mPathBuilder) {
+    mPathBuilder->Close();
+  } else {
+    mDSPathBuilder->Close();
+  }
+
   return NS_OK;
 }
 
-void
+NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::Fill()
 {
   EnsureUserSpacePath();
 
   if (!mPath) {
-    return;
+    return NS_OK;
   }
 
   mgfx::Rect bounds;
 
   if (NeedToDrawShadow()) {
     bounds = mPath->GetBounds(mTarget->GetTransform());
   }
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
     Fill(mPath, GeneralPattern().ForStyle(this, STYLE_FILL, mTarget),
          DrawOptions(CurrentState().globalAlpha, UsedOperation()));
 
-  Redraw();
+  return Redraw();
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::MozFill()
-{
-  Fill();
-  return NS_OK;
-}
-
-void
 nsCanvasRenderingContext2DAzure::Stroke()
 {
   EnsureUserSpacePath();
 
   if (!mPath) {
-    return;
+    return NS_OK;
   }
 
   const ContextState &state = CurrentState();
 
   StrokeOptions strokeOptions(state.lineWidth, state.lineJoin,
                               state.lineCap, state.miterLimit,
                               state.dash.Length(), state.dash.Elements(),
                               state.dashOffset);
@@ -2247,126 +2371,169 @@ nsCanvasRenderingContext2DAzure::Stroke(
     bounds =
       mPath->GetStrokedBounds(strokeOptions, mTarget->GetTransform());
   }
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
     Stroke(mPath, GeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
            strokeOptions, DrawOptions(state.globalAlpha, UsedOperation()));
 
-  Redraw();
+  return Redraw();
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::MozStroke()
-{
-  Stroke();
-  return NS_OK;
-}
-
-void
 nsCanvasRenderingContext2DAzure::Clip()
 {
   EnsureUserSpacePath();
 
   if (!mPath) {
-    return;
+    return NS_OK;
   }
 
   mTarget->PushClip(mPath);
   CurrentState().clipsPushed.push_back(mPath);
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::MozClip()
-{
-  Clip();
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::MoveTo(float x, float y)
 {
-  MoveTo((double)x, (double)y);
+  if (!FloatValidate(x,y))
+      return NS_OK;
+
+  EnsureWritablePath();
+
+  if (mPathBuilder) {
+    mPathBuilder->MoveTo(Point(x, y));
+  } else {
+    mDSPathBuilder->MoveTo(mTarget->GetTransform() * Point(x, y));
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::LineTo(float x, float y)
 {
-  LineTo((double)x, (double)y);
-  return NS_OK;
+  if (!FloatValidate(x,y))
+      return NS_OK;
+
+  EnsureWritablePath();
+    
+  return LineTo(Point(x, y));;
 }
   
+nsresult 
+nsCanvasRenderingContext2DAzure::LineTo(const Point& aPoint)
+{
+  if (mPathBuilder) {
+    mPathBuilder->LineTo(aPoint);
+  } else {
+    mDSPathBuilder->LineTo(mTarget->GetTransform() * aPoint);
+  }
+
+  return NS_OK;
+}
+
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::QuadraticCurveTo(float cpx, float cpy, float x,
-                                                  float y)
+nsCanvasRenderingContext2DAzure::QuadraticCurveTo(float cpx, float cpy, float x, float y)
 {
-  QuadraticCurveTo((double)cpx, (double)cpy, (double)x, (double)y);
+  if (!FloatValidate(cpx, cpy, x, y)) {
+    return NS_OK;
+  }
+
+  EnsureWritablePath();
+
+  if (mPathBuilder) {
+    mPathBuilder->QuadraticBezierTo(Point(cpx, cpy), Point(x, y));
+  } else {
+    Matrix transform = mTarget->GetTransform();
+    mDSPathBuilder->QuadraticBezierTo(transform * Point(cpx, cpy), transform * Point(x, y));
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::BezierCurveTo(float cp1x, float cp1y,
-                                               float cp2x, float cp2y,
-                                               float x, float y)
+                                              float cp2x, float cp2y,
+                                              float x, float y)
 {
-  BezierCurveTo((double)cp1x, (double)cp1y, (double)cp2x, (double)cp2y,
-                (double)x, (double)y);
+  if (!FloatValidate(cp1x, cp1y, cp2x, cp2y, x, y)) {
+    return NS_OK;
+  }
+
+  EnsureWritablePath();
+
+  return BezierTo(Point(cp1x, cp1y), Point(cp2x, cp2y), Point(x, y));
+}
+
+nsresult
+nsCanvasRenderingContext2DAzure::BezierTo(const Point& aCP1,
+                                          const Point& aCP2,
+                                          const Point& aCP3)
+{
+  if (mPathBuilder) {
+    mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
+  } else {
+    Matrix transform = mTarget->GetTransform();
+    mDSPathBuilder->BezierTo(transform * aCP1,
+                              transform * aCP2,
+                              transform * aCP3);
+  }
+
   return NS_OK;
 }
 
-void
-nsCanvasRenderingContext2DAzure::ArcTo(double x1, double y1, double x2,
-                                       double y2, double radius,
-                                       ErrorResult& error)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::ArcTo(float x1, float y1, float x2, float y2, float radius)
 {
   if (!FloatValidate(x1, y1, x2, y2, radius)) {
-    return;
+    return NS_OK;
   }
 
   if (radius < 0) {
-    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return;
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   EnsureWritablePath();
 
   // Current point in user space!
   Point p0;
   if (mPathBuilder) {
     p0 = mPathBuilder->CurrentPoint();
   } else {
     Matrix invTransform = mTarget->GetTransform();
     if (!invTransform.Invert()) {
-      return;
+      return NS_OK;
     }
 
     p0 = invTransform * mDSPathBuilder->CurrentPoint();
   }
 
   Point p1(x1, y1);
   Point p2(x2, y2);
 
   // Execute these calculations in double precision to avoid cumulative
   // rounding errors.
   double dir, a2, b2, c2, cosx, sinx, d, anx, any,
           bnx, bny, x3, y3, x4, y4, cx, cy, angle0, angle1;
   bool anticlockwise;
 
   if (p0 == p1 || p1 == p2 || radius == 0) {
     LineTo(p1.x, p1.y);
-    return;
+    return NS_OK;
   }
 
   // Check for colinearity
   dir = (p2.x - p1.x) * (p0.y - p1.y) + (p2.y - p1.y) * (p1.x - p0.x);
   if (dir == 0) {
     LineTo(p1.x, p1.y);
-    return;
+    return NS_OK;
   }
 
 
   // XXX - Math for this code was already available from the non-azure code
   // and would be well tested. Perhaps converting to bezier directly might
   // be more efficient longer run.
   a2 = (p0.x-x1)*(p0.x-x1) + (p0.y-y1)*(p0.y-y1);
   b2 = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
@@ -2389,61 +2556,43 @@ nsCanvasRenderingContext2DAzure::ArcTo(d
   cy = y3 - anx*radius*(anticlockwise ? 1 : -1);
   angle0 = atan2((y3-cy), (x3-cx));
   angle1 = atan2((y4-cy), (x4-cx));
 
 
   LineTo(x3, y3);
 
   Arc(cx, cy, radius, angle0, angle1, anticlockwise);
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::ArcTo(float x1, float y1, float x2, float y2, float radius)
-{
-  ErrorResult rv;
-  ArcTo(x1, y1, x2, y2, radius, rv);
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::Arc(double x, double y, double r,
-                                     double startAngle, double endAngle,
-                                     bool anticlockwise, ErrorResult& error)
-{
-  if (!FloatValidate(x, y, r, startAngle, endAngle)) {
-    return;
-  }
-
-  if (r < 0.0) {
-    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return;
-  }
-
-  EnsureWritablePath();
-
-  ArcToBezier(this, Point(x, y), r, startAngle, endAngle, anticlockwise);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::Arc(float x, float y,
                                      float r,
                                      float startAngle, float endAngle,
                                      bool ccw)
 {
-  ErrorResult rv;
-  Arc(x, y, r, startAngle, endAngle, ccw, rv);
-  return rv.ErrorCode();
+  if (!FloatValidate(x, y, r, startAngle, endAngle)) {
+    return NS_OK;
+  }
+
+  if (r < 0.0)
+      return NS_ERROR_DOM_INDEX_SIZE_ERR;
+
+  EnsureWritablePath();
+
+  ArcToBezier(this, Point(x, y), r, startAngle, endAngle, ccw);
+  return NS_OK;
 }
 
-void
-nsCanvasRenderingContext2DAzure::Rect(double x, double y, double w, double h)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::Rect(float x, float y, float w, float h)
 {
   if (!FloatValidate(x, y, w, h)) {
-    return;
+    return NS_OK;
   }
 
   EnsureWritablePath();
 
   if (mPathBuilder) {
     mPathBuilder->MoveTo(Point(x, y));
     mPathBuilder->LineTo(Point(x + w, y));
     mPathBuilder->LineTo(Point(x + w, y + h));
@@ -2451,22 +2600,17 @@ nsCanvasRenderingContext2DAzure::Rect(do
     mPathBuilder->Close();
   } else {
     mDSPathBuilder->MoveTo(mTarget->GetTransform() * Point(x, y));
     mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(x + w, y));
     mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(x + w, y + h));
     mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(x, y + h));
     mDSPathBuilder->Close();
   }
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Rect(float x, float y, float w, float h)
-{
-  Rect((double)x, (double)y, (double)w, (double)h);
+
   return NS_OK;
 }
 
 void
 nsCanvasRenderingContext2DAzure::EnsureWritablePath()
 {
   if (mDSPathBuilder) {
     return;
@@ -2607,64 +2751,63 @@ CreateFontStyleRule(const nsAString& aFo
   }
 
   rule->RuleMatched();
 
   rule.forget(aResult);
   return NS_OK;
 }
 
-void
-nsCanvasRenderingContext2DAzure::SetFont(const nsAString& font,
-                                         ErrorResult& error)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::SetFont(const nsAString& font)
 {
+  nsresult rv;
+
   /*
     * If font is defined with relative units (e.g. ems) and the parent
     * style context changes in between calls, setting the font to the
     * same value as previous could result in a different computed value,
     * so we cannot have the optimization where we check if the new font
     * string is equal to the old one.
     */
 
   if (!mCanvasElement && !mDocShell) {
-    NS_WARNING("Canvas element must be non-null or a docshell must be provided");
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+      NS_WARNING("Canvas element must be non-null or a docshell must be provided");
+      return NS_ERROR_FAILURE;
   }
 
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+    return NS_ERROR_FAILURE;
   }
   nsIDocument* document = presShell->GetDocument();
 
   nsCOMArray<nsIStyleRule> rules;
 
   nsRefPtr<css::StyleRule> rule;
-  error = CreateFontStyleRule(font, document, getter_AddRefs(rule));
-
-  if (error.Failed()) {
-    return;
+  rv = CreateFontStyleRule(font, document, getter_AddRefs(rule));
+
+  if (NS_FAILED(rv)) {
+    return rv;
   }
 
   css::Declaration *declaration = rule->GetDeclaration();
   // The easiest way to see whether we got a syntax error or whether
   // we got 'inherit' or 'initial' is to look at font-size-adjust,
   // which the shorthand resets to either 'none' or
   // '-moz-system-font'.
   // We know the declaration is not !important, so we can use
   // GetNormalBlock().
   const nsCSSValue *fsaVal =
     declaration->GetNormalBlock()->ValueFor(eCSSProperty_font_size_adjust);
   if (!fsaVal || (fsaVal->GetUnit() != eCSSUnit_None &&
                   fsaVal->GetUnit() != eCSSUnit_System_Font)) {
       // We got an all-property value or a syntax error.  The spec says
       // this value must be ignored.
-    return;
+    return NS_OK;
   }
 
   rules.AppendObject(rule);
 
   nsStyleSet* styleSet = presShell->StyleSet();
 
   // have to get a parent style context for inherit-like relative
   // values (2em, bolder, etc.)
@@ -2674,39 +2817,37 @@ nsCanvasRenderingContext2DAzure::SetFont
       // inherit from the canvas element
       parentContext = nsComputedDOMStyle::GetStyleContextForElement(
               mCanvasElement,
               nsnull,
               presShell);
   } else {
     // otherwise inherit from default (10px sans-serif)
     nsRefPtr<css::StyleRule> parentRule;
-    error = CreateFontStyleRule(NS_LITERAL_STRING("10px sans-serif"),
-                                document,
-                                getter_AddRefs(parentRule));
-
-    if (error.Failed()) {
-      return;
+    rv = CreateFontStyleRule(NS_LITERAL_STRING("10px sans-serif"),
+                              document,
+                              getter_AddRefs(parentRule));
+
+    if (NS_FAILED(rv)) {
+      return rv;
     }
 
     nsCOMArray<nsIStyleRule> parentRules;
     parentRules.AppendObject(parentRule);
     parentContext = styleSet->ResolveStyleForRules(nsnull, parentRules);
   }
 
   if (!parentContext) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+      return NS_ERROR_FAILURE;
   }
 
   nsRefPtr<nsStyleContext> sc =
       styleSet->ResolveStyleForRules(parentContext, rules);
   if (!sc) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+    return NS_ERROR_FAILURE;
   }
 
   const nsStyleFont* fontStyle = sc->GetStyleFont();
 
   NS_ASSERTION(fontStyle, "Could not obtain font style");
 
   nsIAtom* language = sc->GetStyleFont()->mLanguage;
   if (!language) {
@@ -2744,56 +2885,48 @@ nsCanvasRenderingContext2DAzure::SetFont
                                                   presShell->GetPresContext()->GetUserFontSet());
   NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
 
   // The font getter is required to be reserialized based on what we
   // parsed (including having line-height removed).  (Older drafts of
   // the spec required font sizes be converted to pixels, but that no
   // longer seems to be required.)
   declaration->GetValue(eCSSProperty_font, CurrentState().font);
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozFont(const nsAString& font)
+nsCanvasRenderingContext2DAzure::GetFont(nsAString& font)
 {
-  ErrorResult rv;
-  SetFont(font, rv);
-  return rv.ErrorCode();
+  /* will initilize the value if not set, else does nothing */
+  GetCurrentFontStyle();
+
+  font = CurrentState().font;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozFont(nsAString& font)
-{
-  font = GetFont();
-  return NS_OK;
-}
-
-void
 nsCanvasRenderingContext2DAzure::SetTextAlign(const nsAString& ta)
 {
   if (ta.EqualsLiteral("start"))
     CurrentState().textAlign = TEXT_ALIGN_START;
   else if (ta.EqualsLiteral("end"))
     CurrentState().textAlign = TEXT_ALIGN_END;
   else if (ta.EqualsLiteral("left"))
     CurrentState().textAlign = TEXT_ALIGN_LEFT;
   else if (ta.EqualsLiteral("right"))
     CurrentState().textAlign = TEXT_ALIGN_RIGHT;
   else if (ta.EqualsLiteral("center"))
     CurrentState().textAlign = TEXT_ALIGN_CENTER;
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozTextAlign(const nsAString& ta)
-{
-  SetTextAlign(ta);
-  return NS_OK;
-}
-
-void
 nsCanvasRenderingContext2DAzure::GetTextAlign(nsAString& ta)
 {
   switch (CurrentState().textAlign)
   {
   case TEXT_ALIGN_START:
     ta.AssignLiteral("start");
     break;
   case TEXT_ALIGN_END:
@@ -2804,50 +2937,40 @@ nsCanvasRenderingContext2DAzure::GetText
     break;
   case TEXT_ALIGN_RIGHT:
     ta.AssignLiteral("right");
     break;
   case TEXT_ALIGN_CENTER:
     ta.AssignLiteral("center");
     break;
   }
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozTextAlign(nsAString& ta)
-{
-  GetTextAlign(ta);
-  return NS_OK;
-}
-
-void
 nsCanvasRenderingContext2DAzure::SetTextBaseline(const nsAString& tb)
 {
   if (tb.EqualsLiteral("top"))
     CurrentState().textBaseline = TEXT_BASELINE_TOP;
   else if (tb.EqualsLiteral("hanging"))
     CurrentState().textBaseline = TEXT_BASELINE_HANGING;
   else if (tb.EqualsLiteral("middle"))
     CurrentState().textBaseline = TEXT_BASELINE_MIDDLE;
   else if (tb.EqualsLiteral("alphabetic"))
     CurrentState().textBaseline = TEXT_BASELINE_ALPHABETIC;
   else if (tb.EqualsLiteral("ideographic"))
     CurrentState().textBaseline = TEXT_BASELINE_IDEOGRAPHIC;
   else if (tb.EqualsLiteral("bottom"))
     CurrentState().textBaseline = TEXT_BASELINE_BOTTOM;
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozTextBaseline(const nsAString& tb)
-{
-  SetTextBaseline(tb);
-  return NS_OK;
-}
-
-void
 nsCanvasRenderingContext2DAzure::GetTextBaseline(nsAString& tb)
 {
   switch (CurrentState().textBaseline)
   {
   case TEXT_BASELINE_TOP:
     tb.AssignLiteral("top");
     break;
   case TEXT_BASELINE_HANGING:
@@ -2861,101 +2984,65 @@ nsCanvasRenderingContext2DAzure::GetText
     break;
   case TEXT_BASELINE_IDEOGRAPHIC:
     tb.AssignLiteral("ideographic");
     break;
   case TEXT_BASELINE_BOTTOM:
     tb.AssignLiteral("bottom");
     break;
   }
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozTextBaseline(nsAString& tb)
-{
-  GetTextBaseline(tb);
+
   return NS_OK;
 }
 
 /*
  * Helper function that replaces the whitespace characters in a string
  * with U+0020 SPACE. The whitespace characters are defined as U+0020 SPACE,
  * U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000B LINE
  * TABULATION, U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR).
  * @param str The string whose whitespace characters to replace.
  */
 static inline void
 TextReplaceWhitespaceCharacters(nsAutoString& str)
 {
   str.ReplaceChar("\x09\x0A\x0B\x0C\x0D", PRUnichar(' '));
 }
 
-void
-nsCanvasRenderingContext2DAzure::FillText(const nsAString& text, double x,
-                                          double y,
-                                          const Optional<double>& maxWidth,
-                                          ErrorResult& error)
-{
-  error = DrawOrMeasureText(text, x, y, maxWidth, TEXT_DRAW_OPERATION_FILL, nsnull);
-}
-
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::FillText(const nsAString& text, float x, float y, float maxWidth)
 {
-  ErrorResult rv;
-  Optional<double> optionalMaxWidth;
-  optionalMaxWidth.Construct();
-  optionalMaxWidth.Value() = maxWidth;
-  FillText(text, x, y, optionalMaxWidth, rv);
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::StrokeText(const nsAString& text, double x,
-                                            double y,
-                                            const Optional<double>& maxWidth,
-                                            ErrorResult& error)
-{
-  error = DrawOrMeasureText(text, x, y, maxWidth, TEXT_DRAW_OPERATION_STROKE, nsnull);
+  return DrawOrMeasureText(text, x, y, maxWidth, TEXT_DRAW_OPERATION_FILL, nsnull);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::StrokeText(const nsAString& text, float x, float y, float maxWidth)
 {
-  ErrorResult rv;
-  Optional<double> optionalMaxWidth;
-  optionalMaxWidth.Construct();
-  optionalMaxWidth.Value() = maxWidth;
-  StrokeText(text, x, y, optionalMaxWidth, rv);
-  return rv.ErrorCode();
-}
-
-already_AddRefed<nsIDOMTextMetrics>
-nsCanvasRenderingContext2DAzure::MeasureText(const nsAString& rawText,
-                                             ErrorResult& error)
-{
-  float width;
-  Optional<double> maxWidth;
-  error = DrawOrMeasureText(rawText, 0, 0, maxWidth, TEXT_DRAW_OPERATION_MEASURE, &width);
-  if (error.Failed()) {
-    return NULL;
-  }
-
-  nsRefPtr<nsIDOMTextMetrics> textMetrics = new nsTextMetricsAzure(width);
-
-  return textMetrics.forget();
+  return DrawOrMeasureText(text, x, y, maxWidth, TEXT_DRAW_OPERATION_STROKE, nsnull);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::MeasureText(const nsAString& rawText,
-                                             nsIDOMTextMetrics** _retval)
+                                      nsIDOMTextMetrics** _retval)
 {
-  ErrorResult rv;
-  *_retval = MeasureText(rawText, rv).get();
-  return rv.ErrorCode();
+  float width;
+
+  nsresult rv = DrawOrMeasureText(rawText, 0, 0, 0, TEXT_DRAW_OPERATION_MEASURE, &width);
+
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  nsRefPtr<nsIDOMTextMetrics> textMetrics = new nsTextMetricsAzure(width);
+  if (!textMetrics.get()) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  *_retval = textMetrics.forget().get();
+
+  return NS_OK;
 }
 
 /**
  * Used for nsBidiPresUtils::ProcessText
  */
 struct NS_STACK_CLASS nsCanvasBidiProcessorAzure : public nsBidiPresUtils::BidiProcessor
 {
   typedef nsCanvasRenderingContext2DAzure::ContextState ContextState;
@@ -3090,27 +3177,27 @@ struct NS_STACK_CLASS nsCanvasBidiProces
         // This may happen for glyph runs for a 0 size font.
         continue;
       }
 
       buffer.mGlyphs = &glyphBuf.front();
       buffer.mNumGlyphs = glyphBuf.size();
 
       if (mOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_FILL) {
-        AdjustedTarget(mCtx)->
+        nsCanvasRenderingContext2DAzure::AdjustedTarget(mCtx)->
           FillGlyphs(scaledFont, buffer,
-                     GeneralPattern().
+                      nsCanvasRenderingContext2DAzure::GeneralPattern().
                         ForStyle(mCtx, nsCanvasRenderingContext2DAzure::STYLE_FILL, mCtx->mTarget),
                       DrawOptions(mState->globalAlpha, mCtx->UsedOperation()));
       } else if (mOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_STROKE) {
         RefPtr<Path> path = scaledFont->GetPathForGlyphs(buffer, mCtx->mTarget);
 
         const ContextState& state = *mState;
-        AdjustedTarget(mCtx)->
-          Stroke(path, GeneralPattern().
+        nsCanvasRenderingContext2DAzure::AdjustedTarget(mCtx)->
+          Stroke(path, nsCanvasRenderingContext2DAzure::GeneralPattern().
                     ForStyle(mCtx, nsCanvasRenderingContext2DAzure::STYLE_STROKE, mCtx->mTarget),
                   StrokeOptions(state.lineWidth, state.lineJoin,
                                 state.lineCap, state.miterLimit,
                                 state.dash.Length(),
                                 state.dash.Elements(),
                                 state.dashOffset),
                   DrawOptions(state.globalAlpha, mCtx->UsedOperation()));
 
@@ -3148,31 +3235,30 @@ struct NS_STACK_CLASS nsCanvasBidiProces
   // true iff the bounding box should be measured
   bool mDoMeasureBoundingBox;
 };
 
 nsresult
 nsCanvasRenderingContext2DAzure::DrawOrMeasureText(const nsAString& aRawText,
                                                    float aX,
                                                    float aY,
-                                                   const Optional<double>& aMaxWidth,
+                                                   float aMaxWidth,
                                                    TextDrawOperation aOp,
                                                    float* aWidth)
 {
   nsresult rv;
 
-  if (!FloatValidate(aX, aY) ||
-      (aMaxWidth.WasPassed() && !FloatValidate(aMaxWidth.Value())))
+  if (!FloatValidate(aX, aY, aMaxWidth))
       return NS_ERROR_DOM_SYNTAX_ERR;
 
   // spec isn't clear on what should happen if aMaxWidth <= 0, so
   // treat it as an invalid argument
   // technically, 0 should be an invalid value as well, but 0 is the default
   // arg, and there is no way to tell if the default was used
-  if (aMaxWidth.WasPassed() && aMaxWidth.Value() < 0)
+  if (aMaxWidth < 0)
     return NS_ERROR_INVALID_ARG;
 
   if (!mCanvasElement && !mDocShell) {
     NS_WARNING("Canvas element must be non-null or a docshell must be provided");
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
@@ -3306,24 +3392,23 @@ nsCanvasRenderingContext2DAzure::DrawOrM
   processor.mBoundingBox.MoveBy(processor.mPt);
 
   processor.mPt.x *= processor.mAppUnitsPerDevPixel;
   processor.mPt.y *= processor.mAppUnitsPerDevPixel;
 
   Matrix oldTransform = mTarget->GetTransform();
   // if text is over aMaxWidth, then scale the text horizontally such that its
   // width is precisely aMaxWidth
-  if (aMaxWidth.WasPassed() && aMaxWidth.Value() > 0 &&
-      totalWidth > aMaxWidth.Value()) {
+  if (aMaxWidth > 0 && totalWidth > aMaxWidth) {
     Matrix newTransform = oldTransform;
 
     // Translate so that the anchor point is at 0,0, then scale and then
     // translate back.
     newTransform.Translate(aX, 0);
-    newTransform.Scale(aMaxWidth.Value() / totalWidth, 1);
+    newTransform.Scale(aMaxWidth / totalWidth, 1);
     newTransform.Translate(-aX, 0);
     /* we do this to avoid an ICE in the android compiler */
     Matrix androidCompilerBug = newTransform;
     mTarget->SetTransform(androidCompilerBug);
   }
 
   // save the previous bounding box
   gfxRect boundingBox = processor.mBoundingBox;
@@ -3340,46 +3425,41 @@ nsCanvasRenderingContext2DAzure::DrawOrM
                                     nsnull,
                                     0,
                                     nsnull,
                                     &bidiEngine);
 
 
   mTarget->SetTransform(oldTransform);
 
-  if (aOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_FILL &&
-      !doDrawShadow) {
-    RedrawUser(boundingBox);
-    return NS_OK;
-  }
-
-  Redraw();
-  return NS_OK;
+  if (aOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_FILL && !doDrawShadow)
+    return RedrawUser(boundingBox);
+
+  return Redraw();
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetTextStyle(const nsAString& textStyle)
+nsCanvasRenderingContext2DAzure::SetMozTextStyle(const nsAString& textStyle)
 {
-  ErrorResult rv;
-  SetMozTextStyle(textStyle, rv);
-  return rv.ErrorCode();
+    // font and mozTextStyle are the same value
+    return SetFont(textStyle);
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetTextStyle(nsAString& textStyle)
+nsCanvasRenderingContext2DAzure::GetMozTextStyle(nsAString& textStyle)
 {
-  GetMozTextStyle(textStyle);
-  return NS_OK;
+    // font and mozTextStyle are the same value
+    return GetFont(textStyle);
 }
 
 gfxFontGroup *nsCanvasRenderingContext2DAzure::GetCurrentFontStyle()
 {
   // use lazy initilization for the font group since it's rather expensive
   if (!CurrentState().fontGroup) {
-    nsresult rv = SetMozFont(kDefaultFontStyle);
+    nsresult rv = SetFont(kDefaultFontStyle);
     if (NS_FAILED(rv)) {
       gfxFontStyle style;
       style.size = kDefaultFontSize;
       CurrentState().fontGroup =
         gfxPlatform::GetPlatform()->CreateFontGroup(kDefaultFontName,
                                                     &style,
                                                     nsnull);
       if (CurrentState().fontGroup) {
@@ -3394,188 +3474,151 @@ gfxFontGroup *nsCanvasRenderingContext2D
   }
 
   return CurrentState().fontGroup;
 }
 
 //
 // line caps/joins
 //
-
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetLineWidth(float width)
 {
-  SetLineWidth((double)width);
+  if (!FloatValidate(width) || width <= 0.0) {
+    return NS_OK;
+  }
+
+  CurrentState().lineWidth = width;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetLineWidth(float *width)
 {
-  *width = GetLineWidth();
+  *width = CurrentState().lineWidth;
   return NS_OK;
 }
 
-void
+NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetLineCap(const nsAString& capstyle)
 {
   CapStyle cap;
 
   if (capstyle.EqualsLiteral("butt")) {
     cap = CAP_BUTT;
   } else if (capstyle.EqualsLiteral("round")) {
     cap = CAP_ROUND;
   } else if (capstyle.EqualsLiteral("square")) {
     cap = CAP_SQUARE;
   } else {
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    return;
+    return NS_OK;
   }
 
   CurrentState().lineCap = cap;
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozLineCap(const nsAString& capstyle)
-{
-  SetLineCap(capstyle);
-  return NS_OK;
-}
-
-void
 nsCanvasRenderingContext2DAzure::GetLineCap(nsAString& capstyle)
 {
   switch (CurrentState().lineCap) {
   case CAP_BUTT:
     capstyle.AssignLiteral("butt");
     break;
   case CAP_ROUND:
     capstyle.AssignLiteral("round");
     break;
   case CAP_SQUARE:
     capstyle.AssignLiteral("square");
     break;
   }
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozLineCap(nsAString& capstyle)
-{
-  GetLineCap(capstyle);
-  return NS_OK;
-}
-
-void
 nsCanvasRenderingContext2DAzure::SetLineJoin(const nsAString& joinstyle)
 {
   JoinStyle j;
 
   if (joinstyle.EqualsLiteral("round")) {
     j = JOIN_ROUND;
   } else if (joinstyle.EqualsLiteral("bevel")) {
     j = JOIN_BEVEL;
   } else if (joinstyle.EqualsLiteral("miter")) {
     j = JOIN_MITER_OR_BEVEL;
   } else {
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    return;
+    return NS_OK;
   }
 
   CurrentState().lineJoin = j;
+   
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozLineJoin(const nsAString& joinstyle)
-{
-  SetLineJoin(joinstyle);
-  return NS_OK;
-}
-
-void
-nsCanvasRenderingContext2DAzure::GetLineJoin(nsAString& joinstyle, ErrorResult& error)
+nsCanvasRenderingContext2DAzure::GetLineJoin(nsAString& joinstyle)
 {
   switch (CurrentState().lineJoin) {
   case JOIN_ROUND:
     joinstyle.AssignLiteral("round");
     break;
   case JOIN_BEVEL:
     joinstyle.AssignLiteral("bevel");
     break;
   case JOIN_MITER_OR_BEVEL:
     joinstyle.AssignLiteral("miter");
     break;
   default:
-    error.Throw(NS_ERROR_FAILURE);
+    return NS_ERROR_FAILURE;
   }
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozLineJoin(nsAString& joinstyle)
-{
-  ErrorResult rv;
-  nsString linejoin;
-  GetLineJoin(linejoin, rv);
-  if (!rv.Failed()) {
-    joinstyle = linejoin;
-  }
-  return rv.ErrorCode();
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMiterLimit(float miter)
 {
-  SetMiterLimit((double)miter);
+  if (!FloatValidate(miter) || miter <= 0.0)
+    return NS_OK;
+
+  CurrentState().miterLimit = miter;
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMiterLimit(float *miter)
 {
-  *miter = GetMiterLimit();
+  *miter = CurrentState().miterLimit;
   return NS_OK;
 }
 
-void
-nsCanvasRenderingContext2DAzure::SetMozDash(JSContext* cx,
-                                            const JS::Value& mozDash,
-                                            ErrorResult& error)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::SetMozDash(JSContext *cx, const jsval& patternArray)
 {
   FallibleTArray<Float> dash;
-  error = JSValToDashArray(cx, mozDash, dash);
-  if (!error.Failed()) {
+  nsresult rv = JSValToDashArray(cx, patternArray, dash);
+  if (NS_SUCCEEDED(rv)) {
     ContextState& state = CurrentState();
     state.dash = dash;
     if (state.dash.IsEmpty()) {
       state.dashOffset = 0;
     }
   }
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozDash(JSContext *cx, const jsval& patternArray)
-{
-  ErrorResult rv;
-  SetMozDash(cx, patternArray, rv);
-  return rv.ErrorCode();
-}
-
-JS::Value
-nsCanvasRenderingContext2DAzure::GetMozDash(JSContext* cx, ErrorResult& error)
-{
-  JS::Value mozDash;
-  DashArrayToJSVal(CurrentState().dash, cx, &mozDash);
-  return mozDash;
+  return rv;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozDash(JSContext* cx, jsval* dashArray)
 {
-  ErrorResult rv;
-  *dashArray = GetMozDash(cx, rv);
-  return rv.ErrorCode();
+  return DashArrayToJSVal(CurrentState().dash, cx, dashArray);
 }
  
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozDashOffset(float offset)
 {
   if (!FloatValidate(offset)) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
@@ -3584,176 +3627,187 @@ nsCanvasRenderingContext2DAzure::SetMozD
     state.dashOffset = offset;
   }
   return NS_OK;
 }
  
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozDashOffset(float* offset)
 {
-  *offset = GetMozDashOffset();
+  *offset = CurrentState().dashOffset;
   return NS_OK;
 }
 
-bool
-nsCanvasRenderingContext2DAzure::IsPointInPath(double x, double y)
-{
-  if (!FloatValidate(x,y)) {
-    return false;
-  }
-
-  EnsureUserSpacePath();
-
-  return mPath && mPath->ContainsPoint(Point(x, y), mTarget->GetTransform());
-}
-
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::IsPointInPath(float x, float y, bool *retVal)
 {
-  *retVal = IsPointInPath(x, y);
+  if (!FloatValidate(x,y)) {
+    *retVal = false;
+    return NS_OK;
+  }
+
+  EnsureUserSpacePath();
+
+  *retVal = false;
+
+  if (mPath) {
+    *retVal = mPath->ContainsPoint(Point(x, y), mTarget->GetTransform());
+  }
+
   return NS_OK;
 }
 
 //
 // image
 //
 
 // drawImage(in HTMLImageElement image, in float dx, in float dy);
 //   -- render image from 0,0 at dx,dy top-left coords
 // drawImage(in HTMLImageElement image, in float dx, in float dy, in float sw, in float sh);
 //   -- render image from 0,0 at dx,dy top-left coords clipping it to sw,sh
 // drawImage(in HTMLImageElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);
 //   -- render the region defined by (sx,sy,sw,wh) in image-local space into the region (dx,dy,dw,dh) on the canvas
 
-// If only dx and dy are passed in then optional_argc should be 0. If only
-// dx, dy, dw and dh are passed in then optional_argc should be 2. The only
-// other valid value for optional_argc is 6 if sx, sy, sw, sh, dx, dy, dw and dh
-// are all passed in.
-
-void
-nsCanvasRenderingContext2DAzure::DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
-                                           double sx, double sy, double sw,
-                                           double sh, double dx, double dy,
-                                           double dw, double dh, 
-                                           PRUint8 optional_argc,
-                                           ErrorResult& error)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
+                                           float a2, float a3, float a4, float a5,
+                                           float a6, float a7, float a8,
+                                           PRUint8 optional_argc)
 {
-  MOZ_ASSERT(optional_argc == 0 || optional_argc == 2 || optional_argc == 6);
+  nsCOMPtr<nsIContent> content = do_QueryInterface(imgElt);
+  if (!content) {
+    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
+  }
+
+  if (optional_argc == 0) {
+    if (!FloatValidate(a1, a2)) {
+      return NS_OK;
+    }
+  } else if (optional_argc == 2) {
+    if (!FloatValidate(a1, a2, a3, a4)) {
+      return NS_OK;
+    }
+  } else if (optional_argc == 6) {
+    if (!FloatValidate(a1, a2, a3, a4, a5, a6) || !FloatValidate(a7, a8)) {
+      return NS_OK;
+    }
+  }
+
+  double sx,sy,sw,sh;
+  double dx,dy,dw,dh;
 
   RefPtr<SourceSurface> srcSurf;
   gfxIntSize imgSize;
 
-  Element* element;
-  nsIDOMElement* domElement;
-  if (image.IsHTMLCanvasElement()) {
-    nsHTMLCanvasElement* canvas = image.GetAsHTMLCanvasElement();
-    element = canvas;
-    domElement = canvas;
+  nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content);
+  if (canvas) {
     nsIntSize size = canvas->GetSize();
     if (size.width == 0 || size.height == 0) {
-      error.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
-      return;
+      return NS_ERROR_DOM_INVALID_STATE_ERR;
     }
 
     // Special case for Canvas, which could be an Azure canvas!
     nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
     if (srcCanvas == this) {
       // Self-copy.
       srcSurf = mTarget->Snapshot();
       imgSize = gfxIntSize(mWidth, mHeight);
     } else if (srcCanvas) {
       // This might not be an Azure canvas!
       srcSurf = srcCanvas->GetSurfaceSnapshot();
 
       if (srcSurf && mCanvasElement) {
         // Do security check here.
         CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
-                                              element->NodePrincipal(),
-                                              canvas->IsWriteOnly(),
+                                              content->NodePrincipal(), canvas->IsWriteOnly(),
                                               false);
         imgSize = gfxIntSize(srcSurf->GetSize().width, srcSurf->GetSize().height);
       }
     }
   } else {
-    if (image.IsHTMLImageElement()) {
-      nsHTMLImageElement* img = image.GetAsHTMLImageElement();
-      element = img;
-      domElement = img;
-    } else {
-      nsHTMLVideoElement* video = image.GetAsHTMLVideoElement();
-      element = video;
-      domElement = video;
-    }
-
     gfxASurface* imgsurf =
-      CanvasImageCache::Lookup(domElement, mCanvasElement, &imgSize);
+      CanvasImageCache::Lookup(imgElt, mCanvasElement, &imgSize);
     if (imgsurf) {
       srcSurf = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, imgsurf);
     }
   }
 
   if (!srcSurf) {
     // The canvas spec says that drawImage should draw the first frame
     // of animated images
     PRUint32 sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME;
     nsLayoutUtils::SurfaceFromElementResult res =
-      nsLayoutUtils::SurfaceFromElement(element, sfeFlags);
+      nsLayoutUtils::SurfaceFromElement(content->AsElement(), sfeFlags);
 
     if (!res.mSurface) {
       // Spec says to silently do nothing if the element is still loading.
-      if (!res.mIsStillLoading) {
-        error.Throw(NS_ERROR_NOT_AVAILABLE);
-      }
-      return;
+      return res.mIsStillLoading ? NS_OK : NS_ERROR_NOT_AVAILABLE;
     }
 
     // Ignore cairo surfaces that are bad! See bug 666312.
     if (res.mSurface->CairoStatus()) {
-      return;
+      return NS_OK;
     }
 
     imgSize = res.mSize;
 
     if (mCanvasElement) {
       CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
                                             res.mPrincipal, res.mIsWriteOnly,
                                             res.mCORSUsed);
     }
 
     if (res.mImageRequest) {
-      CanvasImageCache::NotifyDrawImage(domElement, mCanvasElement,
+      CanvasImageCache::NotifyDrawImage(imgElt, mCanvasElement,
                                         res.mImageRequest, res.mSurface, imgSize);
     }
 
     srcSurf = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, res.mSurface);
   }
 
   if (optional_argc == 0) {
+    dx = a1;
+    dy = a2;
     sx = sy = 0.0;
     dw = sw = (double) imgSize.width;
     dh = sh = (double) imgSize.height;
   } else if (optional_argc == 2) {
+    dx = a1;
+    dy = a2;
+    dw = a3;
+    dh = a4;
     sx = sy = 0.0;
     sw = (double) imgSize.width;
     sh = (double) imgSize.height;
+  } else if (optional_argc == 6) {
+    sx = a1;
+    sy = a2;
+    sw = a3;
+    sh = a4;
+    dx = a5;
+    dy = a6;
+    dw = a7;
+    dh = a8;
+  } else {
+    // XXX ERRMSG we need to report an error to developers here! (bug 329026)
+    return NS_ERROR_INVALID_ARG;
   }
 
   if (dw == 0.0 || dh == 0.0) {
     // not really failure, but nothing to do --
     // and noone likes a divide-by-zero
-    return;
+    return NS_OK;
   }
 
   if (sx < 0.0 || sy < 0.0 ||
       sw < 0.0 || sw > (double) imgSize.width ||
       sh < 0.0 || sh > (double) imgSize.height ||
       dw < 0.0 || dh < 0.0) {
     // XXX - Unresolved spec issues here, for now return error.
-    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return;
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   Filter filter;
 
   if (CurrentState().imageSmoothingEnabled)
     filter = mgfx::FILTER_LINEAR;
   else
     filter = mgfx::FILTER_POINT;
@@ -3767,57 +3821,21 @@ nsCanvasRenderingContext2DAzure::DrawIma
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
     DrawSurface(srcSurf,
                 mgfx::Rect(dx, dy, dw, dh),
                 mgfx::Rect(sx, sy, sw, sh),
                 DrawSurfaceOptions(filter),
                 DrawOptions(CurrentState().globalAlpha, UsedOperation()));
 
-  RedrawUser(gfxRect(dx, dy, dw, dh));
+  return RedrawUser(gfxRect(dx, dy, dw, dh));
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
-                                           float a2, float a3, float a4, float a5,
-                                           float a6, float a7, float a8,
-                                           PRUint8 optional_argc)
-{
-  if (!(optional_argc == 0 || optional_argc == 2 || optional_argc == 6)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  HTMLImageOrCanvasOrVideoElement element;
-  if (!ToHTMLImageOrCanvasOrVideoElement(imgElt, element)) {
-    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
-  }
-
-  ErrorResult rv;
-  if (optional_argc == 0) {
-    if (!FloatValidate(a1, a2)) {
-      return NS_OK;
-    }
-    DrawImage(element, 0, 0, 0, 0, a1, a2, 0, 0, 0, rv);
-  } else if (optional_argc == 2) {
-    if (!FloatValidate(a1, a2, a3, a4)) {
-      return NS_OK;
-    }
-    DrawImage(element, 0, 0, 0, 0, a1, a2, a3, a4, 2, rv);
-  } else if (optional_argc == 6) {
-    if (!FloatValidate(a1, a2, a3, a4) || !FloatValidate(a5, a6, a7, a8)) {
-      return NS_OK;
-    }
-    DrawImage(element, a1, a2, a3, a4, a5, a6, a7, a8, 6, rv);
-  }
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::SetGlobalCompositeOperation(const nsAString& op,
-                                                             ErrorResult& error)
+nsCanvasRenderingContext2DAzure::SetGlobalCompositeOperation(const nsAString& op)
 {
   CompositionOp comp_op;
 
 #define CANVAS_OP_TO_GFX_OP(cvsop, op2d) \
   if (op.EqualsLiteral(cvsop))   \
     comp_op = OP_##op2d;
 
   CANVAS_OP_TO_GFX_OP("copy", SOURCE)
@@ -3827,33 +3845,25 @@ nsCanvasRenderingContext2DAzure::SetGlob
   else CANVAS_OP_TO_GFX_OP("source-over", OVER)
   else CANVAS_OP_TO_GFX_OP("destination-in", DEST_IN)
   else CANVAS_OP_TO_GFX_OP("destination-out", DEST_OUT)
   else CANVAS_OP_TO_GFX_OP("destination-over", DEST_OVER)
   else CANVAS_OP_TO_GFX_OP("destination-atop", DEST_ATOP)
   else CANVAS_OP_TO_GFX_OP("lighter", ADD)
   else CANVAS_OP_TO_GFX_OP("xor", XOR)
   // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-  else return;
+  else return NS_OK;
 
 #undef CANVAS_OP_TO_GFX_OP
   CurrentState().op = comp_op;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetGlobalCompositeOperation(const nsAString& op)
-{
-  ErrorResult rv;
-  SetGlobalCompositeOperation(op, rv);
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::GetGlobalCompositeOperation(nsAString& op,
-                                                             ErrorResult& error)
+nsCanvasRenderingContext2DAzure::GetGlobalCompositeOperation(nsAString& op)
 {
   CompositionOp comp_op = CurrentState().op;
 
 #define CANVAS_OP_TO_GFX_OP(cvsop, op2d) \
   if (comp_op == OP_##op2d) \
     op.AssignLiteral(cvsop);
 
   CANVAS_OP_TO_GFX_OP("copy", SOURCE)
@@ -3862,48 +3872,36 @@ nsCanvasRenderingContext2DAzure::GetGlob
   else CANVAS_OP_TO_GFX_OP("destination-out", DEST_OUT)
   else CANVAS_OP_TO_GFX_OP("destination-over", DEST_OVER)
   else CANVAS_OP_TO_GFX_OP("lighter", ADD)
   else CANVAS_OP_TO_GFX_OP("source-atop", ATOP)
   else CANVAS_OP_TO_GFX_OP("source-in", IN)
   else CANVAS_OP_TO_GFX_OP("source-out", OUT)
   else CANVAS_OP_TO_GFX_OP("source-over", OVER)
   else CANVAS_OP_TO_GFX_OP("xor", XOR)
-  else {
-    error.Throw(NS_ERROR_FAILURE);
-  }
+  else return NS_ERROR_FAILURE;
 
 #undef CANVAS_OP_TO_GFX_OP
+    
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetGlobalCompositeOperation(nsAString& op)
+nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY,
+                                            float aW, float aH,
+                                            const nsAString& aBGColor,
+                                            PRUint32 flags)
 {
-  nsString globalCompositeOperation;
-  ErrorResult rv;
-  GetGlobalCompositeOperation(globalCompositeOperation, rv);
-  if (!rv.Failed()) {
-    op = globalCompositeOperation;
-  }
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* window, double x,
-                                            double y, double w, double h,
-                                            const nsAString& bgColor,
-                                            uint32_t flags, ErrorResult& error)
-{
+  NS_ENSURE_ARG(aWindow != nsnull);
+
   // protect against too-large surfaces that will cause allocation
   // or overflow issues
-  if (!gfxASurface::CheckSurfaceSize(gfxIntSize(PRInt32(w), PRInt32(h)),
-                                     0xffff)) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
-  }
+  if (!gfxASurface::CheckSurfaceSize(gfxIntSize(PRInt32(aW), PRInt32(aH)),
+                                     0xffff))
+    return NS_ERROR_FAILURE;
 
   nsRefPtr<gfxASurface> drawSurf;
   GetThebesSurface(getter_AddRefs(drawSurf));
 
   nsRefPtr<gfxContext> thebes = new gfxContext(drawSurf);
 
   Matrix matrix = mTarget->GetTransform();
   thebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21,
@@ -3913,47 +3911,43 @@ nsCanvasRenderingContext2DAzure::DrawWin
   // following potential security issues:
   // -- rendering cross-domain IFRAMEs and then extracting the results
   // -- rendering the user's theme and then extracting the results
   // -- rendering native anonymous content (e.g., file input paths;
   // scrollbars should be allowed)
   if (!nsContentUtils::IsCallerTrustedForRead()) {
     // not permitted to use DrawWindow
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    error.Throw(NS_ERROR_DOM_SECURITY_ERR);
-    return;
+    return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // Flush layout updates
   if (!(flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH))
-    nsContentUtils::FlushLayoutForTree(window);
+      nsContentUtils::FlushLayoutForTree(aWindow);
 
   nsRefPtr<nsPresContext> presContext;
-  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aWindow);
   if (win) {
     nsIDocShell* docshell = win->GetDocShell();
     if (docshell) {
       docshell->GetPresContext(getter_AddRefs(presContext));
     }
   }
-  if (!presContext) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
+  if (!presContext)
+    return NS_ERROR_FAILURE;
+
+  nscolor bgColor;
+  if (!ParseColor(aBGColor, &bgColor)) {
+    return NS_ERROR_FAILURE;
   }
 
-  nscolor backgroundColor;
-  if (!ParseColor(bgColor, &backgroundColor)) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsRect r(nsPresContext::CSSPixelsToAppUnits((float)x),
-           nsPresContext::CSSPixelsToAppUnits((float)y),
-           nsPresContext::CSSPixelsToAppUnits((float)w),
-           nsPresContext::CSSPixelsToAppUnits((float)h));
+  nsRect r(nsPresContext::CSSPixelsToAppUnits(aX),
+           nsPresContext::CSSPixelsToAppUnits(aY),
+           nsPresContext::CSSPixelsToAppUnits(aW),
+           nsPresContext::CSSPixelsToAppUnits(aH));
   PRUint32 renderDocFlags = (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
                              nsIPresShell::RENDER_DOCUMENT_RELATIVE);
   if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
     renderDocFlags |= nsIPresShell::RENDER_CARET;
   }
   if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
     renderDocFlags &= ~(nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
                         nsIPresShell::RENDER_DOCUMENT_RELATIVE);
@@ -3961,135 +3955,103 @@ nsCanvasRenderingContext2DAzure::DrawWin
   if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_USE_WIDGET_LAYERS) {
     renderDocFlags |= nsIPresShell::RENDER_USE_WIDGET_LAYERS;
   }
   if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_ASYNC_DECODE_IMAGES) {
     renderDocFlags |= nsIPresShell::RENDER_ASYNC_DECODE_IMAGES;
   }
 
   unused << presContext->PresShell()->
-    RenderDocument(r, renderDocFlags, backgroundColor, thebes);
-
-  // note that x and y are coordinates in the document that
-  // we're drawing; x and y are drawn to 0,0 in current user
+    RenderDocument(r, renderDocFlags, bgColor, thebes);
+
+  // note that aX and aY are coordinates in the document that
+  // we're drawing; aX and aY are drawn to 0,0 in current user
   // space.
-  RedrawUser(gfxRect(0, 0, w, h));
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY,
-                                            float aW, float aH,
-                                            const nsAString& aBGColor,
-                                            PRUint32 flags)
-{
-  NS_ENSURE_ARG(aWindow);
-
-  ErrorResult rv;
-  DrawWindow(aWindow, aX, aY, aW, aH, aBGColor, flags, rv);
-  return rv.ErrorCode();
-}
-
-void
-nsCanvasRenderingContext2DAzure::AsyncDrawXULElement(nsIDOMXULElement* elem,
-                                                     double x, double y,
-                                                     double w, double h,
-                                                     const nsAString& bgColor,
-                                                     uint32_t flags,
-                                                     ErrorResult& error)
-{
-  // We can't allow web apps to call this until we fix at least the
-  // following potential security issues:
-  // -- rendering cross-domain IFRAMEs and then extracting the results
-  // -- rendering the user's theme and then extracting the results
-  // -- rendering native anonymous content (e.g., file input paths;
-  // scrollbars should be allowed)
-  if (!nsContentUtils::IsCallerTrustedForRead()) {
-      // not permitted to use DrawWindow
-      // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    error.Throw(NS_ERROR_DOM_SECURITY_ERR);
-    return;
-  }
-
-#if 0
-  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(elem);
-  if (!loaderOwner) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsRefPtr<nsFrameLoader> frameloader = loaderOwner->GetFrameLoader();
-  if (!frameloader) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  PBrowserParent *child = frameloader->GetRemoteBrowser();
-  if (!child) {
-    nsCOMPtr<nsIDOMWindow> window =
-      do_GetInterface(frameloader->GetExistingDocShell());
-    if (!window) {
-      error.Throw(NS_ERROR_FAILURE);
-      return;
-    }
-
-    return DrawWindow(window, x, y, w, h, bgColor, flags);
-  }
-
-  // protect against too-large surfaces that will cause allocation
-  // or overflow issues
-  if (!gfxASurface::CheckSurfaceSize(gfxIntSize(w, h), 0xffff)) {
-    error.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  bool flush =
-    (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH) == 0;
-
-  PRUint32 renderDocFlags = nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
-  if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
-    renderDocFlags |= nsIPresShell::RENDER_CARET;
-  }
-  if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
-    renderDocFlags &= ~nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
-  }
-
-  nsRect rect(nsPresContext::CSSPixelsToAppUnits(x),
-              nsPresContext::CSSPixelsToAppUnits(y),
-              nsPresContext::CSSPixelsToAppUnits(w),
-              nsPresContext::CSSPixelsToAppUnits(h));
-  if (mIPC) {
-    PDocumentRendererParent *pdocrender =
-      child->SendPDocumentRendererConstructor(rect,
-                                              mThebes->CurrentMatrix(),
-                                              nsString(aBGColor),
-                                              renderDocFlags, flush,
-                                              nsIntSize(mWidth, mHeight));
-    if (!pdocrender)
-      return NS_ERROR_FAILURE;
-
-    DocumentRendererParent *docrender =
-      static_cast<DocumentRendererParent *>(pdocrender);
-
-    docrender->SetCanvasContext(this, mThebes);
-  }
-#endif
+  RedrawUser(gfxRect(0, 0, aW, aH));
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::AsyncDrawXULElement(nsIDOMXULElement* aElem,
                                                      float aX, float aY,
                                                      float aW, float aH,
                                                      const nsAString& aBGColor,
                                                      PRUint32 flags)
 {
-  NS_ENSURE_ARG(aElem);
-
-  ErrorResult rv;
-  AsyncDrawXULElement(aElem, aX, aY, aW, aH, aBGColor, flags, rv);
-  return rv.ErrorCode();
+    NS_ENSURE_ARG(aElem != nsnull);
+
+    // We can't allow web apps to call this until we fix at least the
+    // following potential security issues:
+    // -- rendering cross-domain IFRAMEs and then extracting the results
+    // -- rendering the user's theme and then extracting the results
+    // -- rendering native anonymous content (e.g., file input paths;
+    // scrollbars should be allowed)
+    if (!nsContentUtils::IsCallerTrustedForRead()) {
+        // not permitted to use DrawWindow
+        // XXX ERRMSG we need to report an error to developers here! (bug 329026)
+        return NS_ERROR_DOM_SECURITY_ERR;
+    }
+
+#if 0
+    nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aElem);
+    if (!loaderOwner)
+        return NS_ERROR_FAILURE;
+
+    nsRefPtr<nsFrameLoader> frameloader = loaderOwner->GetFrameLoader();
+    if (!frameloader)
+        return NS_ERROR_FAILURE;
+
+    PBrowserParent *child = frameloader->GetRemoteBrowser();
+    if (!child) {
+        nsCOMPtr<nsIDOMWindow> window =
+            do_GetInterface(frameloader->GetExistingDocShell());
+        if (!window)
+            return NS_ERROR_FAILURE;
+
+        return DrawWindow(window, aX, aY, aW, aH, aBGColor, flags);
+    }
+
+    // protect against too-large surfaces that will cause allocation
+    // or overflow issues
+    if (!gfxASurface::CheckSurfaceSize(gfxIntSize(aW, aH), 0xffff))
+        return NS_ERROR_FAILURE;
+
+    bool flush =
+        (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH) == 0;
+
+    PRUint32 renderDocFlags = nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
+    if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
+        renderDocFlags |= nsIPresShell::RENDER_CARET;
+    }
+    if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
+        renderDocFlags &= ~nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
+    }
+
+    nsRect rect(nsPresContext::CSSPixelsToAppUnits(aX),
+                nsPresContext::CSSPixelsToAppUnits(aY),
+                nsPresContext::CSSPixelsToAppUnits(aW),
+                nsPresContext::CSSPixelsToAppUnits(aH));
+    if (mIPC) {
+        PDocumentRendererParent *pdocrender =
+            child->SendPDocumentRendererConstructor(rect,
+                                                    mThebes->CurrentMatrix(),
+                                                    nsString(aBGColor),
+                                                    renderDocFlags, flush,
+                                                    nsIntSize(mWidth, mHeight));
+        if (!pdocrender)
+            return NS_ERROR_FAILURE;
+
+        DocumentRendererParent *docrender =
+            static_cast<DocumentRendererParent *>(pdocrender);
+
+        docrender->SetCanvasContext(this, mThebes);
+    }
+#endif
+    return NS_OK;
 }
 
 //
 // device pixel getting/setting
 //
 
 void
 nsCanvasRenderingContext2DAzure::EnsureUnpremultiplyTable() {
@@ -4113,51 +4075,46 @@ nsCanvasRenderingContext2DAzure::EnsureU
   for (int a = 1; a <= 255; a++) {
     for (int c = 0; c <= 255; c++) {
       sUnpremultiplyTable[a][c] = (PRUint8)((c * 255) / a);
     }
   }
 }
 
 
-already_AddRefed<ImageData>
-nsCanvasRenderingContext2DAzure::GetImageData(JSContext* aCx, double aSx,
-                                              double aSy, double aSw,
-                                              double aSh, ErrorResult& error)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetImageData(double aSx, double aSy,
+                                              double aSw, double aSh,
+                                              JSContext* aCx,
+                                              nsIDOMImageData** aRetval)
 {
-  if (!mValid) {
-    error.Throw(NS_ERROR_FAILURE);
-    return NULL;
-  }
+  if (!mValid)
+    return NS_ERROR_FAILURE;
 
   if (!mCanvasElement && !mDocShell) {
     NS_ERROR("No canvas element and no docshell in GetImageData!!!");
-    error.Throw(NS_ERROR_DOM_SECURITY_ERR);
-    return NULL;
+    return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // Check only if we have a canvas element; if we were created with a docshell,
   // then it's special internal use.
   if (mCanvasElement && mCanvasElement->IsWriteOnly() &&
       !nsContentUtils::IsCallerTrustedForRead())
   {
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    error.Throw(NS_ERROR_DOM_SECURITY_ERR);
-    return NULL;
+    return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   if (!NS_finite(aSx) || !NS_finite(aSy) ||
       !NS_finite(aSw) || !NS_finite(aSh)) {
-    error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-    return NULL;
+    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
   }
 
   if (!aSw || !aSh) {
-    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return NULL;
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   int32_t x = JS_DoubleToInt32(aSx);
   int32_t y = JS_DoubleToInt32(aSy);
   int32_t wi = JS_DoubleToInt32(aSw);
   int32_t hi = JS_DoubleToInt32(aSh);
 
   // Handle negative width and height by flipping the rectangle over in the
@@ -4179,35 +4136,23 @@ nsCanvasRenderingContext2DAzure::GetImag
   if (w == 0) {
     w = 1;
   }
   if (h == 0) {
     h = 1;
   }
 
   JSObject* array;
-  error = GetImageDataArray(aCx, x, y, w, h, &array);
-  if (error.Failed()) {
-    return NULL;
-  }
+  nsresult rv = GetImageDataArray(aCx, x, y, w, h, &array);
+  NS_ENSURE_SUCCESS(rv, rv);
   MOZ_ASSERT(array);
 
   nsRefPtr<ImageData> imageData = new ImageData(w, h, *array);
-  return imageData.forget();
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetImageData(double aSx, double aSy,
-                                              double aSw, double aSh,
-                                              JSContext* aCx,
-                                              nsIDOMImageData** aRetval)
-{
-  ErrorResult rv;
-  *aRetval = GetImageData(aCx, aSx, aSy, aSw, aSh, rv).get();
-  return rv.ErrorCode();
+  imageData.forget(aRetval);
+  return NS_OK;
 }
 
 nsresult
 nsCanvasRenderingContext2DAzure::GetImageDataArray(JSContext* aCx,
                                                    int32_t aX,
                                                    int32_t aY,
                                                    uint32_t aWidth,
                                                    uint32_t aHeight,
@@ -4317,57 +4262,16 @@ void
 nsCanvasRenderingContext2DAzure::FillRuleChanged()
 {
   if (mPath) {
     mPathBuilder = mPath->CopyToBuilder(CurrentState().fillRule);
     mPath = nsnull;
   }
 }
 
-void
-nsCanvasRenderingContext2DAzure::PutImageData(JSContext* cx,
-                                              ImageData* imageData, double dx,
-                                              double dy, ErrorResult& error)
-{
-  if (!FloatValidate(dx, dy)) {
-    error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-    return;
-  }
-
-  dom::Uint8ClampedArray arr(cx, imageData->GetDataObject());
-
-  error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
-                                imageData->GetWidth(), imageData->GetHeight(),
-                                arr.mData, arr.mLength, false, 0, 0, 0, 0);
-}
-
-void
-nsCanvasRenderingContext2DAzure::PutImageData(JSContext* cx,
-                                              ImageData* imageData, double dx,
-                                              double dy, double dirtyX,
-                                              double dirtyY, double dirtyWidth,
-                                              double dirtyHeight,
-                                              ErrorResult& error)
-{
-  if (!FloatValidate(dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)) {
-    error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-    return;
-  }
-
-  dom::Uint8ClampedArray arr(cx, imageData->GetDataObject());
-
-  error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
-                                imageData->GetWidth(), imageData->GetHeight(),
-                                arr.mData, arr.mLength, true,
-                                JS_DoubleToInt32(dirtyX),
-                                JS_DoubleToInt32(dirtyY),
-                                JS_DoubleToInt32(dirtyWidth),
-                                JS_DoubleToInt32(dirtyHeight));
-}
-
 // void putImageData (in ImageData d, in float x, in float y);
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::PutImageData()
 {
   /* Should never be called -- PutImageData_explicit is the QS entry point */
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
@@ -4507,92 +4411,37 @@ nsCanvasRenderingContext2DAzure::GetTheb
   }
 
   *surface = mThebesSurface;
   NS_ADDREF(*surface);
 
   return NS_OK;
 }
 
-static already_AddRefed<ImageData>
-CreateImageData(JSContext* cx, nsCanvasRenderingContext2DAzure* context,
-                uint32_t w, uint32_t h, ErrorResult& error)
-{
-  if (w == 0)
-      w = 1;
-  if (h == 0)
-      h = 1;
-
-  CheckedInt<uint32_t> len = CheckedInt<uint32_t>(w) * h * 4;
-  if (!len.isValid()) {
-    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return NULL;
-  }
-
-  // Create the fast typed array; it's initialized to 0 by default.
-  JSObject* darray = Uint8ClampedArray::Create(cx, context, len.value());
-  if (!darray) {
-    error.Throw(NS_ERROR_OUT_OF_MEMORY);
-    return NULL;
-  }
-
-  nsRefPtr<mozilla::dom::ImageData> imageData =
-    new mozilla::dom::ImageData(w, h, *darray);
-  return imageData.forget();
-}
-
-already_AddRefed<ImageData>
-nsCanvasRenderingContext2DAzure::CreateImageData(JSContext* cx, double sw,
-                                                 double sh, ErrorResult& error)
-{
-  if (!FloatValidate(sw, sh)) {
-    error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-    return NULL;
-  }
-
-  if (!sw || !sh) {
-    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return NULL;
-  }
-
-  int32_t wi = JS_DoubleToInt32(sw);
-  int32_t hi = JS_DoubleToInt32(sh);
-
-  uint32_t w = NS_ABS(wi);
-  uint32_t h = NS_ABS(hi);
-  return ::CreateImageData(cx, this, w, h, error);
-}
-
-already_AddRefed<ImageData>
-nsCanvasRenderingContext2DAzure::CreateImageData(JSContext* cx,
-                                                 ImageData* imagedata,
-                                                 ErrorResult& error)
-{
-  return ::CreateImageData(cx, this, imagedata->GetWidth(),
-                           imagedata->GetHeight(), error);
-}
-
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::CreateImageData()
 {
   /* Should never be called; handled entirely in the quickstub */
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozImageSmoothingEnabled(bool *retVal)
 {
-  *retVal = GetImageSmoothingEnabled();
+  *retVal = CurrentState().imageSmoothingEnabled;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozImageSmoothingEnabled(bool val)
 {
-  SetImageSmoothingEnabled(val);
+  if (val != CurrentState().imageSmoothingEnabled) {
+      CurrentState().imageSmoothingEnabled = val;
+  }
+
   return NS_OK;
 }
 
 static PRUint8 g2DContextLayerUserData;
 
 already_AddRefed<CanvasLayer>
 nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                            CanvasLayer *aOldLayer,
deleted file mode 100644
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.h
+++ /dev/null
@@ -1,943 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsCanvasRenderingContext2DAzure_h
-#define nsCanvasRenderingContext2DAzure_h
-
-#include <vector>
-#include "nsIDOMCanvasRenderingContext2D.h"
-#include "nsICanvasRenderingContextInternal.h"
-#include "mozilla/RefPtr.h"
-#include "nsColor.h"
-#include "nsHTMLCanvasElement.h"
-#include "CanvasUtils.h"
-#include "nsHTMLImageElement.h"
-#include "nsHTMLVideoElement.h"
-#include "gfxFont.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/dom/ImageData.h"
-#include "mozilla/dom/UnionTypes.h"
-
-namespace mozilla {
-namespace dom {
-template<typename T> class Optional;
-}
-namespace gfx {
-struct Rect;
-class SourceSurface;
-}
-}
-
-extern const mozilla::gfx::Float SIGMA_MAX;
-
-/**
- ** nsCanvasGradientAzure
- **/
-#define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
-    {0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
-class nsCanvasGradientAzure : public nsIDOMCanvasGradient
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENTAZURE_PRIVATE_IID)
-
-  enum Type
-  {
-    LINEAR = 0,
-    RADIAL
-  };
-
-  Type GetType()
-  {
-    return mType;
-  }
-
-
-  mozilla::gfx::GradientStops *
-  GetGradientStopsForTarget(mozilla::gfx::DrawTarget *aRT)
-  {
-    if (mStops && mStops->GetBackendType() == aRT->GetType()) {
-      return mStops;
-    }
-
-    mStops = aRT->CreateGradientStops(mRawStops.Elements(), mRawStops.Length());
-
-    return mStops;
-  }
-
-  NS_DECL_ISUPPORTS
-
-  /* nsIDOMCanvasGradient */
-  NS_IMETHOD AddColorStop(float offset, const nsAString& colorstr);
-
-protected:
-  nsCanvasGradientAzure(Type aType) : mType(aType)
-  {}
-
-  nsTArray<mozilla::gfx::GradientStop> mRawStops;
-  mozilla::RefPtr<mozilla::gfx::GradientStops> mStops;
-  Type mType;
-  virtual ~nsCanvasGradientAzure() {}
-};
-
-/**
- ** nsCanvasPatternAzure
- **/
-#define NS_CANVASPATTERNAZURE_PRIVATE_IID \
-    {0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
-class nsCanvasPatternAzure MOZ_FINAL : public nsIDOMCanvasPattern
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERNAZURE_PRIVATE_IID)
-
-  enum RepeatMode
-  {
-    REPEAT,
-    REPEATX,
-    REPEATY,
-    NOREPEAT
-  };
-
-  nsCanvasPatternAzure(mozilla::gfx::SourceSurface* aSurface,
-                       RepeatMode aRepeat,
-                       nsIPrincipal* principalForSecurityCheck,
-                       bool forceWriteOnly,
-                       bool CORSUsed)
-    : mSurface(aSurface)
-    , mRepeat(aRepeat)
-    , mPrincipal(principalForSecurityCheck)
-    , mForceWriteOnly(forceWriteOnly)
-    , mCORSUsed(CORSUsed)
-  {
-  }
-
-  NS_DECL_ISUPPORTS
-
-  mozilla::RefPtr<mozilla::gfx::SourceSurface> mSurface;
-  const RepeatMode mRepeat;
-  nsCOMPtr<nsIPrincipal> mPrincipal;
-  const bool mForceWriteOnly;
-  const bool mCORSUsed;
-};
-
-struct nsCanvasBidiProcessorAzure;
-class CanvasRenderingContext2DUserDataAzure;
-
-/**
- ** nsCanvasRenderingContext2DAzure
- **/
-class nsCanvasRenderingContext2DAzure :
-  public nsIDOMCanvasRenderingContext2D,
-  public nsICanvasRenderingContextInternal,
-  public nsWrapperCache
-{
-typedef mozilla::dom::HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
-  HTMLImageOrCanvasOrVideoElement;
-
-public:
-  nsCanvasRenderingContext2DAzure();
-  virtual ~nsCanvasRenderingContext2DAzure();
-
-  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
-                               bool *triedToWrap);
-
-  nsHTMLCanvasElement* GetCanvas() const
-  {
-    return mCanvasElement;
-  }
-
-  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);
-
-  double GetGlobalAlpha()
-  {
-    return CurrentState().globalAlpha;
-  }
-
-  void SetGlobalAlpha(double globalAlpha)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(globalAlpha) &&
-        globalAlpha >= 0.0 && globalAlpha <= 1.0) {
-      CurrentState().globalAlpha = globalAlpha;
-    }
-  }
-
-  void GetGlobalCompositeOperation(nsAString& op, mozilla::ErrorResult& error);
-  void SetGlobalCompositeOperation(const nsAString& op,
-                                   mozilla::ErrorResult& error);
-  JS::Value GetStrokeStyle(JSContext* cx, mozilla::ErrorResult& error);
-
-  void SetStrokeStyle(JSContext* cx, JS::Value& value)
-  {
-    SetStyleFromJSValue(cx, value, STYLE_STROKE);
-  }
-
-  JS::Value GetFillStyle(JSContext* cx, mozilla::ErrorResult& error);
-
-  void SetFillStyle(JSContext* cx, JS::Value& value)
-  {
-    SetStyleFromJSValue(cx, value, STYLE_FILL);
-  }
-
-  already_AddRefed<nsIDOMCanvasGradient>
-    CreateLinearGradient(double x0, double y0, double x1, double y1,
-                         mozilla::ErrorResult& aError);
-  already_AddRefed<nsIDOMCanvasGradient>
-    CreateRadialGradient(double x0, double y0, double r0, double x1, double y1,
-                         double r1, mozilla::ErrorResult& aError);
-  already_AddRefed<nsIDOMCanvasPattern>
-    CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
-                  const nsAString& repeat, mozilla::ErrorResult& error);
-
-  double GetShadowOffsetX()
-  {
-    return CurrentState().shadowOffset.x;
-  }
-
-  void SetShadowOffsetX(double shadowOffsetX)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(shadowOffsetX)) {
-      CurrentState().shadowOffset.x = shadowOffsetX;
-    }
-  }
-
-  double GetShadowOffsetY()
-  {
-    return CurrentState().shadowOffset.y;
-  }
-
-  void SetShadowOffsetY(double shadowOffsetY)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(shadowOffsetY)) {
-      CurrentState().shadowOffset.y = shadowOffsetY;
-    }
-  }
-
-  double GetShadowBlur()
-  {
-    return CurrentState().shadowBlur;
-  }
-
-  void SetShadowBlur(double shadowBlur)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(shadowBlur) && shadowBlur >= 0.0) {
-      CurrentState().shadowBlur = shadowBlur;
-    }
-  }
-
-  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();
-  void Fill();
-  void Stroke();
-  void Clip();
-  bool IsPointInPath(double x, double y);
-  void FillText(const nsAString& text, double x, double y,
-                const mozilla::dom::Optional<double>& maxWidth,
-                mozilla::ErrorResult& error);
-  void StrokeText(const nsAString& text, double x, double y,
-                  const mozilla::dom::Optional<double>& maxWidth,
-                  mozilla::ErrorResult& error);
-  already_AddRefed<nsIDOMTextMetrics>
-    MeasureText(const nsAString& rawText, mozilla::ErrorResult& error);
-
-  void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
-                 double dx, double dy, mozilla::ErrorResult& error)
-  {
-    if (!mozilla::CanvasUtils::FloatValidate(dx, dy)) {
-      return;
-    }
-    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)
-  {
-    if (!mozilla::CanvasUtils::FloatValidate(dx, dy, dw, dh)) {
-      return;
-    }
-    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)
-  {
-    if (!mozilla::CanvasUtils::FloatValidate(sx, sy, sw, sh) ||
-        !mozilla::CanvasUtils::FloatValidate(dx, dy, dw, dh)) {
-      return;
-    }
-    DrawImage(image, sx, sy, sw, sh, dx, dy, dw, dh, 6, error);
-  }
-
-  already_AddRefed<mozilla::dom::ImageData>
-    CreateImageData(JSContext* cx, double sw, double sh,
-                    mozilla::ErrorResult& error);
-  already_AddRefed<mozilla::dom::ImageData>
-    CreateImageData(JSContext* cx, mozilla::dom::ImageData* imagedata,
-                    mozilla::ErrorResult& error);
-  already_AddRefed<mozilla::dom::ImageData>
-    GetImageData(JSContext* cx, double sx, double sy, double sw, double sh,
-                 mozilla::ErrorResult& error);
-  void PutImageData(JSContext* cx, mozilla::dom::ImageData* imageData,
-                    double dx, double dy, mozilla::ErrorResult& error);
-  void PutImageData(JSContext* cx, mozilla::dom::ImageData* imageData,
-                    double dx, double dy, double dirtyX, double dirtyY,
-                    double dirtyWidth, double dirtyHeight,
-                    mozilla::ErrorResult& error);
-
-  double GetLineWidth()
-  {
-    return CurrentState().lineWidth;
-  }
-
-  void SetLineWidth(double width)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(width) && width > 0.0) {
-      CurrentState().lineWidth = width;
-    }
-  }
-  void GetLineCap(nsAString& linecap);
-  void SetLineCap(const nsAString& linecap);
-  void GetLineJoin(nsAString& linejoin, mozilla::ErrorResult& error);
-  void SetLineJoin(const nsAString& linejoin);
-
-  double GetMiterLimit()
-  {
-    return CurrentState().miterLimit;
-  }
-
-  void SetMiterLimit(double miter)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(miter) && miter > 0.0) {
-      CurrentState().miterLimit = miter;
-    }
-  }
-
-  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)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(x, y)) {
-      EnsureWritablePath();
-
-      if (mPathBuilder) {
-        mPathBuilder->MoveTo(mozilla::gfx::Point(x, y));
-      } else {
-        mDSPathBuilder->MoveTo(mTarget->GetTransform() *
-                                 mozilla::gfx::Point(x, y));
-      }
-    }
-  }
-
-  void LineTo(double x, double y)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(x, y)) {
-      EnsureWritablePath();
-    
-      LineTo(mozilla::gfx::Point(x, y));
-    }
-  }
-
-  void QuadraticCurveTo(double cpx, double cpy, double x, double y)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(cpx, cpy, x, y)) {
-      EnsureWritablePath();
-
-      if (mPathBuilder) {
-        mPathBuilder->QuadraticBezierTo(mozilla::gfx::Point(cpx, cpy),
-                                        mozilla::gfx::Point(x, y));
-      } else {
-        mozilla::gfx::Matrix transform = mTarget->GetTransform();
-        mDSPathBuilder->QuadraticBezierTo(transform *
-                                            mozilla::gfx::Point(cpx, cpy),
-                                          transform *
-                                            mozilla::gfx::Point(x, y));
-      }
-    }
-  }
-
-  void BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y)
-  {
-    if (mozilla::CanvasUtils::FloatValidate(cp1x, cp1y, cp2x, cp2y, x, y)) {
-      EnsureWritablePath();
-
-      BezierTo(mozilla::gfx::Point(cp1x, cp1y),
-               mozilla::gfx::Point(cp2x, cp2y),
-               mozilla::gfx::Point(x, y));
-    }
-  }
-
-  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;
-  void SetMozCurrentTransform(JSContext* cx, JSObject& currentTransform,
-                              mozilla::ErrorResult& error);
-  JSObject* GetMozCurrentTransformInverse(JSContext* cx,
-                                          mozilla::ErrorResult& error) const;
-  void SetMozCurrentTransformInverse(JSContext* cx, JSObject& currentTransform, 
-                                     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);
-
-  double GetMozDashOffset()
-  {
-    return CurrentState().dashOffset;
-  }
-
-  void SetMozDashOffset(double mozDashOffset, mozilla::ErrorResult& error);
-
-  void GetMozTextStyle(nsAString& mozTextStyle)
-  {
-    GetFont(mozTextStyle);
-  }
-
-  void SetMozTextStyle(const nsAString& mozTextStyle,
-                       mozilla::ErrorResult& error)
-  {
-    SetFont(mozTextStyle, error);
-  }
-
-  bool GetImageSmoothingEnabled()
-  {
-    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);
-  void AsyncDrawXULElement(nsIDOMXULElement* elem, double x, double y, double w,
-                           double h, const nsAString& bgColor, uint32_t flags,
-                           mozilla::ErrorResult& error);
-
-  nsresult Redraw();
-
-  // nsICanvasRenderingContextInternal
-  NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
-  NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, PRInt32 width, PRInt32 height)
-  { return NS_ERROR_NOT_IMPLEMENTED; }
-
-  NS_IMETHOD Render(gfxContext *ctx,
-                    gfxPattern::GraphicsFilter aFilter,
-                    PRUint32 aFlags = RenderFlagPremultAlpha);
-  NS_IMETHOD GetInputStream(const char* aMimeType,
-                            const PRUnichar* aEncoderOptions,
-                            nsIInputStream **aStream);
-  NS_IMETHOD GetThebesSurface(gfxASurface **surface);
-
-  mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot()
-  { return mTarget ? mTarget->Snapshot() : nsnull; }
-
-  NS_IMETHOD SetIsOpaque(bool isOpaque);
-  NS_IMETHOD Reset();
-  already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
-                                                CanvasLayer *aOldLayer,
-                                                LayerManager *aManager);
-  void MarkContextClean();
-  NS_IMETHOD SetIsIPC(bool isIPC);
-  // this rect is in canvas device space
-  void Redraw(const mozilla::gfx::Rect &r);
-  NS_IMETHOD Redraw(const gfxRect &r) { Redraw(ToRect(r)); return NS_OK; }
-
-  // this rect is in mTarget's current user space
-  void RedrawUser(const gfxRect &r);
-
-  // nsISupports interface + CC
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-
-  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCanvasRenderingContext2DAzure,
-                                                                   nsIDOMCanvasRenderingContext2D)
-
-  // nsIDOMCanvasRenderingContext2D interface
-  NS_DECL_NSIDOMCANVASRENDERINGCONTEXT2D
-
-  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);
-    }
-  }
-
-  friend class CanvasRenderingContext2DUserDataAzure;
-
-protected:
-  nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
-                             uint32_t aWidth, uint32_t aHeight,
-                             JSObject** aRetval);
-
-  nsresult InitializeWithTarget(mozilla::gfx::DrawTarget *surface,
-                                PRInt32 width, PRInt32 height);
-
-  /**
-    * The number of living nsCanvasRenderingContexts.  When this goes down to
-    * 0, we free the premultiply and unpremultiply tables, if they exist.
-    */
-  static PRUint32 sNumLivingContexts;
-
-  /**
-    * Lookup table used to speed up GetImageData().
-    */
-  static PRUint8 (*sUnpremultiplyTable)[256];
-
-  /**
-    * Lookup table used to speed up PutImageData().
-    */
-  static PRUint8 (*sPremultiplyTable)[256];
-
-  // Some helpers.  Doesn't modify a color on failure.
-  void SetStyleFromJSValue(JSContext* cx, JS::Value& value, Style whichStyle);
-  void SetStyleFromString(const nsAString& str, Style whichStyle);
-
-  void SetStyleFromGradient(nsCanvasGradientAzure *gradient, Style whichStyle)
-  {
-    CurrentState().SetGradientStyle(whichStyle, gradient);
-  }
-
-  void SetStyleFromPattern(nsCanvasPatternAzure *pattern, Style whichStyle)
-  {
-    CurrentState().SetPatternStyle(whichStyle, pattern);
-  }
-
-  void SetStyleFromStringOrInterface(const nsAString& aStr, nsISupports *aInterface, Style aWhichStyle);
-  nsISupports* GetStyleAsStringOrInterface(nsAString& aStr, CanvasMultiGetterType& aType, Style aWhichStyle);
-
-  // Returns whether a color was successfully parsed.
-  bool ParseColor(const nsAString& aString, nscolor* aColor);
-
-  static void StyleColorToString(const nscolor& aColor, nsAString& aStr);
-
-  /**
-    * Creates the unpremultiply lookup table, if it doesn't exist.
-    */
-  void EnsureUnpremultiplyTable();
-
-  /**
-    * Creates the premultiply lookup table, if it doesn't exist.
-    */
-  void EnsurePremultiplyTable();
-
-  /* This function ensures there is a writable pathbuilder available, this
-   * pathbuilder may be working in user space or in device space or
-   * device space.
-   */
-  void EnsureWritablePath();
-
-  // Ensures a path in UserSpace is available.
-  void EnsureUserSpacePath();
-
-  void TransformWillUpdate();
-
-  // Report the fillRule has changed.
-  void FillRuleChanged();
-
-  /**
-    * 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, 
-                 PRUint8 optional_argc, mozilla::ErrorResult& error);
-
-  nsString& GetFont()
-  {
-    /* will initilize the value if not set, else does nothing */
-    GetCurrentFontStyle();
-
-    return CurrentState().font;
-  }
-
-  static bool
-  ToHTMLImageOrCanvasOrVideoElement(nsIDOMElement* html,
-                                    HTMLImageOrCanvasOrVideoElement& element)
-  {
-    nsCOMPtr<nsIContent> content = do_QueryInterface(html);
-    if (content) {
-      if (content->IsHTML(nsGkAtoms::canvas)) {
-        element.SetAsHTMLCanvasElement() =
-          static_cast<nsHTMLCanvasElement*>(html);
-        return true;
-      }
-      if (content->IsHTML(nsGkAtoms::img)) {
-        element.SetAsHTMLImageElement() =
-          static_cast<nsHTMLImageElement*>(html);
-        return true;
-      }
-      if (content->IsHTML(nsGkAtoms::video)) {
-        element.SetAsHTMLVideoElement() =
-          static_cast<nsHTMLVideoElement*>(html);
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  // Member vars
-  PRInt32 mWidth, mHeight;
-
-  // This is true when the canvas is valid, false otherwise, this occurs when
-  // for some reason initialization of the drawtarget fails. If the canvas
-  // is invalid certain behavior is expected.
-  bool mValid;
-  // 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;
-
-  nsTArray<CanvasRenderingContext2DUserDataAzure*> mUserDatas;
-
-  // If mCanvasElement is not provided, then a docshell is
-  nsCOMPtr<nsIDocShell> mDocShell;
-
-  // our drawing surfaces, contexts, and layers
-  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
-    */
-  PRUint32 mInvalidateCount;
-  static const PRUint32 kCanvasMaxInvalidateCount = 100;
-
-  /**
-    * 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) {
-      nsCOMPtr<nsIPresShell> shell;
-      mDocShell->GetPresShell(getter_AddRefs(shell));
-      return shell.get();
-    }
-    return nsnull;
-  }
-
-  // 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,
-                              float x,
-                              float y,
-                              const mozilla::dom::Optional<double>& maxWidth,
-                              TextDrawOperation op,
-                              float* aWidth);
-
-  // state stack handling
-  class ContextState {
-  public:
-      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];
-          }
-      }
-
-      void SetColorStyle(Style whichStyle, nscolor color) {
-          colorStyles[whichStyle] = color;
-          gradientStyles[whichStyle] = nsnull;
-          patternStyles[whichStyle] = nsnull;
-      }
-
-      void SetPatternStyle(Style whichStyle, nsCanvasPatternAzure* pat) {
-          gradientStyles[whichStyle] = nsnull;
-          patternStyles[whichStyle] = pat;
-      }
-
-      void SetGradientStyle(Style whichStyle, nsCanvasGradientAzure* grad) {
-          gradientStyles[whichStyle] = grad;
-          patternStyles[whichStyle] = nsnull;
-      }
-
-      /**
-        * returns true iff the given style is a solid color.
-        */
-      bool StyleIsColor(Style whichStyle) const
-      {
-          return !(patternStyles[whichStyle] || gradientStyles[whichStyle]);
-      }
-
-
-      std::vector<mozilla::RefPtr<mozilla::gfx::Path> > clipsPushed;
-
-      nsRefPtr<gfxFontGroup> fontGroup;
-      nsRefPtr<nsCanvasGradientAzure> gradientStyles[STYLE_MAX];
-      nsRefPtr<nsCanvasPatternAzure> patternStyles[STYLE_MAX];
-
-      nsString font;
-      TextAlign textAlign;
-      TextBaseline textBaseline;
-
-      nscolor colorStyles[STYLE_MAX];
-      nscolor shadowColor;
-
-      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;
-
-      mozilla::gfx::CompositionOp op;
-      mozilla::gfx::FillRule fillRule;
-      mozilla::gfx::CapStyle lineCap;
-      mozilla::gfx::JoinStyle lineJoin;
-
-      bool imageSmoothingEnabled;
-  };
-
-  nsAutoTArray<ContextState, 3> mStyleStack;
-
-  inline ContextState& CurrentState() {
-    return mStyleStack[mStyleStack.Length() - 1];
-  }
-
-  friend class GeneralPattern;
-  friend class AdjustedTarget;
-
-  // other helpers
-  void GetAppUnitsValues(PRUint32 *perDevPixel, PRUint32 *perCSSPixel) {
-    // If we don't have a canvas element, we just return something generic.
-    PRUint32 devPixel = 60;
-    PRUint32 cssPixel = 60;
-
-    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;
-  }
-
-  friend struct nsCanvasBidiProcessorAzure;
-};
-
-#endif /* nsCanvasRenderingContext2DAzure_h */
--- a/content/canvas/test/test_canvas.html
+++ b/content/canvas/test/test_canvas.html
@@ -19543,21 +19543,17 @@ ok(window.CanvasRenderingContext2D.proto
 ok(window.CanvasRenderingContext2D.prototype.fill, "window.CanvasRenderingContext2D.prototype.fill");
 window.CanvasRenderingContext2D.prototype = null;
 ok(window.CanvasRenderingContext2D.prototype, "window.CanvasRenderingContext2D.prototype");
 delete window.CanvasRenderingContext2D.prototype;
 ok(window.CanvasRenderingContext2D.prototype, "window.CanvasRenderingContext2D.prototype");
 window.CanvasRenderingContext2D.prototype.fill = 1;
 ok(window.CanvasRenderingContext2D.prototype.fill === 1, "window.CanvasRenderingContext2D.prototype.fill === 1");
 delete window.CanvasRenderingContext2D.prototype.fill;
-if (IsAzureEnabled()) {
-  ok(window.CanvasRenderingContext2D.prototype.fill === undefined, "window.CanvasRenderingContext2D.prototype.fill === undefined");
-} else {
-  todo(window.CanvasRenderingContext2D.prototype.fill === undefined, "window.CanvasRenderingContext2D.prototype.fill === undefined");
-}
+todo(window.CanvasRenderingContext2D.prototype.fill === undefined, "window.CanvasRenderingContext2D.prototype.fill === undefined");
 
 //restore the original method to ensure that other tests can run successfully
 window.CanvasRenderingContext2D.prototype.fill = fill;
 }
 </script>
 
 <!-- [[[ test_2d.type.replace.html ]]] -->
 
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -760,14 +760,18 @@ nsHTMLCanvasElement::RenderContextsExter
 
 nsresult NS_NewCanvasRenderingContext2DThebes(nsIDOMCanvasRenderingContext2D** aResult);
 nsresult NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult);
 
 nsresult
 NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult)
 {
   Telemetry::Accumulate(Telemetry::CANVAS_2D_USED, 1);
-  if (AzureCanvasEnabled()) {
-    return NS_NewCanvasRenderingContext2DAzure(aResult);
+  if (Preferences::GetBool("gfx.canvas.azure.enabled", false)) {
+    nsresult rv = NS_NewCanvasRenderingContext2DAzure(aResult);
+    // If Azure fails, fall back to a classic canvas.
+    if (NS_SUCCEEDED(rv)) {
+      return rv;
+    }
   }
 
   return NS_NewCanvasRenderingContext2DThebes(aResult);
 }
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -529,17 +529,16 @@ using mozilla::dom::indexedDB::IDBWrappe
 #include "DOMFileHandle.h"
 #include "FileRequest.h"
 #include "LockedFile.h"
 
 #include "mozilla/Likely.h"
 
 #undef None // something included above defines this preprocessor symbol, maybe Xlib headers
 #include "WebGLContext.h"
-#include "nsICanvasRenderingContextInternal.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 
 static const char kDOMStringBundleURL[] =
   "chrome://global/locale/dom/dom.properties";
@@ -4586,20 +4585,16 @@ nsDOMClassInfo::Init()
     Preferences::GetBool("browser.dom.global_scope_pollution.disabled");
 
   // Proxy bindings
   mozilla::dom::binding::Register(nameSpaceManager);
 
   // Non-proxy bindings
   mozilla::dom::Register(nameSpaceManager);
 
-  if (!AzureCanvasEnabled()) {
-    nameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING("CanvasRenderingContext2D"), NULL);
-  }
-
   sIsInitialized = true;
 
   return NS_OK;
 }
 
 // static
 PRInt32
 nsDOMClassInfo::GetArrayIndexFromId(JSContext *cx, jsid id, bool *aIsNumber)
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -73,17 +73,16 @@
 #include "prlog.h"
 #include "prthread.h"
 
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #include "sampler.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 const size_t gStackSize = 8192;
 
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -15,17 +15,16 @@
 #include "jsfriendapi.h"
 #include "jswrapper.h"
 
 #include "nsIXPConnect.h"
 #include "qsObjectHelper.h"
 #include "xpcpublic.h"
 #include "nsTraceRefcnt.h"
 #include "nsWrapperCacheInlines.h"
-#include "mozilla/Likely.h"
 
 // nsGlobalWindow implements nsWrapperCache, but doesn't always use it. Don't
 // try to use it without fixing that first.
 class nsGlobalWindow;
 
 namespace mozilla {
 namespace dom {
 
@@ -183,17 +182,17 @@ IsPlatformObject(JSContext* cx, JSObject
 }
 
 // U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>).
 template <class T, typename U>
 inline nsresult
 UnwrapObject(JSContext* cx, JSObject* obj, U& value)
 {
   return UnwrapObject<static_cast<prototypes::ID>(
-           PrototypeIDMap<T>::PrototypeID), T>(cx, obj, value);
+           PrototypeIDMap<T>::PrototypeID)>(cx, obj, value);
 }
 
 const size_t kProtoOrIfaceCacheCount =
   prototypes::id::_ID_Count + constructors::id::_ID_Count;
 
 inline void
 AllocateProtoOrIfaceCache(JSObject* obj)
 {
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -63,50 +63,16 @@ DOMInterfaces = {
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
     'castable': False
 }],
 
-'CanvasRenderingContext2D': [
-{
-    'nativeType': 'nsCanvasRenderingContext2DAzure',
-    # Making this non-prefable requires that we ensure that nothing takes this
-    # type as an argument or that the non-Azure variant is removed.
-    'prefable': True,
-    'infallible': {
-        'all': [
-            'canvas', 'save', 'restore', 'globalAlpha', 'shadowOffsetX',
-            'shadowOffsetY', 'shadowBlur', 'shadowColor', 'clearRect',
-            'fillRect', 'strokeRect', 'beginPath', 'fill', 'stroke', 'clip',
-            'isPointInPath', 'lineWidth', 'lineCap', 'miterLimit', 'textAlign',
-            'textBaseline', 'closePath', 'moveTo', 'lineTo', 'quadraticCurveTo',
-            'bezierCurveTo', 'rect', 'mozFillRule', 'mozDashOffset',
-            'mozImageSmoothingEnabled'
-        ],
-        'setterOnly': [
-            'strokeStyle', 'fillStyle', 'lineJoin'
-        ],
-        'getterOnly': [
-            'font', 'mozTextStyle'
-        ]
-    },
-    'implicitJSContext': [
-        'createImageData', 'getImageData', 'putImageData', 'strokeStyle',
-        'fillStyle', 'mozDash'
-    ],
-    'resultNotAddRefed': [ 'canvas' ],
-    'binaryNames': {
-        'mozImageSmoothingEnabled': 'imageSmoothingEnabled',
-        'mozFillRule': 'fillRule'
-    }
-}],
-
 'Document': [
 {
     'nativeType': 'nsIDocument',
     'prefable': True,
     'castable': False
 },
 {
     'workers': True,
@@ -386,21 +352,17 @@ def addExternalIface(iface, nativeType=N
 def addExternalHTMLElement(element):
    nativeElement = 'ns' + element
    addExternalIface(element, nativeType=nativeElement,
                     headerFile=nativeElement + '.h')
 
 addExternalHTMLElement('HTMLCanvasElement')
 addExternalHTMLElement('HTMLImageElement')
 addExternalHTMLElement('HTMLVideoElement')
-addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h')
-addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h')
-addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
-addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLContextAttributes', nativeType='JSObject',
                  headerFile='jsapi.h')
 addExternalIface('WebGLExtension', nativeType='nsIWebGLExtension',
                  headerFile='WebGLContext.h')
@@ -412,10 +374,8 @@ addExternalIface('WebGLRenderbuffer', na
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLShader', nativeType='mozilla::WebGLShader',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLShaderPrecisionFormat',
                  nativeType='mozilla::WebGLShaderPrecisionFormat',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture',
                  headerFile='WebGLContext.h')
-addExternalIface('Window')
-addExternalIface('XULElement')
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -70,17 +70,16 @@ EXPORTS_$(binding_include_path) = \
   BindingUtils.h \
   UnionTypes.h \
   UnionConversions.h \
   $(exported_binding_headers) \
   $(NULL)
 
 LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
   -I$(topsrcdir)/js/xpconnect/wrappers \
-  -I$(topsrcdir)/content/canvas/src \
   -I$(topsrcdir)/content/html/content/src
 
 include $(topsrcdir)/config/rules.mk
 
 # If you change bindinggen_dependencies here, change it in
 # dom/bindings/test/Makefile.in too.
 bindinggen_dependencies := \
   BindingGen.py \
--- a/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
+++ b/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
@@ -41,19 +41,17 @@ interface nsIDOMImageData : nsISupports
 [scriptable, uuid(c835c768-2dcc-461c-82f5-3653710d2942)]
 interface nsIDOMCanvasRenderingContext2D : nsISupports
 {
   // back-reference to the canvas element for which
   // this context was created
   readonly attribute nsIDOMHTMLCanvasElement canvas;
 
   // state
-  [binaryname(MozSave)]
   void save();
-  [binaryname(MozRestore)]
   void restore();
 
   // transformations
   void scale(in float x, in float y);
   void rotate(in float angle);
   void translate(in float x, in float y);
   void transform(in float m11, in float m12, in float m21, in float m22, in float dx, in float dy);
   void setTransform(in float m11, in float m12, in float m21, in float m22, in float dx, in float dy);
@@ -90,74 +88,62 @@ enum CanvasMultiGetterType {
 
   //attribute DOMString fillRule;
   attribute DOMString mozFillRule; /* "evenodd", "nonzero" (default) */
 
   nsIDOMCanvasGradient createLinearGradient (in float x0, in float y0, in float x1, in float y1);
   nsIDOMCanvasGradient createRadialGradient(in float x0, in float y0, in float r0, in float x1, in float y1, in float r1);
   nsIDOMCanvasPattern createPattern(in nsIDOMHTMLElement image, [Null(Stringify)] in DOMString repetition);
   attribute float lineWidth; /* default 1 */
-  [binaryname(MozLineCap)]
   attribute DOMString lineCap; /* "butt", "round", "square" (default) */
-  [binaryname(MozLineJoin)]
   attribute DOMString lineJoin; /* "round", "bevel", "miter" (default) */
   attribute float miterLimit; /* default 10 */
 
   [implicit_jscontext]
   attribute jsval mozDash; /* default |null| */
   attribute float mozDashOffset; /* default 0.0 */
 
   // shadows
   attribute float shadowOffsetX;
   attribute float shadowOffsetY;
   attribute float shadowBlur;
-  [binaryname(MozShadowColor)]
   attribute DOMString shadowColor;
 
   // rects
   void clearRect(in float x, in float y, in float w, in float h);
   void fillRect(in float x, in float y, in float w, in float h);
   void strokeRect(in float x, in float y, in float w, in float h);
 
   // path API
-  [binaryname(MozBeginPath)]
   void beginPath();
-  [binaryname(MozClosePath)]
   void closePath();
 
   void moveTo(in float x, in float y);
   void lineTo(in float x, in float y);
   void quadraticCurveTo(in float cpx, in float cpy, in float x, in float y);
   void bezierCurveTo(in float cp1x, in float cp1y, in float cp2x, in float cp2y, in float x, in float y);
   void arcTo(in float x1, in float y1, in float x2, in float y2, in float radius);
   void arc(in float x, in float y, in float r, in float startAngle, in float endAngle, [optional] in boolean anticlockwise);
   void rect(in float x, in float y, in float w, in float h);
 
-  [binaryname(MozFill)]
   void fill();
-  [binaryname(MozStroke)]
   void stroke();
-  [binaryname(MozClip)]
   void clip();
 
   // text api
-  [binaryname(MozFont)]
   attribute DOMString font; /* default "10px sans-serif" */
-  [binaryname(MozTextAlign)]
   attribute DOMString textAlign; /* "start" (default), "end", "left", "right",
                                  "center" */
-  [binaryname(MozTextBaseline)]
   attribute DOMString textBaseline; /* "alphabetic" (default), "top", "hanging",
                                     "middle", "ideographic", "bottom" */
 
   void fillText(in DOMString text, in float x, in float y, [optional] in float maxWidth);
   void strokeText(in DOMString text, in float x, in float y, [optional] in float maxWidth);
   nsIDOMTextMetrics measureText(in DOMString text);
 
-  [binaryname(TextStyle)]
   attribute DOMString mozTextStyle;
 
   // image api
 
   [optional_argc] void drawImage(in nsIDOMElement image,
                                  in float a1, in float a2,
                                  [optional] in float a3,
                                  [optional] in float a4,
deleted file mode 100644
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ /dev/null
@@ -1,210 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * http://www.whatwg.org/specs/web-apps/current-work/
- *
- * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
- * Opera Software ASA. You are granted a license to use, reproduce
- * and create derivative works of this document.
- */
-
-interface CanvasGradient;
-interface CanvasPattern;
-interface HitRegionOptions;
-interface HTMLCanvasElement;
-interface HTMLImageElement;
-interface HTMLVideoElement;
-interface ImageData;
-interface TextMetrics;
-interface Window;
-interface XULElement;
-
-interface CanvasRenderingContext2D {
-
-  // back-reference to the canvas
-  readonly attribute HTMLCanvasElement canvas;
-
-  // state
-  void save(); // push state on state stack
-  void restore(); // pop state stack and restore state
-
-  // transformations (default transform is the identity matrix)
-// NOT IMPLEMENTED           attribute SVGMatrix currentTransform;
-  void scale(double x, double y);
-  void rotate(double angle);
-  void translate(double x, double y);
-  void transform(double a, double b, double c, double d, double e, double f);
-  void setTransform(double a, double b, double c, double d, double e, double f);
-// NOT IMPLEMENTED  void resetTransform();
-
-  // compositing
-           attribute double globalAlpha; // (default 1.0)
-           attribute DOMString globalCompositeOperation; // (default source-over)
-
-  // colors and styles (see also the CanvasDrawingStyles interface)
-           attribute any strokeStyle; // (default black)
-           attribute any fillStyle; // (default black)
-  CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1);
-  CanvasGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1);
-  CanvasPattern createPattern((HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) image, DOMString repetition);
-
-  // shadows
-           attribute double shadowOffsetX; // (default 0)
-           attribute double shadowOffsetY; // (default 0)
-           attribute double shadowBlur; // (default 0)
-           attribute DOMString shadowColor; // (default transparent black)
-
-  // rects
-  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);
-
-  // path API (see also CanvasPathMethods)
-  void beginPath();
-  void fill();
-// NOT IMPLEMENTED  void fill(Path path);
-  void stroke();
-// NOT IMPLEMENTED  void stroke(Path path);
-// NOT IMPLEMENTED  void drawSystemFocusRing(Element element);
-// NOT IMPLEMENTED  void drawSystemFocusRing(Path path, Element element);
-// NOT IMPLEMENTED  boolean drawCustomFocusRing(Element element);
-// NOT IMPLEMENTED  boolean drawCustomFocusRing(Path path, Element element);
-// NOT IMPLEMENTED  void scrollPathIntoView();
-// NOT IMPLEMENTED  void scrollPathIntoView(Path path);
-  void clip();
-// NOT IMPLEMENTED  void clip(Path path);
-// NOT IMPLEMENTED  void resetClip();
-  boolean isPointInPath(double x, double y);
-// NOT IMPLEMENTED  boolean isPointInPath(Path path, double x, double y);
-
-  // text (see also the CanvasDrawingStyles interface)
-  void fillText(DOMString text, double x, double y, optional double maxWidth);
-  void strokeText(DOMString text, double x, double y, optional double maxWidth);
-  TextMetrics measureText(DOMString text);
-
-  // drawing images
-// NOT IMPLEMENTED           attribute boolean imageSmoothingEnabled; // (default true)
-  void drawImage((HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) image, double dx, double dy);
-  void drawImage((HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) image, double dx, double dy, double dw, double dh);
-  void drawImage((HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh);
-
-  // hit regions
-// NOT IMPLEMENTED  void addHitRegion(HitRegionOptions options);
-
-  // pixel manipulation
-  [Creator] ImageData createImageData(double sw, double sh);
-  [Creator] ImageData createImageData(ImageData imagedata);
-  [Creator] ImageData getImageData(double sx, double sy, double sw, double sh);
-  void putImageData(ImageData imagedata, double dx, double dy);
-  void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
-
-  // Mozilla-specific stuff
-  // FIXME Bug 768048 mozCurrentTransform/mozCurrentTransformInverse should return a WebIDL array.
-  attribute object mozCurrentTransform; // [ m11, m12, m21, m22, dx, dy ], i.e. row major
-  attribute object mozCurrentTransformInverse;
-  attribute DOMString mozFillRule; /* "evenodd", "nonzero" (default) */
-  attribute any mozDash; /* default |null| */
-  attribute double mozDashOffset; /* default 0.0 */
-  attribute DOMString mozTextStyle;
-
-  // image smoothing mode -- if disabled, images won't be smoothed
-  // if scaled.
-  attribute boolean mozImageSmoothingEnabled;
-
-  // Show the caret if appropriate when drawing
-  const unsigned long DRAWWINDOW_DRAW_CARET   = 0x01;
-  // Don't flush pending layout notifications that could otherwise
-  // be batched up
-  const unsigned long DRAWWINDOW_DO_NOT_FLUSH = 0x02;
-  // Draw scrollbars and scroll the viewport if they are present
-  const unsigned long DRAWWINDOW_DRAW_VIEW    = 0x04;
-  // Use the widget layer manager if available. This means hardware
-  // acceleration may be used, but it might actually be slower or
-  // lower quality than normal. It will however more accurately reflect
-  // the pixels rendered to the screen.
-  const unsigned long DRAWWINDOW_USE_WIDGET_LAYERS = 0x08;
-  // Don't synchronously decode images - draw what we have
-  const unsigned long DRAWWINDOW_ASYNC_DECODE_IMAGES = 0x10;
-
-  /**
-   * Renders a region of a window into the canvas.  The contents of
-   * the window's viewport are rendered, ignoring viewport clipping
-   * and scrolling.
-   *
-   * @param x
-   * @param y
-   * @param w
-   * @param h specify the area of the window to render, in CSS
-   * pixels.
-   *
-   * @param backgroundColor the canvas is filled with this color
-   * before we render the window into it. This color may be
-   * transparent/translucent. It is given as a CSS color string
-   * (e.g., rgb() or rgba()).
-   *
-   * @param flags Used to better control the drawWindow call.
-   * Flags can be ORed together.
-   *
-   * Of course, the rendering obeys the current scale, transform and
-   * globalAlpha values.
-   *
-   * Hints:
-   * -- If 'rgba(0,0,0,0)' is used for the background color, the
-   * drawing will be transparent wherever the window is transparent.
-   * -- Top-level browsed documents are usually not transparent
-   * because the user's background-color preference is applied,
-   * but IFRAMEs are transparent if the page doesn't set a background.
-   * -- If an opaque color is used for the background color, rendering
-   * will be faster because we won't have to compute the window's
-   * transparency.
-   *
-   * This API cannot currently be used by Web content. It is chrome
-   * only.
-   * FIXME Bug 767931 - Mark drawWindow and asyncDrawXULElement as ChromeOnly
-   *                    in WebIDL
-   */
-  void drawWindow(Window window, double x, double y, double w, double h,
-                  DOMString bgColor, optional unsigned long flags = 0);
-  void asyncDrawXULElement(XULElement elem, double x, double y, double w,
-                           double h, DOMString bgColor,
-                           optional unsigned long flags = 0);
-};
-CanvasRenderingContext2D implements CanvasDrawingStyles;
-CanvasRenderingContext2D implements CanvasPathMethods;
-
-[NoInterfaceObject]
-interface CanvasDrawingStyles {
-  // line caps/joins
-           attribute double lineWidth; // (default 1)
-           attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
-           attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
-           attribute double miterLimit; // (default 10)
-
-  // dashed lines
-// NOT IMPLEMENTED    void setLineDash(sequence<double> segments); // default empty
-// NOT IMPLEMENTED    sequence<double> getLineDash();
-// NOT IMPLEMENTED             attribute double lineDashOffset;
-
-  // text
-           attribute DOMString font; // (default 10px sans-serif)
-           attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
-           attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
-};
-
-[NoInterfaceObject]
-interface CanvasPathMethods {
-  // shared path API methods
-  void closePath();
-  void moveTo(double x, double y);
-  void lineTo(double x, double y);
-  void quadraticCurveTo(double cpx, double cpy, double x, double y);
-  void bezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y);
-  void arcTo(double x1, double y1, double x2, double y2, double radius); 
-// NOT IMPLEMENTED  void arcTo(double x1, double y1, double x2, double y2, double radiusX, double radiusY, double rotation);
-  void rect(double x, double y, double w, double h);
-  void arc(double x, double y, double radius, double startAngle, double endAngle, optional boolean anticlockwise = false); 
-// NOT IMPLEMENTED  void ellipse(double x, double y, double radiusX, double radiusY, double rotation, double startAngle, double endAngle, boolean anticlockwise);
-};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -1,16 +1,15 @@
 # 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/.
 
 webidl_base = $(topsrcdir)/dom/webidl
 
 webidl_files = \
-  CanvasRenderingContext2D.webidl \
   Function.webidl \
   EventListener.webidl \
   EventTarget.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
   XMLHttpRequestUpload.webidl \
   WebGLRenderingContext.webidl \
   $(NULL)