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 idunknown
push userunknown
push dateunknown
reviewersjrmuizel, roc
bugs651858
milestone7.0a1
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))