Bug 651858 - Part 1: Add the Azure API and Direct2D backend. r=jrmuizel sr=roc
authorBas Schouten <bschouten@mozilla.com>
Fri, 24 Jun 2011 19:41:16 +0200
changeset 72228 4ede291d2e4c9dff7e75c2062db29e62f8e81984
parent 72227 c65f1fb0449d470709639c9bba937021f2756b55
child 72229 95039cfae6a3d88fe0b906e97c9657f4557d38c4
push id159
push usereakhgari@mozilla.com
push dateTue, 16 Aug 2011 17:53:11 +0000
treeherdermozilla-beta@8786e3e49240 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, roc
bugs651858
milestone7.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 651858 - Part 1: Add the Azure API and Direct2D backend. r=jrmuizel sr=roc
gfx/2d/2D.h
gfx/2d/BaseMargin.h
gfx/2d/BasePoint.h
gfx/2d/BaseRect.h
gfx/2d/BaseSize.h
gfx/2d/DrawTargetCG.cpp
gfx/2d/DrawTargetCG.h
gfx/2d/DrawTargetCairo.cpp
gfx/2d/DrawTargetCairo.h
gfx/2d/DrawTargetD2D.cpp
gfx/2d/DrawTargetD2D.h
gfx/2d/Factory.cpp
gfx/2d/GradientStopsD2D.h
gfx/2d/HelpersD2D.h
gfx/2d/Logging.h
gfx/2d/Makefile.in
gfx/2d/Matrix.cpp
gfx/2d/Matrix.h
gfx/2d/PathD2D.cpp
gfx/2d/PathD2D.h
gfx/2d/Point.h
gfx/2d/Rect.h
gfx/2d/ScaledFontDWrite.cpp
gfx/2d/ScaledFontDWrite.h
gfx/2d/ShadersD2D.fx
gfx/2d/ShadersD2D.h
gfx/2d/SourceSurfaceCG.cpp
gfx/2d/SourceSurfaceCG.h
gfx/2d/SourceSurfaceCairo.cpp
gfx/2d/SourceSurfaceCairo.h
gfx/2d/SourceSurfaceD2D.cpp
gfx/2d/SourceSurfaceD2D.h
gfx/2d/SourceSurfaceD2DTarget.cpp
gfx/2d/SourceSurfaceD2DTarget.h
gfx/2d/Tools.h
gfx/2d/Types.h
gfx/2d/gfx2d.sln
gfx/2d/gfx2d.vcxproj
gfx/Makefile.in
gfx/src/BaseMargin.h
gfx/src/BasePoint.h
gfx/src/BaseRect.h
gfx/src/BaseSize.h
gfx/src/Makefile.in
gfx/src/gfxCore.h
gfx/src/nsMargin.h
gfx/src/nsPoint.h
gfx/src/nsRect.h
gfx/src/nsSize.h
gfx/thebes/gfxPoint.h
gfx/thebes/gfxRect.h
layout/tables/celldata.h
toolkit/library/libxul-config.mk
new file mode 100644
--- /dev/null
+++ b/gfx/2d/2D.h
@@ -0,0 +1,668 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _MOZILLA_GFX_2D_H
+#define _MOZILLA_GFX_2D_H
+
+#include "Point.h"
+#include "Rect.h"
+#include "Matrix.h"
+
+// This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
+// outparams using the &-operator. But it will have to do as there's no easy
+// solution.
+#include "mozilla/RefPtr.h"
+
+struct _cairo_surface;
+typedef _cairo_surface cairo_surface_t;
+
+struct ID3D10Device1;
+struct ID3D10Texture2D;
+
+namespace mozilla {
+namespace gfx {
+
+class SourceSurface;
+class DataSourceSurface;
+class DrawTarget;
+
+struct NativeSurface {
+  NativeSurfaceType mType;
+  SurfaceFormat mFormat;
+  void *mSurface;
+};
+
+struct NativeFont {
+  NativeFontType mType;
+  void *mFont;
+};
+
+/*
+ * This structure is used to send draw options that are universal to all drawing
+ * operations. It consists of the following:
+ *
+ * mAlpha         - Alpha value by which the mask generated by this operation is
+ *                  multiplied.
+ * mCompositionOp - The operator that indicates how the source and destination
+ *                  patterns are blended.
+ * mAntiAliasMode - The AntiAlias mode used for this drawing operation.
+ * mSnapping      - Whether this operation is snapped to pixel boundaries.
+ */
+struct DrawOptions {
+  DrawOptions(Float aAlpha = 1.0f,
+              CompositionOp aCompositionOp = OP_OVER,
+              AntialiasMode aAntialiasMode = AA_GRAY,
+              Snapping aSnapping = SNAP_NONE)
+    : mAlpha(aAlpha)
+    , mCompositionOp(aCompositionOp)
+    , mAntialiasMode(aAntialiasMode)
+    , mSnapping(aSnapping)
+  {}
+
+  Float mAlpha;
+  CompositionOp mCompositionOp : 8;
+  AntialiasMode mAntialiasMode : 2;
+  Snapping mSnapping : 1;
+};
+
+/*
+ * This structure is used to send stroke options that are used in stroking
+ * operations. It consists of the following:
+ *
+ * mLineWidth    - Width of the stroke in userspace.
+ * mLineJoin     - Join style used for joining lines.
+ * mLineCap      - Cap style used for capping lines.
+ * mMiterLimit   - Miter limit in units of linewidth
+ */
+struct StrokeOptions {
+  StrokeOptions(Float aLineWidth = 1.0f,
+                JoinStyle aLineJoin = JOIN_MITER_OR_BEVEL,
+                CapStyle aLineCap = CAP_BUTT,
+                Float aMiterLimit = 10.0f)
+    : mLineWidth(aLineWidth)
+    , mMiterLimit(aMiterLimit)
+    , mLineJoin(aLineJoin)
+    , mLineCap(aLineCap)
+  {}
+
+  Float mLineWidth;
+  Float mMiterLimit;
+  JoinStyle mLineJoin : 4;
+  CapStyle mLineCap : 3;
+};
+
+/*
+ * This structure supplies additional options for calls to DrawSurface.
+ *
+ * mFilter - Filter used when resampling source surface region to the
+ *           destination region.
+ */
+struct DrawSurfaceOptions {
+  DrawSurfaceOptions(Filter aFilter = FILTER_LINEAR)
+    : mFilter(aFilter)
+  { }
+
+  Filter mFilter : 3;
+};
+
+/*
+ * This class is used to store gradient stops, it can only be used with a
+ * matching DrawTarget. Not adhering to this condition will make a draw call
+ * fail.
+ */
+class GradientStops : public RefCounted<GradientStops>
+{
+public:
+  virtual ~GradientStops() {}
+
+  virtual BackendType GetBackendType() const = 0;
+
+protected:
+  GradientStops() {}
+};
+
+/*
+ * This is the base class for 'patterns'. Patterns describe the pixels used as
+ * the source for a masked composition operation that is done by the different
+ * drawing commands. These objects are not backend specific, however for
+ * example the gradient stops on a gradient pattern can be backend specific.
+ */
+class Pattern
+{
+public:
+  virtual ~Pattern() {}
+
+  virtual PatternType GetType() const = 0;
+
+protected:
+  Pattern() {}
+};
+
+class ColorPattern : public Pattern
+{
+public:
+  ColorPattern(const Color &aColor)
+    : mColor(aColor)
+  {}
+
+  virtual PatternType GetType() const { return PATTERN_COLOR; }
+
+  Color mColor;
+};
+
+/*
+ * This class is used for Linear Gradient Patterns, the gradient stops are
+ * stored in a separate object and are backend dependent. This class itself
+ * may be used on the stack.
+ */
+class LinearGradientPattern : public Pattern
+{
+public:
+  /*
+   * aBegin Start of the linear gradient
+   * aEnd End of the linear gradient
+   * aStops GradientStops object for this gradient, this should match the
+   *        backend type of the draw target this pattern will be used with.
+   */
+  LinearGradientPattern(const Point &aBegin,
+                        const Point &aEnd,
+                        GradientStops *aStops)
+    : mBegin(aBegin)
+    , mEnd(aEnd)
+    , mStops(aStops)
+  {
+  }
+
+  virtual PatternType GetType() const { return PATTERN_LINEAR_GRADIENT; }
+
+  Point mBegin;
+  Point mEnd;
+  RefPtr<GradientStops> mStops;
+};
+
+/*
+ * This class is used for Radial Gradient Patterns, the gradient stops are
+ * stored in a separate object and are backend dependent. This class itself
+ * may be used on the stack.
+ */
+class RadialGradientPattern : public Pattern
+{
+public:
+  /*
+   * aBegin Start of the linear gradient
+   * aEnd End of the linear gradient
+   * aStops GradientStops object for this gradient, this should match the
+   *        backend type of the draw target this pattern will be used with.
+   */
+  RadialGradientPattern(const Point &aCenter,
+                        const Point &aOrigin,
+                        Float aRadius,
+                        GradientStops *aStops)
+    : mCenter(aCenter)
+    , mOrigin(aOrigin)
+    , mRadius(aRadius)
+    , mStops(aStops)
+  {
+  }
+
+  virtual PatternType GetType() const { return PATTERN_RADIAL_GRADIENT; }
+
+  Point mCenter;
+  Point mOrigin;
+  Float mRadius;
+  RefPtr<GradientStops> mStops;
+};
+
+/*
+ * This class is used for Surface Patterns, they wrap a surface and a
+ * repetition mode for the surface. This may be used on the stack.
+ */
+class SurfacePattern : public Pattern
+{
+public:
+  SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode)
+    : mSurface(aSourceSurface)
+    , mExtendMode(aExtendMode)
+  {}
+
+  virtual PatternType GetType() const { return PATTERN_SURFACE; }
+
+  RefPtr<SourceSurface> mSurface;
+  ExtendMode mExtendMode;
+  Filter mFilter;
+};
+
+/*
+ * This is the base class for source surfaces. These objects are surfaces
+ * which may be used as a source in a SurfacePattern of a DrawSurface call.
+ * They cannot be drawn to directly.
+ */
+class SourceSurface : public RefCounted<SourceSurface>
+{
+public:
+  virtual ~SourceSurface() {}
+
+  virtual SurfaceType GetType() const = 0;
+  virtual IntSize GetSize() const = 0;
+  virtual SurfaceFormat GetFormat() const = 0;
+
+  /*
+   * This function will get a DataSourceSurface for this surface, a
+   * DataSourceSurface's data can be accessed directly.
+   */
+  virtual TemporaryRef<DataSourceSurface> GetDataSurface() = 0;
+};
+
+class DataSourceSurface : public SourceSurface
+{
+public:
+  /* Get the raw bitmap data of the surface */
+  virtual unsigned char *GetData() = 0;
+  /*
+   * Stride of the surface, distance in bytes between the start of the image
+   * data belonging to row y and row y+1. This may be negative.
+   */
+  virtual int32_t Stride() = 0;
+
+  virtual TemporaryRef<DataSourceSurface> GetDataSurface() { RefPtr<DataSourceSurface> temp = this; return temp.forget(); }
+};
+
+/* This is an abstract object that accepts path segments. */
+class PathSink : public RefCounted<PathSink>
+{
+public:
+  virtual ~PathSink() {}
+
+  /* Move the current point in the path, any figure currently being drawn will
+   * be considered closed during fill operations, however when stroking the
+   * closing line segment will not be drawn.
+   */
+  virtual void MoveTo(const Point &aPoint) = 0;
+  /* Add a linesegment to the current figure */
+  virtual void LineTo(const Point &aPoint) = 0;
+  /* Add a cubic bezier curve to the current figure */
+  virtual void BezierTo(const Point &aCP1,
+                        const Point &aCP2,
+                        const Point &aCP3) = 0;
+  /* Add a quadratic bezier curve to the current figure */
+  virtual void QuadraticBezierTo(const Point &aCP1,
+                                 const Point &aCP2) = 0;
+  /* Close the current figure, this will essentially generate a line segment
+   * from the current point to the starting point for the current figure
+   */
+  virtual void Close() = 0;
+  /* Add an arc to the current figure */
+  virtual void Arc(const Point &aOrigin, float aRadius, float aStartAngle,
+                   float aEndAngle, bool aAntiClockwise = false) = 0;
+  /* Point the current subpath is at - or where the next subpath will start
+   * if there is no active subpath.
+   */
+  virtual Point CurrentPoint() const = 0;
+};
+
+class PathBuilder;
+
+/* The path class is used to create (sets of) figures of any shape that can be
+ * filled or stroked to a DrawTarget
+ */
+class Path : public RefCounted<Path>
+{
+public:
+  virtual ~Path() {}
+  
+  virtual BackendType GetBackendType() const = 0;
+
+  /* This returns a PathBuilder object that contains a copy of the contents of
+   * this path and is still writable.
+   */
+  virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FILL_WINDING) const = 0;
+  virtual TemporaryRef<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
+                                                             FillRule aFillRule = FILL_WINDING) const = 0;
+
+  /* This function checks if a point lies within a path. It allows passing a
+   * transform that will transform the path to the coordinate space in which
+   * aPoint is given.
+   */
+  virtual bool ContainsPoint(const Point &aPoint, const Matrix &aTransform) const = 0;
+
+  /* This gets the fillrule this path's builder was created with. This is not
+   * mutable.
+   */
+  virtual FillRule GetFillRule() const = 0;
+};
+
+/* The PathBuilder class allows path creation. Once finish is called on the
+ * pathbuilder it may no longer be written to.
+ */
+class PathBuilder : public PathSink
+{
+public:
+  /* Finish writing to the path and return a Path object that can be used for
+   * drawing. Future use of the builder results in a crash!
+   */
+  virtual TemporaryRef<Path> Finish() = 0;
+};
+
+struct Glyph
+{
+  uint32_t mIndex;
+  Point mPosition;
+};
+
+/* This class functions as a glyph buffer that can be drawn to a DrawTarget.
+ * XXX - This should probably contain the guts of gfxTextRun in the future as
+ * roc suggested. But for now it's a simple container for a glyph vector.
+ */
+struct GlyphBuffer
+{
+  // A pointer to a buffer of glyphs. Managed by the caller.
+  const Glyph *mGlyphs;
+  // Number of glyphs mGlyphs points to.
+  uint32_t mNumGlyphs;
+};
+
+/* This class is an abstraction of a backend/platform specific font object
+ * at a particular size. It is passed into text drawing calls to describe
+ * the font used for the drawing call.
+ */
+class ScaledFont : public RefCounted<ScaledFont>
+{
+public:
+  virtual ~ScaledFont() {}
+
+  virtual FontType GetType() const = 0;
+
+  /* This allows getting a path that describes the outline of a set of glyphs.
+   * A target is passed in so that the guarantee is made the returned path
+   * can be used with any DrawTarget that has the same backend as the one
+   * passed in.
+   */
+  virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) = 0;
+
+protected:
+  ScaledFont() {}
+};
+
+/* This is the main class used for all the drawing. It is created through the
+ * factory and accepts drawing commands. The results of drawing to a target
+ * may be used either through a Snapshot or by flushing the target and directly
+ * accessing the backing store a DrawTarget was created with.
+ */
+class DrawTarget : public RefCounted<DrawTarget>
+{
+public:
+  DrawTarget() : mTransformDirty(false) {}
+  virtual ~DrawTarget() {}
+
+  virtual BackendType GetType() const = 0;
+  virtual TemporaryRef<SourceSurface> Snapshot() = 0;
+  virtual IntSize GetSize() = 0;
+
+  /* Ensure that the DrawTarget backend has flushed all drawing operations to
+   * this draw target. This must be called before using the backing surface of
+   * this draw target outside of GFX 2D code.
+   */
+  virtual void Flush() = 0;
+
+  /*
+   * Draw a surface to the draw target. Possibly doing partial drawing or
+   * applying scaling. No sampling happens outside the source.
+   *
+   * aSurface Source surface to draw
+   * aDest Destination rectangle that this drawing operation should draw to
+   * aSource Source rectangle in aSurface coordinates, this area of aSurface
+   *         will be stretched to the size of aDest.
+   * aOptions General draw options that are applied to the operation
+   * aSurfOptions DrawSurface options that are applied
+   */
+  virtual void DrawSurface(SourceSurface *aSurface,
+                           const Rect &aDest,
+                           const Rect &aSource,
+                           const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
+                           const DrawOptions &aOptions = DrawOptions()) = 0;
+
+  /*
+   * Blend a surface to the draw target with a shadow. The shadow is drawn as a
+   * gaussian blur using a specified sigma.
+   * NOTE: This function works in device space!
+   *
+   * aSurface Source surface to draw.
+   * aDest Destination point that this drawing operation should draw to.
+   * aColor Color of the drawn shadow
+   * aOffset Offset of the shadow
+   * aSigma Sigma used for the guassian filter kernel
+   */
+  virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
+                                     const Point &aDest,
+                                     const Color &aColor,
+                                     const Point &aOffset,
+                                     Float aSigma) = 0;
+
+  /* 
+   * Clear a rectangle on the draw target to transparent black. This will
+   * respect the clipping region and transform.
+   *
+   * aRect Rectangle to clear
+   */
+  virtual void ClearRect(const Rect &aRect) = 0;
+
+  /*
+   * This is essentially a 'memcpy' between two surfaces. It moves a pixel
+   * aligned area from the source surface unscaled directly onto the
+   * drawtarget. This ignores both transform and clip.
+   *
+   * aSurface Surface to copy from
+   * aSourceRect Source rectangle to be copied
+   * aDest Destination point to copy the surface to
+   */
+  virtual void CopySurface(SourceSurface *aSurface,
+                           const IntRect &aSourceRect,
+                           const IntPoint &aDestination) = 0;
+
+  /*
+   * Fill a rectangle on the DrawTarget with a certain source pattern.
+   *
+   * aRect Rectangle that forms the mask of this filling operation
+   * aPattern Pattern that forms the source of this filling operation
+   * aOptions Options that are applied to this operation
+   */
+  virtual void FillRect(const Rect &aRect,
+                        const Pattern &aPattern,
+                        const DrawOptions &aOptions = DrawOptions()) = 0;
+
+  /*
+   * Stroke a rectangle on the DrawTarget with a certain source pattern.
+   *
+   * aRect Rectangle that forms the mask of this stroking operation
+   * aPattern Pattern that forms the source of this stroking operation
+   * aOptions Options that are applied to this operation
+   */
+  virtual void StrokeRect(const Rect &aRect,
+                          const Pattern &aPattern,
+                          const StrokeOptions &aStrokeOptions = StrokeOptions(),
+                          const DrawOptions &aOptions = DrawOptions()) = 0;
+
+  /*
+   * Stroke a line on the DrawTarget with a certain source pattern.
+   *
+   * aStart Starting point of the line
+   * aEnd End point of the line
+   * aPattern Pattern that forms the source of this stroking operation
+   * aOptions Options that are applied to this operation
+   */
+  virtual void StrokeLine(const Point &aStart,
+                          const Point &aEnd,
+                          const Pattern &aPattern,
+                          const StrokeOptions &aStrokeOptions = StrokeOptions(),
+                          const DrawOptions &aOptions = DrawOptions()) = 0;
+
+  /*
+   * Stroke a path on the draw target with a certain source pattern.
+   *
+   * aPath Path that is to be stroked
+   * aPattern Pattern that should be used for the stroke
+   * aStrokeOptions Stroke options used for this operation
+   * aOptions Draw options used for this operation
+   */
+  virtual void Stroke(const Path *aPath,
+                      const Pattern &aPattern,
+                      const StrokeOptions &aStrokeOptions = StrokeOptions(),
+                      const DrawOptions &aOptions = DrawOptions()) = 0;
+  
+  /*
+   * Fill a path on the draw target with a certain source pattern.
+   *
+   * aPath Path that is to be filled
+   * aPattern Pattern that should be used for the fill
+   * aOptions Draw options used for this operation
+   */
+  virtual void Fill(const Path *aPath,
+                    const Pattern &aPattern,
+                    const DrawOptions &aOptions = DrawOptions()) = 0;
+
+  /*
+   * Fill a series of clyphs on the draw target with a certain source pattern.
+   */
+  virtual void FillGlyphs(ScaledFont *aFont,
+                          const GlyphBuffer &aBuffer,
+                          const Pattern &aPattern,
+                          const DrawOptions &aOptions = DrawOptions()) = 0;
+
+  /*
+   * Push a clip to the DrawTarget.
+   *
+   * aPath The path to clip to
+   */
+  virtual void PushClip(const Path *aPath) = 0;
+
+  /* Pop a clip from the DrawTarget. A pop without a corresponding push will
+   * be ignored.
+   */
+  virtual void PopClip() = 0;
+
+  /*
+   * Create a SourceSurface optimized for use with this DrawTarget for
+   * existing bitmap data in memory.
+   */
+  virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
+                                                            const IntSize &aSize,
+                                                            int32_t aStride,
+                                                            SurfaceFormat aFormat) const = 0;
+
+  /*
+   * Create a SourceSurface optimized for use with this DrawTarget from
+   * an arbitrary other SourceSurface. This may return aSourceSurface or some
+   * other existing surface.
+   */
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const = 0;
+
+  /*
+   * Create a SourceSurface for a type of NativeSurface. This may fail if the
+   * draw target does not know how to deal with the type of NativeSurface passed
+   * in.
+   */
+  virtual TemporaryRef<SourceSurface>
+    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const = 0;
+
+  /*
+   * Create a DrawTarget whose snapshot is optimized for use with this DrawTarget.
+   */
+  virtual TemporaryRef<DrawTarget>
+    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const = 0;
+
+  /*
+   * Create a path builder with the specified fillmode.
+   */
+  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const = 0;
+
+  /*
+   * Create a GradientStops object that holds information about a set of
+   * gradient stops, this object is required for linear or radial gradient
+   * patterns to represent the color stops in the gradient.
+   *
+   * aStops An array of gradient stops
+   * aNumStops Number of stops in the array aStops
+   */
+  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const = 0;
+
+  const Matrix &GetTransform() const { return mTransform; }
+
+  /*
+   * Set a transform on the surface, this transform is applied at drawing time
+   * to both the mask and source of the operation.
+   */
+  virtual void SetTransform(const Matrix &aTransform)
+    { mTransform = aTransform; mTransformDirty = true; }
+
+  SurfaceFormat GetFormat() { return mFormat; }
+
+  /* Tries to get a native surface for a DrawTarget, this may fail if the
+   * draw target cannot convert to this surface type.
+   */
+  virtual void *GetNativeSurface(NativeSurfaceType aType) = 0;
+
+protected:
+  Matrix mTransform;
+  bool mTransformDirty : 1;
+
+  SurfaceFormat mFormat;
+};
+
+class Factory
+{
+public:
+#ifdef USE_CAIRO
+  static TemporaryRef<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface);
+#endif
+
+  static TemporaryRef<DrawTarget> CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
+  static TemporaryRef<ScaledFont> CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);
+
+#ifdef WIN32
+  static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
+  static void SetDirect3D10Device(ID3D10Device1 *aDevice);
+  static ID3D10Device1 *GetDirect3D10Device();
+
+private:
+  static ID3D10Device1 *mD3D10Device;
+#endif
+};
+
+}
+}
+
+#endif // _MOZILLA_GFX_2D_H
rename from gfx/src/BaseMargin.h
rename to gfx/2d/BaseMargin.h
--- a/gfx/src/BaseMargin.h
+++ b/gfx/2d/BaseMargin.h
@@ -30,22 +30,23 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#ifndef MOZILLA_BASEMARGIN_H_
-#define MOZILLA_BASEMARGIN_H_
+#ifndef MOZILLA_GFX_BASEMARGIN_H_
+#define MOZILLA_GFX_BASEMARGIN_H_
 
-#include "gfxCore.h"
+#include "Types.h"
 
 namespace mozilla {
+namespace gfx {
 
 /**
  * Do not use this class directly. Subclass it, pass that subclass as the
  * Sub parameter, and only use that subclass.
  */
 template <class T, class Sub>
 struct BaseMargin {
   typedef mozilla::css::Side SideT;
@@ -63,22 +64,20 @@ struct BaseMargin {
   {
     left = aLeft; top = aTop; right = aRight; bottom = aBottom;
   }
 
   T LeftRight() const { return left + right; }
   T TopBottom() const { return top + bottom; }
 
   T& Side(SideT aSide) {
-    NS_PRECONDITION(aSide <= NS_SIDE_LEFT, "Out of range side");
     // This is ugly!
     return *(&top + aSide);
   }
   T Side(SideT aSide) const {
-    NS_PRECONDITION(aSide <= NS_SIDE_LEFT, "Out of range side");
     // This is ugly!
     return *(&top + aSide);
   }
 
   // Overloaded operators. Note that '=' isn't defined so we'll get the
   // compiler generated default assignment operator
   bool operator==(const Sub& aMargin) const {
     return left == aMargin.left && top == aMargin.top &&
@@ -100,10 +99,11 @@ struct BaseMargin {
     top += aMargin.top;
     right += aMargin.right;
     bottom += aMargin.bottom;
     return *static_cast<Sub*>(this);
   }
 };
 
 }
+}
 
-#endif /* MOZILLA_BASEMARGIN_H_ */
+#endif /* MOZILLA_GFX_BASEMARGIN_H_ */
rename from gfx/src/BasePoint.h
rename to gfx/2d/BasePoint.h
--- a/gfx/src/BasePoint.h
+++ b/gfx/2d/BasePoint.h
@@ -30,20 +30,21 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#ifndef MOZILLA_BASEPOINT_H_
-#define MOZILLA_BASEPOINT_H_
+#ifndef MOZILLA_GFX_BASEPOINT_H_
+#define MOZILLA_GFX_BASEPOINT_H_
 
 namespace mozilla {
+namespace gfx {
 
 /**
  * Do not use this class directly. Subclass it, pass that subclass as the
  * Sub parameter, and only use that subclass. This allows methods to safely
  * cast 'this' to 'Sub*'.
  */
 template <class T, class Sub>
 struct BasePoint {
@@ -91,10 +92,11 @@ struct BasePoint {
   }
 
   Sub operator-() const {
     return Sub(-x, -y);
   }
 };
 
 }
+}
 
-#endif /* MOZILLA_BASEPOINT_H_ */
+#endif /* MOZILLA_GFX_BASEPOINT_H_ */
rename from gfx/src/BaseRect.h
rename to gfx/2d/BaseRect.h
--- a/gfx/src/BaseRect.h
+++ b/gfx/2d/BaseRect.h
@@ -30,22 +30,37 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#ifndef MOZILLA_BASERECT_H_
-#define MOZILLA_BASERECT_H_
+#ifndef MOZILLA_GFX_BASERECT_H_
+#define MOZILLA_GFX_BASERECT_H_
 
-#include "nsAlgorithm.h"
+#include <cmath>
 
 namespace mozilla {
+namespace gfx {
+
+// XXX - <algorithm> conflicts with exceptions on 10.6. Define our own gfx_min/gfx_max
+// functions here. Avoid min/max to avoid conflicts with existing #defines on windows.
+template<typename T>
+T gfx_min(T aVal1, T aVal2)
+{
+  return (aVal1 < aVal2) ? aVal1 : aVal2;
+}
+
+template<typename T>
+T gfx_max(T aVal1, T aVal2)
+{
+  return (aVal1 > aVal2) ? aVal1 : aVal2;
+}
 
 /**
  * Rectangles have two interpretations: a set of (zero-size) points,
  * and a rectangular area of the plane. Most rectangle operations behave
  * the same no matter what interpretation is being used, but some operations
  * differ:
  * -- Equality tests behave differently. When a rectangle represents an area,
  * all zero-width and zero-height rectangles are equal to each other since they
@@ -108,33 +123,33 @@ struct BaseRect {
   // Always returns false if aRect is empty or 'this' is empty.
   bool Intersects(const Sub& aRect) const
   {
     return x < aRect.XMost() && aRect.x < XMost() &&
            y < aRect.YMost() && aRect.y < YMost();
   }
   // Returns the rectangle containing the intersection of the points
   // (including edges) of *this and aRect. If there are no points in that
-  // intersection, returns an empty rectangle with x/y set to the max of the x/y
+  // intersection, returns an empty rectangle with x/y set to the gfx_max of the x/y
   // of *this and aRect.
   Sub Intersect(const Sub& aRect) const
   {
     Sub result;
-    result.x = NS_MAX(x, aRect.x);
-    result.y = NS_MAX(y, aRect.y);
-    result.width = NS_MIN(XMost(), aRect.XMost()) - result.x;
-    result.height = NS_MIN(YMost(), aRect.YMost()) - result.y;
+    result.x = gfx_max(x, aRect.x);
+    result.y = gfx_max(y, aRect.y);
+    result.width = gfx_min(XMost(), aRect.XMost()) - result.x;
+    result.height = gfx_min(YMost(), aRect.YMost()) - result.y;
     if (result.width < 0 || result.height < 0) {
       result.SizeTo(0, 0);
     }
     return result;
   }
   // Sets *this to be the rectangle containing the intersection of the points
   // (including edges) of *this and aRect. If there are no points in that
-  // intersection, sets *this to be an empty rectangle with x/y set to the max
+  // intersection, sets *this to be an empty rectangle with x/y set to the gfx_max
   // of the x/y of *this and aRect.
   //
   // 'this' can be the same object as either aRect1 or aRect2
   bool IntersectRect(const Sub& aRect1, const Sub& aRect2)
   {
     *static_cast<Sub*>(this) = aRect1.Intersect(aRect2);
     return !IsEmpty();
   }
@@ -154,20 +169,20 @@ struct BaseRect {
     }
   }
   // Returns the smallest rectangle that contains both the points (including
   // edges) of both aRect1 and aRect2.
   // Thus, empty input rectangles are allowed to affect the result.
   Sub UnionEdges(const Sub& aRect) const
   {
     Sub result;
-    result.x = NS_MIN(x, aRect.x);
-    result.y = NS_MIN(y, aRect.y);
-    result.width = NS_MAX(XMost(), aRect.XMost()) - result.x;
-    result.height = NS_MAX(YMost(), aRect.YMost()) - result.y;
+    result.x = gfx_min(x, aRect.x);
+    result.y = gfx_min(y, aRect.y);
+    result.width = gfx_max(XMost(), aRect.XMost()) - result.x;
+    result.height = gfx_max(YMost(), aRect.YMost()) - result.y;
     return result;
   }
   // Computes the smallest rectangle that contains both the area of both
   // aRect1 and aRect2, and fills 'this' with the result.
   // Thus, empty input rectangles are ignored.
   // If both rectangles are empty, sets 'this' to aRect2.
   //
   // 'this' can be the same object as either aRect1 or aRect2
@@ -218,25 +233,25 @@ struct BaseRect {
   }
   void Inflate(const SizeT& aSize) { Inflate(aSize.width, aSize.height); }
 
   void Deflate(T aD) { Deflate(aD, aD); }
   void Deflate(T aDx, T aDy)
   {
     x += aDx;
     y += aDy;
-    width = NS_MAX(T(0), width - 2 * aDx);
-    height = NS_MAX(T(0), height - 2 * aDy);
+    width = gfx_max(T(0), width - 2 * aDx);
+    height = gfx_max(T(0), height - 2 * aDy);
   }
   void Deflate(const Margin& aMargin)
   {
     x += aMargin.left;
     y += aMargin.top;
-    width = NS_MAX(T(0), width - aMargin.LeftRight());
-    height = NS_MAX(T(0), height - aMargin.TopBottom());
+    width = gfx_max(T(0), width - aMargin.LeftRight());
+    height = gfx_max(T(0), height - aMargin.TopBottom());
   }
   void Deflate(const SizeT& aSize) { Deflate(aSize.width, aSize.height); }
 
   // Return true if the rectangles contain the same set of points, including
   // points on the edges.
   // Use when we care about the exact x/y/width/height values being
   // equal (i.e. we care about differences in empty rectangles).
   bool IsEqualEdges(const Sub& aRect) const
@@ -298,37 +313,37 @@ struct BaseRect {
   // Note: this can turn an empty rectangle into a non-empty rectangle
   void ScaleRoundOut(double aScale) { ScaleRoundOut(aScale, aScale); }
   // Scale 'this' by aXScale and aYScale, converting coordinates to integers so
   // that the result is the smallest integer-coordinate rectangle containing the
   // unrounded result.
   // Note: this can turn an empty rectangle into a non-empty rectangle
   void ScaleRoundOut(double aXScale, double aYScale)
   {
-    T right = static_cast<T>(NS_ceil(double(XMost()) * aXScale));
-    T bottom = static_cast<T>(NS_ceil(double(YMost()) * aYScale));
-    x = static_cast<T>(NS_floor(double(x) * aXScale));
-    y = static_cast<T>(NS_floor(double(y) * aYScale));
+    T right = static_cast<T>(ceil(double(XMost()) * aXScale));
+    T bottom = static_cast<T>(ceil(double(YMost()) * aYScale));
+    x = static_cast<T>(floor(double(x) * aXScale));
+    y = static_cast<T>(floor(double(y) * aYScale));
     width = right - x;
     height = bottom - y;
   }
   // Scale 'this' by aScale, converting coordinates to integers so that the result is
   // the largest integer-coordinate rectangle contained by the unrounded result.
   void ScaleRoundIn(double aScale) { ScaleRoundIn(aScale, aScale); }
   // Scale 'this' by aXScale and aYScale, converting coordinates to integers so
   // that the result is the largest integer-coordinate rectangle contained by the
   // unrounded result.
   void ScaleRoundIn(double aXScale, double aYScale)
   {
-    T right = static_cast<T>(NS_floor(double(XMost()) * aXScale));
-    T bottom = static_cast<T>(NS_floor(double(YMost()) * aYScale));
-    x = static_cast<T>(NS_ceil(double(x) * aXScale));
-    y = static_cast<T>(NS_ceil(double(y) * aYScale));
-    width = NS_MAX<T>(0, right - x);
-    height = NS_MAX<T>(0, bottom - y);
+    T right = static_cast<T>(floor(double(XMost()) * aXScale));
+    T bottom = static_cast<T>(floor(double(YMost()) * aYScale));
+    x = static_cast<T>(ceil(double(x) * aXScale));
+    y = static_cast<T>(ceil(double(y) * aYScale));
+    width = gfx_max<T>(0, right - x);
+    height = gfx_max<T>(0, bottom - y);
   }
   // Scale 'this' by 1/aScale, converting coordinates to integers so that the result is
   // the smallest integer-coordinate rectangle containing the unrounded result.
   // Note: this can turn an empty rectangle into a non-empty rectangle
   void ScaleInverseRoundOut(double aScale) { ScaleInverseRoundOut(aScale, aScale); }
   // Scale 'this' by 1/aXScale and 1/aYScale, converting coordinates to integers so
   // that the result is the smallest integer-coordinate rectangle containing the
   // unrounded result.
@@ -346,10 +361,11 @@ struct BaseRect {
 private:
   // Do not use the default operator== or operator!= !
   // Use IsEqualEdges or IsEqualInterior explicitly.
   bool operator==(const Sub& aRect) const { return false; }
   bool operator!=(const Sub& aRect) const { return false; }
 };
 
 }
+}
 
-#endif /* MOZILLA_BASERECT_H_ */
+#endif /* MOZILLA_GFX_BASERECT_H_ */
rename from gfx/src/BaseSize.h
rename to gfx/2d/BaseSize.h
--- a/gfx/src/BaseSize.h
+++ b/gfx/2d/BaseSize.h
@@ -30,20 +30,21 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#ifndef MOZILLA_BASESIZE_H_
-#define MOZILLA_BASESIZE_H_
+#ifndef MOZILLA_GFX_BASESIZE_H_
+#define MOZILLA_GFX_BASESIZE_H_
 
 namespace mozilla {
+namespace gfx {
 
 /**
  * Do not use this class directly. Subclass it, pass that subclass as the
  * Sub parameter, and only use that subclass. This allows methods to safely
  * cast 'this' to 'Sub*'.
  */
 template <class T, class Sub>
 struct BaseSize {
@@ -92,10 +93,11 @@ struct BaseSize {
     return Sub(width * aScale, height * aScale);
   }
   Sub operator/(T aScale) const {
     return Sub(width / aScale, height / aScale);
   }
 };
 
 }
+}
 
-#endif /* MOZILLA_BASESIZE_H_ */
+#endif /* MOZILLA_GFX_BASESIZE_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "DrawTargetCG.h"
+#include "SourceSurfaceCG.h"
+#include "Rect.h"
+
+//CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, PrivateCGCompositeMode);
+
+namespace mozilla {
+namespace gfx {
+
+static CGRect RectToCGRect(Rect r)
+{
+  return CGRectMake(r.x, r.y, r.width, r.height);
+}
+
+CGBlendMode ToBlendMode(CompositionOp op)
+{
+  CGBlendMode mode;
+  switch (op) {
+    case OP_OVER:
+      mode = kCGBlendModeNormal;
+      break;
+    case OP_SOURCE:
+      mode = kCGBlendModeCopy;
+      break;
+    case OP_CLEAR:
+      mode = kCGBlendModeClear;
+      break;
+    case OP_ADD:
+      mode = kCGBlendModePlusLighter;
+      break;
+    case OP_ATOP:
+      mode = kCGBlendModeSourceAtop;
+      break;
+    default:
+      mode = kCGBlendModeNormal;
+  }
+  return mode;
+}
+
+
+
+DrawTargetCG::DrawTargetCG()
+{
+}
+
+DrawTargetCG::~DrawTargetCG()
+{
+}
+
+TemporaryRef<SourceSurface>
+DrawTargetCG::Snapshot()
+{
+  return NULL;
+}
+
+TemporaryRef<SourceSurface>
+DrawTargetCG::CreateSourceSurfaceFromData(unsigned char *aData,
+                                           const IntSize &aSize,
+                                           int32_t aStride,
+                                           SurfaceFormat aFormat) const
+{
+  RefPtr<SourceSurfaceCG> newSurf = new SourceSurfaceCG();
+
+  if (!newSurf->InitFromData(aData, aSize, aStride, aFormat)) {
+    return NULL;
+  }
+
+  return newSurf;
+}
+
+TemporaryRef<SourceSurface>
+DrawTargetCG::OptimizeSourceSurface(SourceSurface *aSurface) const
+{
+  return NULL;
+}
+
+void
+DrawTargetCG::DrawSurface(SourceSurface *aSurface,
+                           const Rect &aDest,
+                           const Rect &aSource,
+                           const DrawOptions &aOptions,
+                           const DrawSurfaceOptions &aSurfOptions)
+{
+  CGImageRef image;
+  CGImageRef subimage = NULL;
+  if (aSurface->GetType() == COREGRAPHICS_IMAGE) {
+    image = static_cast<SourceSurfaceCG*>(aSurface)->GetImage();
+    /* we have two options here:
+     *  - create a subimage -- this is slower
+     *  - fancy things with clip and different dest rects */
+    {
+      subimage = CGImageCreateWithImageInRect(image, RectToCGRect(aSource));
+      image = subimage;
+    }
+
+    CGContextDrawImage(mCg, RectToCGRect(aDest), image);
+
+    CGImageRelease(subimage);
+  }
+}
+
+void
+DrawTargetCG::FillRect(const Rect &aRect,
+                        const Pattern &aPattern,
+                        const DrawOptions &aOptions)
+{
+  //XXX: it would be nice to hang a CGColor off of the pattern here
+  if (aPattern.GetType() == COLOR) {
+    Color color = static_cast<const ColorPattern*>(&aPattern)->mColor;
+    //XXX: the m prefixes are painful here
+    CGContextSetRGBFillColor(mCg, color.mR, color.mG, color.mB, color.mA);
+  }
+
+  CGContextSetBlendMode(mCg, ToBlendMode(aOptions.mCompositionOp));
+  CGContextFillRect(mCg, RectToCGRect(aRect));
+}
+
+
+bool
+DrawTargetCG::Init(const IntSize &aSize)
+{
+  CGColorSpaceRef cgColorspace;
+  cgColorspace = CGColorSpaceCreateDeviceRGB();
+
+  mSize = aSize;
+
+  int bitsPerComponent = 8;
+  int stride = mSize.width;
+
+  CGBitmapInfo bitinfo;
+
+  bitinfo = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst;
+
+  // XXX: mWidth is ugly
+  mCg = CGBitmapContextCreate (NULL,
+                         mSize.width,
+			 mSize.height,
+			 bitsPerComponent,
+			 stride,
+			 cgColorspace,
+			 bitinfo);
+
+  CGColorSpaceRelease (cgColorspace);
+
+  return true;
+}
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/DrawTargetCG.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Jeff Muizelaar <jmuizelaar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#pragma once
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#include "2D.h"
+#include "Rect.h"
+namespace mozilla {
+namespace gfx {
+
+class DrawTargetCG : public DrawTarget
+{
+public:
+  DrawTargetCG();
+  virtual ~DrawTargetCG();
+
+  virtual BackendType GetType() const { return COREGRAPHICS; }
+  virtual TemporaryRef<SourceSurface> Snapshot();
+
+  virtual void DrawSurface(SourceSurface *aSurface,
+                           const Rect &aDest,
+                           const Rect &aSource,
+                           const DrawOptions &aOptions = DrawOptions(),
+                           const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions());
+
+  virtual void FillRect(const Rect &aRect,
+                        const Pattern &aPattern,
+                        const DrawOptions &aOptions = DrawOptions());
+
+
+  bool Init(const IntSize &aSize);
+  bool Init(CGContextRef cgContext, const IntSize &aSize);
+
+  /* This is for creating good compatible surfaces */
+  virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
+                                                            const IntSize &aSize,
+                                                            int32_t aStride,
+                                                            SurfaceFormat aFormat) const;
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
+private:
+  bool InitCGRenderTarget();
+
+  IntSize mSize;
+  CGContextRef mCg;
+
+};
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "DrawTargetCairo.h"
+#include "SourceSurfaceCairo.h"
+
+#include "cairo/cairo.h"
+
+namespace mozilla {
+namespace gfx {
+
+cairo_operator_t
+GfxOpToCairoOp(CompositionOp op)
+{
+  switch (op)
+  {
+    case OP_OVER:
+      return CAIRO_OPERATOR_OVER;
+    case OP_SOURCE:
+      return CAIRO_OPERATOR_SOURCE;
+    case OP_ADD:
+      return CAIRO_OPERATOR_ADD;
+    case OP_ATOP:
+      return CAIRO_OPERATOR_ATOP;
+    case OP_COUNT:
+      break;
+  }
+
+  return CAIRO_OPERATOR_OVER;
+}
+
+cairo_filter_t
+GfxFilterToCairoFilter(Filter filter)
+{
+  switch (filter)
+  {
+    case FILTER_LINEAR:
+      return CAIRO_FILTER_BILINEAR;
+    case FILTER_POINT:
+      return CAIRO_FILTER_NEAREST;
+  }
+
+  return CAIRO_FILTER_BILINEAR;
+}
+
+cairo_format_t
+GfxFormatToCairoFormat(SurfaceFormat format)
+{
+  switch (format)
+  {
+    case FORMAT_B8G8R8A8:
+      return CAIRO_FORMAT_ARGB32;
+    case FORMAT_B8G8R8X8:
+      return CAIRO_FORMAT_RGB24;
+    case FORMAT_A8:
+      return CAIRO_FORMAT_A8;
+  }
+
+  return CAIRO_FORMAT_ARGB32;
+}
+
+void
+GfxMatrixToCairoMatrix(const Matrix& mat, cairo_matrix_t& retval)
+{
+  cairo_matrix_init(&retval, mat._11, mat._12, mat._21, mat._22, mat._31, mat._32);
+}
+
+DrawTargetCairo::DrawTargetCairo()
+  : mContext(NULL)
+{
+}
+
+DrawTargetCairo::~DrawTargetCairo()
+{
+  cairo_destroy(mContext);
+}
+
+TemporaryRef<SourceSurface>
+DrawTargetCairo::Snapshot()
+{
+  return NULL;
+}
+
+void
+DrawTargetCairo::Flush()
+{
+  cairo_surface_t* surf = cairo_get_target(mContext);
+  cairo_surface_flush(surf);
+}
+
+void
+DrawTargetCairo::DrawSurface(SourceSurface *aSurface,
+                             const Rect &aDest,
+                             const Rect &aSource,
+                             const DrawSurfaceOptions &aSurfOptions,
+                             const DrawOptions &aOptions)
+{
+  float sx = aSource.Width() / aDest.Width();
+  float sy = aSource.Height() / aDest.Height();
+
+  cairo_matrix_t src_mat;
+  cairo_matrix_init_scale(&src_mat, sx, sy);
+  cairo_matrix_translate(&src_mat, -aSource.X(), -aSource.Y());
+
+  cairo_surface_t* surf = NULL;
+  if (aSurface->GetType() == SURFACE_CAIRO) {
+    surf = static_cast<SourceSurfaceCairo*>(aSurface)->GetSurface();
+  }
+
+  cairo_pattern_t* pat = cairo_pattern_create_for_surface(surf);
+  cairo_pattern_set_matrix(pat, &src_mat);
+  cairo_pattern_set_filter(pat, GfxFilterToCairoFilter(aSurfOptions.mFilter));
+
+  cairo_set_operator(mContext, GfxOpToCairoOp(aOptions.mCompositionOp));
+  cairo_rectangle(mContext, aDest.X(), aDest.Y(),
+                  aDest.Width(), aDest.Height());
+  cairo_fill(mContext);
+
+  cairo_pattern_destroy(pat);
+}
+
+void
+DrawTargetCairo::FillRect(const Rect &aRect,
+                          const Pattern &aPattern,
+                          const DrawOptions &aOptions)
+{
+  cairo_new_path(mContext);
+  cairo_rectangle(mContext, aRect.x, aRect.y, aRect.Width(), aRect.Height());
+
+  cairo_set_operator(mContext, GfxOpToCairoOp(aOptions.mCompositionOp));
+
+  if (aPattern.GetType() == PATTERN_COLOR) {
+    Color color = static_cast<const ColorPattern&>(aPattern).mColor;
+    cairo_set_source_rgba(mContext, color.r, color.g,
+                                    color.b, color.a);
+  }
+
+  cairo_fill(mContext);
+}
+
+TemporaryRef<SourceSurface>
+DrawTargetCairo::CreateSourceSurfaceFromData(unsigned char *aData,
+                                             const IntSize &aSize,
+                                             int32_t aStride,
+                                             SurfaceFormat aFormat) const
+{
+  cairo_surface_t* surf = cairo_image_surface_create_for_data(aData,
+                                                              GfxFormatToCairoFormat(aFormat),
+                                                              aSize.width,
+                                                              aSize.height,
+                                                              aStride);
+  RefPtr<SourceSurfaceCairo> source_surf = new SourceSurfaceCairo();
+  source_surf->InitFromSurface(surf, aSize, aFormat);
+  cairo_surface_destroy(surf);
+  return source_surf;
+}
+
+TemporaryRef<SourceSurface>
+DrawTargetCairo::OptimizeSourceSurface(SourceSurface *aSurface) const
+{
+  return NULL;
+}
+
+TemporaryRef<SourceSurface>
+DrawTargetCairo::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
+{
+  return NULL;
+}
+
+bool
+DrawTargetCairo::Init(cairo_surface_t* aSurface)
+{
+  mContext = cairo_create(aSurface);
+
+  return true;
+}
+
+void
+DrawTargetCairo::SetTransform(const Matrix& aTransform)
+{
+  cairo_matrix_t mat;
+  GfxMatrixToCairoMatrix(aTransform, mat);
+  cairo_set_matrix(mContext, &mat);
+  mTransform = aTransform;
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/DrawTargetCairo.h
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _MOZILLA_GFX_DRAWTARGET_CAIRO_H_
+#define _MOZILLA_GFX_DRAWTARGET_CAIRO_H_
+
+#include "2D.h"
+#include "cairo/cairo.h"
+
+namespace mozilla {
+namespace gfx {
+
+class DrawTargetCairo : public DrawTarget
+{
+public:
+  DrawTargetCairo();
+  virtual ~DrawTargetCairo();
+
+  virtual BackendType GetType() const { return BACKEND_CAIRO; }
+  virtual TemporaryRef<SourceSurface> Snapshot();
+  virtual IntSize GetSize() { return IntSize(); }
+
+  virtual void Flush();
+  virtual void DrawSurface(SourceSurface *aSurface,
+                           const Rect &aDest,
+                           const Rect &aSource,
+                           const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
+                           const DrawOptions &aOptions = DrawOptions());
+  virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
+                                     const Point &aDest,
+                                     const Color &aColor,
+                                     const Point &aOffset,
+                                     Float aSigma)
+  { }
+
+  virtual void ClearRect(const Rect &aRect)
+  { }
+
+  virtual void CopySurface(SourceSurface *aSurface,
+                           const IntRect &aSourceRect,
+                           const IntPoint &aDestination)
+  { }
+
+  virtual void FillRect(const Rect &aRect,
+                        const Pattern &aPattern,
+                        const DrawOptions &aOptions = DrawOptions());
+  virtual void StrokeRect(const Rect &aRect,
+                          const Pattern &aPattern,
+                          const StrokeOptions &aStrokeOptions = StrokeOptions(),
+                          const DrawOptions &aOptions = DrawOptions())
+  { return; }
+  virtual void StrokeLine(const Point &aStart,
+                          const Point &aEnd,
+                          const Pattern &aPattern,
+                          const StrokeOptions &aStrokeOptions = StrokeOptions(),
+                          const DrawOptions &aOptions = DrawOptions())
+  { return; }
+
+  virtual void Stroke(const Path *aPath,
+                      const Pattern &aPattern,
+                      const StrokeOptions &aStrokeOptions = StrokeOptions(),
+                      const DrawOptions &aOptions = DrawOptions())
+  { return; }
+
+  virtual void Fill(const Path *aPath,
+                    const Pattern &aPattern,
+                    const DrawOptions &aOptions = DrawOptions())
+  { return; }
+
+  virtual void FillGlyphs(ScaledFont *aFont,
+                          const GlyphBuffer &aBuffer,
+                          const Pattern &aPattern,
+                          const DrawOptions &aOptions)
+  { return; }
+
+  virtual void PushClip(const Path *aPath) { }
+  virtual void PopClip() { }
+
+  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const { return NULL; }
+
+  virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
+                                                            const IntSize &aSize,
+                                                            int32_t aStride,
+                                                            SurfaceFormat aFormat) const;
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
+  virtual TemporaryRef<SourceSurface>
+    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
+  virtual TemporaryRef<DrawTarget>
+    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
+  { return NULL; }
+
+  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const
+  { return NULL; }
+
+  virtual void *GetNativeSurface(NativeSurfaceType aType)
+  { return NULL; }
+
+  virtual void SetTransform(const Matrix& aTransform);
+
+  bool Init(cairo_surface_t* aSurface);
+
+private:
+
+  cairo_t* mContext;
+};
+
+}
+}
+
+#endif // _MOZILLA_GFX_DRAWTARGET_CAIRO_H_
new file mode 100644
--- /dev/null
+++ b/gfx/2d/DrawTargetD2D.cpp
@@ -0,0 +1,1679 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "DrawTargetD2D.h"
+#include "SourceSurfaceD2D.h"
+#include "SourceSurfaceD2DTarget.h"
+#include "ShadersD2D.h"
+#include "PathD2D.h"
+#include "GradientStopsD2D.h"
+#include "ScaledFontDWrite.h"
+#include "Logging.h"
+#include "Tools.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
+    __in D2D1_FACTORY_TYPE factoryType,
+    __in REFIID iid,
+    __in_opt CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
+    __out void **factory
+);
+
+typedef HRESULT (WINAPI*D3D10CreateEffectFromMemoryFunc)(
+  __in   void *pData,
+  __in   SIZE_T DataLength,
+  __in   UINT FXFlags,
+  __in   ID3D10Device *pDevice,
+  __in   ID3D10EffectPool *pEffectPool,
+  __out  ID3D10Effect **ppEffect
+);
+
+namespace mozilla {
+namespace gfx {
+
+struct Vertex {
+  float x;
+  float y;
+};
+
+ID2D1Factory *DrawTargetD2D::mFactory;
+
+// Helper class to restore surface contents that was clipped out but may have
+// been altered by a drawing call.
+class AutoSaveRestoreClippedOut
+{
+public:
+  AutoSaveRestoreClippedOut(DrawTargetD2D *aDT)
+    : mDT(aDT)
+  {}
+
+  void Save() {
+    if (!mDT->mPushedClips.size()) {
+      return;
+    }
+
+    mDT->Flush();
+
+    RefPtr<ID3D10Texture2D> tmpTexture;
+    IntSize size = mDT->mSize;
+    SurfaceFormat format = mDT->mFormat;
+
+    CD3D10_TEXTURE2D_DESC desc(DXGIFormat(format), size.width, size.height,
+                               1, 1);
+    desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+
+    HRESULT hr = mDT->mDevice->CreateTexture2D(&desc, NULL, byRef(tmpTexture));
+    if (FAILED(hr)) {
+      gfxWarning() << "Failed to create temporary texture to hold surface data.";
+    }
+    mDT->mDevice->CopyResource(tmpTexture, mDT->mTexture);
+
+    D2D1_BITMAP_PROPERTIES props =
+      D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(format),
+                             AlphaMode(format)));
+
+    RefPtr<IDXGISurface> surf;
+
+    tmpTexture->QueryInterface((IDXGISurface**)byRef(surf));
+
+    hr = mDT->mRT->CreateSharedBitmap(IID_IDXGISurface, surf,
+                                      &props, byRef(mOldSurfBitmap));
+
+    if (FAILED(hr)) {
+      gfxWarning() << "Failed to create shared bitmap for old surface.";
+    }
+
+    factory()->CreatePathGeometry(byRef(mClippedArea));
+    RefPtr<ID2D1GeometrySink> currentSink;
+    mClippedArea->Open(byRef(currentSink));
+      
+    std::vector<DrawTargetD2D::PushedClip>::iterator iter = mDT->mPushedClips.begin();
+    iter->mPath->GetGeometry()->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
+                                     iter->mTransform, currentSink);
+
+    currentSink->Close();
+
+    iter++;
+    for (;iter != mDT->mPushedClips.end(); iter++) {
+      RefPtr<ID2D1PathGeometry> newGeom;
+      factory()->CreatePathGeometry(byRef(newGeom));
+
+      newGeom->Open(byRef(currentSink));
+      mClippedArea->CombineWithGeometry(iter->mPath->GetGeometry(), D2D1_COMBINE_MODE_INTERSECT,
+                                        iter->mTransform, currentSink);
+
+      currentSink->Close();
+
+      mClippedArea = newGeom;
+    }
+  }
+
+  ID2D1Factory *factory() { return mDT->factory(); }
+
+  ~AutoSaveRestoreClippedOut()
+  {
+    if (!mOldSurfBitmap) {
+      return;
+    }
+
+    ID2D1RenderTarget *rt = mDT->mRT;
+
+    // Write the area that was clipped out back to the surface. This all
+    // happens in device space.
+    rt->SetTransform(D2D1::IdentityMatrix());
+    mDT->mTransformDirty = true;
+
+    RefPtr<ID2D1RectangleGeometry> rectGeom;
+    factory()->CreateRectangleGeometry(D2D1::InfiniteRect(), byRef(rectGeom));
+
+    RefPtr<ID2D1PathGeometry> invClippedArea;
+    factory()->CreatePathGeometry(byRef(invClippedArea));
+    RefPtr<ID2D1GeometrySink> sink;
+    invClippedArea->Open(byRef(sink));
+
+    HRESULT hr = rectGeom->CombineWithGeometry(mClippedArea, D2D1_COMBINE_MODE_EXCLUDE,
+                                               NULL, sink);
+    sink->Close();
+
+    RefPtr<ID2D1BitmapBrush> brush;
+    rt->CreateBitmapBrush(mOldSurfBitmap, D2D1::BitmapBrushProperties(), D2D1::BrushProperties(), byRef(brush));                   
+
+    rt->FillGeometry(invClippedArea, brush);
+  }
+
+private:
+
+  DrawTargetD2D *mDT;  
+
+  // If we have an operator unbound by the source, this will contain a bitmap
+  // with the old dest surface data.
+  RefPtr<ID2D1Bitmap> mOldSurfBitmap;
+  // This contains the area drawing is clipped to.
+  RefPtr<ID2D1PathGeometry> mClippedArea;
+};
+
+DrawTargetD2D::DrawTargetD2D()
+  : mClipsArePushed(false)
+  , mPrivateData(NULL)
+{
+}
+
+DrawTargetD2D::~DrawTargetD2D()
+{
+  if (mRT) {  
+    PopAllClips();
+
+    mRT->EndDraw();
+  }
+  if (mTempRT) {
+    mTempRT->EndDraw();
+  }
+}
+
+/*
+ * DrawTarget Implementation
+ */
+TemporaryRef<SourceSurface>
+DrawTargetD2D::Snapshot()
+{
+  RefPtr<SourceSurfaceD2DTarget> newSurf = new SourceSurfaceD2DTarget();
+
+  newSurf->mFormat = mFormat;
+  newSurf->mTexture = mTexture;
+  newSurf->mDrawTarget = this;
+
+  mSnapshots.push_back(newSurf);
+
+  Flush();
+
+  return newSurf;
+}
+
+void
+DrawTargetD2D::Flush()
+{
+  PopAllClips();
+
+  HRESULT hr = mRT->Flush();
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Error reported when trying to flush D2D rendertarget. Code: " << hr;
+  }
+}
+
+void
+DrawTargetD2D::DrawSurface(SourceSurface *aSurface,
+                           const Rect &aDest,
+                           const Rect &aSource,
+                           const DrawSurfaceOptions &aSurfOptions,
+                           const DrawOptions &aOptions)
+{
+  RefPtr<ID2D1Bitmap> bitmap;
+
+  ID2D1RenderTarget *rt = GetRTForOperator(aOptions.mCompositionOp);
+  
+  PrepareForDrawing(rt);
+
+  Rect srcRect = aSource;
+
+  switch (aSurface->GetType()) {
+
+  case SURFACE_D2D1_BITMAP:
+    {
+      SourceSurfaceD2D *srcSurf = static_cast<SourceSurfaceD2D*>(aSurface);
+      bitmap = srcSurf->GetBitmap();
+
+      if (!bitmap) {
+        if (aSource.width > rt->GetMaximumBitmapSize() ||
+            aSource.height > rt->GetMaximumBitmapSize()) {
+          gfxDebug() << "Bitmap source larger than texture size specified. DrawBitmap will silently fail.";
+          // Don't know how to deal with this yet.
+          return;
+        }
+
+        int stride = srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat());
+
+        unsigned char *data = &srcSurf->mRawData.front() +
+                              (uint32_t)aSource.y * stride +
+                              (uint32_t)aSource.x * BytesPerPixel(srcSurf->GetFormat());
+
+        D2D1_BITMAP_PROPERTIES props =
+          D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(srcSurf->GetFormat()), AlphaMode(srcSurf->GetFormat())));
+        mRT->CreateBitmap(D2D1::SizeU(UINT32(aSource.width), UINT32(aSource.height)), data, stride, props, byRef(bitmap));
+
+        srcRect.x -= (uint32_t)aSource.x;
+        srcRect.y -= (uint32_t)aSource.y;
+      }
+    }
+    break;
+  case SURFACE_D2D1_DRAWTARGET:
+    {
+      SourceSurfaceD2DTarget *srcSurf = static_cast<SourceSurfaceD2DTarget*>(aSurface);
+      bitmap = srcSurf->GetBitmap(mRT);
+
+      if (!srcSurf->IsCopy()) {
+        srcSurf->mDrawTarget->mDependentTargets.push_back(this);
+      }
+    }
+    break;
+  }
+
+  rt->DrawBitmap(bitmap, D2DRect(aDest), aOptions.mAlpha, D2DFilter(aSurfOptions.mFilter), D2DRect(srcRect));
+
+  FinalizeRTForOperator(aOptions.mCompositionOp, aDest);
+}
+
+void
+DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
+                                     const Point &aDest,
+                                     const Color &aColor,
+                                     const Point &aOffset,
+                                     Float aSigma)
+{
+  RefPtr<ID3D10ShaderResourceView> srView = NULL;
+  if (aSurface->GetType() != SURFACE_D2D1_DRAWTARGET) {
+    return;
+  }
+
+  Flush();
+
+  srView = static_cast<SourceSurfaceD2DTarget*>(aSurface)->GetSRView();
+
+  EnsureViews();
+
+  if (!mTempRTView) {
+    // This view is only needed in this path.
+    HRESULT hr = mDevice->CreateRenderTargetView(mTempTexture, NULL, byRef(mTempRTView));
+
+    if (FAILED(hr)) {
+      gfxWarning() << "Failure to create RenderTargetView. Code: " << hr;
+      return;
+    }
+  }
+
+  RefPtr<ID3D10RenderTargetView> destRTView = mRTView;
+  RefPtr<ID3D10Texture2D> destTexture;
+  HRESULT hr;
+
+  if (mPushedClips.size()) {
+    // We need to take clips into account, draw into a temporary surface, which
+    // we then blend back with the proper clips set, using D2D.
+    CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
+                               mSize.width, mSize.height,
+                               1, 1);
+    desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+
+    hr = mDevice->CreateTexture2D(&desc, NULL, byRef(destTexture));
+    if (FAILED(hr)) {
+      gfxWarning() << "Failure to create temporary texture. Size: " << mSize << " Code: " << hr;
+      return;
+    }
+
+    hr = mDevice->CreateRenderTargetView(destTexture, NULL, byRef(destRTView));
+    if (FAILED(hr)) {
+      gfxWarning() << "Failure to create RenderTargetView. Code: " << hr;
+      return;
+    }
+
+    float color[4] = { 0, 0, 0, 0 };
+    mDevice->ClearRenderTargetView(destRTView, color);
+  }
+
+
+  IntSize srcSurfSize;
+  ID3D10RenderTargetView *rtViews;
+  D3D10_VIEWPORT viewport;
+
+  UINT stride = sizeof(Vertex);
+  UINT offset = 0;
+  ID3D10Buffer *buff = mPrivateData->mVB;
+
+  mDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+  mDevice->IASetVertexBuffers(0, 1, &buff, &stride, &offset);
+  mDevice->IASetInputLayout(mPrivateData->mInputLayout);
+
+  mPrivateData->mEffect->GetVariableByName("QuadDesc")->AsVector()->
+    SetFloatVector(ShaderConstantRectD3D10(-1.0f, 1.0f, 2.0f, -2.0f));
+  mPrivateData->mEffect->GetVariableByName("TexCoords")->AsVector()->
+    SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
+
+  // If we create a downsampled source surface we need to correct aOffset for that.
+  Point correctedOffset = aOffset + aDest;
+
+  // The 'practical' scaling factors.
+  Float dsFactorX = 1.0f;
+  Float dsFactorY = 1.0f;
+
+  if (aSigma > 1.7f) {
+    // In this case 9 samples of our original will not cover it. Generate the
+    // mip levels for the original and create a downsampled version from
+    // them. We generate a version downsampled so that a kernel for a sigma
+    // of 1.7 will produce the right results.
+    float blurWeights[9] = { 0.234671f, 0.197389f, 0.197389f, 0.117465f, 0.117465f, 0.049456f, 0.049456f, 0.014732f, 0.014732f };
+    mPrivateData->mEffect->GetVariableByName("BlurWeights")->SetRawValue(blurWeights, 0, sizeof(blurWeights));
+    
+    CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
+                               aSurface->GetSize().width,
+                               aSurface->GetSize().height);
+    desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+    desc.MiscFlags = D3D10_RESOURCE_MISC_GENERATE_MIPS;
+
+    RefPtr<ID3D10Texture2D> mipTexture;
+    hr = mDevice->CreateTexture2D(&desc, NULL, byRef(mipTexture));
+
+    if (FAILED(hr)) {
+      gfxWarning() << "Failure to create temporary texture. Size: " <<
+        aSurface->GetSize() << " Code: " << hr;
+      return;
+    }
+
+    IntSize dsSize = IntSize(int32_t(aSurface->GetSize().width * (1.7f / aSigma)),
+                             int32_t(aSurface->GetSize().height * (1.7f / aSigma)));
+
+    if (dsSize.width < 1) {
+      dsSize.width = 1;
+    }
+    if (dsSize.height < 1) {
+      dsSize.height = 1;
+    }
+
+    dsFactorX = dsSize.width / Float(aSurface->GetSize().width);
+    dsFactorY = dsSize.height / Float(aSurface->GetSize().height);
+    correctedOffset.x *= dsFactorX;
+    correctedOffset.y *= dsFactorY;
+
+    desc = CD3D10_TEXTURE2D_DESC(DXGI_FORMAT_B8G8R8A8_UNORM,
+                                 dsSize.width,
+                                 dsSize.height, 1, 1);
+    desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+    RefPtr<ID3D10Texture2D> tmpDSTexture;
+    hr = mDevice->CreateTexture2D(&desc, NULL, byRef(tmpDSTexture));
+
+    if (FAILED(hr)) {
+      gfxWarning() << "Failure to create temporary texture. Size: " << dsSize << " Code: " << hr;
+      return;
+    }
+
+    D3D10_BOX box;
+    box.left = box.top = box.front = 0;
+    box.back = 1;
+    box.right = aSurface->GetSize().width;
+    box.bottom = aSurface->GetSize().height;
+    mDevice->CopySubresourceRegion(mipTexture, 0, 0, 0, 0, static_cast<SourceSurfaceD2DTarget*>(aSurface)->mTexture, 0, &box);
+
+    mDevice->CreateShaderResourceView(mipTexture, NULL,  byRef(srView));
+    mDevice->GenerateMips(srView);
+
+    RefPtr<ID3D10RenderTargetView> dsRTView;
+    RefPtr<ID3D10ShaderResourceView> dsSRView;
+    mDevice->CreateRenderTargetView(tmpDSTexture, NULL,  byRef(dsRTView));
+    mDevice->CreateShaderResourceView(tmpDSTexture, NULL,  byRef(dsSRView));
+
+    rtViews = dsRTView;
+    mDevice->OMSetRenderTargets(1, &rtViews, NULL);
+
+    viewport.MaxDepth = 1;
+    viewport.MinDepth = 0;
+    viewport.Height = dsSize.height;
+    viewport.Width = dsSize.width;
+    viewport.TopLeftX = 0;
+    viewport.TopLeftY = 0;
+
+    mDevice->RSSetViewports(1, &viewport);
+    mPrivateData->mEffect->GetVariableByName("tex")->AsShaderResource()->SetResource(srView);
+    mPrivateData->mEffect->GetTechniqueByName("SampleTexture")->
+      GetPassByIndex(0)->Apply(0);
+
+    mDevice->OMSetBlendState(GetBlendStateForOperator(OP_OVER), NULL, 0xffffffff);
+
+    mDevice->Draw(4, 0);
+    
+    srcSurfSize = dsSize;
+
+    srView = dsSRView;
+  } else {
+    // In this case generate a kernel to draw the blur directly to the temp
+    // surf in one direction and to final in the other.
+    float blurWeights[9];
+
+    float normalizeFactor = 1.0f;
+    if (aSigma != 0) {
+      normalizeFactor = 1.0f / Float(sqrt(2 * M_PI * pow(aSigma, 2)));
+    }
+
+    blurWeights[0] = normalizeFactor;
+
+    // XXX - We should actually optimize for Sigma = 0 here. We could use a
+    // much simpler shader and save a lot of texture lookups.
+    for (int i = 1; i < 9; i += 2) {
+      if (aSigma != 0) {
+        blurWeights[i] = blurWeights[i + 1] = normalizeFactor *
+          exp(-pow(float((i + 1) / 2), 2) / (2 * pow(aSigma, 2)));
+      } else {
+        blurWeights[i] = blurWeights[i + 1] = 0;
+      }
+    }
+    
+    mPrivateData->mEffect->GetVariableByName("BlurWeights")->SetRawValue(blurWeights, 0, sizeof(blurWeights));
+
+    viewport.MaxDepth = 1;
+    viewport.MinDepth = 0;
+    viewport.Height = aSurface->GetSize().height;
+    viewport.Width = aSurface->GetSize().width;
+    viewport.TopLeftX = 0;
+    viewport.TopLeftY = 0;
+
+    mDevice->RSSetViewports(1, &viewport);
+
+    srcSurfSize = aSurface->GetSize();
+  }
+
+  // We may need to draw to a different intermediate surface if our temp
+  // texture isn't big enough.
+  bool needBiggerTemp = srcSurfSize.width > mSize.width ||
+                        srcSurfSize.height > mSize.height;
+
+  RefPtr<ID3D10RenderTargetView> tmpRTView;
+  RefPtr<ID3D10ShaderResourceView> tmpSRView;
+  RefPtr<ID3D10Texture2D> tmpTexture;
+  
+  IntSize tmpSurfSize = mSize;
+
+  if (!needBiggerTemp) {
+    tmpRTView = mTempRTView;
+    tmpSRView = mSRView;
+  } else {
+    CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
+                               srcSurfSize.width,
+                               srcSurfSize.height,
+                               1, 1);
+    desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+
+    mDevice->CreateTexture2D(&desc, NULL,  byRef(tmpTexture));
+    mDevice->CreateRenderTargetView(tmpTexture, NULL,  byRef(tmpRTView));
+    mDevice->CreateShaderResourceView(tmpTexture, NULL,  byRef(tmpSRView));
+
+    tmpSurfSize = srcSurfSize;
+  }
+
+  rtViews = tmpRTView;
+  mDevice->OMSetRenderTargets(1, &rtViews, NULL);
+
+  mPrivateData->mEffect->GetVariableByName("tex")->AsShaderResource()->SetResource(srView);
+
+  // Premultiplied!
+  float shadowColor[4] = { aColor.r * aColor.a, aColor.g * aColor.a,
+                           aColor.b * aColor.a, aColor.a };
+  mPrivateData->mEffect->GetVariableByName("ShadowColor")->AsVector()->
+    SetFloatVector(shadowColor);
+
+  float pixelOffset = 1.0f / float(srcSurfSize.width);
+  float blurOffsetsH[9] = { 0, pixelOffset, -pixelOffset,
+                            2.0f * pixelOffset, -2.0f * pixelOffset,
+                            3.0f * pixelOffset, -3.0f * pixelOffset,
+                            4.0f * pixelOffset, - 4.0f * pixelOffset };
+
+  pixelOffset = 1.0f / float(tmpSurfSize.height);
+  float blurOffsetsV[9] = { 0, pixelOffset, -pixelOffset,
+                            2.0f * pixelOffset, -2.0f * pixelOffset,
+                            3.0f * pixelOffset, -3.0f * pixelOffset,
+                            4.0f * pixelOffset, - 4.0f * pixelOffset };
+
+  mPrivateData->mEffect->GetVariableByName("BlurOffsetsH")->
+    SetRawValue(blurOffsetsH, 0, sizeof(blurOffsetsH));
+  mPrivateData->mEffect->GetVariableByName("BlurOffsetsV")->
+    SetRawValue(blurOffsetsV, 0, sizeof(blurOffsetsV));
+
+  mPrivateData->mEffect->GetTechniqueByName("SampleTextureWithShadow")->
+    GetPassByIndex(0)->Apply(0);
+
+  mDevice->Draw(4, 0);
+
+  viewport.MaxDepth = 1;
+  viewport.MinDepth = 0;
+  viewport.Height = mSize.height;
+  viewport.Width = mSize.width;
+  viewport.TopLeftX = 0;
+  viewport.TopLeftY = 0;
+
+  mDevice->RSSetViewports(1, &viewport);
+
+  mPrivateData->mEffect->GetVariableByName("tex")->AsShaderResource()->SetResource(tmpSRView);
+
+  rtViews = destRTView;
+  mDevice->OMSetRenderTargets(1, &rtViews, NULL);
+
+  mPrivateData->mEffect->GetVariableByName("TexCoords")->AsVector()->
+    SetFloatVector(ShaderConstantRectD3D10(-correctedOffset.x / Float(tmpSurfSize.width), -correctedOffset.y / Float(tmpSurfSize.height),
+                                           mSize.width / Float(tmpSurfSize.width) * dsFactorX,
+                                           mSize.height / Float(tmpSurfSize.height) * dsFactorY));
+  mPrivateData->mEffect->GetTechniqueByName("SampleTextureWithShadow")->
+    GetPassByIndex(1)->Apply(0);
+
+  mDevice->Draw(4, 0);
+
+  mPrivateData->mEffect->GetVariableByName("tex")->AsShaderResource()->SetResource(static_cast<SourceSurfaceD2DTarget*>(aSurface)->GetSRView());
+  mPrivateData->mEffect->GetVariableByName("TexCoords")->AsVector()->
+    SetFloatVector(ShaderConstantRectD3D10(-aDest.x / aSurface->GetSize().width, -aDest.y / aSurface->GetSize().height,
+                                           Float(mSize.width) / aSurface->GetSize().width,
+                                           Float(mSize.height) / aSurface->GetSize().height));
+  mPrivateData->mEffect->GetTechniqueByName("SampleTexture")->
+    GetPassByIndex(0)->Apply(0);
+  mDevice->OMSetBlendState(GetBlendStateForOperator(OP_OVER), NULL, 0xffffffff);
+
+  mDevice->Draw(4, 0);
+
+  if (mPushedClips.size()) {
+    // Assert destTexture
+
+    // Blend back using the proper clips.
+    PrepareForDrawing(mRT);
+
+    RefPtr<IDXGISurface> surf;
+    hr = destTexture->QueryInterface((IDXGISurface**) byRef(surf));
+
+    if (FAILED(hr)) {
+      gfxWarning() << "Failure to QI texture to surface. Code: " << hr;
+      return;
+    }
+
+    D2D1_BITMAP_PROPERTIES props =
+      D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(mFormat), AlphaMode(mFormat)));
+    RefPtr<ID2D1Bitmap> bitmap;
+    hr = mRT->CreateSharedBitmap(IID_IDXGISurface, surf, 
+                                 &props,  byRef(bitmap));
+
+    if (FAILED(hr)) {
+      gfxWarning() << "Failure to create shared bitmap for surface. Code: " << hr;
+      return;
+    }
+
+    mRT->DrawBitmap(bitmap);
+  }
+}
+
+void
+DrawTargetD2D::ClearRect(const Rect &aRect)
+{
+  mRT->SetTransform(D2DMatrix(mTransform));
+  PopAllClips();
+
+  AutoSaveRestoreClippedOut restoreClippedOut(this);
+
+  restoreClippedOut.Save();
+
+  bool needsClip = false;
+
+  needsClip = aRect.x > 0 || aRect.y > 0 ||
+              aRect.XMost() < mSize.width ||
+              aRect.YMost() < mSize.height;
+
+  if (needsClip) {
+    mRT->PushAxisAlignedClip(D2DRect(aRect), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
+  }
+  mRT->Clear(D2D1::ColorF(0, 0.0f));
+  if (needsClip) {
+    mRT->PopAxisAlignedClip();
+  }
+  return;
+}
+
+void
+DrawTargetD2D::CopySurface(SourceSurface *aSurface,
+                           const IntRect &aSourceRect,
+                           const IntPoint &aDestination)
+{
+  Rect srcRect(aSourceRect.x, aSourceRect.y, aSourceRect.width, aSourceRect.height);
+  Rect dstRect(aDestination.x, aDestination.y, aSourceRect.width, aSourceRect.height);
+
+  mRT->SetTransform(D2D1::IdentityMatrix());
+  mRT->PushAxisAlignedClip(D2DRect(dstRect), D2D1_ANTIALIAS_MODE_ALIASED);
+  mRT->Clear(D2D1::ColorF(0, 0.0f));
+  mRT->PopAxisAlignedClip();
+
+  RefPtr<ID2D1Bitmap> bitmap;
+
+  switch (aSurface->GetType()) {
+  case SURFACE_D2D1_BITMAP:
+    {
+      SourceSurfaceD2D *srcSurf = static_cast<SourceSurfaceD2D*>(aSurface);
+      bitmap = srcSurf->GetBitmap();
+    }
+    break;
+  case SURFACE_D2D1_DRAWTARGET:
+    {
+      SourceSurfaceD2DTarget *srcSurf = static_cast<SourceSurfaceD2DTarget*>(aSurface);
+      bitmap = srcSurf->GetBitmap(mRT);
+
+      if (!srcSurf->IsCopy()) {
+        srcSurf->mDrawTarget->mDependentTargets.push_back(this);
+      }
+    }
+    break;
+  }
+
+  if (!bitmap) {
+    return;
+  }
+
+  mRT->DrawBitmap(bitmap, D2DRect(dstRect), 1.0f,
+                  D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
+                  D2DRect(srcRect));
+}
+
+void
+DrawTargetD2D::FillRect(const Rect &aRect,
+                        const Pattern &aPattern,
+                        const DrawOptions &aOptions)
+{
+  ID2D1RenderTarget *rt = GetRTForOperator(aOptions.mCompositionOp);
+
+  PrepareForDrawing(rt);
+
+  RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
+
+  if (brush) {
+    rt->FillRectangle(D2DRect(aRect), brush);
+  }
+
+  FinalizeRTForOperator(aOptions.mCompositionOp, aRect);
+}
+
+void
+DrawTargetD2D::StrokeRect(const Rect &aRect,
+                          const Pattern &aPattern,
+                          const StrokeOptions &aStrokeOptions,
+                          const DrawOptions &aOptions)
+{
+  ID2D1RenderTarget *rt = GetRTForOperator(aOptions.mCompositionOp);
+
+  PrepareForDrawing(rt);
+
+  RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
+
+  RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions);
+
+  if (brush && strokeStyle) {
+    rt->DrawRectangle(D2DRect(aRect), brush, aStrokeOptions.mLineWidth, strokeStyle);
+  }
+
+  FinalizeRTForOperator(aOptions.mCompositionOp, aRect);
+}
+
+void
+DrawTargetD2D::StrokeLine(const Point &aStart,
+                          const Point &aEnd,
+                          const Pattern &aPattern,
+                          const StrokeOptions &aStrokeOptions,
+                          const DrawOptions &aOptions)
+{
+  ID2D1RenderTarget *rt = GetRTForOperator(aOptions.mCompositionOp);
+
+  PrepareForDrawing(rt);
+
+  RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
+
+  RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions);
+
+  if (brush && strokeStyle) {
+    rt->DrawLine(D2DPoint(aStart), D2DPoint(aEnd), brush, aStrokeOptions.mLineWidth, strokeStyle);
+  }
+
+  FinalizeRTForOperator(aOptions.mCompositionOp, Rect(0, 0, Float(mSize.width), Float(mSize.height)));
+}
+
+void
+DrawTargetD2D::Stroke(const Path *aPath,
+                      const Pattern &aPattern,
+                      const StrokeOptions &aStrokeOptions,
+                      const DrawOptions &aOptions)
+{
+  if (aPath->GetBackendType() != BACKEND_DIRECT2D) {
+    gfxDebug() << *this << ": Ignoring drawing call for incompatible path.";
+    return;
+  }
+
+  const PathD2D *d2dPath = static_cast<const PathD2D*>(aPath);
+
+  ID2D1RenderTarget *rt = GetRTForOperator(aOptions.mCompositionOp);
+
+  PrepareForDrawing(rt);
+
+  RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
+
+  RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions);
+
+  if (brush && strokeStyle) {
+    rt->DrawGeometry(d2dPath->mGeometry, brush, aStrokeOptions.mLineWidth, strokeStyle);
+  }
+
+  FinalizeRTForOperator(aOptions.mCompositionOp, Rect(0, 0, Float(mSize.width), Float(mSize.height)));
+}
+
+void
+DrawTargetD2D::Fill(const Path *aPath,
+                    const Pattern &aPattern,
+                    const DrawOptions &aOptions)
+{
+  if (aPath->GetBackendType() != BACKEND_DIRECT2D) {
+    gfxDebug() << *this << ": Ignoring drawing call for incompatible path.";
+    return;
+  }
+
+  const PathD2D *d2dPath = static_cast<const PathD2D*>(aPath);
+
+  ID2D1RenderTarget *rt = GetRTForOperator(aOptions.mCompositionOp);
+
+  PrepareForDrawing(rt);
+
+  RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
+
+  if (brush) {
+    rt->FillGeometry(d2dPath->mGeometry, brush);
+  }
+
+  Rect bounds;
+  if (aOptions.mCompositionOp != OP_OVER) {
+    D2D1_RECT_F d2dbounds;
+    d2dPath->mGeometry->GetBounds(D2D1::IdentityMatrix(), &d2dbounds);
+    bounds = ToRect(d2dbounds);
+  }
+  FinalizeRTForOperator(aOptions.mCompositionOp, bounds);
+}
+
+void
+DrawTargetD2D::FillGlyphs(ScaledFont *aFont,
+                          const GlyphBuffer &aBuffer,
+                          const Pattern &aPattern,
+                          const DrawOptions &aOptions)
+{
+  if (aFont->GetType() != FONT_DWRITE) {
+    gfxDebug() << *this << ": Ignoring drawing call for incompatible font.";
+    return;
+  }
+
+  ScaledFontDWrite *font = static_cast<ScaledFontDWrite*>(aFont);
+
+  ID2D1RenderTarget *rt = GetRTForOperator(aOptions.mCompositionOp);
+
+  PrepareForDrawing(rt);
+
+  RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
+
+  DWRITE_GLYPH_RUN glyphRun;
+
+  glyphRun.bidiLevel = 0;
+  glyphRun.fontEmSize = font->mSize;
+  glyphRun.isSideways = FALSE;
+  glyphRun.fontFace = font->mFontFace;
+  glyphRun.glyphCount = aBuffer.mNumGlyphs;
+  
+  std::vector<UINT16> indices;
+  std::vector<FLOAT> advances;
+  std::vector<DWRITE_GLYPH_OFFSET> offsets;
+  indices.resize(aBuffer.mNumGlyphs);
+  advances.resize(aBuffer.mNumGlyphs);
+  offsets.resize(aBuffer.mNumGlyphs);
+
+  memset(&advances.front(), 0, sizeof(FLOAT) * aBuffer.mNumGlyphs);
+  for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
+    indices[i] = aBuffer.mGlyphs[i].mIndex;
+    offsets[i].advanceOffset = aBuffer.mGlyphs[i].mPosition.x;
+    offsets[i].ascenderOffset = -aBuffer.mGlyphs[i].mPosition.y;
+  }
+
+  glyphRun.glyphAdvances = &advances.front();
+  glyphRun.glyphIndices = &indices.front();
+  glyphRun.glyphOffsets = &offsets.front();
+
+  if (brush) {
+    rt->DrawGlyphRun(D2D1::Point2F(), &glyphRun, brush);
+  }
+
+  FinalizeRTForOperator(aOptions.mCompositionOp, Rect(0, 0, (Float)mSize.width, (Float)mSize.height));
+}
+
+void
+DrawTargetD2D::PushClip(const Path *aPath)
+{
+  if (aPath->GetBackendType() != BACKEND_DIRECT2D) {
+    gfxDebug() << *this << ": Ignoring clipping call for incompatible path.";
+    return;
+  }
+
+  RefPtr<PathD2D> pathD2D = static_cast<PathD2D*>(const_cast<Path*>(aPath));
+
+  PushedClip clip;
+  clip.mTransform = D2DMatrix(mTransform);
+  clip.mPath = pathD2D;
+  
+  RefPtr<ID2D1Layer> layer;
+  pathD2D->mGeometry->GetBounds(clip.mTransform, &clip.mBounds);
+
+  mRT->CreateLayer( byRef(layer));
+
+  clip.mLayer = layer;
+  mPushedClips.push_back(clip);
+
+  // The transform of clips is relative to the world matrix, since we use the total
+  // transform for the clips, make the world matrix identity.
+  mRT->SetTransform(D2D1::IdentityMatrix());
+  mTransformDirty = true;
+
+  if (mClipsArePushed) {
+    mRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), pathD2D->mGeometry,
+                                         D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
+                                         clip.mTransform), layer);
+  }
+}
+
+void
+DrawTargetD2D::PopClip()
+{
+  if (mClipsArePushed) {
+    mRT->PopLayer();
+  }
+  mPushedClips.pop_back();
+}
+
+TemporaryRef<SourceSurface> 
+DrawTargetD2D::CreateSourceSurfaceFromData(unsigned char *aData,
+                                           const IntSize &aSize,
+                                           int32_t aStride,
+                                           SurfaceFormat aFormat) const
+{
+  RefPtr<SourceSurfaceD2D> newSurf = new SourceSurfaceD2D();
+
+  if (!newSurf->InitFromData(aData, aSize, aStride, aFormat, mRT)) {
+    gfxDebug() << *this << ": Failure to create source surface from data. Size: " << aSize;
+    return NULL;
+  }
+
+  return newSurf;
+}
+
+TemporaryRef<SourceSurface> 
+DrawTargetD2D::OptimizeSourceSurface(SourceSurface *aSurface) const
+{
+  // Unsupported!
+  return NULL;
+}
+
+TemporaryRef<SourceSurface>
+DrawTargetD2D::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
+{
+  if (aSurface.mType != NATIVE_SURFACE_D3D10_TEXTURE) {
+    gfxDebug() << *this << ": Failure to create source surface from non-D3D10 texture native surface.";
+    return NULL;
+  }
+  RefPtr<SourceSurfaceD2D> newSurf = new SourceSurfaceD2D();
+
+  if (!newSurf->InitFromTexture(static_cast<ID3D10Texture2D*>(aSurface.mSurface),
+                                aSurface.mFormat,
+                                mRT))
+  {
+    gfxWarning() << *this << ": Failed to create SourceSurface from texture.";
+    return NULL;
+  }
+
+  return newSurf;
+}
+
+TemporaryRef<DrawTarget>
+DrawTargetD2D::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
+{
+  RefPtr<DrawTargetD2D> newTarget =
+    new DrawTargetD2D();
+
+  if (!newTarget->Init(aSize, aFormat)) {
+    gfxDebug() << *this << ": Failed to create optimal draw target. Size: " << aSize;
+    return NULL;
+  }
+
+  return newTarget;
+}
+
+TemporaryRef<PathBuilder>
+DrawTargetD2D::CreatePathBuilder(FillRule aFillRule) const
+{
+  RefPtr<ID2D1PathGeometry> path;
+  HRESULT hr = factory()->CreatePathGeometry(byRef(path));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create Direct2D Path Geometry. Code: " << hr;
+    return NULL;
+  }
+
+  RefPtr<ID2D1GeometrySink> sink;
+  hr = path->Open(byRef(sink));
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to access Direct2D Path Geometry. Code: " << hr;
+    return NULL;
+  }
+
+  if (aFillRule == FILL_WINDING) {
+    sink->SetFillMode(D2D1_FILL_MODE_WINDING);
+  }
+
+  return new PathBuilderD2D(sink, path, aFillRule);
+}
+
+TemporaryRef<GradientStops>
+DrawTargetD2D::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const
+{
+  D2D1_GRADIENT_STOP *stops = new D2D1_GRADIENT_STOP[aNumStops];
+
+  for (uint32_t i = 0; i < aNumStops; i++) {
+    stops[i].position = aStops[i].offset;
+    stops[i].color = D2DColor(aStops[i].color);
+  }
+
+  RefPtr<ID2D1GradientStopCollection> stopCollection;
+
+  HRESULT hr = mRT->CreateGradientStopCollection(stops, aNumStops, byRef(stopCollection));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create GradientStopCollection. Code: " << hr;
+    return NULL;
+  }
+
+  return new GradientStopsD2D(stopCollection);
+}
+
+void*
+DrawTargetD2D::GetNativeSurface(NativeSurfaceType aType)
+{
+  if (aType != NATIVE_SURFACE_D3D10_TEXTURE) {
+    return NULL;
+  }
+
+  return mTexture;
+}
+
+/*
+ * Public functions
+ */
+bool
+DrawTargetD2D::Init(const IntSize &aSize, SurfaceFormat aFormat)
+{
+  HRESULT hr;
+
+  mSize = aSize;
+  mFormat = aFormat;
+
+  if (!Factory::GetDirect3D10Device()) {
+    gfxDebug() << "Failed to Init Direct2D DrawTarget (No D3D10 Device set.)";
+    return false;
+  }
+  mDevice = Factory::GetDirect3D10Device();
+
+  CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
+                             mSize.width,
+                             mSize.height,
+                             1, 1);
+  desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+
+  hr = mDevice->CreateTexture2D(&desc, NULL, byRef(mTexture));
+
+  if (FAILED(hr)) {
+    gfxDebug() << "Failed to init Direct2D DrawTarget. Size: " << mSize << " Code: " << hr;
+    return false;
+  }
+
+  return InitD2DRenderTarget();
+}
+
+bool
+DrawTargetD2D::Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
+{
+  HRESULT hr;
+
+  mTexture = aTexture;
+  mFormat = aFormat;
+
+  if (!mTexture) {
+    gfxDebug() << "No valid texture for Direct2D draw target initialization.";
+    return false;
+  }
+
+  RefPtr<ID3D10Device> device;
+  mTexture->GetDevice(byRef(device));
+
+  hr = device->QueryInterface((ID3D10Device1**)byRef(mDevice));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to get D3D10 device from texture.";
+    return false;
+  }
+
+  D3D10_TEXTURE2D_DESC desc;
+  mTexture->GetDesc(&desc);
+  mSize.width = desc.Width;
+  mSize.height = desc.Height;
+
+  return InitD2DRenderTarget();
+}
+
+// {0D398B49-AE7B-416F-B26D-EA3C137D1CF7}
+static const GUID sPrivateDataD2D = 
+{ 0xd398b49, 0xae7b, 0x416f, { 0xb2, 0x6d, 0xea, 0x3c, 0x13, 0x7d, 0x1c, 0xf7 } };
+
+bool
+DrawTargetD2D::InitD3D10Data()
+{
+  HRESULT hr;
+  
+  UINT privateDataSize;
+  privateDataSize = sizeof(mPrivateData);
+  hr = mDevice->GetPrivateData(sPrivateDataD2D, &privateDataSize, &mPrivateData);
+
+  if (SUCCEEDED(hr)) {
+      return true;
+  }
+
+  mPrivateData = new PrivateD3D10DataD2D;
+
+  D3D10CreateEffectFromMemoryFunc createD3DEffect;
+  HMODULE d3dModule = LoadLibraryW(L"d3d10_1.dll");
+  createD3DEffect = (D3D10CreateEffectFromMemoryFunc)
+      GetProcAddress(d3dModule, "D3D10CreateEffectFromMemory");
+
+  hr = createD3DEffect((void*)d2deffect, sizeof(d2deffect), 0, mDevice, NULL, byRef(mPrivateData->mEffect));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to initialize Direct2D required effects. Code: " << hr;
+    return false;
+  }
+
+  privateDataSize = sizeof(mPrivateData);
+  mDevice->SetPrivateData(sPrivateDataD2D, privateDataSize, &mPrivateData);
+
+  D3D10_INPUT_ELEMENT_DESC layout[] =
+  {
+    { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
+  };
+  D3D10_PASS_DESC passDesc;
+  
+  mPrivateData->mEffect->GetTechniqueByName("SampleTexture")->GetPassByIndex(0)->GetDesc(&passDesc);
+
+  hr = mDevice->CreateInputLayout(layout,
+                                  sizeof(layout) / sizeof(D3D10_INPUT_ELEMENT_DESC),
+                                  passDesc.pIAInputSignature,
+                                  passDesc.IAInputSignatureSize,
+                                  byRef(mPrivateData->mInputLayout));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to initialize Direct2D required InputLayout. Code: " << hr;
+    return false;
+  }
+
+  D3D10_SUBRESOURCE_DATA data;
+  Vertex vertices[] = { {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0} };
+  data.pSysMem = vertices;
+  CD3D10_BUFFER_DESC bufferDesc(sizeof(vertices), D3D10_BIND_VERTEX_BUFFER);
+
+  hr = mDevice->CreateBuffer(&bufferDesc, &data, byRef(mPrivateData->mVB));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to initialize Direct2D required VertexBuffer. Code: " << hr;
+    return false;
+  }
+
+  return true;
+}
+
+/*
+ * Private helpers
+ */
+bool
+DrawTargetD2D::InitD2DRenderTarget()
+{
+  if (!factory()) {
+    return false;
+  }
+
+  mRT = CreateRTForTexture(mTexture);
+
+  if (!mRT) {
+    return false;
+  }
+
+  mRT->BeginDraw();
+
+  mRT->Clear(D2D1::ColorF(0, 0));
+
+  return InitD3D10Data();
+}
+
+void
+DrawTargetD2D::PrepareForDrawing(ID2D1RenderTarget *aRT)
+{
+  if (!mClipsArePushed || aRT == mTempRT) {
+    if (mPushedClips.size()) {
+      // The transform of clips is relative to the world matrix, since we use the total
+      // transform for the clips, make the world matrix identity.
+      mRT->SetTransform(D2D1::IdentityMatrix());
+      for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
+           iter != mPushedClips.end(); iter++) {
+        aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
+                                             D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
+                                             iter->mTransform), iter->mLayer);
+      }
+      if (aRT == mRT) {
+        mClipsArePushed = true;
+      }
+    }
+  }
+  mRT->SetTransform(D2DMatrix(mTransform));
+  MarkChanged();
+
+  if (aRT == mTempRT) {
+    mTempRT->SetTransform(D2DMatrix(mTransform));
+  }
+}
+
+void
+DrawTargetD2D::MarkChanged()
+{
+  if (mSnapshots.size()) {
+    for (std::vector<SourceSurfaceD2DTarget*>::iterator iter = mSnapshots.begin();
+         iter != mSnapshots.end(); iter++) {
+      (*iter)->DrawTargetWillChange();
+    }
+    // All snapshots will now have copied data.
+    mSnapshots.clear();
+  }
+  if (mDependentTargets.size()) {
+    for (std::vector<RefPtr<DrawTargetD2D>>::iterator iter = mDependentTargets.begin();
+         iter != mDependentTargets.end(); iter++) {
+      (*iter)->Flush();
+    }
+    mDependentTargets.clear();
+  }
+}
+
+ID3D10BlendState*
+DrawTargetD2D::GetBlendStateForOperator(CompositionOp aOperator)
+{
+  if (mPrivateData->mBlendStates[aOperator]) {
+    return mPrivateData->mBlendStates[aOperator];
+  }
+
+  D3D10_BLEND_DESC desc;
+
+  memset(&desc, 0, sizeof(D3D10_BLEND_DESC));
+
+  desc.AlphaToCoverageEnable = FALSE;
+  desc.BlendEnable[0] = TRUE;
+  desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
+  desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+
+  switch (aOperator) {
+  case OP_ADD:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ONE;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ONE;
+    break;
+  case OP_IN:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_DEST_ALPHA;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ZERO;
+    break;
+  case OP_OUT:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_INV_DEST_ALPHA;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ZERO;
+    break;
+  case OP_ATOP:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_DEST_ALPHA;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
+    break;
+  case OP_DEST_IN:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ZERO;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_SRC_ALPHA;
+    break;
+  case OP_DEST_OUT:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ZERO;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
+    break;
+  case OP_DEST_ATOP:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_INV_DEST_ALPHA;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_SRC_ALPHA;
+    break;
+  case OP_DEST_OVER:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_INV_DEST_ALPHA;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ONE;
+    break;
+  case OP_XOR:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_INV_DEST_ALPHA;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
+    break;
+  case OP_SOURCE:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ONE;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ZERO;
+    break;
+  default:
+    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ONE;
+    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
+  }
+  
+  mDevice->CreateBlendState(&desc, byRef(mPrivateData->mBlendStates[aOperator]));
+
+  return mPrivateData->mBlendStates[aOperator];
+}
+
+/* This function prepares the temporary RT for drawing and returns it when a
+ * drawing operation other than OVER is required.
+ */
+ID2D1RenderTarget*
+DrawTargetD2D::GetRTForOperator(CompositionOp aOperator)
+{
+  if (aOperator == OP_OVER) {
+    return mRT;
+  }
+
+  PopAllClips();
+
+  if (mTempRT) {
+    mTempRT->Clear(D2D1::ColorF(0, 0));
+    return mTempRT;
+  }
+
+  EnsureViews();
+
+  if (!mRTView || !mSRView) {
+    gfxDebug() << *this << ": Failed to get required views. Defaulting to OP_OVER.";
+    return mRT;
+  }
+
+  mTempRT = CreateRTForTexture(mTempTexture);
+
+  if (!mTempRT) {
+    return mRT;
+  }
+
+  mTempRT->BeginDraw();
+
+  mTempRT->Clear(D2D1::ColorF(0, 0));
+
+  return mTempRT;
+}
+
+/* This function blends back the content of a drawing operation (drawn to an
+ * empty surface with OVER, so the surface now contains the source operation
+ * contents) to the rendertarget using the requested composition operation.
+ * In order to respect clip for operations which are unbound by their mask,
+ * the old content of the surface outside the clipped area may be blended back
+ * to the surface.
+ */
+void
+DrawTargetD2D::FinalizeRTForOperator(CompositionOp aOperator, const Rect &aBounds)
+{
+  if (aOperator == OP_OVER) {
+    return;
+  }
+
+  if (!mTempRT) {
+    return;
+  }
+
+  for (unsigned int i = 0; i < mPushedClips.size(); i++) {
+    mTempRT->PopLayer();
+  }
+
+  mRT->Flush();
+  mTempRT->Flush();
+
+  AutoSaveRestoreClippedOut restoreClippedOut(this);
+
+  bool needsWriteBack =
+    !IsOperatorBoundByMask(aOperator) && mPushedClips.size();
+
+  if (needsWriteBack) {
+    restoreClippedOut.Save();
+  }
+
+  ID3D10RenderTargetView *rtViews = mRTView;
+  mDevice->OMSetRenderTargets(1, &rtViews, NULL);
+
+  UINT stride = sizeof(Vertex);
+  UINT offset = 0;
+  ID3D10Buffer *buff = mPrivateData->mVB;
+
+  mDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+  mDevice->IASetVertexBuffers(0, 1, &buff, &stride, &offset);
+  mDevice->IASetInputLayout(mPrivateData->mInputLayout);
+
+  D3D10_VIEWPORT viewport;
+  viewport.MaxDepth = 1;
+  viewport.MinDepth = 0;
+  viewport.Height = mSize.height;
+  viewport.Width = mSize.width;
+  viewport.TopLeftX = 0;
+  viewport.TopLeftY = 0;
+
+  mDevice->RSSetViewports(1, &viewport);
+  mPrivateData->mEffect->GetVariableByName("tex")->AsShaderResource()->SetResource(mSRView);
+  mPrivateData->mEffect->GetVariableByName("QuadDesc")->AsVector()->
+    SetFloatVector(ShaderConstantRectD3D10(-1.0f, 1.0f, 2.0f, -2.0f));
+  mPrivateData->mEffect->GetVariableByName("TexCoords")->AsVector()->
+    SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
+
+  mPrivateData->mEffect->GetTechniqueByName("SampleTexture")->GetPassByIndex(0)->Apply(0);
+
+  mDevice->OMSetBlendState(GetBlendStateForOperator(aOperator), NULL, 0xffffffff);
+  
+  mDevice->Draw(4, 0);
+}
+
+TemporaryRef<ID2D1RenderTarget>
+DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture)
+{
+  HRESULT hr;
+
+  RefPtr<IDXGISurface> surface;
+  RefPtr<ID2D1RenderTarget> rt;
+
+  hr = aTexture->QueryInterface((IDXGISurface**)byRef(surface));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to QI texture to surface.";
+    return NULL;
+  }
+
+  D3D10_TEXTURE2D_DESC desc;
+  aTexture->GetDesc(&desc);
+
+  D2D1_RENDER_TARGET_PROPERTIES props =
+    D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(desc.Format, D2D1_ALPHA_MODE_PREMULTIPLIED));
+  hr = factory()->CreateDxgiSurfaceRenderTarget(surface, props, byRef(rt));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create D2D render target for texture.";
+    return NULL;
+  }
+
+  return rt;
+}
+
+void
+DrawTargetD2D::EnsureViews()
+{
+  if (mTempTexture && mSRView && mRTView) {
+    return;
+  }
+
+  HRESULT hr;
+
+  CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
+                             mSize.width,
+                             mSize.height,
+                             1, 1);
+  desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+
+  hr = mDevice->CreateTexture2D(&desc, NULL, byRef(mTempTexture));
+
+  if (FAILED(hr)) {
+    gfxWarning() << *this << "Failed to create temporary texture for rendertarget. Size: "
+      << mSize << " Code: " << hr;
+    return;
+  }
+
+  hr = mDevice->CreateShaderResourceView(mTempTexture, NULL, byRef(mSRView));
+
+  if (FAILED(hr)) {
+    gfxWarning() << *this << "Failed to create shader resource view for temp texture. Code: " << hr;
+    return;
+  }
+
+  hr = mDevice->CreateRenderTargetView(mTexture, NULL, byRef(mRTView));
+
+  if (FAILED(hr)) {
+    gfxWarning() << *this << "Failed to create rendertarget view for temp texture. Code: " << hr;
+  }
+}
+
+void
+DrawTargetD2D::PopAllClips()
+{
+  if (mClipsArePushed) {
+    for (unsigned int i = 0; i < mPushedClips.size(); i++) {
+      mRT->PopLayer();
+    }
+  
+    mClipsArePushed = false;
+  }
+}
+
+TemporaryRef<ID2D1Brush>
+DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
+{
+  if (aPattern.GetType() == PATTERN_COLOR) {
+    RefPtr<ID2D1SolidColorBrush> colBrush;
+    Color color = static_cast<const ColorPattern*>(&aPattern)->mColor;
+    mRT->CreateSolidColorBrush(D2D1::ColorF(color.r, color.g,
+                                            color.b, color.a),
+                               D2D1::BrushProperties(aAlpha),
+                               byRef(colBrush));
+    return colBrush;
+  } else if (aPattern.GetType() == PATTERN_LINEAR_GRADIENT) {
+    RefPtr<ID2D1LinearGradientBrush> gradBrush;
+    const LinearGradientPattern *pat =
+      static_cast<const LinearGradientPattern*>(&aPattern);
+
+    GradientStopsD2D *stops = static_cast<GradientStopsD2D*>(pat->mStops.get());
+
+    if (!stops) {
+      gfxDebug() << "No stops specified for gradient pattern.";
+      return NULL;
+    }
+
+    mRT->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2DPoint(pat->mBegin),
+                                                                       D2DPoint(pat->mEnd)),
+                                   D2D1::BrushProperties(aAlpha),
+                                   stops->mStopCollection,
+                                   byRef(gradBrush));
+    return gradBrush;
+  } else if (aPattern.GetType() == PATTERN_RADIAL_GRADIENT) {
+    RefPtr<ID2D1RadialGradientBrush> gradBrush;
+    const RadialGradientPattern *pat =
+      static_cast<const RadialGradientPattern*>(&aPattern);
+
+    GradientStopsD2D *stops = static_cast<GradientStopsD2D*>(pat->mStops.get());
+
+    if (!stops) {
+      gfxDebug() << "No stops specified for gradient pattern.";
+      return NULL;
+    }
+
+    mRT->CreateRadialGradientBrush(D2D1::RadialGradientBrushProperties(D2DPoint(pat->mCenter),
+                                                                       D2DPoint(pat->mOrigin - pat->mCenter),
+                                                                       pat->mRadius,
+                                                                       pat->mRadius),
+                                   D2D1::BrushProperties(aAlpha),
+                                   stops->mStopCollection,
+                                   byRef(gradBrush));
+    return gradBrush;
+  } else if (aPattern.GetType() == PATTERN_SURFACE) {
+    RefPtr<ID2D1BitmapBrush> bmBrush;
+    const SurfacePattern *pat =
+      static_cast<const SurfacePattern*>(&aPattern);
+
+    if (!pat->mSurface) {
+      gfxDebug() << "No source surface specified for surface pattern";
+      return NULL;
+    }
+
+    RefPtr<ID2D1Bitmap> bitmap;
+    
+    switch (pat->mSurface->GetType()) {
+    case SURFACE_D2D1_BITMAP:
+      {
+        SourceSurfaceD2D *surf = static_cast<SourceSurfaceD2D*>(pat->mSurface.get());
+
+        bitmap = surf->mBitmap;
+
+        if (!bitmap) {
+          gfxDebug() << "Source surface used for pattern too large!";
+          return NULL;
+        }
+      }
+      break;
+    case SURFACE_D2D1_DRAWTARGET:
+      {
+        SourceSurfaceD2DTarget *surf =
+          static_cast<SourceSurfaceD2DTarget*>(pat->mSurface.get());
+
+        bitmap = surf->GetBitmap(mRT);
+
+        if (!surf->IsCopy()) {
+          surf->mDrawTarget->mDependentTargets.push_back(this);
+        }
+      }
+      break;
+    }
+
+    D2D1_EXTEND_MODE extend = D2D1_EXTEND_MODE_CLAMP;
+    switch (pat->mExtendMode) {
+    case EXTEND_WRAP:
+      extend = D2D1_EXTEND_MODE_WRAP;
+      break;
+    case EXTEND_MIRROR:
+      extend = D2D1_EXTEND_MODE_MIRROR;
+      break;
+    }
+
+    mRT->CreateBitmapBrush(bitmap,
+                           D2D1::BitmapBrushProperties(extend,
+                                                       extend,
+                                                       D2DFilter(pat->mFilter)),
+                           D2D1::BrushProperties(aAlpha),
+                           byRef(bmBrush));
+
+    return bmBrush;
+  }
+
+  gfxWarning() << "Invalid pattern type detected.";
+  return NULL;
+}
+
+TemporaryRef<ID2D1StrokeStyle>
+DrawTargetD2D::CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions)
+{
+  RefPtr<ID2D1StrokeStyle> style;
+
+  D2D1_CAP_STYLE capStyle;
+  D2D1_LINE_JOIN joinStyle;
+
+  switch (aStrokeOptions.mLineCap) {
+  case CAP_BUTT:
+    capStyle = D2D1_CAP_STYLE_FLAT;
+    break;
+  case CAP_ROUND:
+    capStyle = D2D1_CAP_STYLE_ROUND;
+    break;
+  case CAP_SQUARE:
+    capStyle = D2D1_CAP_STYLE_SQUARE;
+    break;
+  }
+
+  switch (aStrokeOptions.mLineJoin) {
+  case JOIN_MITER:
+    joinStyle = D2D1_LINE_JOIN_MITER;
+    break;
+  case JOIN_MITER_OR_BEVEL:
+    joinStyle = D2D1_LINE_JOIN_MITER_OR_BEVEL;
+    break;
+  case JOIN_ROUND:
+    joinStyle = D2D1_LINE_JOIN_ROUND;
+    break;
+  case JOIN_BEVEL:
+    joinStyle = D2D1_LINE_JOIN_BEVEL;
+    break;
+  }
+
+
+  HRESULT hr = factory()->CreateStrokeStyle(D2D1::StrokeStyleProperties(capStyle, capStyle,
+                                                                        capStyle, joinStyle,
+                                                                        aStrokeOptions.mMiterLimit),
+                                            NULL, 0, byRef(style));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create Direct2D stroke style.";
+  }
+
+  return style;
+}
+
+ID2D1Factory*
+DrawTargetD2D::factory()
+{
+  if (mFactory) {
+    return mFactory;
+  }
+
+  D2D1CreateFactoryFunc createD2DFactory;
+  HMODULE d2dModule = LoadLibraryW(L"d2d1.dll");
+  createD2DFactory = (D2D1CreateFactoryFunc)
+      GetProcAddress(d2dModule, "D2D1CreateFactory");
+
+  if (!createD2DFactory) {
+    gfxWarning() << "Failed to locate D2D1CreateFactory function.";
+    return NULL;
+  }
+
+  D2D1_FACTORY_OPTIONS options;
+#ifdef _DEBUG
+  options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
+#else
+  options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
+#endif
+
+  HRESULT hr = createD2DFactory(D2D1_FACTORY_TYPE_MULTI_THREADED,
+                                __uuidof(ID2D1Factory),
+                                &options,
+                                (void**)&mFactory);
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create Direct2D factory.";
+  }
+
+  return mFactory;
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/DrawTargetD2D.h
@@ -0,0 +1,204 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_DRAWTARGETD2D_H_
+#define MOZILLA_GFX_DRAWTARGETD2D_H_
+
+#include "2D.h"
+#include "PathD2D.h"
+#include <d3d10_1.h>
+#include "HelpersD2D.h"
+
+#include <vector>
+#include <sstream>
+
+namespace mozilla {
+namespace gfx {
+
+class SourceSurfaceD2DTarget;
+
+struct PrivateD3D10DataD2D
+{
+  RefPtr<ID3D10Effect> mEffect;
+  RefPtr<ID3D10InputLayout> mInputLayout;
+  RefPtr<ID3D10Buffer> mVB;
+  RefPtr<ID3D10BlendState> mBlendStates[OP_COUNT];
+};
+
+class DrawTargetD2D : public DrawTarget
+{
+public:
+  DrawTargetD2D();
+  virtual ~DrawTargetD2D();
+
+  virtual BackendType GetType() const { return BACKEND_DIRECT2D; }
+  virtual TemporaryRef<SourceSurface> Snapshot();
+  virtual IntSize GetSize() { return mSize; }
+
+  virtual void Flush();
+  virtual void DrawSurface(SourceSurface *aSurface,
+                           const Rect &aDest,
+                           const Rect &aSource,
+                           const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
+                           const DrawOptions &aOptions = DrawOptions());
+  virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
+                                     const Point &aDest,
+                                     const Color &aColor,
+                                     const Point &aOffset,
+                                     Float aSigma);
+  virtual void ClearRect(const Rect &aRect);
+
+  virtual void CopySurface(SourceSurface *aSurface,
+                           const IntRect &aSourceRect,
+                           const IntPoint &aDestination);
+
+  virtual void FillRect(const Rect &aRect,
+                        const Pattern &aPattern,
+                        const DrawOptions &aOptions = DrawOptions());
+  virtual void StrokeRect(const Rect &aRect,
+                          const Pattern &aPattern,
+                          const StrokeOptions &aStrokeOptions = StrokeOptions(),
+                          const DrawOptions &aOptions = DrawOptions());
+  virtual void StrokeLine(const Point &aStart,
+                          const Point &aEnd,
+                          const Pattern &aPattern,
+                          const StrokeOptions &aStrokeOptions = StrokeOptions(),
+                          const DrawOptions &aOptions = DrawOptions());
+  virtual void Stroke(const Path *aPath,
+                      const Pattern &aPattern,
+                      const StrokeOptions &aStrokeOptions = StrokeOptions(),
+                      const DrawOptions &aOptions = DrawOptions());
+  virtual void Fill(const Path *aPath,
+                    const Pattern &aPattern,
+                    const DrawOptions &aOptions = DrawOptions());
+  virtual void FillGlyphs(ScaledFont *aFont,
+                          const GlyphBuffer &aBuffer,
+                          const Pattern &aPattern,
+                          const DrawOptions &aOptions = DrawOptions());
+  virtual void PushClip(const Path *aPath);
+  virtual void PopClip();
+
+  virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
+                                                            const IntSize &aSize,
+                                                            int32_t aStride,
+                                                            SurfaceFormat aFormat) const;
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
+
+  virtual TemporaryRef<SourceSurface>
+    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
+  
+  virtual TemporaryRef<DrawTarget>
+    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
+
+  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const;
+
+  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const;
+
+  virtual void *GetNativeSurface(NativeSurfaceType aType);
+
+  bool Init(const IntSize &aSize, SurfaceFormat aFormat);
+  bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
+  bool InitD3D10Data();
+
+  static ID2D1Factory *factory();
+
+  operator std::string() const {
+    std::stringstream stream;
+    stream << "DrawTargetD2D(" << this << ")";
+    return stream.str();
+  }
+private:
+  friend class AutoSaveRestoreClippedOut;
+  friend class SourceSurfaceD2DTarget;
+
+  bool InitD2DRenderTarget();
+  void PrepareForDrawing(ID2D1RenderTarget *aRT);
+
+  // This function will mark the surface as changing, and make sure any
+  // copy-on-write snapshots are notified.
+  void MarkChanged();
+
+  ID3D10BlendState *GetBlendStateForOperator(CompositionOp aOperator);
+  ID2D1RenderTarget *GetRTForOperator(CompositionOp aOperator);
+  void FinalizeRTForOperator(CompositionOp aOperator, const Rect &aBounds);
+  void EnsureViews();
+  void PopAllClips();
+
+  TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture);
+
+  TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
+  TemporaryRef<ID2D1StrokeStyle> CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions);
+
+  IntSize mSize;
+
+  RefPtr<ID3D10Device1> mDevice;
+  RefPtr<ID3D10Texture2D> mTexture;
+  mutable RefPtr<ID2D1RenderTarget> mRT;
+
+  // Temporary texture and render target used for supporting alternative operators.
+  RefPtr<ID3D10Texture2D> mTempTexture;
+  RefPtr<ID3D10RenderTargetView> mRTView;
+  RefPtr<ID3D10ShaderResourceView> mSRView;
+  RefPtr<ID2D1RenderTarget> mTempRT;
+  RefPtr<ID3D10RenderTargetView> mTempRTView;
+
+  // List of pushed clips.
+  struct PushedClip
+  {
+    RefPtr<ID2D1Layer> mLayer;
+    D2D1_RECT_F mBounds;
+    D2D1_MATRIX_3X2_F mTransform;
+    RefPtr<PathD2D> mPath;
+  };
+  std::vector<PushedClip> mPushedClips;
+  
+  // List of Snapshots of this surface, these need to be told when this
+  // surface is modified. Possibly vector is not the best choice here.
+  std::vector<SourceSurfaceD2DTarget*> mSnapshots;
+  // A list of targets we need to flush when we're modified.
+  std::vector<RefPtr<DrawTargetD2D>> mDependentTargets;
+
+  // True of the current clip stack is pushed to the main RT.
+  bool mClipsArePushed;
+  PrivateD3D10DataD2D *mPrivateData;
+  static ID2D1Factory *mFactory;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_DRAWTARGETD2D_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Factory.cpp
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "2D.h"
+
+#ifdef USE_CAIRO
+#include "DrawTargetCairo.h"
+#endif
+
+#ifdef WIN32
+#include "DrawTargetD2D.h"
+#include "ScaledFontDWrite.h"
+#include <d3d10_1.h>
+#endif
+
+#include "Logging.h"
+
+#ifdef PR_LOGGING
+PRLogModuleInfo *sGFX2DLog = PR_NewLogModule("gfx2d");
+#endif
+
+namespace mozilla {
+namespace gfx {
+
+// XXX - Need to define an API to set this.
+int sGfxLogLevel = LOG_DEBUG;
+
+#ifdef WIN32
+ID3D10Device1 *Factory::mD3D10Device;
+#endif
+
+TemporaryRef<DrawTarget>
+Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat)
+{
+  switch (aBackend) {
+#ifdef WIN32
+  case BACKEND_DIRECT2D:
+    {
+      RefPtr<DrawTargetD2D> newTarget;
+      newTarget = new DrawTargetD2D();
+      if (newTarget->Init(aSize, aFormat)) {
+        return newTarget;
+      }
+      break;
+    }
+#endif
+  default:
+    gfxDebug() << "Invalid draw target type specified.";
+    return NULL;
+  }
+
+  gfxDebug() << "Failed to create DrawTarget, Type: " << aBackend << " Size: " << aSize;
+  // Failed
+  return NULL;
+}
+
+TemporaryRef<ScaledFont>
+Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize)
+{
+  switch (aNativeFont.mType) {
+#ifdef WIN32
+  case NATIVE_FONT_DWRITE_FONT_FACE:
+    {
+      return new ScaledFontDWrite(static_cast<IDWriteFontFace*>(aNativeFont.mFont), aSize);
+    }
+#endif
+  default:
+    gfxWarning() << "Invalid native font type specified.";
+    return NULL;
+  }
+}
+
+#ifdef WIN32
+TemporaryRef<DrawTarget>
+Factory::CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
+{
+  RefPtr<DrawTargetD2D> newTarget;
+
+  newTarget = new DrawTargetD2D();
+  if (newTarget->Init(aTexture, aFormat)) {
+    return newTarget;
+  }
+
+  gfxWarning() << "Failed to create draw target for D3D10 texture.";
+
+  // Failed
+  return NULL;
+}
+
+void
+Factory::SetDirect3D10Device(ID3D10Device1 *aDevice)
+{
+  mD3D10Device = aDevice;
+}
+
+ID3D10Device1*
+Factory::GetDirect3D10Device()
+{
+  return mD3D10Device;
+}
+
+#endif // XP_WIN
+
+#ifdef USE_CAIRO
+TemporaryRef<DrawTarget>
+Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface)
+{
+  RefPtr<DrawTargetCairo> newTarget = new DrawTargetCairo();
+  if (newTarget->Init(aSurface)) {
+    return newTarget;
+  }
+
+  return NULL;
+}
+#endif
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/GradientStopsD2D.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_GRADIENTSTOPSD2D_H_
+#define MOZILLA_GFX_GRADIENTSTOPSD2D_H_
+
+#include "2D.h"
+
+#include <D2D1.h>
+
+namespace mozilla {
+namespace gfx {
+
+class GradientStopsD2D : public GradientStops
+{
+public:
+  GradientStopsD2D(ID2D1GradientStopCollection *aStopCollection)
+    : mStopCollection(aStopCollection)
+  {}
+
+  virtual BackendType GetBackendType() const { return BACKEND_DIRECT2D; }
+
+private:
+  friend class DrawTargetD2D;
+
+  mutable RefPtr<ID2D1GradientStopCollection> mStopCollection;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_GRADIENTSTOPSD2D_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/HelpersD2D.h
@@ -0,0 +1,175 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_HELPERSD2D_H_
+#define MOZILLA_GFX_HELPERSD2D_H_
+
+#include <D2D1.h>
+#include "2D.h"
+
+namespace mozilla {
+namespace gfx {
+
+static inline D2D1_POINT_2F D2DPoint(const Point &aPoint)
+{
+  return D2D1::Point2F(aPoint.x, aPoint.y);
+}
+
+static inline D2D1_SIZE_U D2DIntSize(const IntSize &aSize)
+{
+  return D2D1::SizeU(aSize.width, aSize.height);
+}
+
+static inline D2D1_RECT_F D2DRect(const Rect &aRect)
+{
+  return D2D1::RectF(aRect.x, aRect.y, aRect.XMost(), aRect.YMost());
+}
+
+static inline D2D1_BITMAP_INTERPOLATION_MODE D2DFilter(const Filter &aFilter)
+{
+  switch (aFilter) {
+  case FILTER_POINT:
+    return D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
+  }
+
+  return D2D1_BITMAP_INTERPOLATION_MODE_LINEAR;
+}
+
+static inline D2D1_ANTIALIAS_MODE D2DAAMode(const AntialiasMode &aMode)
+{
+  switch (aMode) {
+  case AA_NONE:
+    D2D1_ANTIALIAS_MODE_ALIASED;
+  }
+
+  return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
+}
+
+static inline D2D1_MATRIX_3X2_F D2DMatrix(const Matrix &aTransform)
+{
+  return D2D1::Matrix3x2F(aTransform._11, aTransform._12,
+                          aTransform._21, aTransform._22,
+                          aTransform._31, aTransform._32);
+}
+
+static inline D2D1_COLOR_F D2DColor(const Color &aColor)
+{
+  return D2D1::ColorF(aColor.r, aColor.g, aColor.b, aColor.a);
+}
+
+static inline IntSize ToIntSize(const D2D1_SIZE_U &aSize)
+{
+  return IntSize(aSize.width, aSize.height);
+}
+
+static inline SurfaceFormat ToPixelFormat(const D2D1_PIXEL_FORMAT &aFormat)
+{
+  switch(aFormat.format) {
+  case DXGI_FORMAT_A8_UNORM:
+    return FORMAT_A8;
+  case DXGI_FORMAT_B8G8R8A8_UNORM:
+    if (aFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) {
+      return FORMAT_B8G8R8X8;
+    } else {
+      return FORMAT_B8G8R8A8;
+    }
+  }
+
+  return FORMAT_B8G8R8A8;
+}
+
+static inline Rect ToRect(const D2D1_RECT_F &aRect)
+{
+  return Rect(aRect.left, aRect.top, aRect.right - aRect.left, aRect.bottom - aRect.top);
+}
+
+static inline DXGI_FORMAT DXGIFormat(SurfaceFormat aFormat)
+{
+  switch (aFormat) {
+  case FORMAT_B8G8R8A8:
+    return DXGI_FORMAT_B8G8R8A8_UNORM;
+  case FORMAT_B8G8R8X8:
+    return DXGI_FORMAT_B8G8R8A8_UNORM;
+  case FORMAT_A8:
+    return DXGI_FORMAT_A8_UNORM;
+  }
+
+  return DXGI_FORMAT_UNKNOWN;
+}
+
+static inline D2D1_ALPHA_MODE AlphaMode(SurfaceFormat aFormat)
+{
+  switch (aFormat) {
+  case FORMAT_B8G8R8X8:
+    return D2D1_ALPHA_MODE_IGNORE;
+  }
+
+  return D2D1_ALPHA_MODE_PREMULTIPLIED;
+}
+
+static inline int BytesPerPixel(SurfaceFormat aFormat)
+{
+  switch (aFormat) {
+  case FORMAT_A8:
+    return 1;
+  default:
+    return 4;
+  }
+}
+
+/**
+ * This structure is used to pass rectangles to our shader constant. We can use
+ * this for passing rectangular areas to SetVertexShaderConstant. In the format
+ * of a 4 component float(x,y,width,height). Our vertex shader can then use
+ * this to construct rectangular positions from the 0,0-1,1 quad that we source
+ * it with.
+ */
+struct ShaderConstantRectD3D10
+{
+  float mX, mY, mWidth, mHeight;
+  ShaderConstantRectD3D10(float aX, float aY, float aWidth, float aHeight)
+    : mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight)
+  { }
+
+  // For easy passing to SetVertexShaderConstantF.
+  operator float* () { return &mX; }
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_HELPERSD2D_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Logging.h
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_LOGGING_H_
+#define MOZILLA_GFX_LOGGING_H_
+
+#include <string>
+#include <sstream>
+
+#include "Point.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#ifdef PR_LOGGING
+#include <prlog.h>
+
+extern PRLogModuleInfo *sGFX2DLog;
+#endif
+
+namespace mozilla {
+namespace gfx {
+
+const int LOG_DEBUG = 1;
+const int LOG_WARNING = 2;
+
+#ifdef PR_LOGGING
+
+inline PRLogModuleLevel PRLogLevelForLevel(int aLevel) {
+  switch (aLevel) {
+  case LOG_DEBUG:
+    return PR_LOG_DEBUG;
+  case LOG_WARNING:
+    return PR_LOG_WARNING;
+  }
+  return PR_LOG_DEBUG;
+}
+
+#endif
+
+extern int sGfxLogLevel;
+
+static void OutputMessage(const std::string &aString, int aLevel) {
+#if defined(WIN32) && !defined(PR_LOGGING)
+  if (aLevel >= sGfxLogLevel) {
+    ::OutputDebugStringA(aString.c_str());
+  }
+#elif defined(PR_LOGGING)
+  if (PR_LOG_TEST(sGFX2DLog, PRLogLevelForLevel(aLevel))) {
+    PR_LogPrint(aString.c_str());
+  }
+#else
+  if (aLevel >= sGfxLogLevel) {
+    printf(aString.c_str());
+  }
+#endif
+}
+
+class NoLog
+{
+public:
+  NoLog() {}
+  ~NoLog() {}
+
+  template<typename T>
+  NoLog &operator <<(const T &aLogText) { return *this; }
+};
+
+template<int L>
+class Log
+{
+public:
+  Log() {}
+  ~Log() { mMessage << '\n'; WriteLog(mMessage.str()); }
+
+  Log &operator <<(const std::string &aLogText) { mMessage << aLogText; return *this; }
+  Log &operator <<(unsigned int aInt) { mMessage << aInt; return *this; }
+  Log &operator <<(const Size &aSize)
+    { mMessage << "(" << aSize.width << "x" << aSize.height << ")"; return *this; }
+  Log &operator <<(const IntSize &aSize)
+    { mMessage << "(" << aSize.width << "x" << aSize.height << ")"; return *this; }
+
+private:
+
+  void WriteLog(const std::string &aString) {
+    OutputMessage(aString, L);
+  }
+
+  std::stringstream mMessage;
+};
+
+typedef Log<LOG_DEBUG> DebugLog;
+typedef Log<LOG_WARNING> WarningLog;
+
+#ifdef GFX_LOG_DEBUG
+#define gfxDebug DebugLog
+#else
+#define gfxDebug if (1) ; else NoLog
+#endif
+#ifdef GFX_LOG_WARNING
+#define gfxWarning WarningLog
+#else
+#define gfxWarning if (1) ; else NoLog
+#endif
+
+}
+}
+
+#endif /* MOZILLA_GFX_LOGGING_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Makefile.in
@@ -0,0 +1,100 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Corporation code.
+#
+# The Initial Developer of the Original Code is Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Bas Schouten <bschouten@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= gfx2d
+LIBRARY_NAME	= gfx2d
+LIBXUL_LIBRARY	= 1
+EXPORT_LIBRARY	= 1
+
+EXPORTS_NAMESPACES = mozilla/gfx
+EXPORTS_mozilla/gfx	= \
+        2D.h \
+        BasePoint.h \
+        BaseMargin.h \
+        BaseRect.h \
+        BaseSize.h \
+        Point.h \
+        Matrix.h \
+        Rect.h \
+        Types.h \
+	$(NULL)
+
+CPPSRCS	= \
+	Factory.cpp \
+        Matrix.cpp \
+        DrawTargetCairo.cpp \
+        SourceSurfaceCairo.cpp \
+        $(NULL)
+
+DEFINES += -DMOZ_GFX -DUSE_CAIRO
+
+ifdef MOZ_DEBUG
+DEFINES += -DGFX_LOG_DEBUG -DGFX_LOG_WARNING
+endif
+
+ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
+CPPSRCS	+= \
+        DrawTargetD2D.cpp \
+        SourceSurfaceD2D.cpp \
+        SourceSurfaceD2DTarget.cpp \
+        PathD2D.cpp \
+        ScaledFontDWrite.cpp \
+	$(NULL)
+
+DEFINES += -DWIN32
+endif
+
+#ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
+#CPPSRCS	+= \
+#        DrawTargetCG.cpp \
+#        SourceSurfaceCG.cpp \
+#	$(NULL)
+#
+## Always link with OpenGL/AGL
+#EXTRA_DSO_LDOPTS += -framework OpenGL -framework AGL -framework QuickTime -framework AppKit -framework QuartzCore
+#endif
+
+
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Matrix.cpp
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "Matrix.h"
+#include <math.h>
+
+namespace mozilla {
+namespace gfx {
+
+Matrix
+Matrix::Rotation(Float aAngle)
+{
+  Matrix newMatrix;
+
+  Float s = sin(aAngle);
+  Float c = cos(aAngle);
+
+  newMatrix._11 = c;
+  newMatrix._12 = s;
+  newMatrix._21 = -s;
+  newMatrix._22 = c;
+  
+  return newMatrix;
+}
+
+Rect
+Matrix::TransformBounds(const Rect &aRect) const
+{
+  int i;
+  Point quad[4];
+  Float min_x, max_x;
+  Float min_y, max_y;
+
+  quad[0] = *this * aRect.TopLeft();
+  quad[1] = *this * aRect.TopRight();
+  quad[2] = *this * aRect.BottomLeft();
+  quad[3] = *this * aRect.BottomRight();
+
+  min_x = max_x = quad[0].x;
+  min_y = max_y = quad[0].y;
+
+  for (i = 1; i < 4; i++) {
+    if (quad[i].x < min_x)
+      min_x = quad[i].x;
+    if (quad[i].x > max_x)
+      max_x = quad[i].x;
+
+    if (quad[i].y < min_y)
+      min_y = quad[i].y;
+    if (quad[i].y > max_y)
+      max_y = quad[i].y;
+  }
+
+  return Rect(min_x, min_y, max_x - min_x, max_y - min_y);
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Matrix.h
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_MATRIX_H_
+#define MOZILLA_GFX_MATRIX_H_
+
+#include "Types.h"
+#include "Rect.h"
+#include "Point.h"
+#include <math.h>
+
+namespace mozilla {
+namespace gfx {
+
+class Matrix
+{
+public:
+  Matrix()
+    : _11(1.0f), _12(0)
+    , _21(0), _22(1.0f)
+    , _31(0), _32(0)
+  {}
+  Matrix(Float a11, Float a12, Float a21, Float a22, Float a31, Float a32)
+    : _11(a11), _12(a12)
+    , _21(a21), _22(a22)
+    , _31(a31), _32(a32)
+  {}
+  Float _11, _12;
+  Float _21, _22;
+  Float _31, _32;
+
+  Point operator *(const Point &aPoint) const
+  {
+    Point retPoint;
+
+    retPoint.x = aPoint.x * _11 + aPoint.y * _21 + _31;
+    retPoint.y = aPoint.x * _12 + aPoint.y * _22 + _32;
+
+    return retPoint;
+  }
+
+  Rect TransformBounds(const Rect& rect) const;
+
+  // Apply a scale to this matrix. This scale will be applied -before- the
+  // existing transformation of the matrix.
+  Matrix &Scale(Float aX, Float aY)
+  {
+    _11 *= aX;
+    _12 *= aX;
+    _21 *= aY;
+    _22 *= aY;
+
+    return *this;
+  }
+
+  Matrix &Translate(Float aX, Float aY)
+  {
+    _31 += _11 * aX + _21 * aY;
+    _32 += _12 * aX + _22 * aY;
+
+    return *this;
+  }
+
+  bool Invert()
+  {
+    // Compute co-factors.
+    Float A = _22;
+    Float B = -_21;
+    Float C = _21 * _32 - _22 * _31;
+    Float D = -_12;
+    Float E = _11;
+    Float F = _31 * _12 - _11 * _32;
+
+    Float det = Determinant();
+
+    if (!det) {
+      return false;
+    }
+
+    Float inv_det = 1 / det;
+
+    _11 = inv_det * A;
+    _12 = inv_det * D;
+    _21 = inv_det * B;
+    _22 = inv_det * E;
+    _31 = inv_det * C;
+    _32 = inv_det * F;
+
+    return true;
+  }
+
+  Float Determinant() const
+  {
+    return _11 * _22 - _12 * _21;
+  }
+  
+  static Matrix Rotation(Float aAngle);
+
+  Matrix operator*(const Matrix &aMatrix) const
+  {
+    Matrix resultMatrix;
+
+    resultMatrix._11 = this->_11 * aMatrix._11 + this->_12 * aMatrix._21;
+    resultMatrix._12 = this->_11 * aMatrix._12 + this->_12 * aMatrix._22;
+    resultMatrix._21 = this->_21 * aMatrix._11 + this->_22 * aMatrix._21;
+    resultMatrix._22 = this->_21 * aMatrix._12 + this->_22 * aMatrix._22;
+    resultMatrix._31 = this->_31 * aMatrix._11 + this->_32 * aMatrix._21 + aMatrix._31;
+    resultMatrix._32 = this->_31 * aMatrix._12 + this->_32 * aMatrix._22 + aMatrix._32;
+
+    return resultMatrix;
+  }
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_MATRIX_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/PathD2D.cpp
@@ -0,0 +1,348 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#pragma once
+
+#include "PathD2D.h"
+#include "HelpersD2D.h"
+#include <math.h>
+#include "DrawTargetD2D.h"
+#include "Logging.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+namespace mozilla {
+namespace gfx {
+
+// This class exists as a wrapper for ID2D1SimplifiedGeometry sink, it allows
+// a geometry to be duplicated into a geometry sink, while removing the final
+// figure end and thus allowing a figure that was implicitly closed to be
+// continued.
+class OpeningGeometrySink : public ID2D1SimplifiedGeometrySink
+{
+public:
+  OpeningGeometrySink(ID2D1SimplifiedGeometrySink *aSink)
+    : mSink(aSink)
+    , mNeedsFigureEnded(false)
+  {
+  }
+
+  HRESULT STDMETHODCALLTYPE QueryInterface(const IID &aIID, void **aPtr)
+  {
+    if (!aPtr) {
+      return E_POINTER;
+    }
+
+    if (aIID == IID_IUnknown) {
+      *aPtr = static_cast<IUnknown*>(this);
+      return S_OK;
+    } else if (aIID == IID_ID2D1SimplifiedGeometrySink) {
+      *aPtr = static_cast<ID2D1SimplifiedGeometrySink*>(this);
+      return S_OK;
+    }
+
+    return E_NOINTERFACE;
+  }
+
+  ULONG STDMETHODCALLTYPE AddRef()
+  {
+    return 1;
+  }
+
+  ULONG STDMETHODCALLTYPE Release()
+  {
+    return 1;
+  }
+
+  // We ignore SetFillMode, the copier will decide.
+  STDMETHOD_(void, SetFillMode)(D2D1_FILL_MODE aMode)
+  { EnsureFigureEnded(); return; }
+  STDMETHOD_(void, BeginFigure)(D2D1_POINT_2F aPoint, D2D1_FIGURE_BEGIN aBegin)
+  { EnsureFigureEnded(); return mSink->BeginFigure(aPoint, aBegin); }
+  STDMETHOD_(void, AddLines)(const D2D1_POINT_2F *aLines, UINT aCount)
+  { EnsureFigureEnded(); return mSink->AddLines(aLines, aCount); }
+  STDMETHOD_(void, AddBeziers)(const D2D1_BEZIER_SEGMENT *aSegments, UINT aCount)
+  { EnsureFigureEnded(); return mSink->AddBeziers(aSegments, aCount); }
+  STDMETHOD(Close)()
+  { /* Should never be called! */ return S_OK; }
+  STDMETHOD_(void, SetSegmentFlags)(D2D1_PATH_SEGMENT aFlags)
+  { return mSink->SetSegmentFlags(aFlags); }
+
+  // This function is special - it's the reason this class exists.
+  // It needs to intercept the very last endfigure. So that a user can
+  // continue writing to this sink as if they never stopped.
+  STDMETHOD_(void, EndFigure)(D2D1_FIGURE_END aEnd)
+  {
+    if (aEnd == D2D1_FIGURE_END_CLOSED) {
+      return mSink->EndFigure(aEnd);
+    } else {
+      mNeedsFigureEnded = true;
+    }
+  }
+private:
+  void EnsureFigureEnded()
+  {
+    if (mNeedsFigureEnded) {
+      mSink->EndFigure(D2D1_FIGURE_END_OPEN);
+      mNeedsFigureEnded = false;
+    }
+  }
+
+  ID2D1SimplifiedGeometrySink *mSink;
+  bool mNeedsFigureEnded;
+};
+
+PathBuilderD2D::~PathBuilderD2D()
+{
+}
+
+void
+PathBuilderD2D::MoveTo(const Point &aPoint)
+{
+  if (mFigureActive) {
+    mSink->EndFigure(D2D1_FIGURE_END_OPEN);
+    mFigureActive = false;
+  }
+  EnsureActive(aPoint);
+  mCurrentPoint = aPoint;
+}
+
+void
+PathBuilderD2D::LineTo(const Point &aPoint)
+{
+  EnsureActive(aPoint);
+  mSink->AddLine(D2DPoint(aPoint));
+
+  mCurrentPoint = aPoint;
+}
+
+void
+PathBuilderD2D::BezierTo(const Point &aCP1,
+                         const Point &aCP2,
+                         const Point &aCP3)
+  {
+  EnsureActive(aCP1);
+  mSink->AddBezier(D2D1::BezierSegment(D2DPoint(aCP1),
+                                       D2DPoint(aCP2),
+                                       D2DPoint(aCP3)));
+
+  mCurrentPoint = aCP3;
+}
+
+void
+PathBuilderD2D::QuadraticBezierTo(const Point &aCP1,
+                                  const Point &aCP2)
+{
+  EnsureActive(aCP1);
+  mSink->AddQuadraticBezier(D2D1::QuadraticBezierSegment(D2DPoint(aCP1),
+                                                         D2DPoint(aCP2)));
+
+  mCurrentPoint = aCP2;
+}
+
+void
+PathBuilderD2D::Close()
+{
+  if (mFigureActive) {
+    mSink->EndFigure(D2D1_FIGURE_END_CLOSED);
+
+    mFigureActive = false;
+
+    EnsureActive(mBeginPoint);
+  }
+}
+
+void
+PathBuilderD2D::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
+                 Float aEndAngle, bool aAntiClockwise)
+{
+  if (aAntiClockwise && aStartAngle < aEndAngle) {
+    // D2D does things a little differently, and draws the arc by specifying an
+    // beginning and an end point. This means the circle will be the wrong way
+    // around if the start angle is smaller than the end angle. It might seem
+    // tempting to invert aAntiClockwise but that would change the sweeping
+    // direction of the arc to instead we exchange start/begin.
+    Float oldStart = aStartAngle;
+    aStartAngle = aEndAngle;
+    aEndAngle = oldStart;
+  }
+
+  // XXX - Workaround for now, D2D does not appear to do the desired thing when
+  // the angle sweeps a complete circle.
+  if (aEndAngle - aStartAngle >= 2 * M_PI) {
+    aEndAngle = Float(aStartAngle + M_PI * 1.9999);
+  } else if (aStartAngle - aEndAngle >= 2 * M_PI) {
+    aStartAngle = Float(aEndAngle + M_PI * 1.9999);
+  }
+
+  Point startPoint;
+  startPoint.x = aOrigin.x + aRadius * cos(aStartAngle);
+  startPoint.y = aOrigin.y + aRadius * sin(aStartAngle);
+
+  if (!mFigureActive) {
+    EnsureActive(startPoint);
+  } else {
+    mSink->AddLine(D2DPoint(startPoint));
+  }
+
+  Point endPoint;
+  endPoint.x = aOrigin.x + aRadius * cos(aEndAngle);
+  endPoint.y = aOrigin.y + aRadius * sin(aEndAngle);
+
+  D2D1_ARC_SIZE arcSize = D2D1_ARC_SIZE_SMALL;
+
+  if (aAntiClockwise) {
+    if (aStartAngle - aEndAngle > M_PI) {
+      arcSize = D2D1_ARC_SIZE_LARGE;
+    }
+  } else {
+    if (aEndAngle - aStartAngle > M_PI) {
+      arcSize = D2D1_ARC_SIZE_LARGE;
+    }
+  }
+
+  mSink->AddArc(D2D1::ArcSegment(D2DPoint(endPoint),
+                                 D2D1::SizeF(aRadius, aRadius),
+                                 0.0f,
+                                 aAntiClockwise ? D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE :
+                                                  D2D1_SWEEP_DIRECTION_CLOCKWISE,
+                                 arcSize));
+
+  mCurrentPoint = endPoint;
+}
+
+Point
+PathBuilderD2D::CurrentPoint() const
+{
+  return mCurrentPoint;
+}
+
+void
+PathBuilderD2D::EnsureActive(const Point &aPoint)
+{
+  if (!mFigureActive) {
+    mSink->BeginFigure(D2DPoint(aPoint), D2D1_FIGURE_BEGIN_FILLED);
+    mBeginPoint = aPoint;
+    mFigureActive = true;
+  }
+}
+
+TemporaryRef<Path>
+PathBuilderD2D::Finish()
+{
+  if (mFigureActive) {
+    mSink->EndFigure(D2D1_FIGURE_END_OPEN);
+  }
+
+  HRESULT hr = mSink->Close();
+  if (FAILED(hr)) {
+    gfxDebug() << "Failed to close PathSink. Code: " << hr;
+    return NULL;
+  }
+
+  return new PathD2D(mGeometry, mFigureActive, mCurrentPoint, mFillRule);
+}
+
+TemporaryRef<PathBuilder>
+PathD2D::CopyToBuilder(FillRule aFillRule) const
+{
+  return TransformedCopyToBuilder(Matrix(), aFillRule);
+}
+
+TemporaryRef<PathBuilder>
+PathD2D::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
+{
+  RefPtr<ID2D1PathGeometry> path;
+  HRESULT hr = DrawTargetD2D::factory()->CreatePathGeometry(byRef(path));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create PathGeometry. Code: " << hr;
+    return NULL;
+  }
+
+  RefPtr<ID2D1GeometrySink> sink;
+  hr = path->Open(byRef(sink));
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to open Geometry for writing. Code: " << hr;
+    return NULL;
+  }
+
+  if (aFillRule == FILL_WINDING) {
+    sink->SetFillMode(D2D1_FILL_MODE_WINDING);
+  }
+
+  if (mEndedActive) {
+    OpeningGeometrySink wrapSink(sink);
+    mGeometry->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
+                        D2DMatrix(aTransform),
+                        &wrapSink);
+  } else {
+    mGeometry->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
+                        D2DMatrix(aTransform),
+                        sink);
+  }
+
+  RefPtr<PathBuilderD2D> pathBuilder = new PathBuilderD2D(sink, path, mFillRule);
+  
+  pathBuilder->mCurrentPoint = aTransform * mEndPoint;
+  
+  if (mEndedActive) {
+    pathBuilder->mFigureActive = true;
+  }
+
+  return pathBuilder;
+}
+
+bool
+PathD2D::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const
+{
+  BOOL result;
+
+  HRESULT hr = mGeometry->FillContainsPoint(D2DPoint(aPoint), D2DMatrix(aTransform), 0.001f, &result);
+
+  if (FAILED(hr)) {
+    // Log
+    return false;
+  }
+
+  return !!result;
+}
+
+}
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/2d/PathD2D.h
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_PATHD2D_H_
+#define MOZILLA_GFX_PATHD2D_H_
+
+#include "2D.h"
+#include <D2D1.h>
+
+namespace mozilla {
+namespace gfx {
+
+class PathD2D;
+
+class PathBuilderD2D : public PathBuilder
+{
+public:
+  PathBuilderD2D(ID2D1GeometrySink *aSink, ID2D1PathGeometry *aGeom, FillRule aFillRule)
+    : mSink(aSink)
+    , mGeometry(aGeom)
+    , mFigureActive(false)
+    , mFillRule(aFillRule)
+  {
+  }
+  virtual ~PathBuilderD2D();
+
+  virtual void MoveTo(const Point &aPoint);
+  virtual void LineTo(const Point &aPoint);
+  virtual void BezierTo(const Point &aCP1,
+                        const Point &aCP2,
+                        const Point &aCP3);
+  virtual void QuadraticBezierTo(const Point &aCP1,
+                                 const Point &aCP2);
+  virtual void Close();
+  virtual void Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
+                   Float aEndAngle, bool aAntiClockwise = false);
+  virtual Point CurrentPoint() const;
+
+  virtual TemporaryRef<Path> Finish();
+
+  ID2D1GeometrySink *GetSink() { return mSink; }
+
+private:
+  friend class PathD2D;
+
+  void EnsureActive(const Point &aPoint);
+
+  RefPtr<ID2D1GeometrySink> mSink;
+  RefPtr<ID2D1PathGeometry> mGeometry;
+
+  bool mFigureActive;
+  Point mCurrentPoint;
+  Point mBeginPoint;
+  FillRule mFillRule;
+};
+
+class PathD2D : public Path
+{
+public:
+  PathD2D(ID2D1PathGeometry *aGeometry, bool aEndedActive,
+          const Point &aEndPoint, FillRule aFillRule)
+    : mGeometry(aGeometry)
+    , mEndedActive(aEndedActive)
+    , mEndPoint(aEndPoint)
+    , mFillRule(aFillRule)
+  {}
+  
+  virtual BackendType GetBackendType() const { return BACKEND_DIRECT2D; }
+
+  virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FILL_WINDING) const;
+  virtual TemporaryRef<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
+                                                             FillRule aFillRule = FILL_WINDING) const;
+
+  virtual bool ContainsPoint(const Point &aPoint, const Matrix &aTransform) const;
+
+  virtual FillRule GetFillRule() const { return mFillRule; }
+
+  ID2D1Geometry *GetGeometry() { return mGeometry; }
+
+private:
+  friend class DrawTargetD2D;
+
+  mutable RefPtr<ID2D1PathGeometry> mGeometry;
+  bool mEndedActive;
+  Point mEndPoint;
+  FillRule mFillRule;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_PATHD2D_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Point.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_POINT_H_
+#define MOZILLA_GFX_POINT_H_
+
+#include "Types.h"
+#include "BasePoint.h"
+#include "BaseSize.h"
+
+namespace mozilla {
+namespace gfx {
+
+struct Point :
+  public BasePoint<Float, Point> {
+  typedef BasePoint<Float, Point> Super;
+  Point() : Super() {}
+  Point(Float aX, Float aY) : Super(aX, aY) {}
+};
+
+struct IntPoint :
+  public BasePoint<int32_t, Point> {
+  typedef BasePoint<int32_t, Point> Super;
+  IntPoint() : Super() {}
+  IntPoint(int32_t aX, int32_t aY) : Super(aX, aY) {}
+};
+
+struct Size :
+  public BaseSize<Float, Size> {
+  typedef BaseSize<Float, Size> Super;
+
+  Size() : Super() {}
+  Size(Float aWidth, Float aHeight) : Super(aWidth, aHeight) {}
+};
+
+struct IntSize :
+  public BaseSize<int32_t, IntSize> {
+  typedef BaseSize<int32_t, IntSize> Super;
+
+  IntSize() : Super() {}
+  IntSize(int32_t aWidth, int32_t aHeight) : Super(aWidth, aHeight) {}
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_POINT_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Rect.h
@@ -0,0 +1,83 @@
+/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (Sub) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Robert O'Callahan <robert@ocallahan.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_RECT_H_
+#define MOZILLA_GFX_RECT_H_
+
+#include "BaseRect.h"
+#include "BaseMargin.h"
+#include "Point.h"
+
+namespace mozilla {
+namespace gfx {
+
+struct Margin :
+  public BaseMargin<Float, Margin> {
+  typedef BaseMargin<Float, Margin> Super;
+
+  // Constructors
+  Margin(const Margin& aMargin) : Super(aMargin) {}
+  Margin(Float aLeft,  Float aTop, Float aRight, Float aBottom)
+    : Super(aLeft, aTop, aRight, aBottom) {}
+};
+
+struct Rect :
+    public BaseRect<Float, Rect, Point, Size, Margin> {
+    typedef BaseRect<Float, Rect, Point, mozilla::gfx::Size, Margin> Super;
+
+    Rect() : Super() {}
+    Rect(Point aPos, mozilla::gfx::Size aSize) :
+        Super(aPos, aSize) {}
+    Rect(Float _x, Float _y, Float _width, Float _height) :
+        Super(_x, _y, _width, _height) {}
+};
+
+struct IntRect :
+    public BaseRect<int32_t, IntRect, IntPoint, IntSize, Margin> {
+    typedef BaseRect<int32_t, IntRect, IntPoint, mozilla::gfx::IntSize, Margin> Super;
+
+    IntRect() : Super() {}
+    IntRect(IntPoint aPos, mozilla::gfx::IntSize aSize) :
+        Super(aPos, aSize) {}
+    IntRect(int32_t _x, int32_t _y, int32_t _width, int32_t _height) :
+        Super(_x, _y, _width, _height) {}
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_RECT_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontDWrite.cpp
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ScaledFontDWrite.h"
+#include "PathD2D.h"
+
+#include <vector>
+
+namespace mozilla {
+namespace gfx {
+
+TemporaryRef<Path>
+ScaledFontDWrite::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
+{
+  if (aTarget->GetType() != BACKEND_DIRECT2D) {
+    // For now we only support Direct2D.
+    return NULL;
+  }
+
+  RefPtr<PathBuilder> pathBuilder = aTarget->CreatePathBuilder();
+
+  PathBuilderD2D *pathBuilderD2D =
+    static_cast<PathBuilderD2D*>(pathBuilder.get());
+
+  std::vector<UINT16> indices;
+  std::vector<FLOAT> advances;
+  std::vector<DWRITE_GLYPH_OFFSET> offsets;
+  indices.resize(aBuffer.mNumGlyphs);
+  advances.resize(aBuffer.mNumGlyphs);
+  offsets.resize(aBuffer.mNumGlyphs);
+
+  memset(&advances.front(), 0, sizeof(FLOAT) * aBuffer.mNumGlyphs);
+  for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
+    indices[i] = aBuffer.mGlyphs[i].mIndex;
+    offsets[i].advanceOffset = aBuffer.mGlyphs[i].mPosition.x;
+    offsets[i].ascenderOffset = -aBuffer.mGlyphs[i].mPosition.y;
+  }
+
+  mFontFace->GetGlyphRunOutline(mSize, &indices.front(), &advances.front(),
+                                &offsets.front(), aBuffer.mNumGlyphs,
+                                FALSE, FALSE, pathBuilderD2D->GetSink());
+
+  return pathBuilder->Finish();
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontDWrite.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_SCALEDFONTDWRITE_H_
+#define MOZILLA_GFX_SCALEDFONTDWRITE_H_
+
+#include "2D.h"
+#include <dwrite.h>
+
+namespace mozilla {
+namespace gfx {
+
+class ScaledFontDWrite : public ScaledFont
+{
+public:
+  ScaledFontDWrite(IDWriteFontFace *aFont, Float aSize)
+    : mFontFace(aFont)
+    , mSize(aSize)
+  {}
+
+  virtual FontType GetType() const { return FONT_DWRITE; }
+
+  virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
+
+private:
+  friend class DrawTargetD2D;
+
+  RefPtr<IDWriteFontFace> mFontFace;
+  Float mSize;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_SCALEDFONTDWRITE_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ShadersD2D.fx
@@ -0,0 +1,156 @@
+// We store vertex coordinates and the quad shape in a constant buffer, this is
+// easy to update and allows us to use a single call to set the x, y, w, h of
+// the quad.
+// The QuadDesc and TexCoords both work as follows:
+// The x component is the quad left point, the y component is the top point
+// the z component is the width, and the w component is the height. The quad
+// are specified in viewport coordinates, i.e. { -1.0f, 1.0f, 2.0f, -2.0f }
+// would cover the entire viewport (which runs from <-1.0f, 1.0f> left to right
+// and <-1.0f, 1.0f> -bottom- to top. The TexCoords desc is specified in texture
+// space <0, 1.0f> left to right and top to bottom. The input vertices of the
+// shader stage always form a rectangle from {0, 0} - {1, 1}
+cbuffer cb0
+{
+    float4 QuadDesc;
+    float4 TexCoords;
+}
+
+cbuffer cb1
+{
+    float4 BlurOffsetsH[3];
+    float4 BlurOffsetsV[3];
+    float4 BlurWeights[3];
+    float4 ShadowColor;
+}
+
+struct VS_OUTPUT
+{
+    float4 Position : SV_Position;
+    float2 TexCoord : TEXCOORD0;
+};
+
+Texture2D tex;
+
+sampler sSampler = sampler_state {
+    Filter = MIN_MAG_MIP_LINEAR;
+    Texture = tex;
+    AddressU = Clamp;
+    AddressV = Clamp;
+};
+
+sampler sShadowSampler = sampler_state {
+    Filter = MIN_MAG_MIP_LINEAR;
+    Texture = tex;
+    AddressU = Border;
+    AddressV = Border;
+    BorderColor = float4(0, 0, 0, 0);
+};
+
+RasterizerState TextureRast
+{
+  ScissorEnable = False;
+  CullMode = None;
+};
+
+BlendState ShadowBlendH
+{
+  BlendEnable[0] = False;
+  RenderTargetWriteMask[0] = 0xF;
+};
+
+BlendState ShadowBlendV
+{
+  BlendEnable[0] = True;
+  SrcBlend = One;
+  DestBlend = Inv_Src_Alpha;
+  BlendOp = Add;
+  SrcBlendAlpha = One;
+  DestBlendAlpha = Inv_Src_Alpha;
+  BlendOpAlpha = Add;
+  RenderTargetWriteMask[0] = 0xF;
+};
+
+VS_OUTPUT SampleTextureVS(float3 pos : POSITION)
+{
+    VS_OUTPUT Output;
+    Output.Position.w = 1.0f;
+    Output.Position.x = pos.x * QuadDesc.z + QuadDesc.x;
+    Output.Position.y = pos.y * QuadDesc.w + QuadDesc.y;
+    Output.Position.z = 0;
+    Output.TexCoord.x = pos.x * TexCoords.z + TexCoords.x;
+    Output.TexCoord.y = pos.y * TexCoords.w + TexCoords.y;
+    return Output;
+}
+
+float4 SampleTexturePS( VS_OUTPUT In) : SV_Target
+{
+    return tex.Sample(sSampler, In.TexCoord);
+};
+
+float4 SampleShadowHPS( VS_OUTPUT In) : SV_Target
+{
+    float outputStrength = 0;
+
+    outputStrength += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].x, In.TexCoord.y)).a;
+    outputStrength += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].y, In.TexCoord.y)).a;
+    outputStrength += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].z, In.TexCoord.y)).a;
+    outputStrength += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].w, In.TexCoord.y)).a;
+    outputStrength += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].x, In.TexCoord.y)).a;
+    outputStrength += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].y, In.TexCoord.y)).a;
+    outputStrength += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].z, In.TexCoord.y)).a;
+    outputStrength += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].w, In.TexCoord.y)).a;
+    outputStrength += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[2].x, In.TexCoord.y)).a;
+
+    return ShadowColor * outputStrength;
+};
+
+float4 SampleShadowVPS( VS_OUTPUT In) : SV_Target
+{
+    float4 outputColor = float4(0, 0, 0, 0);
+
+    outputColor += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].x));
+    outputColor += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].y));
+    outputColor += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].z));
+    outputColor += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].w));
+    outputColor += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].x));
+    outputColor += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].y));
+    outputColor += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].z));
+    outputColor += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].w));
+    outputColor += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[2].x));
+
+    return outputColor;
+};
+
+technique10 SampleTexture
+{
+    pass P0
+    {
+        SetRasterizerState(TextureRast);
+        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
+        SetGeometryShader(NULL);
+        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTexturePS()));
+    }
+}
+
+
+technique10 SampleTextureWithShadow
+{
+    // Horizontal pass
+    pass P0
+    {
+        SetRasterizerState(TextureRast);
+        SetBlendState(ShadowBlendH, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
+        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
+        SetGeometryShader(NULL);
+        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleShadowHPS()));
+    }
+    // Vertical pass
+    pass P1
+    {
+        SetRasterizerState(TextureRast);
+        SetBlendState(ShadowBlendV, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
+        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
+        SetGeometryShader(NULL);
+        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleShadowVPS()));
+    }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ShadersD2D.h
@@ -0,0 +1,2411 @@
+#if 0
+//
+// FX Version: fx_4_0
+// Child effect (requires effect pool): false
+//
+// 2 local buffer(s)
+//
+cbuffer cb0
+{
+    float4  QuadDesc;                   // Offset:    0, size:   16
+    float4  TexCoords;                  // Offset:   16, size:   16
+}
+
+cbuffer cb1
+{
+    float4  BlurOffsetsH[3];            // Offset:    0, size:   48
+    float4  BlurOffsetsV[3];            // Offset:   48, size:   48
+    float4  BlurWeights[3];             // Offset:   96, size:   48
+    float4  ShadowColor;                // Offset:  144, size:   16
+}
+
+//
+// 6 local object(s)
+//
+Texture2D tex;
+SamplerState sSampler
+{
+    Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
+    Texture  = tex;
+    AddressU = uint(CLAMP /* 3 */);
+    AddressV = uint(CLAMP /* 3 */);
+};
+SamplerState sShadowSampler
+{
+    Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
+    Texture  = tex;
+    AddressU = uint(BORDER /* 4 */);
+    AddressV = uint(BORDER /* 4 */);
+    BorderColor = float4(0, 0, 0, 0);
+};
+RasterizerState TextureRast
+{
+    ScissorEnable = bool(FALSE /* 0 */);
+    CullMode = uint(NONE /* 1 */);
+};
+BlendState ShadowBlendH
+{
+    BlendEnable[0] = bool(FALSE /* 0 */);
+    RenderTargetWriteMask[0] = byte(0x0f);
+};
+BlendState ShadowBlendV
+{
+    BlendEnable[0] = bool(TRUE /* 1 */);
+    SrcBlend[0] = uint(ONE /* 2 */);
+    DestBlend[0] = uint(INV_SRC_ALPHA /* 6 */);
+    BlendOp[0] = uint(ADD /* 1 */);
+    SrcBlendAlpha[0] = uint(ONE /* 2 */);
+    DestBlendAlpha[0] = uint(INV_SRC_ALPHA /* 6 */);
+    BlendOpAlpha[0] = uint(ADD /* 1 */);
+    RenderTargetWriteMask[0] = byte(0x0f);
+};
+
+//
+// 2 technique(s)
+//
+technique10 SampleTexture
+{
+    pass P0
+    {
+        RasterizerState = TextureRast;
+        VertexShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb0
+            // {
+            //
+            //   float4 QuadDesc;                   // Offset:    0 Size:    16
+            //   float4 TexCoords;                  // Offset:   16 Size:    16
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // cb0                               cbuffer      NA          NA    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // POSITION                 0   xyz         0     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float   xyzw
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Runtime generated constant mappings:
+            //
+            // Target Reg                               Constant Description
+            // ---------- --------------------------------------------------
+            // c0                              Vertex Shader position offset
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                vs_2_x
+                def c3, 0, 1, 0, 0
+                dcl_texcoord v0
+                mad oT0.xy, v0, c2.zwzw, c2
+                mad r0.xy, v0, c1.zwzw, c1
+                add oPos.xy, r0, c0
+                mov oPos.zw, c3.xyxy
+            
+            // approximately 4 instruction slots used
+            vs_4_0
+            dcl_constantbuffer cb0[2], immediateIndexed
+            dcl_input v0.xy
+            dcl_output_siv o0.xyzw, position
+            dcl_output o1.xy
+            mad o0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
+            mov o0.zw, l(0,0,0,1.000000)
+            mad o1.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx
+            ret 
+            // Approximately 4 instruction slots used
+                    
+        };
+        GeometryShader = NULL;
+        PixelShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // sSampler                          sampler      NA          NA    0        1
+            // tex                               texture  float4          2d    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float       
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Target                0   xyzw        0   TARGET  float   xyzw
+            //
+            //
+            // Sampler/Resource to DX9 shader sampler mappings:
+            //
+            // Target Sampler Source Sampler  Source Resource
+            // -------------- --------------- ----------------
+            // s0             s0              t0               
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                ps_2_x
+                dcl t0.xy
+                dcl_2d s0
+                texld r0, t0, s0
+                mov oC0, r0
+            
+            // approximately 2 instruction slots used (1 texture, 1 arithmetic)
+            ps_4_0
+            dcl_sampler s0, mode_default
+            dcl_resource_texture2d (float,float,float,float) t0
+            dcl_input_ps linear v1.xy
+            dcl_output o0.xyzw
+            sample o0.xyzw, v1.xyxx, t0.xyzw, s0
+            ret 
+            // Approximately 2 instruction slots used
+                    
+        };
+    }
+
+}
+
+technique10 SampleTextureWithShadow
+{
+    pass P0
+    {
+        RasterizerState = TextureRast;
+        AB_BlendFactor = float4(1, 1, 1, 1);
+        AB_SampleMask = uint(0xffffffff);
+        BlendState = ShadowBlendH;
+        VertexShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb0
+            // {
+            //
+            //   float4 QuadDesc;                   // Offset:    0 Size:    16
+            //   float4 TexCoords;                  // Offset:   16 Size:    16
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // cb0                               cbuffer      NA          NA    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // POSITION                 0   xyz         0     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float   xyzw
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Runtime generated constant mappings:
+            //
+            // Target Reg                               Constant Description
+            // ---------- --------------------------------------------------
+            // c0                              Vertex Shader position offset
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                vs_2_x
+                def c3, 0, 1, 0, 0
+                dcl_texcoord v0
+                mad oT0.xy, v0, c2.zwzw, c2
+                mad r0.xy, v0, c1.zwzw, c1
+                add oPos.xy, r0, c0
+                mov oPos.zw, c3.xyxy
+            
+            // approximately 4 instruction slots used
+            vs_4_0
+            dcl_constantbuffer cb0[2], immediateIndexed
+            dcl_input v0.xy
+            dcl_output_siv o0.xyzw, position
+            dcl_output o1.xy
+            mad o0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
+            mov o0.zw, l(0,0,0,1.000000)
+            mad o1.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx
+            ret 
+            // Approximately 4 instruction slots used
+                    
+        };
+        GeometryShader = NULL;
+        PixelShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb1
+            // {
+            //
+            //   float4 BlurOffsetsH[3];            // Offset:    0 Size:    48
+            //   float4 BlurOffsetsV[3];            // Offset:   48 Size:    48 [unused]
+            //   float4 BlurWeights[3];             // Offset:   96 Size:    48
+            //   float4 ShadowColor;                // Offset:  144 Size:    16
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // sShadowSampler                    sampler      NA          NA    0        1
+            // tex                               texture  float4          2d    0        1
+            // cb1                               cbuffer      NA          NA    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float       
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Target                0   xyzw        0   TARGET  float   xyzw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c0         cb0             0         3  ( FLT, FLT, FLT, FLT)
+            // c3         cb0             6         4  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Sampler/Resource to DX9 shader sampler mappings:
+            //
+            // Target Sampler Source Sampler  Source Resource
+            // -------------- --------------- ----------------
+            // s0             s0              t0               
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                ps_2_x
+                dcl t0.xy
+                dcl_2d s0
+                add r0.x, t0.x, c0.y
+                mov r0.y, t0.y
+                add r1.x, t0.x, c0.x
+                mov r1.y, t0.y
+                texld r0, r0, s0
+                texld r1, r1, s0
+                mul r0.x, r0.w, c3.y
+                mad r0.x, c3.x, r1.w, r0.x
+                add r1.x, t0.x, c0.z
+                mov r1.y, t0.y
+                add r2.x, t0.x, c0.w
+                mov r2.y, t0.y
+                texld r1, r1, s0
+                texld r2, r2, s0
+                mad r0.x, c3.z, r1.w, r0.x
+                mad r0.x, c3.w, r2.w, r0.x
+                add r1.x, t0.x, c1.x
+                mov r1.y, t0.y
+                add r2.x, t0.x, c1.y
+                mov r2.y, t0.y
+                texld r1, r1, s0
+                texld r2, r2, s0
+                mad r0.x, c4.x, r1.w, r0.x
+                mad r0.x, c4.y, r2.w, r0.x
+                add r1.x, t0.x, c1.z
+                mov r1.y, t0.y
+                add r2.x, t0.x, c1.w
+                mov r2.y, t0.y
+                texld r1, r1, s0
+                texld r2, r2, s0
+                mad r0.x, c4.z, r1.w, r0.x
+                mad r0.x, c4.w, r2.w, r0.x
+                add r1.x, t0.x, c2.x
+                mov r1.y, t0.y
+                texld r1, r1, s0
+                mad r0.x, c5.x, r1.w, r0.x
+                mul r0, r0.x, c6
+                mov oC0, r0
+            
+            // approximately 38 instruction slots used (9 texture, 29 arithmetic)
+            ps_4_0
+            dcl_constantbuffer cb0[10], immediateIndexed
+            dcl_sampler s0, mode_default
+            dcl_resource_texture2d (float,float,float,float) t0
+            dcl_input_ps linear v1.xy
+            dcl_output o0.xyzw
+            dcl_temps 4
+            add r0.xyzw, v1.xxxx, cb0[0].zxwy
+            mov r1.xz, r0.yywy
+            mov r1.yw, v1.yyyy
+            sample r2.xyzw, r1.zwzz, t0.xyzw, s0
+            sample r1.xyzw, r1.xyxx, t0.xyzw, s0
+            mul r1.x, r2.w, cb0[6].y
+            mad r1.x, cb0[6].x, r1.w, r1.x
+            mov r0.yw, v1.yyyy
+            sample r2.xyzw, r0.xyxx, t0.xyzw, s0
+            sample r0.xyzw, r0.zwzz, t0.xyzw, s0
+            mad r0.x, cb0[6].z, r2.w, r1.x
+            mad r0.x, cb0[6].w, r0.w, r0.x
+            add r1.xyzw, v1.xxxx, cb0[1].zxwy
+            mov r2.xz, r1.yywy
+            mov r2.yw, v1.yyyy
+            sample r3.xyzw, r2.xyxx, t0.xyzw, s0
+            sample r2.xyzw, r2.zwzz, t0.xyzw, s0
+            mad r0.x, cb0[7].x, r3.w, r0.x
+            mad r0.x, cb0[7].y, r2.w, r0.x
+            mov r1.yw, v1.yyyy
+            sample r2.xyzw, r1.xyxx, t0.xyzw, s0
+            sample r1.xyzw, r1.zwzz, t0.xyzw, s0
+            mad r0.x, cb0[7].z, r2.w, r0.x
+            mad r0.x, cb0[7].w, r1.w, r0.x
+            add r1.x, v1.x, cb0[2].x
+            mov r1.y, v1.y
+            sample r1.xyzw, r1.xyxx, t0.xyzw, s0
+            mad r0.x, cb0[8].x, r1.w, r0.x
+            mul o0.xyzw, r0.xxxx, cb0[9].xyzw
+            ret 
+            // Approximately 30 instruction slots used
+                    
+        };
+    }
+
+    pass P1
+    {
+        RasterizerState = TextureRast;
+        AB_BlendFactor = float4(1, 1, 1, 1);
+        AB_SampleMask = uint(0xffffffff);
+        BlendState = ShadowBlendV;
+        VertexShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb0
+            // {
+            //
+            //   float4 QuadDesc;                   // Offset:    0 Size:    16
+            //   float4 TexCoords;                  // Offset:   16 Size:    16
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // cb0                               cbuffer      NA          NA    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // POSITION                 0   xyz         0     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float   xyzw
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Runtime generated constant mappings:
+            //
+            // Target Reg                               Constant Description
+            // ---------- --------------------------------------------------
+            // c0                              Vertex Shader position offset
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                vs_2_x
+                def c3, 0, 1, 0, 0
+                dcl_texcoord v0
+                mad oT0.xy, v0, c2.zwzw, c2
+                mad r0.xy, v0, c1.zwzw, c1
+                add oPos.xy, r0, c0
+                mov oPos.zw, c3.xyxy
+            
+            // approximately 4 instruction slots used
+            vs_4_0
+            dcl_constantbuffer cb0[2], immediateIndexed
+            dcl_input v0.xy
+            dcl_output_siv o0.xyzw, position
+            dcl_output o1.xy
+            mad o0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
+            mov o0.zw, l(0,0,0,1.000000)
+            mad o1.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx
+            ret 
+            // Approximately 4 instruction slots used
+                    
+        };
+        GeometryShader = NULL;
+        PixelShader = asm {
+            //
+            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+            //
+            //
+            // Buffer Definitions: 
+            //
+            // cbuffer cb1
+            // {
+            //
+            //   float4 BlurOffsetsH[3];            // Offset:    0 Size:    48 [unused]
+            //   float4 BlurOffsetsV[3];            // Offset:   48 Size:    48
+            //   float4 BlurWeights[3];             // Offset:   96 Size:    48
+            //   float4 ShadowColor;                // Offset:  144 Size:    16 [unused]
+            //
+            // }
+            //
+            //
+            // Resource Bindings:
+            //
+            // Name                                 Type  Format         Dim Slot Elements
+            // ------------------------------ ---------- ------- ----------- ---- --------
+            // sShadowSampler                    sampler      NA          NA    0        1
+            // tex                               texture  float4          2d    0        1
+            // cb1                               cbuffer      NA          NA    0        1
+            //
+            //
+            //
+            // Input signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Position              0   xyzw        0      POS  float       
+            // TEXCOORD                 0   xy          1     NONE  float   xy  
+            //
+            //
+            // Output signature:
+            //
+            // Name                 Index   Mask Register SysValue Format   Used
+            // -------------------- ----- ------ -------- -------- ------ ------
+            // SV_Target                0   xyzw        0   TARGET  float   xyzw
+            //
+            //
+            // Constant buffer to DX9 shader constant mappings:
+            //
+            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
+            // ---------- ------- --------- --------- ----------------------
+            // c0         cb0             3         6  ( FLT, FLT, FLT, FLT)
+            //
+            //
+            // Sampler/Resource to DX9 shader sampler mappings:
+            //
+            // Target Sampler Source Sampler  Source Resource
+            // -------------- --------------- ----------------
+            // s0             s0              t0               
+            //
+            //
+            // Level9 shader bytecode:
+            //
+                ps_2_x
+                dcl t0.xy
+                dcl_2d s0
+                add r0.y, t0.y, c0.y
+                mov r0.x, t0.x
+                add r1.y, t0.y, c0.x
+                mov r1.x, t0.x
+                texld r0, r0, s0
+                texld r1, r1, s0
+                mul r0, r0, c3.y
+                mad r0, c3.x, r1, r0
+                add r1.y, t0.y, c0.z
+                mov r1.x, t0.x
+                add r2.y, t0.y, c0.w
+                mov r2.x, t0.x
+                texld r1, r1, s0
+                texld r2, r2, s0
+                mad r0, c3.z, r1, r0
+                mad r0, c3.w, r2, r0
+                add r1.y, t0.y, c1.x
+                mov r1.x, t0.x
+                add r2.y, t0.y, c1.y
+                mov r2.x, t0.x
+                texld r1, r1, s0
+                texld r2, r2, s0
+                mad r0, c4.x, r1, r0
+                mad r0, c4.y, r2, r0
+                add r1.y, t0.y, c1.z
+                mov r1.x, t0.x
+                add r2.y, t0.y, c1.w
+                mov r2.x, t0.x
+                texld r1, r1, s0
+                texld r2, r2, s0
+                mad r0, c4.z, r1, r0
+                mad r0, c4.w, r2, r0
+                add r1.y, t0.y, c2.x
+                mov r1.x, t0.x
+                texld r1, r1, s0
+                mad r0, c5.x, r1, r0
+                mov oC0, r0
+            
+            // approximately 37 instruction slots used (9 texture, 28 arithmetic)
+            ps_4_0
+            dcl_constantbuffer cb0[9], immediateIndexed
+            dcl_sampler s0, mode_default
+            dcl_resource_texture2d (float,float,float,float) t0
+            dcl_input_ps linear v1.xy
+            dcl_output o0.xyzw
+            dcl_temps 4
+            mov r0.xz, v1.xxxx
+            add r1.xyzw, v1.yyyy, cb0[3].xzyw
+            mov r0.yw, r1.xxxz
+            sample r2.xyzw, r0.zwzz, t0.xyzw, s0
+            sample r0.xyzw, r0.xyxx, t0.xyzw, s0
+            mul r2.xyzw, r2.xyzw, cb0[6].yyyy
+            mad r0.xyzw, cb0[6].xxxx, r0.xyzw, r2.xyzw
+            mov r1.xz, v1.xxxx
+            sample r2.xyzw, r1.xyxx, t0.xyzw, s0
+            sample r1.xyzw, r1.zwzz, t0.xyzw, s0
+            mad r0.xyzw, cb0[6].zzzz, r2.xyzw, r0.xyzw
+            mad r0.xyzw, cb0[6].wwww, r1.xyzw, r0.xyzw
+            mov r1.xz, v1.xxxx
+            add r2.xyzw, v1.yyyy, cb0[4].xzyw
+            mov r1.yw, r2.xxxz
+            sample r3.xyzw, r1.xyxx, t0.xyzw, s0
+            sample r1.xyzw, r1.zwzz, t0.xyzw, s0
+            mad r0.xyzw, cb0[7].xxxx, r3.xyzw, r0.xyzw
+            mad r0.xyzw, cb0[7].yyyy, r1.xyzw, r0.xyzw
+            mov r2.xz, v1.xxxx
+            sample r1.xyzw, r2.xyxx, t0.xyzw, s0
+            sample r2.xyzw, r2.zwzz, t0.xyzw, s0
+            mad r0.xyzw, cb0[7].zzzz, r1.xyzw, r0.xyzw
+            mad r0.xyzw, cb0[7].wwww, r2.xyzw, r0.xyzw
+            add r1.y, v1.y, cb0[5].x
+            mov r1.x, v1.x
+            sample r1.xyzw, r1.xyxx, t0.xyzw, s0
+            mad o0.xyzw, cb0[8].xxxx, r1.xyzw, r0.xyzw
+            ret 
+            // Approximately 29 instruction slots used
+                    
+        };
+    }
+
+}
+
+#endif
+
+const BYTE d2deffect[] =
+{
+     68,  88,  66,  67, 245,  80, 
+    253, 174,  31,   0,  29, 195, 
+    254,  34,  10,  37, 101, 204, 
+     99,  74,   1,   0,   0,   0, 
+    216,  40,   0,   0,   1,   0, 
+      0,   0,  36,   0,   0,   0, 
+     70,  88,  49,  48, 172,  40, 
+      0,   0,   1,  16, 255, 254, 
+      2,   0,   0,   0,   6,   0, 
+      0,   0,   6,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  80,  36, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      1,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   6,   0, 
+      0,   0,   6,   0,   0,   0, 
+      0,   0,   0,   0,  99,  98, 
+     48,   0, 102, 108, 111,  97, 
+    116,  52,   0,   8,   0,   0, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0,  16,   0,   0, 
+      0,  16,   0,   0,   0,  16, 
+      0,   0,   0,  10,  33,   0, 
+      0,  81, 117,  97, 100,  68, 
+    101, 115,  99,   0,  84, 101, 
+    120,  67, 111, 111, 114, 100, 
+    115,   0,  99,  98,  49,   0, 
+      8,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+     48,   0,   0,   0,  16,   0, 
+      0,   0,  48,   0,   0,   0, 
+     10,  33,   0,   0,  66, 108, 
+    117, 114,  79, 102, 102, 115, 
+    101, 116, 115,  72,   0,  66, 
+    108, 117, 114,  79, 102, 102, 
+    115, 101, 116, 115,  86,   0, 
+     66, 108, 117, 114,  87, 101, 
+    105, 103, 104, 116, 115,   0, 
+     83, 104,  97, 100, 111, 119, 
+     67, 111, 108, 111, 114,   0, 
+     84, 101, 120, 116, 117, 114, 
+    101,  50,  68,   0, 144,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  12,   0, 
+      0,   0, 116, 101, 120,   0, 
+     83,  97, 109, 112, 108, 101, 
+    114,  83, 116,  97, 116, 101, 
+      0, 186,   0,   0,   0,   2, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,  21,   0,   0,   0, 115, 
+     83,  97, 109, 112, 108, 101, 
+    114,   0,   1,   0,   0,   0, 
+      2,   0,   0,   0,  21,   0, 
+      0,   0,   1,   0,   0,   0, 
+      2,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      2,   0,   0,   0,   3,   0, 
+      0,   0, 115,  83, 104,  97, 
+    100, 111, 119,  83,  97, 109, 
+    112, 108, 101, 114,   0,   1, 
+      0,   0,   0,   2,   0,   0, 
+      0,  21,   0,   0,   0,   1, 
+      0,   0,   0,   2,   0,   0, 
+      0,   4,   0,   0,   0,   1, 
+      0,   0,   0,   2,   0,   0, 
+      0,   4,   0,   0,   0,   4, 
+      0,   0,   0,   1,   0,   0, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0,   1,   0,   0, 
+      0,   0,   0,   0,   0,  82, 
+     97, 115, 116, 101, 114, 105, 
+    122, 101, 114,  83, 116,  97, 
+    116, 101,   0, 103,   1,   0, 
+      0,   2,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   4,   0,   0, 
+      0,  84, 101, 120, 116, 117, 
+    114, 101,  82,  97, 115, 116, 
+      0,   1,   0,   0,   0,   2, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   2, 
+      0,   0,   0,   1,   0,   0, 
+      0,  66, 108, 101, 110, 100, 
+     83, 116,  97, 116, 101,   0, 
+    183,   1,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,  83, 104, 
+     97, 100, 111, 119,  66, 108, 
+    101, 110, 100,  72,   0,   1, 
+      0,   0,   0,   2,   0,   0, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,   3,   0,   0, 
+      0,  15,   0,   0,   0,  83, 
+    104,  97, 100, 111, 119,  66, 
+    108, 101, 110, 100,  86,   0, 
+      1,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   2,   0, 
+      0,   0,   2,   0,   0,   0, 
+      1,   0,   0,   0,   2,   0, 
+      0,   0,   6,   0,   0,   0, 
+      1,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   2,   0, 
+      0,   0,   2,   0,   0,   0, 
+      1,   0,   0,   0,   2,   0, 
+      0,   0,   6,   0,   0,   0, 
+      1,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  97, 109, 112, 108, 101, 
+     84, 101, 120, 116, 117, 114, 
+    101,   0,  80,  48,   0, 152, 
+      3,   0,   0,  68,  88,  66, 
+     67, 219, 222, 190, 170, 104, 
+    118, 127, 154, 100, 214,   1, 
+     86,  70, 204,  61, 202,   1, 
+      0,   0,   0, 152,   3,   0, 
+      0,   6,   0,   0,   0,  56, 
+      0,   0,   0, 228,   0,   0, 
+      0, 168,   1,   0,   0,  36, 
+      2,   0,   0,  12,   3,   0, 
+      0,  64,   3,   0,   0,  65, 
+    111, 110,  57, 164,   0,   0, 
+      0, 164,   0,   0,   0,   0, 
+      2, 254, 255, 112,   0,   0, 
+      0,  52,   0,   0,   0,   1, 
+      0,  36,   0,   0,   0,  48, 
+      0,   0,   0,  48,   0,   0, 
+      0,  36,   0,   1,   0,  48, 
+      0,   0,   0,   0,   0,   2, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   1, 
+      2, 254, 255,  81,   0,   0, 
+      5,   3,   0,  15, 160,   0, 
+      0,   0,   0,   0,   0, 128, 
+     63,   0,   0,   0,   0,   0, 
+      0,   0,   0,  31,   0,   0, 
+      2,   5,   0,   0, 128,   0, 
+      0,  15, 144,   4,   0,   0, 
+      4,   0,   0,   3, 224,   0, 
+      0, 228, 144,   2,   0, 238, 
+    160,   2,   0, 228, 160,   4, 
+      0,   0,   4,   0,   0,   3, 
+    128,   0,   0, 228, 144,   1, 
+      0, 238, 160,   1,   0, 228, 
+    160,   2,   0,   0,   3,   0, 
+      0,   3, 192,   0,   0, 228, 
+    128,   0,   0, 228, 160,   1, 
+      0,   0,   2,   0,   0,  12, 
+    192,   3,   0,  68, 160, 255, 
+    255,   0,   0,  83,  72,  68, 
+     82, 188,   0,   0,   0,  64, 
+      0,   1,   0,  47,   0,   0, 
+      0,  89,   0,   0,   4,  70, 
+    142,  32,   0,   0,   0,   0, 
+      0,   2,   0,   0,   0,  95, 
+      0,   0,   3,  50,  16,  16, 
+      0,   0,   0,   0,   0, 103, 
+      0,   0,   4, 242,  32,  16, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0, 101,   0,   0, 
+      3,  50,  32,  16,   0,   1, 
+      0,   0,   0,  50,   0,   0, 
+     11,  50,  32,  16,   0,   0, 
+      0,   0,   0,  70,  16,  16, 
+      0,   0,   0,   0,   0, 230, 
+    138,  32,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,  70, 
+    128,  32,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,  54, 
+      0,   0,   8, 194,  32,  16, 
+      0,   0,   0,   0,   0,   2, 
+     64,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0, 128, 
+     63,  50,   0,   0,  11,  50, 
+     32,  16,   0,   1,   0,   0, 
+      0,  70,  16,  16,   0,   0, 
+      0,   0,   0, 230, 138,  32, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,  70, 128,  32, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,  62,   0,   0, 
+      1,  83,  84,  65,  84, 116, 
+      0,   0,   0,   4,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   3,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,  82, 
+     68,  69,  70, 224,   0,   0, 
+      0,   1,   0,   0,   0,  64, 
+      0,   0,   0,   1,   0,   0, 
+      0,  28,   0,   0,   0,   0, 
+      4, 254, 255,   0,   1,   0, 
+      0, 174,   0,   0,   0,  60, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,   0,   0,   0, 
+      0,  99,  98,  48,   0,  60, 
+      0,   0,   0,   2,   0,   0, 
+      0,  88,   0,   0,   0,  32, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0, 136, 
+      0,   0,   0,   0,   0,   0, 
+      0,  16,   0,   0,   0,   2, 
+      0,   0,   0, 148,   0,   0, 
+      0,   0,   0,   0,   0, 164, 
+      0,   0,   0,  16,   0,   0, 
+      0,  16,   0,   0,   0,   2, 
+      0,   0,   0, 148,   0,   0, 
+      0,   0,   0,   0,   0,  81, 
+    117,  97, 100,  68, 101, 115, 
+     99,   0, 171, 171, 171,   1, 
+      0,   3,   0,   1,   0,   4, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,  84, 101, 120, 
+     67, 111, 111, 114, 100, 115, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     57,  46,  50,  57,  46,  57, 
+     53,  50,  46,  51,  49,  49, 
+     49,   0, 171,  73,  83,  71, 
+     78,  44,   0,   0,   0,   1, 
+      0,   0,   0,   8,   0,   0, 
+      0,  32,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   3,   0,   0,   0,   0, 
+      0,   0,   0,   7,   3,   0, 
+      0,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0, 171, 171, 
+    171,  79,  83,  71,  78,  80, 
+      0,   0,   0,   2,   0,   0, 
+      0,   8,   0,   0,   0,  56, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   3, 
+      0,   0,   0,   0,   0,   0, 
+      0,  15,   0,   0,   0,  68, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   3, 
+      0,   0,   0,   1,   0,   0, 
+      0,   3,  12,   0,   0,  83, 
+     86,  95,  80, 111, 115, 105, 
+    116, 105, 111, 110,   0,  84, 
+     69,  88,  67,  79,  79,  82, 
+     68,   0, 171, 171, 171, 129, 
+      2,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   2, 
+      0,   0,   0,   0,   0,   0, 
+      0, 188,   2,   0,   0,  68, 
+     88,  66,  67,  57, 173, 135, 
+     37,   0,  15, 237,  50, 142, 
+     80,  59, 160,  81, 240,  60, 
+    171,   1,   0,   0,   0, 188, 
+      2,   0,   0,   6,   0,   0, 
+      0,  56,   0,   0,   0, 164, 
+      0,   0,   0,  16,   1,   0, 
+      0, 140,   1,   0,   0,  48, 
+      2,   0,   0, 136,   2,   0, 
+      0,  65, 111, 110,  57, 100, 
+      0,   0,   0, 100,   0,   0, 
+      0,   0,   2, 255, 255,  60, 
+      0,   0,   0,  40,   0,   0, 
+      0,   0,   0,  40,   0,   0, 
+      0,  40,   0,   0,   0,  40, 
+      0,   1,   0,  36,   0,   0, 
+      0,  40,   0,   0,   0,   0, 
+      0,   1,   2, 255, 255,  31, 
+      0,   0,   2,   0,   0,   0, 
+    128,   0,   0,   3, 176,  31, 
+      0,   0,   2,   0,   0,   0, 
+    144,   0,   8,  15, 160,  66, 
+      0,   0,   3,   0,   0,  15, 
+    128,   0,   0, 228, 176,   0, 
+      8, 228, 160,   1,   0,   0, 
+      2,   0,   8,  15, 128,   0, 
+      0, 228, 128, 255, 255,   0, 
+      0,  83,  72,  68,  82, 100, 
+      0,   0,   0,  64,   0,   0, 
+      0,  25,   0,   0,   0,  90, 
+      0,   0,   3,   0,  96,  16, 
+      0,   0,   0,   0,   0,  88, 
+     24,   0,   4,   0, 112,  16, 
+      0,   0,   0,   0,   0,  85, 
+     85,   0,   0,  98,  16,   0, 
+      3,  50,  16,  16,   0,   1, 
+      0,   0,   0, 101,   0,   0, 
+      3, 242,  32,  16,   0,   0, 
+      0,   0,   0,  69,   0,   0, 
+      9, 242,  32,  16,   0,   0, 
+      0,   0,   0,  70,  16,  16, 
+      0,   1,   0,   0,   0,  70, 
+    126,  16,   0,   0,   0,   0, 
+      0,   0,  96,  16,   0,   0, 
+      0,   0,   0,  62,   0,   0, 
+      1,  83,  84,  65,  84, 116, 
+      0,   0,   0,   2,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   2,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,  82, 
+     68,  69,  70, 156,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   2,   0,   0, 
+      0,  28,   0,   0,   0,   0, 
+      4, 255, 255,   0,   1,   0, 
+      0, 105,   0,   0,   0,  92, 
+      0,   0,   0,   3,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,   0,   0,   0, 
+      0, 101,   0,   0,   0,   2, 
+      0,   0,   0,   5,   0,   0, 
+      0,   4,   0,   0,   0, 255, 
+    255, 255, 255,   0,   0,   0, 
+      0,   1,   0,   0,   0,  12, 
+      0,   0,   0, 115,  83,  97, 
+    109, 112, 108, 101, 114,   0, 
+    116, 101, 120,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  57,  46,  50, 
+     57,  46,  57,  53,  50,  46, 
+     51,  49,  49,  49,   0, 171, 
+    171,  73,  83,  71,  78,  80, 
+      0,   0,   0,   2,   0,   0, 
+      0,   8,   0,   0,   0,  56, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   3, 
+      0,   0,   0,   0,   0,   0, 
+      0,  15,   0,   0,   0,  68, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   3, 
+      0,   0,   0,   1,   0,   0, 
+      0,   3,   3,   0,   0,  83, 
+     86,  95,  80, 111, 115, 105, 
+    116, 105, 111, 110,   0,  84, 
+     69,  88,  67,  79,  79,  82, 
+     68,   0, 171, 171, 171,  79, 
+     83,  71,  78,  44,   0,   0, 
+      0,   1,   0,   0,   0,   8, 
+      0,   0,   0,  32,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   3,   0,   0, 
+      0,   0,   0,   0,   0,  15, 
+      0,   0,   0,  83,  86,  95, 
+     84,  97, 114, 103, 101, 116, 
+      0, 171, 171,  49,   6,   0, 
+      0,   0,   0,   0,   0,  83, 
+     97, 109, 112, 108, 101,  84, 
+    101, 120, 116, 117, 114, 101, 
+     87, 105, 116, 104,  83, 104, 
+     97, 100, 111, 119,   0,   4, 
+      0,   0,   0,   1,   0,   0, 
+      0,   0,   0, 128,  63,   1, 
+      0,   0,   0,   0,   0, 128, 
+     63,   1,   0,   0,   0,   0, 
+      0, 128,  63,   1,   0,   0, 
+      0,   0,   0, 128,  63,   1, 
+      0,   0,   0,   3,   0,   0, 
+      0, 255, 255, 255, 255, 152, 
+      3,   0,   0,  68,  88,  66, 
+     67, 219, 222, 190, 170, 104, 
+    118, 127, 154, 100, 214,   1, 
+     86,  70, 204,  61, 202,   1, 
+      0,   0,   0, 152,   3,   0, 
+      0,   6,   0,   0,   0,  56, 
+      0,   0,   0, 228,   0,   0, 
+      0, 168,   1,   0,   0,  36, 
+      2,   0,   0,  12,   3,   0, 
+      0,  64,   3,   0,   0,  65, 
+    111, 110,  57, 164,   0,   0, 
+      0, 164,   0,   0,   0,   0, 
+      2, 254, 255, 112,   0,   0, 
+      0,  52,   0,   0,   0,   1, 
+      0,  36,   0,   0,   0,  48, 
+      0,   0,   0,  48,   0,   0, 
+      0,  36,   0,   1,   0,  48, 
+      0,   0,   0,   0,   0,   2, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   1, 
+      2, 254, 255,  81,   0,   0, 
+      5,   3,   0,  15, 160,   0, 
+      0,   0,   0,   0,   0, 128, 
+     63,   0,   0,   0,   0,   0, 
+      0,   0,   0,  31,   0,   0, 
+      2,   5,   0,   0, 128,   0, 
+      0,  15, 144,   4,   0,   0, 
+      4,   0,   0,   3, 224,   0, 
+      0, 228, 144,   2,   0, 238, 
+    160,   2,   0, 228, 160,   4, 
+      0,   0,   4,   0,   0,   3, 
+    128,   0,   0, 228, 144,   1, 
+      0, 238, 160,   1,   0, 228, 
+    160,   2,   0,   0,   3,   0, 
+      0,   3, 192,   0,   0, 228, 
+    128,   0,   0, 228, 160,   1, 
+      0,   0,   2,   0,   0,  12, 
+    192,   3,   0,  68, 160, 255, 
+    255,   0,   0,  83,  72,  68, 
+     82, 188,   0,   0,   0,  64, 
+      0,   1,   0,  47,   0,   0, 
+      0,  89,   0,   0,   4,  70, 
+    142,  32,   0,   0,   0,   0, 
+      0,   2,   0,   0,   0,  95, 
+      0,   0,   3,  50,  16,  16, 
+      0,   0,   0,   0,   0, 103, 
+      0,   0,   4, 242,  32,  16, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0, 101,   0,   0, 
+      3,  50,  32,  16,   0,   1, 
+      0,   0,   0,  50,   0,   0, 
+     11,  50,  32,  16,   0,   0, 
+      0,   0,   0,  70,  16,  16, 
+      0,   0,   0,   0,   0, 230, 
+    138,  32,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,  70, 
+    128,  32,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,  54, 
+      0,   0,   8, 194,  32,  16, 
+      0,   0,   0,   0,   0,   2, 
+     64,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0, 128, 
+     63,  50,   0,   0,  11,  50, 
+     32,  16,   0,   1,   0,   0, 
+      0,  70,  16,  16,   0,   0, 
+      0,   0,   0, 230, 138,  32, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,  70, 128,  32, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,  62,   0,   0, 
+      1,  83,  84,  65,  84, 116, 
+      0,   0,   0,   4,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   3,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,  82, 
+     68,  69,  70, 224,   0,   0, 
+      0,   1,   0,   0,   0,  64, 
+      0,   0,   0,   1,   0,   0, 
+      0,  28,   0,   0,   0,   0, 
+      4, 254, 255,   0,   1,   0, 
+      0, 174,   0,   0,   0,  60, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,   0,   0,   0, 
+      0,  99,  98,  48,   0,  60, 
+      0,   0,   0,   2,   0,   0, 
+      0,  88,   0,   0,   0,  32, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0, 136, 
+      0,   0,   0,   0,   0,   0, 
+      0,  16,   0,   0,   0,   2, 
+      0,   0,   0, 148,   0,   0, 
+      0,   0,   0,   0,   0, 164, 
+      0,   0,   0,  16,   0,   0, 
+      0,  16,   0,   0,   0,   2, 
+      0,   0,   0, 148,   0,   0, 
+      0,   0,   0,   0,   0,  81, 
+    117,  97, 100,  68, 101, 115, 
+     99,   0, 171, 171, 171,   1, 
+      0,   3,   0,   1,   0,   4, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,  84, 101, 120, 
+     67, 111, 111, 114, 100, 115, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     57,  46,  50,  57,  46,  57, 
+     53,  50,  46,  51,  49,  49, 
+     49,   0, 171,  73,  83,  71, 
+     78,  44,   0,   0,   0,   1, 
+      0,   0,   0,   8,   0,   0, 
+      0,  32,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   3,   0,   0,   0,   0, 
+      0,   0,   0,   7,   3,   0, 
+      0,  80,  79,  83,  73,  84, 
+     73,  79,  78,   0, 171, 171, 
+    171,  79,  83,  71,  78,  80, 
+      0,   0,   0,   2,   0,   0, 
+      0,   8,   0,   0,   0,  56, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   3, 
+      0,   0,   0,   0,   0,   0, 
+      0,  15,   0,   0,   0,  68, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   3, 
+      0,   0,   0,   1,   0,   0, 
+      0,   3,  12,   0,   0,  83, 
+     86,  95,  80, 111, 115, 105, 
+    116, 105, 111, 110,   0,  84, 
+     69,  88,  67,  79,  79,  82, 
+     68,   0, 171, 171, 171,  65, 
+      9,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   2, 
+      0,   0,   0,   0,   0,   0, 
+      0, 208,   9,   0,   0,  68, 
+     88,  66,  67,  88, 125,  98, 
+     31, 252, 245,  86, 128, 184, 
+    245, 122,  45, 178,  60, 220, 
+     51,   1,   0,   0,   0, 208, 
+      9,   0,   0,   6,   0,   0, 
+      0,  56,   0,   0,   0, 248, 
+      2,   0,   0,   8,   7,   0, 
+      0, 132,   7,   0,   0,  68, 
+      9,   0,   0, 156,   9,   0, 
+      0,  65, 111, 110,  57, 184, 
+      2,   0,   0, 184,   2,   0, 
+      0,   0,   2, 255, 255, 120, 
+      2,   0,   0,  64,   0,   0, 
+      0,   2,   0,  40,   0,   0, 
+      0,  64,   0,   0,   0,  64, 
+      0,   1,   0,  36,   0,   0, 
+      0,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   3, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   6,   0,   4, 
+      0,   3,   0,   0,   0,   0, 
+      0,   1,   2, 255, 255,  31, 
+      0,   0,   2,   0,   0,   0, 
+    128,   0,   0,   3, 176,  31, 
+      0,   0,   2,   0,   0,   0, 
+    144,   0,   8,  15, 160,   2, 
+      0,   0,   3,   0,   0,   1, 
+    128,   0,   0,   0, 176,   0, 
+      0,  85, 160,   1,   0,   0, 
+      2,   0,   0,   2, 128,   0, 
+      0,  85, 176,   2,   0,   0, 
+      3,   1,   0,   1, 128,   0, 
+      0,   0, 176,   0,   0,   0, 
+    160,   1,   0,   0,   2,   1, 
+      0,   2, 128,   0,   0,  85, 
+    176,  66,   0,   0,   3,   0, 
+      0,  15, 128,   0,   0, 228, 
+    128,   0,   8, 228, 160,  66, 
+      0,   0,   3,   1,   0,  15, 
+    128,   1,   0, 228, 128,   0, 
+      8, 228, 160,   5,   0,   0, 
+      3,   0,   0,   1, 128,   0, 
+      0, 255, 128,   3,   0,  85, 
+    160,   4,   0,   0,   4,   0, 
+      0,   1, 128,   3,   0,   0, 
+    160,   1,   0, 255, 128,   0, 
+      0,   0, 128,   2,   0,   0, 
+      3,   1,   0,   1, 128,   0, 
+      0,   0, 176,   0,   0, 170, 
+    160,   1,   0,   0,   2,   1, 
+      0,   2, 128,   0,   0,  85, 
+    176,   2,   0,   0,   3,   2, 
+      0,   1, 128,   0,   0,   0, 
+    176,   0,   0, 255, 160,   1, 
+      0,   0,   2,   2,   0,   2, 
+    128,   0,   0,  85, 176,  66, 
+      0,   0,   3,   1,   0,  15, 
+    128,   1,   0, 228, 128,   0, 
+      8, 228, 160,  66,   0,   0, 
+      3,   2,   0,  15, 128,   2, 
+      0, 228, 128,   0,   8, 228, 
+    160,   4,   0,   0,   4,   0, 
+      0,   1, 128,   3,   0, 170, 
+    160,   1,   0, 255, 128,   0, 
+      0,   0, 128,   4,   0,   0, 
+      4,   0,   0,   1, 128,   3, 
+      0, 255, 160,   2,   0, 255, 
+    128,   0,   0,   0, 128,   2, 
+      0,   0,   3,   1,   0,   1, 
+    128,   0,   0,   0, 176,   1, 
+      0,   0, 160,   1,   0,   0, 
+      2,   1,   0,   2, 128,   0, 
+      0,  85, 176,   2,   0,   0, 
+      3,   2,   0,   1, 128,   0, 
+      0,   0, 176,   1,   0,  85, 
+    160,   1,   0,   0,   2,   2, 
+      0,   2, 128,   0,   0,  85, 
+    176,  66,   0,   0,   3,   1, 
+      0,  15, 128,   1,   0, 228, 
+    128,   0,   8, 228, 160,  66, 
+      0,   0,   3,   2,   0,  15, 
+    128,   2,   0, 228, 128,   0, 
+      8, 228, 160,   4,   0,   0, 
+      4,   0,   0,   1, 128,   4, 
+      0,   0, 160,   1,   0, 255, 
+    128,   0,   0,   0, 128,   4, 
+      0,   0,   4,   0,   0,   1, 
+    128,   4,   0,  85, 160,   2, 
+      0, 255, 128,   0,   0,   0, 
+    128,   2,   0,   0,   3,   1, 
+      0,   1, 128,   0,   0,   0, 
+    176,   1,   0, 170, 160,   1, 
+      0,   0,   2,   1,   0,   2, 
+    128,   0,   0,  85, 176,   2, 
+      0,   0,   3,   2,   0,   1, 
+    128,   0,   0,   0, 176,   1, 
+      0, 255, 160,   1,   0,   0, 
+      2,   2,   0,   2, 128,   0, 
+      0,  85, 176,  66,   0,   0, 
+      3,   1,   0,  15, 128,   1, 
+      0, 228, 128,   0,   8, 228, 
+    160,  66,   0,   0,   3,   2, 
+      0,  15, 128,   2,   0, 228, 
+    128,   0,   8, 228, 160,   4, 
+      0,   0,   4,   0,   0,   1, 
+    128,   4,   0, 170, 160,   1, 
+      0, 255, 128,   0,   0,   0, 
+    128,   4,   0,   0,   4,   0, 
+      0,   1, 128,   4,   0, 255, 
+    160,   2,   0, 255, 128,   0, 
+      0,   0, 128,   2,   0,   0, 
+      3,   1,   0,   1, 128,   0, 
+      0,   0, 176,   2,   0,   0, 
+    160,   1,   0,   0,   2,   1, 
+      0,   2, 128,   0,   0,  85, 
+    176,  66,   0,   0,   3,   1, 
+      0,  15, 128,   1,   0, 228, 
+    128,   0,   8, 228, 160,   4, 
+      0,   0,   4,   0,   0,   1, 
+    128,   5,   0,   0, 160,   1, 
+      0, 255, 128,   0,   0,   0, 
+    128,   5,   0,   0,   3,   0, 
+      0,  15, 128,   0,   0,   0, 
+    128,   6,   0, 228, 160,   1, 
+      0,   0,   2,   0,   8,  15, 
+    128,   0,   0, 228, 128, 255, 
+    255,   0,   0,  83,  72,  68, 
+     82,   8,   4,   0,   0,  64, 
+      0,   0,   0,   2,   1,   0, 
+      0,  89,   0,   0,   4,  70, 
+    142,  32,   0,   0,   0,   0, 
+      0,  10,   0,   0,   0,  90, 
+      0,   0,   3,   0,  96,  16, 
+      0,   0,   0,   0,   0,  88, 
+     24,   0,   4,   0, 112,  16, 
+      0,   0,   0,   0,   0,  85, 
+     85,   0,   0,  98,  16,   0, 
+      3,  50,  16,  16,   0,   1, 
+      0,   0,   0, 101,   0,   0, 
+      3, 242,  32,  16,   0,   0, 
+      0,   0,   0, 104,   0,   0, 
+      2,   4,   0,   0,   0,   0, 
+      0,   0,   8, 242,   0,  16, 
+      0,   0,   0,   0,   0,   6, 
+     16,  16,   0,   1,   0,   0, 
+      0,  38, 135,  32,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,  54,   0,   0,   5,  82, 
+      0,  16,   0,   1,   0,   0, 
+      0,  86,   7,  16,   0,   0, 
+      0,   0,   0,  54,   0,   0, 
+      5, 162,   0,  16,   0,   1, 
+      0,   0,   0,  86,  21,  16, 
+      0,   1,   0,   0,   0,  69, 
+      0,   0,   9, 242,   0,  16, 
+      0,   2,   0,   0,   0, 230, 
+     10,  16,   0,   1,   0,   0, 
+      0,  70, 126,  16,   0,   0, 
+      0,   0,   0,   0,  96,  16, 
+      0,   0,   0,   0,   0,  69, 
+      0,   0,   9, 242,   0,  16, 
+      0,   1,   0,   0,   0,  70, 
+      0,  16,   0,   1,   0,   0, 
+      0,  70, 126,  16,   0,   0, 
+      0,   0,   0,   0,  96,  16, 
+      0,   0,   0,   0,   0,  56, 
+      0,   0,   8,  18,   0,  16, 
+      0,   1,   0,   0,   0,  58, 
+      0,  16,   0,   2,   0,   0, 
+      0,  26, 128,  32,   0,   0, 
+      0,   0,   0,   6,   0,   0, 
+      0,  50,   0,   0,  10,  18, 
+      0,  16,   0,   1,   0,   0, 
+      0,  10, 128,  32,   0,   0, 
+      0,   0,   0,   6,   0,   0, 
+      0,  58,   0,  16,   0,   1, 
+      0,   0,   0,  10,   0,  16, 
+      0,   1,   0,   0,   0,  54, 
+      0,   0,   5, 162,   0,  16, 
+      0,   0,   0,   0,   0,  86, 
+     21,  16,   0,   1,   0,   0, 
+      0,  69,   0,   0,   9, 242, 
+      0,  16,   0,   2,   0,   0, 
+      0,  70,   0,  16,   0,   0, 
+      0,   0,   0,  70, 126,  16, 
+      0,   0,   0,   0,   0,   0, 
+     96,  16,   0,   0,   0,   0, 
+      0,  69,   0,   0,   9, 242, 
+      0,  16,   0,   0,   0,   0, 
+      0, 230,  10,  16,   0,   0, 
+      0,   0,   0,  70, 126,  16, 
+      0,   0,   0,   0,   0,   0, 
+     96,  16,   0,   0,   0,   0, 
+      0,  50,   0,   0,  10,  18, 
+      0,  16,   0,   0,   0,   0, 
+      0,  42, 128,  32,   0,   0, 
+      0,   0,   0,   6,   0,   0, 
+      0,  58,   0,  16,   0,   2, 
+      0,   0,   0,  10,   0,  16, 
+      0,   1,   0,   0,   0,  50, 
+      0,   0,  10,  18,   0,  16, 
+      0,   0,   0,   0,   0,  58, 
+    128,  32,   0,   0,   0,   0, 
+      0,   6,   0,   0,   0,  58, 
+      0,  16,   0,   0,   0,   0, 
+      0,  10,   0,  16,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      8, 242,   0,  16,   0,   1, 
+      0,   0,   0,   6,  16,  16, 
+      0,   1,   0,   0,   0,  38, 
+    135,  32,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,  54, 
+      0,   0,   5,  82,   0,  16, 
+      0,   2,   0,   0,   0,  86, 
+      7,  16,   0,   1,   0,   0, 
+      0,  54,   0,   0,   5, 162, 
+      0,  16,   0,   2,   0,   0, 
+      0,  86,  21,  16,   0,   1, 
+      0,   0,   0,  69,   0,   0, 
+      9, 242,   0,  16,   0,   3, 
+      0,   0,   0,  70,   0,  16, 
+      0,   2,   0,   0,   0,  70, 
+    126,  16,   0,   0,   0,   0, 
+      0,   0,  96,  16,   0,   0, 
+      0,   0,   0,  69,   0,   0, 
+      9, 242,   0,  16,   0,   2, 
+      0,   0,   0, 230,  10,  16, 
+      0,   2,   0,   0,   0,  70, 
+    126,  16,   0,   0,   0,   0, 
+      0,   0,  96,  16,   0,   0, 
+      0,   0,   0,  50,   0,   0, 
+     10,  18,   0,  16,   0,   0, 
+      0,   0,   0,  10, 128,  32, 
+      0,   0,   0,   0,   0,   7, 
+      0,   0,   0,  58,   0,  16, 
+      0,   3,   0,   0,   0,  10, 
+      0,  16,   0,   0,   0,   0, 
+      0,  50,   0,   0,  10,  18, 
+      0,  16,   0,   0,   0,   0, 
+      0,  26, 128,  32,   0,   0, 
+      0,   0,   0,   7,   0,   0, 
+      0,  58,   0,  16,   0,   2, 
+      0,   0,   0,  10,   0,  16, 
+      0,   0,   0,   0,   0,  54, 
+      0,   0,   5, 162,   0,  16, 
+      0,   1,   0,   0,   0,  86, 
+     21,  16,   0,   1,   0,   0, 
+      0,  69,   0,   0,   9, 242, 
+      0,  16,   0,   2,   0,   0, 
+      0,  70,   0,  16,   0,   1, 
+      0,   0,   0,  70, 126,  16, 
+      0,   0,   0,   0,   0,   0, 
+     96,  16,   0,   0,   0,   0, 
+      0,  69,   0,   0,   9, 242, 
+      0,  16,   0,   1,   0,   0, 
+      0, 230,  10,  16,   0,   1, 
+      0,   0,   0,  70, 126,  16, 
+      0,   0,   0,   0,   0,   0, 
+     96,  16,   0,   0,   0,   0, 
+      0,  50,   0,   0,  10,  18, 
+      0,  16,   0,   0,   0,   0, 
+      0,  42, 128,  32,   0,   0, 
+      0,   0,   0,   7,   0,   0, 
+      0,  58,   0,  16,   0,   2, 
+      0,   0,   0,  10,   0,  16, 
+      0,   0,   0,   0,   0,  50, 
+      0,   0,  10,  18,   0,  16, 
+      0,   0,   0,   0,   0,  58, 
+    128,  32,   0,   0,   0,   0, 
+      0,   7,   0,   0,   0,  58, 
+      0,  16,   0,   1,   0,   0, 
+      0,  10,   0,  16,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      8,  18,   0,  16,   0,   1, 
+      0,   0,   0,  10,  16,  16, 
+      0,   1,   0,   0,   0,  10, 
+    128,  32,   0,   0,   0,   0, 
+      0,   2,   0,   0,   0,  54, 
+      0,   0,   5,  34,   0,  16, 
+      0,   1,   0,   0,   0,  26, 
+     16,  16,   0,   1,   0,   0, 
+      0,  69,   0,   0,   9, 242, 
+      0,  16,   0,   1,   0,   0, 
+      0,  70,   0,  16,   0,   1, 
+      0,   0,   0,  70, 126,  16, 
+      0,   0,   0,   0,   0,   0, 
+     96,  16,   0,   0,   0,   0, 
+      0,  50,   0,   0,  10,  18, 
+      0,  16,   0,   0,   0,   0, 
+      0,  10, 128,  32,   0,   0, 
+      0,   0,   0,   8,   0,   0, 
+      0,  58,   0,  16,   0,   1, 
+      0,   0,   0,  10,   0,  16, 
+      0,   0,   0,   0,   0,  56, 
+      0,   0,   8, 242,  32,  16, 
+      0,   0,   0,   0,   0,   6, 
+      0,  16,   0,   0,   0,   0, 
+      0,  70, 142,  32,   0,   0, 
+      0,   0,   0,   9,   0,   0, 
+      0,  62,   0,   0,   1,  83, 
+     84,  65,  84, 116,   0,   0, 
+      0,  30,   0,   0,   0,   4, 
+      0,   0,   0,   0,   0,   0, 
+      0,   2,   0,   0,   0,   5, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   1, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   9,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   9, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,  82,  68,  69, 
+     70, 184,   1,   0,   0,   1, 
+      0,   0,   0, 148,   0,   0, 
+      0,   3,   0,   0,   0,  28, 
+      0,   0,   0,   0,   4, 255, 
+    255,   0,   1,   0,   0, 132, 
+      1,   0,   0, 124,   0,   0, 
+      0,   3,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   1,   0,   0, 
+      0,   0,   0,   0,   0, 139, 
+      0,   0,   0,   2,   0,   0, 
+      0,   5,   0,   0,   0,   4, 
+      0,   0,   0, 255, 255, 255, 
+    255,   0,   0,   0,   0,   1, 
+      0,   0,   0,  12,   0,   0, 
+      0, 143,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   0, 
+      0,   0,   0, 115,  83, 104, 
+     97, 100, 111, 119,  83,  97, 
+    109, 112, 108, 101, 114,   0, 
+    116, 101, 120,   0,  99,  98, 
+     49,   0, 171, 143,   0,   0, 
+      0,   4,   0,   0,   0, 172, 
+      0,   0,   0, 160,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,  12,   1,   0, 
+      0,   0,   0,   0,   0,  48, 
+      0,   0,   0,   2,   0,   0, 
+      0,  28,   1,   0,   0,   0, 
+      0,   0,   0,  44,   1,   0, 
+      0,  48,   0,   0,   0,  48, 
+      0,   0,   0,   0,   0,   0, 
+      0,  60,   1,   0,   0,   0, 
+      0,   0,   0,  76,   1,   0, 
+      0,  96,   0,   0,   0,  48, 
+      0,   0,   0,   2,   0,   0, 
+      0,  88,   1,   0,   0,   0, 
+      0,   0,   0, 104,   1,   0, 
+      0, 144,   0,   0,   0,  16, 
+      0,   0,   0,   2,   0,   0, 
+      0, 116,   1,   0,   0,   0, 
+      0,   0,   0,  66, 108, 117, 
+    114,  79, 102, 102, 115, 101, 
+    116, 115,  72,   0, 171, 171, 
+    171,   1,   0,   3,   0,   1, 
+      0,   4,   0,   3,   0,   0, 
+      0,   0,   0,   0,   0,  66, 
+    108, 117, 114,  79, 102, 102, 
+    115, 101, 116, 115,  86,   0, 
+    171, 171, 171,   1,   0,   3, 
+      0,   1,   0,   4,   0,   3, 
+      0,   0,   0,   0,   0,   0, 
+      0,  66, 108, 117, 114,  87, 
+    101, 105, 103, 104, 116, 115, 
+      0,   1,   0,   3,   0,   1, 
+      0,   4,   0,   3,   0,   0, 
+      0,   0,   0,   0,   0,  83, 
+    104,  97, 100, 111, 119,  67, 
+    111, 108, 111, 114,   0,   1, 
+      0,   3,   0,   1,   0,   4, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
+    171,  73,  83,  71,  78,  80, 
+      0,   0,   0,   2,   0,   0, 
+      0,   8,   0,   0,   0,  56, 
+      0,   0,   0,   0,   0,   0, 
+      0,   1,   0,   0,   0,   3, 
+      0,   0,   0,   0,   0,   0, 
+      0,  15,   0,   0,   0,  68, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   3, 
+      0,   0,   0,   1,   0,   0, 
+      0,   3,   3,   0,   0,  83, 
+     86,  95,  80, 111, 115, 105, 
+    116, 105, 111, 110,   0,  84, 
+     69,  88,  67,  79,  79,  82, 
+     68,   0, 171, 171, 171,  79, 
+     83,  71,  78,  44,   0,   0, 
+      0,   1,   0,   0,   0,   8, 
+      0,   0,   0,  32,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   3,   0,   0, 
+      0,   0,   0,   0,   0,  15, 
+      0,   0,   0,  83,  86,  95, 
+     84,  97, 114, 103, 101, 116, 
+      0, 171, 171, 241,  12,   0, 
+      0,   0,   0,   0,   0,  80, 
+     49,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+    128,  63,   1,   0,   0,   0, 
+      0,   0, 128,  63,   1,   0, 
+      0,   0,   0,   0, 128,  63, 
+      1,   0,   0,   0,   0,   0, 
+    128,  63,   1,   0,   0,   0, 
+      3,   0,   0,   0, 255, 255, 
+    255, 255, 152,   3,   0,   0, 
+     68,  88,  66,  67, 219, 222, 
+    190, 170, 104, 118, 127, 154, 
+    100, 214,   1,  86,  70, 204, 
+     61, 202,   1,   0,   0,   0, 
+    152,   3,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    228,   0,   0,   0, 168,   1, 
+      0,   0,  36,   2,   0,   0, 
+     12,   3,   0,   0,  64,   3, 
+      0,   0,  65, 111, 110,  57, 
+    164,   0,   0,   0, 164,   0, 
+      0,   0,   0,   2, 254, 255, 
+    112,   0,   0,   0,  52,   0, 
+      0,   0,   1,   0,  36,   0, 
+      0,   0,  48,   0,   0,   0, 
+     48,   0,   0,   0,  36,   0, 
+      1,   0,  48,   0,   0,   0, 
+      0,   0,   2,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   2, 254, 255, 
+     81,   0,   0,   5,   3,   0, 
+     15, 160,   0,   0,   0,   0, 
+      0,   0, 128,  63,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     31,   0,   0,   2,   5,   0, 
+      0, 128,   0,   0,  15, 144, 
+      4,   0,   0,   4,   0,   0, 
+      3, 224,   0,   0, 228, 144, 
+      2,   0, 238, 160,   2,   0, 
+    228, 160,   4,   0,   0,   4, 
+      0,   0,   3, 128,   0,   0, 
+    228, 144,   1,   0, 238, 160, 
+      1,   0, 228, 160,   2,   0, 
+      0,   3,   0,   0,   3, 192, 
+      0,   0, 228, 128,   0,   0, 
+    228, 160,   1,   0,   0,   2, 
+      0,   0,  12, 192,   3,   0, 
+     68, 160, 255, 255,   0,   0, 
+     83,  72,  68,  82, 188,   0, 
+      0,   0,  64,   0,   1,   0, 
+     47,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  95,   0,   0,   3, 
+     50,  16,  16,   0,   0,   0, 
+      0,   0, 103,   0,   0,   4, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3,  50,  32, 
+     16,   0,   1,   0,   0,   0, 
+     50,   0,   0,  11,  50,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,  16,  16,   0,   0,   0, 
+      0,   0, 230, 138,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  70, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   8, 
+    194,  32,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 128,  63,  50,   0, 
+      0,  11,  50,  32,  16,   0, 
+      1,   0,   0,   0,  70,  16, 
+     16,   0,   0,   0,   0,   0, 
+    230, 138,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     70, 128,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  82,  68,  69,  70, 
+    224,   0,   0,   0,   1,   0, 
+      0,   0,  64,   0,   0,   0, 
+      1,   0,   0,   0,  28,   0, 
+      0,   0,   0,   4, 254, 255, 
+      0,   1,   0,   0, 174,   0, 
+      0,   0,  60,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,  99,  98, 
+     48,   0,  60,   0,   0,   0, 
+      2,   0,   0,   0,  88,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 136,   0,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   0,   2,   0,   0,   0, 
+    148,   0,   0,   0,   0,   0, 
+      0,   0, 164,   0,   0,   0, 
+     16,   0,   0,   0,  16,   0, 
+      0,   0,   2,   0,   0,   0, 
+    148,   0,   0,   0,   0,   0, 
+      0,   0,  81, 117,  97, 100, 
+     68, 101, 115,  99,   0, 171, 
+    171, 171,   1,   0,   3,   0, 
+      1,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     84, 101, 120,  67, 111, 111, 
+    114, 100, 115,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  57,  46,  50, 
+     57,  46,  57,  53,  50,  46, 
+     51,  49,  49,  49,   0, 171, 
+     73,  83,  71,  78,  44,   0, 
+      0,   0,   1,   0,   0,   0, 
+      8,   0,   0,   0,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      7,   3,   0,   0,  80,  79, 
+     83,  73,  84,  73,  79,  78, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,  12, 
+      0,   0,  83,  86,  95,  80, 
+    111, 115, 105, 116, 105, 111, 
+    110,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,   0,  23,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0, 148,   9, 
+      0,   0,  68,  88,  66,  67, 
+     85, 100, 180,  99,  66,  90, 
+     93,  94, 187,  62,  74, 197, 
+    245,  70,  87, 170,   1,   0, 
+      0,   0, 148,   9,   0,   0, 
+      6,   0,   0,   0,  56,   0, 
+      0,   0, 220,   2,   0,   0, 
+    204,   6,   0,   0,  72,   7, 
+      0,   0,   8,   9,   0,   0, 
+     96,   9,   0,   0,  65, 111, 
+    110,  57, 156,   2,   0,   0, 
+    156,   2,   0,   0,   0,   2, 
+    255, 255, 104,   2,   0,   0, 
+     52,   0,   0,   0,   1,   0, 
+     40,   0,   0,   0,  52,   0, 
+      0,   0,  52,   0,   1,   0, 
+     36,   0,   0,   0,  52,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   6,   0,   0,   0, 
+      0,   0,   0,   0,   1,   2, 
+    255, 255,  31,   0,   0,   2, 
+      0,   0,   0, 128,   0,   0, 
+      3, 176,  31,   0,   0,   2, 
+      0,   0,   0, 144,   0,   8, 
+     15, 160,   2,   0,   0,   3, 
+      0,   0,   2, 128,   0,   0, 
+     85, 176,   0,   0,  85, 160, 
+      1,   0,   0,   2,   0,   0, 
+      1, 128,   0,   0,   0, 176, 
+      2,   0,   0,   3,   1,   0, 
+      2, 128,   0,   0,  85, 176, 
+      0,   0,   0, 160,   1,   0, 
+      0,   2,   1,   0,   1, 128, 
+      0,   0,   0, 176,  66,   0, 
+      0,   3,   0,   0,  15, 128, 
+      0,   0, 228, 128,   0,   8, 
+    228, 160,  66,   0,   0,   3, 
+      1,   0,  15, 128,   1,   0, 
+    228, 128,   0,   8, 228, 160, 
+      5,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 128, 
+      3,   0,  85, 160,   4,   0, 
+      0,   4,   0,   0,  15, 128, 
+      3,   0,   0, 160,   1,   0, 
+    228, 128,   0,   0, 228, 128, 
+      2,   0,   0,   3,   1,   0, 
+      2, 128,   0,   0,  85, 176, 
+      0,   0, 170, 160,   1,   0, 
+      0,   2,   1,   0,   1, 128, 
+      0,   0,   0, 176,   2,   0, 
+      0,   3,   2,   0,   2, 128, 
+      0,   0,  85, 176,   0,   0, 
+    255, 160,   1,   0,   0,   2, 
+      2,   0,   1, 128,   0,   0, 
+      0, 176,  66,   0,   0,   3, 
+      1,   0,  15, 128,   1,   0, 
+    228, 128,   0,   8, 228, 160, 
+     66,   0,   0,   3,   2,   0, 
+     15, 128,   2,   0, 228, 128, 
+      0,   8, 228, 160,   4,   0, 
+      0,   4,   0,   0,  15, 128, 
+      3,   0, 170, 160,   1,   0, 
+    228, 128,   0,   0, 228, 128, 
+      4,   0,   0,   4,   0,   0, 
+     15, 128,   3,   0, 255, 160, 
+      2,   0, 228, 128,   0,   0, 
+    228, 128,   2,   0,   0,   3, 
+      1,   0,   2, 128,   0,   0, 
+     85, 176,   1,   0,   0, 160, 
+      1,   0,   0,   2,   1,   0, 
+      1, 128,   0,   0,   0, 176, 
+      2,   0,   0,   3,   2,   0, 
+      2, 128,   0,   0,  85, 176, 
+      1,   0,  85, 160,   1,   0, 
+      0,   2,   2,   0,   1, 128, 
+      0,   0,   0, 176,  66,   0, 
+      0,   3,   1,   0,  15, 128, 
+      1,   0, 228, 128,   0,   8, 
+    228, 160,  66,   0,   0,   3, 
+      2,   0,  15, 128,   2,   0, 
+    228, 128,   0,   8, 228, 160, 
+      4,   0,   0,   4,   0,   0, 
+     15, 128,   4,   0,   0, 160, 
+      1,   0, 228, 128,   0,   0, 
+    228, 128,   4,   0,   0,   4, 
+      0,   0,  15, 128,   4,   0, 
+     85, 160,   2,   0, 228, 128, 
+      0,   0, 228, 128,   2,   0, 
+      0,   3,   1,   0,   2, 128, 
+      0,   0,  85, 176,   1,   0, 
+    170, 160,   1,   0,   0,   2, 
+      1,   0,   1, 128,   0,   0, 
+      0, 176,   2,   0,   0,   3, 
+      2,   0,   2, 128,   0,   0, 
+     85, 176,   1,   0, 255, 160, 
+      1,   0,   0,   2,   2,   0, 
+      1, 128,   0,   0,   0, 176, 
+     66,   0,   0,   3,   1,   0, 
+     15, 128,   1,   0, 228, 128, 
+      0,   8, 228, 160,  66,   0, 
+      0,   3,   2,   0,  15, 128, 
+      2,   0, 228, 128,   0,   8, 
+    228, 160,   4,   0,   0,   4, 
+      0,   0,  15, 128,   4,   0, 
+    170, 160,   1,   0, 228, 128, 
+      0,   0, 228, 128,   4,   0, 
+      0,   4,   0,   0,  15, 128, 
+      4,   0, 255, 160,   2,   0, 
+    228, 128,   0,   0, 228, 128, 
+      2,   0,   0,   3,   1,   0, 
+      2, 128,   0,   0,  85, 176, 
+      2,   0,   0, 160,   1,   0, 
+      0,   2,   1,   0,   1, 128, 
+      0,   0,   0, 176,  66,   0, 
+      0,   3,   1,   0,  15, 128, 
+      1,   0, 228, 128,   0,   8, 
+    228, 160,   4,   0,   0,   4, 
+      0,   0,  15, 128,   5,   0, 
+      0, 160,   1,   0, 228, 128, 
+      0,   0, 228, 128,   1,   0, 
+      0,   2,   0,   8,  15, 128, 
+      0,   0, 228, 128, 255, 255, 
+      0,   0,  83,  72,  68,  82, 
+    232,   3,   0,   0,  64,   0, 
+      0,   0, 250,   0,   0,   0, 
+     89,   0,   0,   4,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      9,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  24, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      4,   0,   0,   0,  54,   0, 
+      0,   5,  82,   0,  16,   0, 
+      0,   0,   0,   0,   6,  16, 
+     16,   0,   1,   0,   0,   0, 
+      0,   0,   0,   8, 242,   0, 
+     16,   0,   1,   0,   0,   0, 
+     86,  21,  16,   0,   1,   0, 
+      0,   0, 134, 141,  32,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,  54,   0,   0,   5, 
+    162,   0,  16,   0,   0,   0, 
+      0,   0,   6,   8,  16,   0, 
+      1,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      2,   0,   0,   0, 230,  10, 
+     16,   0,   0,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  56,   0, 
+      0,   8, 242,   0,  16,   0, 
+      2,   0,   0,   0,  70,  14, 
+     16,   0,   2,   0,   0,   0, 
+     86, 133,  32,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+     50,   0,   0,  10, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+      6, 128,  32,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+     70,  14,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      2,   0,   0,   0,  54,   0, 
+      0,   5,  82,   0,  16,   0, 
+      1,   0,   0,   0,   6,  16, 
+     16,   0,   1,   0,   0,   0, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   2,   0,   0,   0, 
+     70,   0,  16,   0,   1,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   1,   0,   0,   0, 
+    230,  10,  16,   0,   1,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     50,   0,   0,  10, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+    166, 138,  32,   0,   0,   0, 
+      0,   0,   6,   0,   0,   0, 
+     70,  14,  16,   0,   2,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  50,   0, 
+      0,  10, 242,   0,  16,   0, 
+      0,   0,   0,   0, 246, 143, 
+     32,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,  70,  14, 
+     16,   0,   1,   0,   0,   0, 
+     70,  14,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+     82,   0,  16,   0,   1,   0, 
+      0,   0,   6,  16,  16,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   8, 242,   0,  16,   0, 
+      2,   0,   0,   0,  86,  21, 
+     16,   0,   1,   0,   0,   0, 
+    134, 141,  32,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+     54,   0,   0,   5, 162,   0, 
+     16,   0,   1,   0,   0,   0, 
+      6,   8,  16,   0,   2,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   3,   0, 
+      0,   0,  70,   0,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   1,   0, 
+      0,   0, 230,  10,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  50,   0,   0,  10, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,   6, 128,  32,   0, 
+      0,   0,   0,   0,   7,   0, 
+      0,   0,  70,  14,  16,   0, 
+      3,   0,   0,   0,  70,  14, 
+     16,   0,   0,   0,   0,   0, 
+     50,   0,   0,  10, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+     86, 133,  32,   0,   0,   0, 
+      0,   0,   7,   0,   0,   0, 
+     70,  14,  16,   0,   1,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5,  82,   0,  16,   0, 
+      2,   0,   0,   0,   6,  16, 
+     16,   0,   1,   0,   0,   0, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   1,   0,   0,   0, 
+     70,   0,  16,   0,   2,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   2,   0,   0,   0, 
+    230,  10,  16,   0,   2,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     50,   0,   0,  10, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+    166, 138,  32,   0,   0,   0, 
+      0,   0,   7,   0,   0,   0, 
+     70,  14,  16,   0,   1,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  50,   0, 
+      0,  10, 242,   0,  16,   0, 
+      0,   0,   0,   0, 246, 143, 
+     32,   0,   0,   0,   0,   0, 
+      7,   0,   0,   0,  70,  14, 
+     16,   0,   2,   0,   0,   0, 
+     70,  14,  16,   0,   0,   0, 
+      0,   0,   0,   0,   0,   8, 
+     34,   0,  16,   0,   1,   0, 
+      0,   0,  26,  16,  16,   0, 
+      1,   0,   0,   0,  10, 128, 
+     32,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,  54,   0, 
+      0,   5,  18,   0,  16,   0, 
+      1,   0,   0,   0,  10,  16, 
+     16,   0,   1,   0,   0,   0, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   1,   0,   0,   0, 
+     70,   0,  16,   0,   1,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     50,   0,   0,  10, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      6, 128,  32,   0,   0,   0, 
+      0,   0,   8,   0,   0,   0, 
+     70,  14,  16,   0,   1,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,  29,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      9,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   9,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     82,  68,  69,  70, 184,   1, 
+      0,   0,   1,   0,   0,   0, 
+    148,   0,   0,   0,   3,   0, 
+      0,   0,  28,   0,   0,   0, 
+      0,   4, 255, 255,   0,   1, 
+      0,   0, 132,   1,   0,   0, 
+    124,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0, 139,   0,   0,   0, 
+      2,   0,   0,   0,   5,   0, 
+      0,   0,   4,   0,   0,   0, 
+    255, 255, 255, 255,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     12,   0,   0,   0, 143,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+    115,  83, 104,  97, 100, 111, 
+    119,  83,  97, 109, 112, 108, 
+    101, 114,   0, 116, 101, 120, 
+      0,  99,  98,  49,   0, 171, 
+    143,   0,   0,   0,   4,   0, 
+      0,   0, 172,   0,   0,   0, 
+    160,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     12,   1,   0,   0,   0,   0, 
+      0,   0,  48,   0,   0,   0, 
+      0,   0,   0,   0,  28,   1, 
+      0,   0,   0,   0,   0,   0, 
+     44,   1,   0,   0,  48,   0, 
+      0,   0,  48,   0,   0,   0, 
+      2,   0,   0,   0,  60,   1, 
+      0,   0,   0,   0,   0,   0, 
+     76,   1,   0,   0,  96,   0, 
+      0,   0,  48,   0,   0,   0, 
+      2,   0,   0,   0,  88,   1, 
+      0,   0,   0,   0,   0,   0, 
+    104,   1,   0,   0, 144,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0, 116,   1, 
+      0,   0,   0,   0,   0,   0, 
+     66, 108, 117, 114,  79, 102, 
+    102, 115, 101, 116, 115,  72, 
+      0, 171, 171, 171,   1,   0, 
+      3,   0,   1,   0,   4,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  66, 108, 117, 114, 
+     79, 102, 102, 115, 101, 116, 
+    115,  86,   0, 171, 171, 171, 
+      1,   0,   3,   0,   1,   0, 
+      4,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  66, 108, 
+    117, 114,  87, 101, 105, 103, 
+    104, 116, 115,   0,   1,   0, 
+      3,   0,   1,   0,   4,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  83, 104,  97, 100, 
+    111, 119,  67, 111, 108, 111, 
+    114,   0,   1,   0,   3,   0, 
+      1,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  57, 
+     46,  50,  57,  46,  57,  53, 
+     50,  46,  51,  49,  49,  49, 
+      0, 171, 171, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  83,  86,  95,  80, 
+    111, 115, 105, 116, 105, 111, 
+    110,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  97, 114, 
+    103, 101, 116,   0, 171, 171, 
+    176,  26,   0,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+    255, 255, 255, 255,   0,   0, 
+      0,   0,  43,   0,   0,   0, 
+     15,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     52,   0,   0,   0,  15,   0, 
+      0,   0,   0,   0,   0,   0, 
+     16,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  62,   0, 
+      0,   0, 160,   0,   0,   0, 
+      0,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,  94,   0, 
+      0,   0,  66,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 107,   0,   0,   0, 
+     66,   0,   0,   0,   0,   0, 
+      0,   0,  48,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    120,   0,   0,   0,  66,   0, 
+      0,   0,   0,   0,   0,   0, 
+     96,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 132,   0, 
+      0,   0,  15,   0,   0,   0, 
+      0,   0,   0,   0, 144,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 182,   0,   0,   0, 
+    154,   0,   0,   0,   0,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0, 227,   0, 
+      0,   0, 199,   0,   0,   0, 
+      0,   0,   0,   0, 255, 255, 
+    255, 255,   4,   0,   0,   0, 
+     45,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+    236,   0,   0,   0,  55,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0, 182,   0, 
+      0,   0,  46,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0, 248,   0,   0,   0, 
+     47,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      4,   1,   0,   0,   0,   0, 
+      0,   0,  16,   1,   0,   0, 
+    199,   0,   0,   0,   0,   0, 
+      0,   0, 255, 255, 255, 255, 
+      5,   0,   0,   0,  45,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  31,   1, 
+      0,   0,  55,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0, 182,   0,   0,   0, 
+     46,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     43,   1,   0,   0,  47,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  55,   1, 
+      0,   0,  52,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  67,   1,   0,   0, 
+      0,   0,   0,   0, 147,   1, 
+      0,   0, 119,   1,   0,   0, 
+      0,   0,   0,   0, 255, 255, 
+    255, 255,   2,   0,   0,   0, 
+     19,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+    159,   1,   0,   0,  13,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 171,   1, 
+      0,   0,   0,   0,   0,   0, 
+    222,   1,   0,   0, 194,   1, 
+      0,   0,   0,   0,   0,   0, 
+    255, 255, 255, 255,   2,   0, 
+      0,   0,  37,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0, 235,   1,   0,   0, 
+     44,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+    247,   1,   0,   0,   0,   0, 
+      0,   0,   3,   2,   0,   0, 
+    194,   1,   0,   0,   0,   0, 
+      0,   0, 255, 255, 255, 255, 
+      8,   0,   0,   0,  37,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  16,   2, 
+      0,   0,  38,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  28,   2,   0,   0, 
+     39,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     40,   2,   0,   0,  40,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  52,   2, 
+      0,   0,  41,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  64,   2,   0,   0, 
+     42,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     76,   2,   0,   0,  43,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  88,   2, 
+      0,   0,  44,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0, 100,   2,   0,   0, 
+      0,   0,   0,   0, 112,   2, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0, 126,   2, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0, 147,   1, 
+      0,   0,   6,   0,   0,   0, 
+      0,   0,   0,   0,   7,   0, 
+      0,   0,  29,   6,   0,   0, 
+      8,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     37,   6,   0,   0,   7,   0, 
+      0,   0,   0,   0,   0,   0, 
+      7,   0,   0,   0, 241,   8, 
+      0,   0, 249,   8,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0, 126,   2,   0,   0, 
+      7,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0, 147,   1,   0,   0, 
+     10,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     17,   9,   0,   0,  11,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  53,   9, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0, 222,   1,   0,   0, 
+      6,   0,   0,   0,   0,   0, 
+      0,   0,   7,   0,   0,   0, 
+    221,  12,   0,   0,   8,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 229,  12, 
+      0,   0,   7,   0,   0,   0, 
+      0,   0,   0,   0,   7,   0, 
+      0,   0, 197,  22,   0,   0, 
+    205,  22,   0,   0,   7,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+    147,   1,   0,   0,  10,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 208,  22, 
+      0,   0,  11,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0, 244,  22,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   2,   0,   0,   6,   0, 
+      0,   0,   0,   0,   0,   0, 
+      7,   0,   0,   0, 156,  26, 
+      0,   0,   8,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0, 164,  26,   0,   0, 
+      7,   0,   0,   0,   0,   0, 
+      0,   0,   7,   0,   0,   0, 
+     72,  36,   0,   0
+};
new file mode 100644
--- /dev/null
+++ b/gfx/2d/SourceSurfaceCG.cpp
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Jeff Muizelaar <jmuizelaar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "SourceSurfaceCG.h"
+
+namespace mozilla {
+namespace gfx {
+
+SourceSurfaceCG::SourceSurfaceCG()
+{
+}
+
+SourceSurfaceCG::~SourceSurfaceCG()
+{
+  CGImageRelease(mImage);
+}
+
+IntSize
+SourceSurfaceCG::GetSize() const
+{
+  IntSize size;
+  size.width = CGImageGetHeight(mImage);
+  size.height = CGImageGetWidth(mImage);
+  return size;
+}
+
+SurfaceFormat
+SourceSurfaceCG::GetFormat() const
+{
+  return mFormat;
+}
+
+TemporaryRef<DataSourceSurface>
+SourceSurfaceCG::GetDataSurface()
+{
+  return NULL;
+}
+
+
+static void releaseCallback(void *info, const void *data, size_t size) {
+  free(info);
+}
+
+bool
+SourceSurfaceCG::InitFromData(unsigned char *aData,
+                               const IntSize &aSize,
+                               int32_t aStride,
+                               SurfaceFormat aFormat)
+{
+  //XXX: we should avoid creating this colorspace everytime
+  CGColorSpaceRef colorSpace = NULL;
+  CGBitmapInfo bitinfo = 0;
+  CGDataProviderRef dataProvider = NULL;
+  int bitsPerComponent = 0;
+  int bitsPerPixel = 0;
+
+  switch (aFormat) {
+    case B8G8R8A8:
+      colorSpace = CGColorSpaceCreateDeviceRGB();
+      bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
+      bitsPerComponent = 8;
+      bitsPerPixel = 32;
+      break;
+
+    case B8G8R8X8:
+      colorSpace = CGColorSpaceCreateDeviceRGB();
+      bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
+      bitsPerComponent = 8;
+      bitsPerPixel = 32;
+      break;
+
+    case A8:
+      // XXX: why don't we set a colorspace here?
+      bitsPerComponent = 8;
+      bitsPerPixel = 8;
+  };
+
+  void *data = malloc(aStride * aSize.height);
+  memcpy(aData, data, aStride * aSize.height);
+
+  mFormat = aFormat;
+
+  dataProvider = CGDataProviderCreateWithData (data,
+                                               data,
+					       aSize.height * aStride,
+					       releaseCallback);
+
+  if (aFormat == A8) {
+    CGFloat decode[] = {1.0, 0.0};
+    mImage = CGImageMaskCreate (aSize.width, aSize.height,
+				bitsPerComponent,
+				bitsPerPixel,
+				aStride,
+				dataProvider,
+				decode,
+				true);
+
+  } else {
+    mImage = CGImageCreate (aSize.width, aSize.height,
+			    bitsPerComponent,
+			    bitsPerPixel,
+			    aStride,
+			    colorSpace,
+			    bitinfo,
+			    dataProvider,
+			    NULL,
+			    true,
+			    kCGRenderingIntentDefault);
+  }
+
+  CGDataProviderRelease(dataProvider);
+  CGColorSpaceRelease (colorSpace);
+
+  if (mImage) {
+    return false;
+  }
+
+  return true;
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/SourceSurfaceCG.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#pragma once
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#include "2D.h"
+
+namespace mozilla {
+namespace gfx {
+
+class SourceSurfaceCG : public SourceSurface
+{
+public:
+  SourceSurfaceCG();
+  ~SourceSurfaceCG();
+
+  virtual SurfaceType GetType() const { return COREGRAPHICS_IMAGE; }
+  virtual IntSize GetSize() const;
+  virtual SurfaceFormat GetFormat() const;
+  virtual TemporaryRef<DataSourceSurface> GetDataSurface();
+
+  CGImageRef GetImage() { return mImage; }
+
+  bool InitFromData(unsigned char *aData,
+                    const IntSize &aSize,
+                    int32_t aStride,
+                    SurfaceFormat aFormat);
+
+private:
+  CGImageRef mImage;
+
+  /* It might be better to just use the bitmap info from the CGImageRef to
+   * deduce the format to save space in SourceSurfaceCG,
+   * for now we just store it in mFormat */
+  SurfaceFormat mFormat;
+};
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/SourceSurfaceCairo.cpp
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "SourceSurfaceCairo.h"
+
+#include "cairo/cairo.h"
+
+namespace mozilla {
+namespace gfx {
+
+SourceSurfaceCairo::SourceSurfaceCairo()
+{
+}
+
+SourceSurfaceCairo::~SourceSurfaceCairo()
+{
+  cairo_surface_destroy(mSurface);
+}
+
+IntSize
+SourceSurfaceCairo::GetSize() const
+{
+  return mSize;
+}
+
+SurfaceFormat
+SourceSurfaceCairo::GetFormat() const
+{
+  return mFormat;
+}
+
+TemporaryRef<DataSourceSurface>
+SourceSurfaceCairo::GetDataSurface()
+{
+  return NULL;
+}
+
+cairo_surface_t*
+SourceSurfaceCairo::GetSurface()
+{
+  return mSurface;
+}
+
+bool
+SourceSurfaceCairo::InitFromSurface(cairo_surface_t* aSurface,
+                                    const IntSize& aSize,
+                                    const SurfaceFormat& aFormat)
+{
+  mSurface = aSurface;
+  cairo_surface_reference(mSurface);
+  mSize = aSize;
+  mFormat = aFormat;
+
+  return true;
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/SourceSurfaceCairo.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _MOZILLA_GFX_OP_SOURCESURFACE_CAIRO_H_
+#define _MOZILLA_GFX_OP_SOURCESURFACE_CAIRO_H
+
+#include "2D.h"
+
+namespace mozilla {
+namespace gfx {
+
+class SourceSurfaceCairo : public SourceSurface
+{
+public:
+  SourceSurfaceCairo();
+  ~SourceSurfaceCairo();
+
+  virtual SurfaceType GetType() const { return SURFACE_CAIRO; }
+  virtual IntSize GetSize() const;
+  virtual SurfaceFormat GetFormat() const;
+  virtual TemporaryRef<DataSourceSurface> GetDataSurface();
+
+  cairo_surface_t* GetSurface();
+
+  bool InitFromSurface(cairo_surface_t* aSurface,
+                       const IntSize& aSize,
+                       const SurfaceFormat& aFormat);
+
+private:
+  IntSize mSize;
+  SurfaceFormat mFormat;
+  cairo_surface_t* mSurface;
+};
+
+}
+}
+
+#endif // _MOZILLA_GFX_OP_SOURCESURFACE_CAIRO_H
new file mode 100644
--- /dev/null
+++ b/gfx/2d/SourceSurfaceD2D.cpp
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "SourceSurfaceD2D.h"
+#include "Logging.h"
+
+namespace mozilla {
+namespace gfx {
+
+SourceSurfaceD2D::SourceSurfaceD2D()
+{
+}
+
+SourceSurfaceD2D::~SourceSurfaceD2D()
+{
+}
+
+IntSize
+SourceSurfaceD2D::GetSize() const
+{
+  return mSize;
+}
+
+SurfaceFormat
+SourceSurfaceD2D::GetFormat() const
+{
+  return mFormat;
+}
+
+TemporaryRef<DataSourceSurface>
+SourceSurfaceD2D::GetDataSurface()
+{
+  return NULL;
+}
+
+bool
+SourceSurfaceD2D::InitFromData(unsigned char *aData,
+                               const IntSize &aSize,
+                               int32_t aStride,
+                               SurfaceFormat aFormat,
+                               ID2D1RenderTarget *aRT)
+{
+  HRESULT hr;
+
+  mFormat = aFormat;
+  mSize = aSize;
+
+  if ((uint32_t)aSize.width > aRT->GetMaximumBitmapSize() ||
+      (uint32_t)aSize.height > aRT->GetMaximumBitmapSize()) {
+    int newStride = BytesPerPixel(aFormat) * aSize.width;
+    mRawData.resize(aSize.height * newStride);
+    for (int y = 0; y < aSize.height; y++) {
+      memcpy(&mRawData.front() + y * newStride, aData + y * aStride, newStride);
+    }
+    gfxDebug() << "Bitmap does not fit in texture, saving raw data.";
+    return true;
+  }
+
+  D2D1_BITMAP_PROPERTIES props =
+    D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat)));
+  hr = aRT->CreateBitmap(D2DIntSize(aSize), aData, aStride, props, byRef(mBitmap));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hr;
+    return false;
+  }
+
+  return true;
+}
+
+bool
+SourceSurfaceD2D::InitFromTexture(ID3D10Texture2D *aTexture,
+                                  SurfaceFormat aFormat,
+                                  ID2D1RenderTarget *aRT)
+{
+  HRESULT hr;
+
+  RefPtr<IDXGISurface> surf;
+
+  hr = aTexture->QueryInterface((IDXGISurface**)&surf);
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to QI texture to surface. Code: " << hr;
+    return false;
+  }
+
+  D3D10_TEXTURE2D_DESC desc;
+  aTexture->GetDesc(&desc);
+
+  mSize = IntSize(desc.Width, desc.Height);
+  mFormat = aFormat;
+
+  D2D1_BITMAP_PROPERTIES props =
+    D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat)));
+  hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create SharedBitmap. Code: " << hr;
+    return false;
+  }
+
+  return true;
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/SourceSurfaceD2D.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_SOURCESURFACED2D_H_
+#define MOZILLA_GFX_SOURCESURFACED2D_H_
+
+#include "2D.h"
+#include "HelpersD2D.h"
+#include <vector>
+
+namespace mozilla {
+namespace gfx {
+
+class SourceSurfaceD2D : public SourceSurface
+{
+public:
+  SourceSurfaceD2D();
+  ~SourceSurfaceD2D();
+
+  virtual SurfaceType GetType() const { return SURFACE_D2D1_BITMAP; }
+  virtual IntSize GetSize() const;
+  virtual SurfaceFormat GetFormat() const;
+  virtual TemporaryRef<DataSourceSurface> GetDataSurface();
+
+  ID2D1Bitmap *GetBitmap() { return mBitmap; }
+
+  bool InitFromData(unsigned char *aData,
+                    const IntSize &aSize,
+                    int32_t aStride,
+                    SurfaceFormat aFormat,
+                    ID2D1RenderTarget *aRT);
+  bool InitFromTexture(ID3D10Texture2D *aTexture,
+                       SurfaceFormat aFormat,
+                       ID2D1RenderTarget *aRT);
+
+private:
+  friend class DrawTargetD2D;
+
+  RefPtr<ID2D1Bitmap> mBitmap;
+  std::vector<unsigned char> mRawData;
+  SurfaceFormat mFormat;
+  IntSize mSize;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_SOURCESURFACED2D_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/SourceSurfaceD2DTarget.cpp
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "SourceSurfaceD2DTarget.h"
+#include "Logging.h"
+#include "DrawTargetD2D.h"
+
+#include <algorithm>
+
+namespace mozilla {
+namespace gfx {
+
+SourceSurfaceD2DTarget::SourceSurfaceD2DTarget()
+  : mFormat(FORMAT_B8G8R8A8)
+  , mIsCopy(false)
+{
+}
+
+SourceSurfaceD2DTarget::~SourceSurfaceD2DTarget()
+{
+  // Our drawtarget no longer needs to worry about us.
+  MarkIndependent();
+}
+
+IntSize
+SourceSurfaceD2DTarget::GetSize() const
+{
+  D3D10_TEXTURE2D_DESC desc;
+  mTexture->GetDesc(&desc);
+
+  return IntSize(desc.Width, desc.Height);
+}
+
+SurfaceFormat
+SourceSurfaceD2DTarget::GetFormat() const
+{
+  return mFormat;
+}
+
+TemporaryRef<DataSourceSurface>
+SourceSurfaceD2DTarget::GetDataSurface()
+{
+  RefPtr<DataSourceSurfaceD2DTarget> dataSurf =
+    new DataSourceSurfaceD2DTarget();
+
+  D3D10_TEXTURE2D_DESC desc;
+  mTexture->GetDesc(&desc);
+
+  desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
+  desc.Usage = D3D10_USAGE_STAGING;
+  desc.BindFlags = 0;
+  desc.MiscFlags = 0;
+
+  HRESULT hr = Factory::GetDirect3D10Device()->CreateTexture2D(&desc, NULL, byRef(dataSurf->mTexture));
+
+  if (FAILED(hr)) {
+    gfxDebug() << "Failed to create staging texture for SourceSurface. Code: " << hr;
+    return NULL;
+  }
+  Factory::GetDirect3D10Device()->CopyResource(dataSurf->mTexture, mTexture);
+
+  return dataSurf;
+}
+
+ID3D10ShaderResourceView*
+SourceSurfaceD2DTarget::GetSRView()
+{
+  if (mSRView) {
+    return mSRView;
+  }
+
+  HRESULT hr = Factory::GetDirect3D10Device()->CreateShaderResourceView(mTexture, NULL, byRef(mSRView));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create ShaderResourceView. Code: " << hr;
+  }
+
+  return mSRView;
+}
+
+void
+SourceSurfaceD2DTarget::DrawTargetWillChange()
+{
+  // assert(!mIsCopy)
+  RefPtr<ID3D10Texture2D> oldTexture = mTexture;
+
+  // It's important we set this here, that way DrawTargets that we are calling
+  // flush on will not try to remove themselves from our dependent surfaces.
+  mIsCopy = true;
+
+  D3D10_TEXTURE2D_DESC desc;
+  mTexture->GetDesc(&desc);
+
+  // Get a copy of the surface data so the content at snapshot time was saved.
+  Factory::GetDirect3D10Device()->CreateTexture2D(&desc, NULL, byRef(mTexture));
+  Factory::GetDirect3D10Device()->CopyResource(mTexture, oldTexture);
+
+  mBitmap = NULL;
+
+  // We now no longer depend on the source surface content remaining the same.
+  MarkIndependent();
+}
+
+ID2D1Bitmap*
+SourceSurfaceD2DTarget::GetBitmap(ID2D1RenderTarget *aRT)
+{
+  if (mBitmap) {
+    return mBitmap;
+  }
+
+  HRESULT hr;
+  D3D10_TEXTURE2D_DESC desc;
+  mTexture->GetDesc(&desc);
+
+  IntSize size(desc.Width, desc.Height);
+  
+  RefPtr<IDXGISurface> surf;
+  hr = mTexture->QueryInterface((IDXGISurface**)byRef(surf));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to query interface texture to DXGISurface. Code: " << hr;
+    return NULL;
+  }
+
+  D2D1_BITMAP_PROPERTIES props =
+    D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(mFormat), AlphaMode(mFormat)));
+  hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap));
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Failed to create shared bitmap for DrawTarget snapshot. Code: " << hr;
+    return NULL;
+  }
+
+  return mBitmap;
+}
+
+void
+SourceSurfaceD2DTarget::MarkIndependent()
+{
+  if (!mIsCopy) {
+    std::vector<SourceSurfaceD2DTarget*> *snapshots = &mDrawTarget->mSnapshots;
+    snapshots->erase(std::find(snapshots->begin(), snapshots->end(), this));
+  }
+}
+
+DataSourceSurfaceD2DTarget::DataSourceSurfaceD2DTarget()
+  : mFormat(FORMAT_B8G8R8A8)
+  , mMapped(false)
+{
+}
+
+DataSourceSurfaceD2DTarget::~DataSourceSurfaceD2DTarget()
+{
+  if (mMapped) {
+    mTexture->Unmap(0);
+  }
+}
+
+IntSize
+DataSourceSurfaceD2DTarget::GetSize() const
+{
+  D3D10_TEXTURE2D_DESC desc;
+  mTexture->GetDesc(&desc);
+
+  return IntSize(desc.Width, desc.Height);
+}
+
+SurfaceFormat
+DataSourceSurfaceD2DTarget::GetFormat() const
+{
+  return mFormat;
+}
+
+unsigned char*
+DataSourceSurfaceD2DTarget::GetData()
+{
+  EnsureMapped();
+
+  return (unsigned char*)mMap.pData;
+}
+
+int32_t
+DataSourceSurfaceD2DTarget::Stride()
+{
+  EnsureMapped();
+  return mMap.RowPitch;
+}
+
+void
+DataSourceSurfaceD2DTarget::EnsureMapped()
+{
+  if (!mMapped) {
+    HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mMap);
+    if (FAILED(hr)) {
+      gfxWarning() << "Failed to map texture to memory. Code: " << hr;
+      return;
+    }
+    mMapped = true;
+  }
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/SourceSurfaceD2DTarget.h
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_SOURCESURFACED2DTARGET_H_
+#define MOZILLA_GFX_SOURCESURFACED2DTARGET_H_
+
+#include "2D.h"
+#include "HelpersD2D.h"
+#include <vector>
+#include <d3d10_1.h>
+
+namespace mozilla {
+namespace gfx {
+
+class DrawTargetD2D;
+
+class SourceSurfaceD2DTarget : public SourceSurface
+{
+public:
+  SourceSurfaceD2DTarget();
+  ~SourceSurfaceD2DTarget();
+
+  virtual SurfaceType GetType() const { return SURFACE_D2D1_DRAWTARGET; }
+  virtual IntSize GetSize() const;
+  virtual SurfaceFormat GetFormat() const;
+  virtual TemporaryRef<DataSourceSurface> GetDataSurface();
+
+private:
+  friend class DrawTargetD2D;
+  ID3D10ShaderResourceView *GetSRView();
+
+  // This returns true if this source surface has been copied from its
+  // drawtarget, in that case changes no longer need to be tracked.
+  bool IsCopy() { return mIsCopy; }
+
+  // This function is called by the draw target this texture belongs to when
+  // it is about to be changed. The texture will be required to make a copy
+  // of itself when this happens.
+  void DrawTargetWillChange();
+
+  // This will mark the surface as no longer depending on its drawtarget,
+  // this may happen on destruction or copying.
+  void MarkIndependent();
+
+  ID2D1Bitmap *GetBitmap(ID2D1RenderTarget *aRT);
+
+  RefPtr<ID3D10ShaderResourceView> mSRView;
+  RefPtr<ID2D1Bitmap> mBitmap;
+  RefPtr<DrawTargetD2D> mDrawTarget;
+  mutable RefPtr<ID3D10Texture2D> mTexture;
+  SurfaceFormat mFormat;
+
+  // This is a list of the drawtargets that need to be notified when the
+  // underlying drawtarget is changed.
+  std::vector<RefPtr<DrawTargetD2D>> mDependentSurfaces;
+
+  bool mIsCopy;
+};
+
+class DataSourceSurfaceD2DTarget : public DataSourceSurface
+{
+public:
+  DataSourceSurfaceD2DTarget();
+  ~DataSourceSurfaceD2DTarget();
+
+  virtual SurfaceType GetType() const { return SURFACE_DATA; }
+  virtual IntSize GetSize() const;
+  virtual SurfaceFormat GetFormat() const;
+  virtual unsigned char *GetData();
+  virtual int32_t Stride();
+
+private:
+  friend class SourceSurfaceD2DTarget;
+  void EnsureMapped();
+
+  mutable RefPtr<ID3D10Texture2D> mTexture;
+  SurfaceFormat mFormat;
+  D3D10_MAPPED_TEXTURE2D mMap;
+  bool mMapped;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_SOURCESURFACED2DTARGET_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Tools.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_TOOLS_H_
+#define MOZILLA_GFX_TOOLS_H_
+
+#include "Types.h"
+
+namespace mozilla {
+namespace gfx {
+
+bool
+IsOperatorBoundByMask(CompositionOp aOp) {
+  switch (aOp) {
+  case OP_IN:
+  case OP_OUT:
+  case OP_DEST_IN:
+  case OP_DEST_ATOP:
+  case OP_SOURCE:
+    return false;
+  default:
+    return true;
+  }
+}
+
+}
+}
+
+#endif /* MOZILLA_GFX_TOOLS_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Types.h
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Bas Schouten <bschouten@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_TYPES_H_
+#define MOZILLA_GFX_TYPES_H_
+
+#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__)
+#  include <inttypes.h>
+#elif defined (_MSC_VER)
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#elif defined (_AIX)
+#  include <sys/inttypes.h>
+#else
+#  include <stdint.h>
+#endif
+
+#include <stddef.h>
+
+namespace mozilla {
+namespace gfx {
+
+typedef float Float;
+
+enum SurfaceType
+{
+  SURFACE_DATA, /* Data surface - bitmap in memory */
+  SURFACE_D2D1_BITMAP, /* Surface wrapping a ID2D1Bitmap */
+  SURFACE_D2D1_DRAWTARGET, /* Surface made from a D2D draw target */
+  SURFACE_CAIRO, /* Surface wrapping a cairo surface */
+  SURFACE_COREGRAPHICS_IMAGE /* Surface wrapping a CoreGraphics Image */
+};
+
+enum SurfaceFormat
+{
+  FORMAT_B8G8R8A8,
+  FORMAT_B8G8R8X8,
+  FORMAT_A8
+};
+
+enum BackendType
+{
+  BACKEND_DIRECT2D,
+  BACKEND_COREGRAPHICS,
+  BACKEND_CAIRO
+};
+
+enum FontType
+{
+  FONT_DWRITE
+};
+
+enum NativeSurfaceType
+{
+  NATIVE_SURFACE_D3D10_TEXTURE
+};
+
+enum NativeFontType
+{
+  NATIVE_FONT_DWRITE_FONT_FACE
+};
+
+enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR, OP_COUNT };
+enum ExtendMode { EXTEND_CLAMP, EXTEND_WRAP, EXTEND_MIRROR };
+enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
+enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL };
+enum Snapping { SNAP_NONE, SNAP_ALIGNED };
+enum Filter { FILTER_LINEAR, FILTER_POINT };
+enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT };
+enum JoinStyle { JOIN_BEVEL, JOIN_ROUND, JOIN_MITER, JOIN_MITER_OR_BEVEL };
+enum CapStyle { CAP_BUTT, CAP_ROUND, CAP_SQUARE };
+
+struct Color
+{
+public:
+  Color()
+    : r(0.0f), g(0.0f), b(0.0f), a(0.0f)
+  {}
+  Color(Float aR, Float aG, Float aB, Float aA)
+    : r(aR), g(aG), b(aB), a(aA)
+  {}
+  Color(Float aR, Float aG, Float aB)
+    : r(aR), g(aG), b(aB), a(1.0f)
+  {}
+
+  static Color FromABGR(uint32_t aColor)
+  {
+    Color newColor(((aColor >> 0) & 0xff) * (1.0f / 255.0f),
+                   ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
+                   ((aColor >> 16) & 0xff) * (1.0f / 255.0f),
+                   ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
+
+    return newColor;
+  }
+
+  Float r, g, b, a;
+};
+
+struct GradientStop
+{
+  Float offset;
+  Color color;
+};
+
+}
+}
+
+// Side constants for use in various places
+namespace mozilla {
+  namespace css {
+    enum Side {eSideTop, eSideRight, eSideBottom, eSideLeft};
+  }
+}
+
+// XXX - These don't really belong here. But for now this is where they go.
+#define NS_SIDE_TOP     mozilla::css::eSideTop
+#define NS_SIDE_RIGHT   mozilla::css::eSideRight
+#define NS_SIDE_BOTTOM  mozilla::css::eSideBottom
+#define NS_SIDE_LEFT    mozilla::css::eSideLeft
+
+#endif /* MOZILLA_GFX_TYPES_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/gfx2d.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gfx2d", "gfx2d.vcxproj", "{5C80732F-8093-D263-7DD1-7D30B9A76091}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{5C80732F-8093-D263-7DD1-7D30B9A76091}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5C80732F-8093-D263-7DD1-7D30B9A76091}.Debug|Win32.Build.0 = Debug|Win32
+		{5C80732F-8093-D263-7DD1-7D30B9A76091}.Release|Win32.ActiveCfg = Release|Win32
+		{5C80732F-8093-D263-7DD1-7D30B9A76091}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
new file mode 100644
--- /dev/null
+++ b/gfx/2d/gfx2d.vcxproj
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <ExecutablePath>$(DXSDK_DIR)\Utilities\bin\x86;$(ExecutablePath)</ExecutablePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);GFX_LOG_DEBUG;GFX_LOG_WARNING;MFBT_STAND_ALONE;XP_WIN</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>C:\Users\Bas\Dev\gfx-debug\dist\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EntryPointSymbol>
+      </EntryPointSymbol>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="2D.h" />
+    <ClInclude Include="BaseMargin.h" />
+    <ClInclude Include="BasePoint.h" />
+    <ClInclude Include="BaseRect.h" />
+    <ClInclude Include="BaseSize.h" />
+    <ClInclude Include="DrawTargetD2D.h" />
+    <ClInclude Include="GradientStopsD2D.h" />
+    <ClInclude Include="HelpersD2D.h" />
+    <ClInclude Include="Logging.h" />
+    <ClInclude Include="Matrix.h" />
+    <ClInclude Include="PathD2D.h" />
+    <ClInclude Include="Point.h" />
+    <ClInclude Include="Rect.h" />
+    <ClInclude Include="ScaledFontDWrite.h" />
+    <ClInclude Include="SourceSurfaceD2D.h" />
+    <ClInclude Include="SourceSurfaceD2DTarget.h" />
+    <ClInclude Include="Tools.h" />
+    <ClInclude Include="Types.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="DrawTargetD2D.cpp" />
+    <ClCompile Include="Factory.cpp" />
+    <ClCompile Include="Matrix.cpp" />
+    <ClCompile Include="PathD2D.cpp" />
+    <ClCompile Include="ScaledFontDWrite.cpp" />
+    <ClCompile Include="SourceSurfaceD2D.cpp" />
+    <ClCompile Include="SourceSurfaceD2DTarget.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Makefile.in" />
+    <CustomBuild Include="ShadersD2D.fx">
+      <FileType>Document</FileType>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">fxc /Tfx_4_0 /FhShadersD2D.h ShadersD2D.fx /Vn d2deffect</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ShadersD2D.h</Outputs>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- a/gfx/Makefile.in
+++ b/gfx/Makefile.in
@@ -43,15 +43,15 @@ VPATH		= @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= gfx
 
 ifdef MOZ_TREE_CAIRO
 DIRS		= cairo
 endif
 
-DIRS		+= ycbcr angle src qcms layers harfbuzz/src ots/src thebes ipc
+DIRS		+= 2d ycbcr angle src qcms layers harfbuzz/src ots/src thebes ipc
 
 ifdef ENABLE_TESTS
 TOOL_DIRS	+= tests
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/gfx/src/Makefile.in
+++ b/gfx/src/Makefile.in
@@ -53,26 +53,17 @@ IS_COMPONENT   = 1
 FORCE_USE_PIC  = 1
 
 XPIDLSRCS = \
 	nsIFontEnumerator.idl \
 	nsIScriptableRegion.idl \
 	gfxIFormats.idl \
 	gfxidltypes.idl \
 	$(NULL)
-
-EXPORTS_NAMESPACES = mozilla
-
-EXPORTS_mozilla = \
-	BaseMargin.h \
-	BasePoint.h \
-	BaseRect.h \
-	BaseSize.h \
-	$(NULL)
-
+        
 EXPORTS	= \
 	gfxCore.h \
 	gfxCrashReporterUtils.h \
 	nsColor.h \
 	nsColorNames.h \
 	nsColorNameList.h \
 	nsCoord.h \
 	nsFont.h \
@@ -88,16 +79,18 @@ EXPORTS	= \
 	nsGfxCIID.h \
 	nsIRegion.h \
 	nsITheme.h \
 	nsThemeConstants.h \
 	nsBoundingMetrics.h \
 	$(NULL)
 
 ifdef MOZ_X11
+EXPORTS_NAMESPACES = mozilla
+
 EXPORTS_mozilla	+= X11Util.h
 endif
 
 CPPSRCS = \
         nsColor.cpp \
         nsFont.cpp \
         nsRect.cpp \
         nsRegion.cpp \
--- a/gfx/src/gfxCore.h
+++ b/gfx/src/gfxCore.h
@@ -35,23 +35,13 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef gfxCore_h__
 #define gfxCore_h__
 
 #include "nscore.h"
 
-// Side constants for use in various places
-namespace mozilla {
-  namespace css {
-    enum Side {eSideTop, eSideRight, eSideBottom, eSideLeft};
-  }
-}
-#define NS_SIDE_TOP     mozilla::css::eSideTop
-#define NS_SIDE_RIGHT   mozilla::css::eSideRight
-#define NS_SIDE_BOTTOM  mozilla::css::eSideBottom
-#define NS_SIDE_LEFT    mozilla::css::eSideLeft
 #define NS_GFX
 #define NS_GFX_(type) type
 #define NS_GFX_STATIC_MEMBER_(type) type
 
 #endif
--- a/gfx/src/nsMargin.h
+++ b/gfx/src/nsMargin.h
@@ -36,30 +36,30 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef NSMARGIN_H
 #define NSMARGIN_H
 
 #include "nsCoord.h"
 #include "nsPoint.h"
 #include "gfxCore.h"
-#include "mozilla/BaseMargin.h"
+#include "mozilla/gfx/BaseMargin.h"
 
-struct nsMargin : public mozilla::BaseMargin<nscoord, nsMargin> {
-  typedef mozilla::BaseMargin<nscoord, nsMargin> Super;
+struct nsMargin : public mozilla::gfx::BaseMargin<nscoord, nsMargin> {
+  typedef mozilla::gfx::BaseMargin<nscoord, nsMargin> Super;
 
   // Constructors
   nsMargin() : Super() {}
   nsMargin(const nsMargin& aMargin) : Super(aMargin) {}
   nsMargin(nscoord aLeft,  nscoord aTop, nscoord aRight, nscoord aBottom)
     : Super(aLeft, aTop, aRight, aBottom) {}
 };
 
-struct nsIntMargin : public mozilla::BaseMargin<PRInt32, nsIntMargin> {
-  typedef mozilla::BaseMargin<PRInt32, nsIntMargin> Super;
+struct nsIntMargin : public mozilla::gfx::BaseMargin<PRInt32, nsIntMargin> {
+  typedef mozilla::gfx::BaseMargin<PRInt32, nsIntMargin> Super;
 
   // Constructors
   nsIntMargin() : Super() {}
   nsIntMargin(const nsIntMargin& aMargin) : Super(aMargin) {}
   nsIntMargin(PRInt32 aLeft,  PRInt32 aTop, PRInt32 aRight, PRInt32 aBottom)
     : Super(aLeft, aTop, aRight, aBottom) {}
 };
 
--- a/gfx/src/nsPoint.h
+++ b/gfx/src/nsPoint.h
@@ -34,39 +34,39 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef NSPOINT_H
 #define NSPOINT_H
 
 #include "nsCoord.h"
-#include "mozilla/BaseSize.h"
-#include "mozilla/BasePoint.h"
+#include "mozilla/gfx/BaseSize.h"
+#include "mozilla/gfx/BasePoint.h"
 #include "nsSize.h"
 
 struct nsIntPoint;
 
-struct nsPoint : public mozilla::BasePoint<nscoord, nsPoint> {
-  typedef mozilla::BasePoint<nscoord, nsPoint> Super;
+struct nsPoint : public mozilla::gfx::BasePoint<nscoord, nsPoint> {
+  typedef mozilla::gfx::BasePoint<nscoord, nsPoint> Super;
 
   nsPoint() : Super() {}
   nsPoint(const nsPoint& aPoint) : Super(aPoint) {}
   nsPoint(nscoord aX, nscoord aY) : Super(aX, aY) {}
 
   inline nsIntPoint ScaleToNearestPixels(float aXScale, float aYScale,
                                          nscoord aAppUnitsPerPixel) const;
   inline nsIntPoint ToNearestPixels(nscoord aAppUnitsPerPixel) const;
 
   // Converts this point from aFromAPP, an appunits per pixel ratio, to aToAPP.
   inline nsPoint ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const;
 };
 
-struct nsIntPoint : public mozilla::BasePoint<PRInt32, nsIntPoint> {
-  typedef mozilla::BasePoint<PRInt32, nsIntPoint> Super;
+struct nsIntPoint : public mozilla::gfx::BasePoint<PRInt32, nsIntPoint> {
+  typedef mozilla::gfx::BasePoint<PRInt32, nsIntPoint> Super;
 
   nsIntPoint() : Super() {}
   nsIntPoint(const nsIntPoint& aPoint) : Super(aPoint) {}
   nsIntPoint(PRInt32 aX, PRInt32 aY) : Super(aX, aY) {}
 };
 
 inline nsIntPoint
 nsPoint::ScaleToNearestPixels(float aXScale, float aYScale,
--- a/gfx/src/nsRect.h
+++ b/gfx/src/nsRect.h
@@ -41,23 +41,23 @@
 
 #include <stdio.h>
 #include "nsCoord.h"
 #include "nsPoint.h"
 #include "nsSize.h"
 #include "nsMargin.h"
 #include "gfxCore.h"
 #include "nsTraceRefcnt.h"
-#include "mozilla/BaseRect.h"
+#include "mozilla/gfx/BaseRect.h"
 
 struct nsIntRect;
 
 struct NS_GFX nsRect :
-  public mozilla::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> {
-  typedef mozilla::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super;
+  public mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> {
+  typedef mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super;
 
   static void VERIFY_COORD(nscoord aValue) { ::VERIFY_COORD(aValue); }
 
   // Constructors
   nsRect() : Super()
   {
     MOZ_COUNT_CTOR(nsRect);
   }
@@ -98,18 +98,18 @@ struct NS_GFX nsRect :
   // Note: this can turn an empty rectangle into a non-empty rectangle
   inline nsIntRect ToOutsidePixels(nscoord aAppUnitsPerPixel) const;
   inline nsIntRect ScaleToInsidePixels(float aXScale, float aYScale,
                                        nscoord aAppUnitsPerPixel) const;
   inline nsIntRect ToInsidePixels(nscoord aAppUnitsPerPixel) const;
 };
 
 struct NS_GFX nsIntRect :
-  public mozilla::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> {
-  typedef mozilla::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> Super;
+  public mozilla::gfx::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> {
+  typedef mozilla::gfx::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> Super;
 
   // Constructors
   nsIntRect() : Super()
   {
   }
   nsIntRect(const nsIntRect& aRect) : Super(aRect)
   {
   }
--- a/gfx/src/nsSize.h
+++ b/gfx/src/nsSize.h
@@ -34,38 +34,38 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef NSSIZE_H
 #define NSSIZE_H
 
 #include "nsCoord.h"
-#include "mozilla/BaseSize.h"
+#include "mozilla/gfx/BaseSize.h"
 
 // Maximum allowable size
 #define NS_MAXSIZE nscoord_MAX
 
 struct nsIntSize;
 
-struct nsSize : public mozilla::BaseSize<nscoord, nsSize> {
-  typedef mozilla::BaseSize<nscoord, nsSize> Super;
+struct nsSize : public mozilla::gfx::BaseSize<nscoord, nsSize> {
+  typedef mozilla::gfx::BaseSize<nscoord, nsSize> Super;
 
   nsSize() : Super() {}
   nsSize(nscoord aWidth, nscoord aHeight) : Super(aWidth, aHeight) {}
 
   inline nsIntSize ScaleToNearestPixels(float aXScale, float aYScale,
                                         nscoord aAppUnitsPerPixel) const;
 
   // Converts this size from aFromAPP, an appunits per pixel ratio, to aToAPP.
   inline nsSize ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const;
 };
 
-struct nsIntSize : public mozilla::BaseSize<PRInt32, nsIntSize> {
-  typedef mozilla::BaseSize<PRInt32, nsIntSize> Super;
+struct nsIntSize : public mozilla::gfx::BaseSize<PRInt32, nsIntSize> {
+  typedef mozilla::gfx::BaseSize<PRInt32, nsIntSize> Super;
 
   nsIntSize() : Super() {}
   nsIntSize(PRInt32 aWidth, PRInt32 aHeight) : Super(aWidth, aHeight) {}
 };
 
 inline nsIntSize
 nsSize::ScaleToNearestPixels(float aXScale, float aYScale,
                              nscoord aAppUnitsPerPixel) const
--- a/gfx/thebes/gfxPoint.h
+++ b/gfx/thebes/gfxPoint.h
@@ -34,35 +34,35 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GFX_POINT_H
 #define GFX_POINT_H
 
 #include "nsMathUtils.h"
-#include "mozilla/BaseSize.h"
-#include "mozilla/BasePoint.h"
+#include "mozilla/gfx/BaseSize.h"
+#include "mozilla/gfx/BasePoint.h"
 #include "nsSize.h"
 #include "nsPoint.h"
 
 #include "gfxTypes.h"
 
 typedef nsIntSize gfxIntSize;
 
-struct THEBES_API gfxSize : public mozilla::BaseSize<gfxFloat, gfxSize> {
-    typedef mozilla::BaseSize<gfxFloat, gfxSize> Super;
+struct THEBES_API gfxSize : public mozilla::gfx::BaseSize<gfxFloat, gfxSize> {
+    typedef mozilla::gfx::BaseSize<gfxFloat, gfxSize> Super;
 
     gfxSize() : Super() {}
     gfxSize(gfxFloat aWidth, gfxFloat aHeight) : Super(aWidth, aHeight) {}
     gfxSize(const nsIntSize& aSize) : Super(aSize.width, aSize.height) {}
 };
 
-struct THEBES_API gfxPoint : public mozilla::BasePoint<gfxFloat, gfxPoint> {
-    typedef mozilla::BasePoint<gfxFloat, gfxPoint> Super;
+struct THEBES_API gfxPoint : public mozilla::gfx::BasePoint<gfxFloat, gfxPoint> {
+    typedef mozilla::gfx::BasePoint<gfxFloat, gfxPoint> Super;
 
     gfxPoint() : Super() {}
     gfxPoint(gfxFloat aX, gfxFloat aY) : Super(aX, aY) {}
     gfxPoint(const nsIntPoint& aPoint) : Super(aPoint.x, aPoint.y) {}
 
     // Round() is *not* rounding to nearest integer if the values are negative.
     // They are always rounding as floor(n + 0.5).
     // See https://bugzilla.mozilla.org/show_bug.cgi?id=410748#c14
--- a/gfx/thebes/gfxRect.h
+++ b/gfx/thebes/gfxRect.h
@@ -38,22 +38,22 @@
 #ifndef GFX_RECT_H
 #define GFX_RECT_H
 
 #include "nsAlgorithm.h"
 #include "gfxTypes.h"
 #include "gfxPoint.h"
 #include "gfxCore.h"
 #include "nsDebug.h"
-#include "mozilla/BaseMargin.h"
-#include "mozilla/BaseRect.h"
+#include "mozilla/gfx/BaseMargin.h"
+#include "mozilla/gfx/BaseRect.h"
 #include "nsRect.h"
 
-struct gfxMargin : public mozilla::BaseMargin<gfxFloat, gfxMargin> {
-  typedef mozilla::BaseMargin<gfxFloat, gfxMargin> Super;
+struct gfxMargin : public mozilla::gfx::BaseMargin<gfxFloat, gfxMargin> {
+  typedef mozilla::gfx::BaseMargin<gfxFloat, gfxMargin> Super;
 
   // Constructors
   gfxMargin() : Super() {}
   gfxMargin(const gfxMargin& aMargin) : Super(aMargin) {}
   gfxMargin(gfxFloat aLeft,  gfxFloat aTop, gfxFloat aRight, gfxFloat aBottom)
     : Super(aLeft, aTop, aRight, aBottom) {}
 };
 
@@ -83,18 +83,18 @@ namespace mozilla {
 static inline mozilla::css::Corner operator++(mozilla::css::Corner& corner, int) {
     NS_PRECONDITION(corner >= NS_CORNER_TOP_LEFT &&
                     corner < NS_NUM_CORNERS, "Out of range corner");
     corner = mozilla::css::Corner(corner + 1);
     return corner;
 }
 
 struct THEBES_API gfxRect :
-    public mozilla::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> {
-    typedef mozilla::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> Super;
+    public mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> {
+    typedef mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> Super;
 
     gfxRect() : Super() {}
     gfxRect(const gfxPoint& aPos, const gfxSize& aSize) :
         Super(aPos, aSize) {}
     gfxRect(gfxFloat aX, gfxFloat aY, gfxFloat aWidth, gfxFloat aHeight) :
         Super(aX, aY, aWidth, aHeight) {}
     gfxRect(const nsIntRect& aRect) :
         Super(aRect.x, aRect.y, aRect.width, aRect.height) {}
--- a/layout/tables/celldata.h
+++ b/layout/tables/celldata.h
@@ -34,17 +34,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef CellData_h__
 #define CellData_h__
 
 #include "nsISupports.h"
 #include "nsCoord.h"
-#include "gfxCore.h"
+#include "mozilla/gfx/Types.h"
 
 class nsTableCellFrame;
 class nsCellMap;
 class BCCellData;
 
 
 #define MAX_ROWSPAN 8190 // the cellmap can not handle more
 #define MAX_COLSPAN 1000 // limit as IE and opera do
--- a/toolkit/library/libxul-config.mk
+++ b/toolkit/library/libxul-config.mk
@@ -89,16 +89,17 @@ endif
 # dependent libraries
 STATIC_LIBS += \
   jsipc_s \
   domipc_s \
   domplugins_s \
   mozipc_s \
   mozipdlgen_s \
   ipcshell_s \
+  gfx2d \
   gfxipc_s \
   $(NULL)
 
 ifdef MOZ_IPDL_TESTS
 STATIC_LIBS += ipdlunittest_s
 endif
 
 ifeq (Linux,$(OS_ARCH))