diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 65e76e2..254a624 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -1,12 +1,11 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "gm.h"
 
+#include "gm.h"
 #include "GrContext.h"
 #include "GrRenderTarget.h"
 
@@ -28,6 +27,10 @@
     #include "SkPDFDocument.h"
 #endif
 
+#ifdef SK_SUPPORT_XPS
+    #include "SkXPSDevice.h"
+#endif
+
 #ifdef SK_BUILD_FOR_MAC
     #include "SkCGUtils.h"
     #define CAN_IMAGE_PDF   1
@@ -195,9 +198,10 @@
     return true;
 }
 
-static bool write_pdf(const SkString& path, const SkDynamicMemoryWStream& pdf) {
+static bool write_document(const SkString& path,
+                           const SkDynamicMemoryWStream& document) {
     SkFILEWStream stream(path.c_str());
-    SkAutoDataUnref data(pdf.copyToData());
+    SkAutoDataUnref data(document.copyToData());
     return stream.writeData(data.get());
 }
 
@@ -205,6 +209,7 @@
   kRaster_Backend,
   kGPU_Backend,
   kPDF_Backend,
+  kXPS_Backend,
 };
 
 struct ConfigData {
@@ -278,21 +283,55 @@
 #endif
 }
 
+static void generate_xps(GM* gm, SkDynamicMemoryWStream& xps) {
+#ifdef SK_SUPPORT_XPS
+    SkISize size = gm->getISize();
+    
+    SkSize trimSize = SkSize::Make(SkIntToScalar(size.width()),
+                                   SkIntToScalar(size.height()));
+    static const double inchesPerMeter = 10000.0 / 254.0;
+    static const double upm = 72 * inchesPerMeter;
+    SkVector unitsPerMeter = SkPoint::Make(SkDoubleToScalar(upm),
+                                           SkDoubleToScalar(upm));
+    static const double ppm = 200 * inchesPerMeter;
+    SkVector pixelsPerMeter = SkPoint::Make(SkDoubleToScalar(ppm),
+                                            SkDoubleToScalar(ppm));
+
+    SkXPSDevice* dev = new SkXPSDevice();
+    SkAutoUnref aur(dev);
+
+    SkCanvas c(dev);
+    dev->beginPortfolio(&xps);
+    dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize);
+    gm->draw(&c);
+    dev->endSheet();
+    dev->endPortfolio();
+
+#endif
+}
+
 static bool write_reference_image(const ConfigData& gRec,
                                   const char writePath [],
                                   const char renderModeDescriptor [],
                                   const SkString& name,
                                   SkBitmap& bitmap,
-                                  SkDynamicMemoryWStream* pdf) {
+                                  SkDynamicMemoryWStream* document) {
     SkString path;
     bool success = false;
-    if (gRec.fBackend != kPDF_Backend || CAN_IMAGE_PDF) {
+    if (gRec.fBackend == kRaster_Backend ||
+        gRec.fBackend == kGPU_Backend ||
+        (gRec.fBackend == kPDF_Backend && CAN_IMAGE_PDF)) {
+    
         path = make_filename(writePath, renderModeDescriptor, name, "png");
         success = write_bitmap(path, bitmap);
     }
     if (kPDF_Backend == gRec.fBackend) {
         path = make_filename(writePath, renderModeDescriptor, name, "pdf");
-        success = write_pdf(path, *pdf);
+        success = write_document(path, *document);
+    }
+    if (kXPS_Backend == gRec.fBackend) {
+        path = make_filename(writePath, renderModeDescriptor, name, "xps");
+        success = write_document(path, *document);
     }
     if (!success) {
         fprintf(stderr, "FAILED to write %s\n", path.c_str());
@@ -355,7 +394,10 @@
     if (writePath) {
         write_reference_image(gRec, writePath, renderModeDescriptor,
                               name, bitmap, pdf);
-    } else if (readPath && (gRec.fBackend != kPDF_Backend || CAN_IMAGE_PDF)) {
+    } else if (readPath && (
+                   gRec.fBackend == kRaster_Backend ||
+                   gRec.fBackend == kGPU_Backend ||
+                   (gRec.fBackend == kPDF_Backend && CAN_IMAGE_PDF))) {
         return compare_to_reference_image(readPath, name, bitmap,
                                    diffPath, renderModeDescriptor);
     } else if (comparisonBitmap) {
@@ -409,7 +451,7 @@
                          GrContext* context,
                          GrRenderTarget* rt,
                          SkBitmap* bitmap) {
-    SkDynamicMemoryWStream pdf;
+    SkDynamicMemoryWStream document;
 
     if (gRec.fBackend == kRaster_Backend ||
         gRec.fBackend == kGPU_Backend) {
@@ -419,15 +461,17 @@
             return true;
         }
     } else if (gRec.fBackend == kPDF_Backend) {
-        generate_pdf(gm, pdf);
+        generate_pdf(gm, document);
 #if CAN_IMAGE_PDF
         SkAutoDataUnref data(pdf.copyToData());
         SkMemoryStream stream(data.data(), data.size());
         SkPDFDocumentToBitmap(&stream, bitmap);
 #endif
+    } else if (gRec.fBackend == kXPS_Backend) {
+        generate_xps(gm, document);
     }
     return handle_test_results(gm, gRec, writePath, readPath, diffPath,
-                        "", *bitmap, &pdf, NULL);
+                               "", *bitmap, &document, NULL);
 }
 
 static bool test_picture_playback(GM* gm,
@@ -490,6 +534,9 @@
 #ifdef SK_SUPPORT_PDF
     { SkBitmap::kARGB_8888_Config, kPDF_Backend,    "pdf" },
 #endif
+#ifdef SK_SUPPORT_XPS
+    { SkBitmap::kARGB_8888_Config, kXPS_Backend,    "xps" },
+#endif
 };
 
 namespace skiagm {
diff --git a/gyp/gm.gyp b/gyp/gm.gyp
index 6226546..716e056 100644
--- a/gyp/gm.gyp
+++ b/gyp/gm.gyp
@@ -44,6 +44,7 @@
         'images.gyp:images',
         'pdf.gyp:pdf',
         'utils.gyp:utils',
+        'xps.gyp:xps',
       ],
     },
   ],
diff --git a/gyp/utils.gyp b/gyp/utils.gyp
index 6c53701..73a80eb 100644
--- a/gyp/utils.gyp
+++ b/gyp/utils.gyp
@@ -78,11 +78,13 @@
         
         #windows
         '../include/utils/win/SkAutoCoInitialize.h',
+        '../include/utils/win/SkHRESULT.h',
         '../include/utils/win/SkIStream.h',
         '../include/utils/win/SkTScopedComPtr.h',
         '../src/utils/win/SkAutoCoInitialize.cpp',
         '../src/utils/win/skia_win.cpp',
         '../src/utils/win/SkEGLContext_Win.cpp',
+        '../src/utils/win/SkHRESULT.cpp',
         '../src/utils/win/SkIStream.cpp',
         '../src/utils/win/SkOSWindow_Win.cpp',
       ],
@@ -152,11 +154,13 @@
           ],
           'sources!': [
             '../include/utils/win/SkAutoCoInitialize.h',
+            '../include/utils/win/SkHRESULT.h',
             '../include/utils/win/SkIStream.h',
             '../include/utils/win/SkTScopedComPtr.h',
             '../src/utils/win/SkAutoCoInitialize.cpp',
             '../src/utils/win/skia_win.cpp',
             '../src/utils/win/SkEGLContext_Win.cpp',
+            '../src/utils/win/SkHRESULT.cpp',
             '../src/utils/win/SkIStream.cpp',
             '../src/utils/win/SkOSWindow_Win.cpp',
           ],
diff --git a/gyp/xps.gyp b/gyp/xps.gyp
new file mode 100644
index 0000000..ff68d6f
--- /dev/null
+++ b/gyp/xps.gyp
@@ -0,0 +1,67 @@
+{
+  'includes': [
+    'common.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'xps',
+      'type': 'static_library',
+      'dependencies': [
+        'core.gyp:core',
+        'images.gyp:images',
+        'utils.gyp:utils',
+        'pdf.gyp:pdf', # needed to get SkBitSet
+      ],
+      'include_dirs': [
+        '../include/device/xps',
+        '../include/utils/win',
+        '../src/core', # needed to get SkGlyphCache.h
+      ],
+      'sources': [
+        '../include/device/xps/SkConstexprMath.h',
+        '../include/device/xps/SkXPSDevice.h',
+
+        '../src/device/xps/SkXPSDevice.cpp',
+      ],
+      'conditions': [
+        [ 'skia_os == "win"', {
+          'link_settings': {
+            'libraries': [
+              'T2Embed.lib',
+              'FontSub.lib',
+            ],
+          },
+        },{ #else if 'skia_os != "win"'
+          'include_dirs!': [
+            '../include/utils/win',
+          ],
+          'sources!': [
+            '../include/device/xps/SkXPSDevice.h',
+
+            '../src/device/xps/SkXPSDevice.cpp',
+          ],
+        }],
+      ],
+      # This section makes all targets that depend on this target
+      # #define SK_SUPPORT_XPS and have access to the xps header files.
+      'direct_dependent_settings': {
+        'conditions': [
+          [ 'skia_os == "win"', {
+            'defines': [
+              'SK_SUPPORT_XPS',
+            ],
+          }],
+        ],
+        'include_dirs': [
+          '../include/device/xps',
+        ],
+      },
+    },
+  ],
+}
+
+# Local Variables:
+# tab-width:2
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=2 shiftwidth=2:
diff --git a/include/config/sk_stdint.h b/include/config/sk_stdint.h
index 4169d4a..360755e 100644
--- a/include/config/sk_stdint.h
+++ b/include/config/sk_stdint.h
@@ -5,16 +5,19 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#ifndef sk_stdint_DEFINED
-#define sk_stdint_DEFINED
-
-typedef signed char int8_t;
-typedef unsigned char   uint8_t;
-typedef short  int16_t;
-typedef unsigned short  uint16_t;
-typedef int  int32_t;
-typedef unsigned   uint32_t;
-typedef long long  int64_t;
-typedef unsigned long long   uint64_t;
-
-#endif
+#ifndef sk_stdint_DEFINED
+#define sk_stdint_DEFINED
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned uint32_t;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+#endif
diff --git a/include/device/xps/SkConstexprMath.h b/include/device/xps/SkConstexprMath.h
new file mode 100644
index 0000000..65b70b6
--- /dev/null
+++ b/include/device/xps/SkConstexprMath.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkConstexprMath_DEFINED
+#define SkConstexprMath_DEFINED
+
+#include "SkTypes.h"
+#include <limits.h>
+
+template <uintmax_t N, uintmax_t B>
+struct SK_LOG {
+    //! Compile-time constant ceiling(logB(N)).
+    static const uintmax_t value = 1 + SK_LOG<N/B, B>::value;
+};
+template <uintmax_t B>
+struct SK_LOG<1, B> {
+    static const uintmax_t value = 0;
+};
+template <uintmax_t B>
+struct SK_LOG<0, B> {
+    static const uintmax_t value = 0;
+};
+
+template<uintmax_t N>
+struct SK_2N1 {
+    //! Compile-time constant (2^N)-1.
+    static const uintmax_t value = (SK_2N1<N-1>::value << 1) + 1;
+};
+template<>
+struct SK_2N1<1> {
+    static const uintmax_t value = 1;
+};
+
+/** Compile-time constant number of base n digits in type t
+    if the bits of type t are considered as unsigned base two.
+*/
+#define SK_BASE_N_DIGITS_IN(n, t) (\
+    SK_LOG<SK_2N1<(sizeof(t) * CHAR_BIT)>::value, n>::value\
+)
+/** Compile-time constant number of base 10 digits in type t
+    if the bits of type t are considered as unsigned base two.
+*/
+#define SK_DIGITS_IN(t) SK_BASE_N_DIGITS_IN(10, (t))
+
+//! a > b ? a : b
+#define SK_MAX(a,b) (((a) > (b)) ? (a) : (b))
+
+#endif
diff --git a/include/device/xps/SkXPSDevice.h b/include/device/xps/SkXPSDevice.h
new file mode 100644
index 0000000..1fb9220
--- /dev/null
+++ b/include/device/xps/SkXPSDevice.h
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkXPSDevice_DEFINED
+#define SkXPSDevice_DEFINED
+
+#include "SkTypes.h"
+#include <ObjBase.h>
+#include <XpsObjectModel.h>
+
+#include "SkAutoCoInitialize.h"
+#include "SkBitSet.h"
+#include "SkCanvas.h"
+#include "SkColor.h"
+#include "SkDevice.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkShader.h"
+#include "SkSize.h"
+#include "SkTArray.h"
+#include "SkTScopedComPtr.h"
+#include "SkTypeface.h"
+
+/** \class SkXPSDevice
+
+    The drawing context for the XPS backend.
+*/
+class SkXPSDevice : public SkDevice {
+public:
+    SK_API SkXPSDevice();
+    SK_API virtual ~SkXPSDevice();
+
+    virtual bool beginPortfolio(SkWStream* outputStream);
+    /**
+      @param unitsPerMeter converts geometry units into physical units.
+      @param pixelsPerMeter resolution to use when geometry must be rasterized.
+      @param trimSize final page size in physical units.
+                      The top left of the trim is the origin of physical space.
+      @param mediaBox The size of the physical media in physical units.
+                      The top and left must be less than zero.
+                      The bottom and right must be greater than the trimSize.
+                      The default is to coincide with the trimSize.
+      @param bleedBox The size of the bleed box in physical units.
+                      Must be contained within the mediaBox.
+                      The default is to coincide with the mediaBox.
+      @param artBox The size of the content box in physical units.
+                    Must be contained within the trimSize.
+                    The default is to coincide with the trimSize.
+      @param cropBox The size of the recommended view port in physical units.
+                     Must be contained within the mediaBox.
+                     The default is to coincide with the mediaBox.
+     */
+    virtual bool beginSheet(
+        const SkVector& unitsPerMeter,
+        const SkVector& pixelsPerMeter,
+        const SkSize& trimSize,
+        const SkRect* mediaBox = NULL,
+        const SkRect* bleedBox = NULL,
+        const SkRect* artBox = NULL,
+        const SkRect* cropBox = NULL);
+
+    virtual bool endSheet();
+    virtual bool endPortfolio();
+
+    virtual uint32_t getDeviceCapabilities() SK_OVERRIDE {
+        return kVector_Capability;
+    }
+
+    virtual bool readPixels(const SkIRect& srcRect,
+                            SkBitmap* bitmap) SK_OVERRIDE {
+        return false;
+    }
+
+protected:
+    virtual void clear(SkColor color) SK_OVERRIDE;
+
+    virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
+
+    virtual void drawPoints(
+        const SkDraw&,
+        SkCanvas::PointMode mode,
+        size_t count, const SkPoint[],
+        const SkPaint& paint) SK_OVERRIDE;
+
+    virtual void drawRect(
+        const SkDraw&,
+        const SkRect& r,
+        const SkPaint& paint) SK_OVERRIDE;
+
+    virtual void drawPath(
+        const SkDraw&,
+        const SkPath& platonicPath,
+        const SkPaint& paint,
+        const SkMatrix* prePathMatrix,
+        bool pathIsMutable) SK_OVERRIDE;
+
+    virtual void drawBitmap(
+        const SkDraw&,
+        const SkBitmap& bitmap,
+        const SkIRect* srcRectOrNull,
+        const SkMatrix& matrix,
+        const SkPaint& paint) SK_OVERRIDE;
+
+    virtual void drawSprite(
+        const SkDraw&,
+        const SkBitmap& bitmap,
+        int x, int y,
+        const SkPaint& paint) SK_OVERRIDE;
+
+    virtual void drawText(
+        const SkDraw&,
+        const void* text, size_t len,
+        SkScalar x, SkScalar y,
+        const SkPaint& paint) SK_OVERRIDE;
+
+    virtual void drawPosText(
+        const SkDraw&,
+        const void* text, size_t len,
+        const SkScalar pos[], SkScalar constY, int scalarsPerPos,
+        const SkPaint& paint) SK_OVERRIDE;
+
+    virtual void drawTextOnPath(
+        const SkDraw&,
+        const void* text, size_t len,
+        const SkPath& path,
+        const SkMatrix* matrix,
+        const SkPaint& paint) SK_OVERRIDE;
+
+    virtual void drawVertices(
+        const SkDraw&,
+        SkCanvas::VertexMode,
+        int vertexCount, const SkPoint verts[],
+        const SkPoint texs[], const SkColor colors[],
+        SkXfermode* xmode,
+        const uint16_t indices[], int indexCount,
+        const SkPaint& paint) SK_OVERRIDE;
+
+    virtual void drawDevice(
+        const SkDraw&,
+        SkDevice* device,
+        int x, int y,
+        const SkPaint& paint) SK_OVERRIDE;
+
+private:
+    class TypefaceUse : ::SkNoncopyable {
+    public:
+        SkFontID typefaceId;
+        SkStream* fontData;
+        IXpsOMFontResource* xpsFont;
+        SkBitSet* glyphsUsed;
+        
+        explicit TypefaceUse();
+        ~TypefaceUse();
+    };
+    friend static HRESULT subset_typeface(TypefaceUse* current);
+
+    SkXPSDevice(IXpsOMObjectFactory* xpsFactory);
+
+    SkAutoCoInitialize fAutoCo;
+    SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory;
+    SkTScopedComPtr<IStream> fOutputStream;
+    SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter;
+
+    unsigned int fCurrentPage;
+    SkTScopedComPtr<IXpsOMCanvas> fCurrentXpsCanvas;
+    SkSize fCurrentCanvasSize;
+    SkVector fCurrentUnitsPerMeter;
+    SkVector fCurrentPixelsPerMeter;
+
+    SkTArray<TypefaceUse, true> fTypefaces;
+
+    HRESULT initXpsDocumentWriter(IXpsOMImageResource* image);
+
+    HRESULT createXpsPage(
+        const XPS_SIZE& pageSize,
+        IXpsOMPage** page);
+
+    HRESULT createXpsThumbnail(
+        IXpsOMPage* page, const unsigned int pageNumber,
+        IXpsOMImageResource** image);
+
+    void internalDrawRect(
+        const SkDraw&,
+        const SkRect& r,
+        bool transformRect,
+        const SkPaint& paint);
+
+    HRESULT createXpsBrush(
+        const SkPaint& skPaint,
+        IXpsOMBrush** xpsBrush,
+        const SkMatrix* parentTransform = NULL);
+
+    HRESULT createXpsSolidColorBrush(
+        const SkColor skColor, const SkAlpha alpha,
+        IXpsOMBrush** xpsBrush);
+
+    HRESULT createXpsImageBrush(
+        const SkBitmap& bitmap,
+        const SkMatrix& localMatrix,
+        const SkShader::TileMode (&xy)[2],
+        const SkAlpha alpha,
+        IXpsOMTileBrush** xpsBrush);
+
+    HRESULT createXpsLinearGradient(
+        SkShader::GradientInfo info,
+        const SkAlpha alpha,
+        const SkMatrix& localMatrix,
+        IXpsOMMatrixTransform* xpsMatrixToUse,
+        IXpsOMBrush** xpsBrush);
+
+    HRESULT createXpsRadialGradient(
+        SkShader::GradientInfo info,
+        const SkAlpha alpha,
+        const SkMatrix& localMatrix,
+        IXpsOMMatrixTransform* xpsMatrixToUse,
+        IXpsOMBrush** xpsBrush);
+
+    HRESULT createXpsGradientStop(
+        const SkColor skColor,
+        const SkScalar offset,
+        IXpsOMGradientStop** xpsGradStop);
+
+    HRESULT createXpsTransform(
+        const SkMatrix& matrix,
+        IXpsOMMatrixTransform ** xpsTransform);
+
+    HRESULT createXpsRect(
+        const SkRect& rect,
+        BOOL stroke, BOOL fill,
+        IXpsOMGeometryFigure** xpsRect);
+
+    HRESULT createXpsQuad(
+        const SkPoint (&points)[4],
+        BOOL stroke, BOOL fill,
+        IXpsOMGeometryFigure** xpsQuad);
+
+    HRESULT CreateTypefaceUse(
+        const SkPaint& paint,
+        TypefaceUse** fontResource);
+
+    HRESULT AddGlyphs(
+        const SkDraw& d,
+        IXpsOMObjectFactory* xpsFactory,
+        IXpsOMCanvas* canvas,
+        IXpsOMFontResource* font,
+        LPCWSTR text,
+        XPS_GLYPH_INDEX* xpsGlyphs,
+        UINT32 xpsGlyphsLen,
+        XPS_POINT *origin,
+        FLOAT fontSize,
+        XPS_STYLE_SIMULATION sims,
+        const SkMatrix& transform,
+        const SkPaint& paint);
+
+    HRESULT addXpsPathGeometry(
+        IXpsOMGeometryFigureCollection* figures,
+        BOOL stroke, BOOL fill, const SkPath& path);
+
+    HRESULT createPath(
+        IXpsOMGeometryFigure* figure,
+        IXpsOMVisualCollection* visuals,
+        IXpsOMPath** path);
+
+    HRESULT sideOfClamp(
+        const SkRect& leftPoints, const XPS_RECT& left,
+        IXpsOMImageResource* imageResource,
+        IXpsOMVisualCollection* visuals);
+
+    HRESULT cornerOfClamp(
+        const SkRect& tlPoints,
+        const SkColor color,
+        IXpsOMVisualCollection* visuals);
+
+    HRESULT clip(
+        IXpsOMVisual* xpsVisual,
+        const SkDraw& d);
+    HRESULT clipToPath(
+        IXpsOMVisual* xpsVisual,
+        const SkPath& clipPath,
+        XPS_FILL_RULE fillRule);
+
+    HRESULT drawInverseWindingPath(
+        const SkDraw& d,
+        const SkPath& devicePath,
+        IXpsOMPath* xpsPath);
+
+    HRESULT shadePath(
+        IXpsOMPath* shadedPath,
+        const SkPaint& shaderPaint,
+        const SkMatrix& matrix,
+        BOOL* fill, BOOL* stroke);
+
+    void convertToPpm(
+        const SkMaskFilter* filter,
+        SkMatrix* matrix,
+        SkVector* ppuScale,
+        const SkIRect& clip, SkIRect* clipIRect);
+
+    HRESULT applyMask(
+        const SkDraw& d,
+        const SkMask& mask,
+        const SkVector& ppuScale,
+        IXpsOMPath* shadedPath);
+
+    // override from SkDevice
+    virtual SkDevice* onCreateCompatibleDevice(
+        SkBitmap::Config config,
+        int width, int height,
+        bool isOpaque,
+        Usage usage) SK_OVERRIDE;
+
+    // Disable the default copy and assign implementation.
+    SkXPSDevice(const SkXPSDevice&);
+    void operator=(const SkXPSDevice&);
+
+    typedef SkDevice INHERITED;
+};
+
+#endif
diff --git a/include/pdf/SkBitSet.h b/include/pdf/SkBitSet.h
index fd564a5..484fc2a 100755
--- a/include/pdf/SkBitSet.h
+++ b/include/pdf/SkBitSet.h
@@ -41,9 +41,24 @@
      */
     bool orBits(const SkBitSet& source);
 
-    /** Export set bits to unsigned int array. (used in font subsetting)
+    /** Export indices of set bits to T array.
      */
-    void exportTo(SkTDArray<uint32_t>* array) const;
+    template<typename T>
+    void exportTo(SkTDArray<T>* array) const {
+        SkASSERT(array);
+        uint32_t* data = reinterpret_cast<uint32_t*>(fBitData.get());
+        for (unsigned int i = 0; i < fDwordCount; ++i) {
+            uint32_t value = data[i];
+            if (value) {  // There are set bits
+                unsigned int index = i * 32;
+                for (unsigned int j = 0; j < 32; ++j) {
+                    if (0x1 & (value >> j)) {
+                        array->push(index + j);
+                    }
+                }
+            }
+        }
+    }
 
 private:
     SkAutoFree fBitData;
diff --git a/include/utils/win/SkHRESULT.h b/include/utils/win/SkHRESULT.h
new file mode 100644
index 0000000..ff596c7
--- /dev/null
+++ b/include/utils/win/SkHRESULT.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkHRESULT_DEFINED
+#define SkHRESULT_DEFINED
+
+#include "SkTypes.h"
+
+void SkTraceHR(const char* file, unsigned long line,
+               HRESULT hr, const char* msg);
+
+#ifdef SK_DEBUG
+#define SK_TRACEHR(_hr, _msg) SkTraceHR(__FILE__, __LINE__, _hr, _msg)
+#else
+#define SK_TRACEHR(_hr, _msg) _hr
+#endif
+
+#define HR_GENERAL(_ex, _msg, _ret) {\
+    HRESULT _hr = _ex;\
+    if (FAILED(_hr)) {\
+        SK_TRACEHR(_hr, _msg);\
+        return _ret;\
+    }\
+}
+
+//@{
+/**
+These macros are for reporting HRESULT errors.
+The expression will be evaluated.
+If the resulting HRESULT SUCCEEDED then execution will continue normally.
+If the HRESULT FAILED then the macro will return from the current function.
+In variants ending with 'M' the given message will be traced when FAILED.
+The HR variants will return the HRESULT when FAILED.
+The HRB variants will return false when FAILED.
+The HRV variants will simply return when FAILED.
+*/
+#define HR(ex) HR_GENERAL(ex, NULL, _hr)
+#define HRM(ex, msg) HR_GENERAL(ex, msg, _hr)
+
+#define HRB(ex) HR_GENERAL(ex, NULL, false)
+#define HRBM(ex, msg) HR_GENERAL(ex, msg, false)
+
+#define HRV(ex) HR_GENERAL(ex, NULL, )
+#define HRVM(ex, msg) HR_GENERAL(ex, msg, )
+//@}
+#endif
diff --git a/include/utils/win/SkTScopedComPtr.h b/include/utils/win/SkTScopedComPtr.h
index e0d1634..b9be037 100644
--- a/include/utils/win/SkTScopedComPtr.h
+++ b/include/utils/win/SkTScopedComPtr.h
@@ -6,13 +6,20 @@
  * found in the LICENSE file.
  */
 
-
 #ifndef SkSkTScopedPtr_DEFINED
 #define SkSkTScopedPtr_DEFINED
 
+#include "SkTypes.h"
 #include "SkTemplates.h"
 
 template<typename T>
+class SkBlockComRef : public T {
+private:
+    virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
+    virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
+};
+
+template<typename T>
 class SkTScopedComPtr : SkNoncopyable {
 private:
     T *fPtr;
@@ -23,7 +30,9 @@
         this->reset();
     }
     T &operator*() const { return *fPtr; }
-    T *operator->() const { return fPtr; }
+    SkBlockComRef<T> *operator->() const {
+        return static_cast<SkBlockComRef<T>*>(fPtr);
+    }
     /**
      * Returns the address of the underlying pointer.
      * This is dangerous -- it breaks encapsulation and the reference escapes.
@@ -38,6 +47,18 @@
             this->fPtr = NULL;
         }
     }
+    
+    void swap(SkTScopedComPtr<T>& that) {
+        T* temp = this->fPtr;
+        this->fPtr = that.fPtr;
+        that.fPtr = temp;
+    }
+    
+    T* release() {
+        T* temp = this->fPtr;
+        this->fPtr = NULL;
+        return temp;
+    }
 };
 
 #endif
diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp
new file mode 100644
index 0000000..eaf61ef
--- /dev/null
+++ b/src/device/xps/SkXPSDevice.cpp
@@ -0,0 +1,2394 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef UNICODE
+#define UNICODE
+#endif
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#include "SkTypes.h"
+#include <ObjBase.h>
+#include <XpsObjectModel.h>
+#include <T2EmbApi.h>
+#include <FontSub.h>
+
+#include "SkColor.h"
+#include "SkConstexprMath.h"
+#include "SkData.h"
+#include "SkDraw.h"
+#include "SkDrawProcs.h"
+#include "SkFontHost.h"
+#include "SkGlyphCache.h"
+#include "SkHRESULT.h"
+#include "SkImageEncoder.h"
+#include "SkIStream.h"
+#include "SkMaskFilter.h"
+#include "SkPaint.h"
+#include "SkPoint.h"
+#include "SkRasterizer.h"
+#include "SkShader.h"
+#include "SkSize.h"
+#include "SkStream.h"
+#include "SkTDArray.h"
+#include "SkTLazy.h"
+#include "SkTScopedComPtr.h"
+#include "SkUtils.h"
+#include "SkXPSDevice.h"
+
+//Windows defines a FLOAT type,
+//make it clear when converting a scalar that this is what is wanted.
+#define SkScalarToFLOAT(n) SkScalarToFloat(n)
+
+//Dummy representation of a GUID from create_id.
+#define L_GUID_ID L"XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX"
+//Length of GUID representation from create_id, including NULL terminator.
+#define GUID_ID_LEN SK_ARRAY_COUNT(L_GUID_ID)
+
+/**
+   Formats a GUID and places it into buffer.
+   buffer should have space for at least GUID_ID_LEN wide characters.
+   The string will always be wchar null terminated.
+   XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0
+   @return -1 if there was an error, > 0 if success.
+ */
+static int format_guid(const GUID& guid,
+                       wchar_t* buffer, size_t bufferSize,
+                       wchar_t sep = '-') {
+    SkASSERT(bufferSize >= GUID_ID_LEN);
+    return swprintf_s(buffer,
+                      bufferSize,
+                      L"%08lX%c%04X%c%04X%c%02X%02X%c%02X%02X%02X%02X%02X%02X",
+                      guid.Data1,
+                      sep,
+                      guid.Data2,
+                      sep,
+                      guid.Data3,
+                      sep,
+                      guid.Data4[0],
+                      guid.Data4[1],
+                      sep,
+                      guid.Data4[2],
+                      guid.Data4[3],
+                      guid.Data4[4],
+                      guid.Data4[5],
+                      guid.Data4[6],
+                      guid.Data4[7]);
+}
+/**
+   Creates a GUID based id and places it into buffer.
+   buffer should have space for at least GUID_ID_LEN wide characters.
+   The string will always be wchar null terminated.
+   XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0
+   The string may begin with a digit,
+   and so may not be suitable as a bare resource key.
+ */
+static HRESULT create_id(wchar_t* buffer, size_t bufferSize,
+                         wchar_t sep = '-') {
+    GUID guid = {};
+    HRM(CoCreateGuid(&guid), "Could not create GUID for id.");
+    
+    if (format_guid(guid, buffer, bufferSize, sep) == -1) {
+        HRM(E_UNEXPECTED, "Could not format GUID into id.");
+    }
+    
+    return S_OK;
+}
+
+static SkBitmap make_fake_bitmap(int width, int height) {
+    SkBitmap bitmap;
+    bitmap.setConfig(SkBitmap::kNo_Config, width, height);
+    return bitmap;
+}
+
+SkXPSDevice::SkXPSDevice()
+    : SkDevice(make_fake_bitmap(10000, 10000))
+    , fCurrentPage(0) {
+}
+
+SkXPSDevice::~SkXPSDevice() {
+}
+
+SkXPSDevice::TypefaceUse::TypefaceUse()
+    : typefaceId(0xffffffff)
+    , fontData(NULL)
+    , xpsFont(NULL)
+    , glyphsUsed(NULL) {
+}
+
+SkXPSDevice::TypefaceUse::~TypefaceUse() {
+    //xpsFont owns fontData ref
+    this->xpsFont->Release();
+    delete this->glyphsUsed;
+}
+
+bool SkXPSDevice::beginPortfolio(SkWStream* outputStream) {
+    if (!this->fAutoCo.succeeded()) return false;
+    
+    //Create XPS Factory.
+    HRBM(CoCreateInstance(
+             CLSID_XpsOMObjectFactory,
+             NULL,
+             CLSCTX_INPROC_SERVER,
+             IID_PPV_ARGS(&this->fXpsFactory)),
+         "Could not create XPS factory.");
+    
+    HRBM(SkWIStream::CreateFromSkWStream(outputStream, &this->fOutputStream),
+         "Could not convert SkStream to IStream.");
+    
+    return true;
+}
+
+bool SkXPSDevice::beginSheet(
+        const SkVector& unitsPerMeter,
+        const SkVector& pixelsPerMeter,
+        const SkSize& trimSize,
+        const SkRect* mediaBox,
+        const SkRect* bleedBox,
+        const SkRect* artBox,
+        const SkRect* cropBox) {
+    ++this->fCurrentPage;
+    
+    //For simplicity, just write everything out in geometry units,
+    //then have a base canvas do the scale to physical units.
+    this->fCurrentCanvasSize = trimSize;
+    this->fCurrentUnitsPerMeter = unitsPerMeter;
+    this->fCurrentPixelsPerMeter = pixelsPerMeter;
+    
+    this->fCurrentXpsCanvas.reset();
+    HRBM(this->fXpsFactory->CreateCanvas(&this->fCurrentXpsCanvas),
+         "Could not create base canvas.");
+    
+    return true;
+}
+
+HRESULT SkXPSDevice::createXpsThumbnail(IXpsOMPage* page,
+                                        const unsigned int pageNum,
+                                        IXpsOMImageResource** image) {
+    SkTScopedComPtr<IXpsOMThumbnailGenerator> thumbnailGenerator;
+    HRM(CoCreateInstance(
+            CLSID_XpsOMThumbnailGenerator,
+            NULL,
+            CLSCTX_INPROC_SERVER,
+            IID_PPV_ARGS(&thumbnailGenerator)),
+        "Could not create thumbnail generator.");
+    
+    SkTScopedComPtr<IOpcPartUri> partUri;
+    static const size_t size = SK_MAX(
+        SK_ARRAY_COUNT(L"/Documents/1/Metadata/.png") + SK_DIGITS_IN(pageNum),
+        SK_ARRAY_COUNT(L"/Metadata/" L_GUID_ID L".png")
+    );
+    wchar_t buffer[size];
+    if (pageNum > 0) {
+        swprintf_s(buffer, size, L"/Documents/1/Metadata/%u.png", pageNum);
+    } else {
+        wchar_t id[GUID_ID_LEN];
+        HR(create_id(id, GUID_ID_LEN));
+        swprintf_s(buffer, size, L"/Metadata/%s.png", id);
+    }
+    HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri),
+        "Could not create thumbnail part uri.");
+    
+    HRM(thumbnailGenerator->GenerateThumbnail(page,
+                                              XPS_IMAGE_TYPE_PNG,
+                                              XPS_THUMBNAIL_SIZE_LARGE,
+                                              partUri.get(),
+                                              image),
+        "Could not generate thumbnail.");
+    
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::createXpsPage(const XPS_SIZE& pageSize,
+                                   IXpsOMPage** page) {
+    static const size_t size = SK_ARRAY_COUNT(L"/Documents/1/Pages/.fpage")
+                             + SK_DIGITS_IN(fCurrentPage);
+    wchar_t buffer[size];
+    swprintf_s(buffer, size, L"/Documents/1/Pages/%u.fpage",
+                             this->fCurrentPage);
+    SkTScopedComPtr<IOpcPartUri> partUri;
+    HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri),
+        "Could not create page part uri.");
+    
+    //If the language is unknown, use "und" (XPS Spec 2.3.5.1).
+    HRM(this->fXpsFactory->CreatePage(&pageSize,
+                                      L"und",
+                                      partUri.get(),
+                                      page),
+        "Could not create page.");
+    
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::initXpsDocumentWriter(IXpsOMImageResource* image) {
+    //Create package writer.
+    {
+        SkTScopedComPtr<IOpcPartUri> partUri;
+        HRM(this->fXpsFactory->CreatePartUri(L"/FixedDocumentSequence.fdseq",
+                                             &partUri),
+            "Could not create document sequence part uri.");
+        HRM(this->fXpsFactory->CreatePackageWriterOnStream(
+                this->fOutputStream.get(),
+                TRUE,
+                XPS_INTERLEAVING_OFF, //XPS_INTERLEAVING_ON,
+                partUri.get(),
+                NULL,
+                image,
+                NULL,
+                NULL,
+                &this->fPackageWriter),
+            "Could not create package writer.");
+    }
+    
+    //Begin the lone document.
+    {
+        SkTScopedComPtr<IOpcPartUri> partUri;
+        HRM(this->fXpsFactory->CreatePartUri(
+                L"/Documents/1/FixedDocument.fdoc",
+                &partUri),
+            "Could not create fixed document part uri.");
+        HRM(this->fPackageWriter->StartNewDocument(partUri.get(),
+                                                   NULL,
+                                                   NULL,
+                                                   NULL,
+                                                   NULL),
+            "Could not start document.");
+    }
+    
+    return S_OK;
+}
+
+bool SkXPSDevice::endSheet() {
+    //XPS is fixed at 96dpi (XPS Spec 11.1).
+    static const float xpsDPI = 96.0f;
+    static const float inchesPerMeter = 10000.0f / 254.0f;
+    static const float targetUnitsPerMeter = xpsDPI * inchesPerMeter;
+    const float scaleX = targetUnitsPerMeter
+                       / SkScalarToFLOAT(this->fCurrentUnitsPerMeter.fX);
+    const float scaleY = targetUnitsPerMeter
+                       / SkScalarToFLOAT(this->fCurrentUnitsPerMeter.fY);
+    
+    //Create the scale canvas.
+    SkTScopedComPtr<IXpsOMCanvas> scaleCanvas;
+    HRBM(this->fXpsFactory->CreateCanvas(&scaleCanvas),
+         "Could not create scale canvas.");
+    SkTScopedComPtr<IXpsOMVisualCollection> scaleCanvasVisuals;
+    HRBM(scaleCanvas->GetVisuals(&scaleCanvasVisuals),
+         "Could not get scale canvas visuals.");
+    
+    SkTScopedComPtr<IXpsOMMatrixTransform> geomToPhys;
+    XPS_MATRIX rawGeomToPhys = { scaleX, 0, 0, scaleY, 0, 0, };
+    HRBM(this->fXpsFactory->CreateMatrixTransform(&rawGeomToPhys, &geomToPhys),
+         "Could not create geometry to physical transform.");
+    HRBM(scaleCanvas->SetTransformLocal(geomToPhys.get()),
+         "Could not set transform on scale canvas.");
+    
+    //Add the content canvas to the scale canvas.
+    HRBM(scaleCanvasVisuals->Append(this->fCurrentXpsCanvas.get()),
+         "Could not add base canvas to scale canvas.");
+    
+    //Create the page.
+    XPS_SIZE pageSize = {
+        SkScalarToFLOAT(this->fCurrentCanvasSize.width()) * scaleX,
+        SkScalarToFLOAT(this->fCurrentCanvasSize.height()) * scaleY,
+    };
+    SkTScopedComPtr<IXpsOMPage> page;
+    HRB(this->createXpsPage(pageSize, &page));
+    
+    SkTScopedComPtr<IXpsOMVisualCollection> pageVisuals;
+    HRBM(page->GetVisuals(&pageVisuals), "Could not get page visuals.");
+    
+    //Add the scale canvas to the page.
+    HRBM(pageVisuals->Append(scaleCanvas.get()),
+         "Could not add scale canvas to page.");
+    
+    //Create the package writer if it hasn't been created yet.
+    if (NULL == this->fPackageWriter.get()) {
+        SkTScopedComPtr<IXpsOMImageResource> image;
+        //Ignore return, thumbnail is completely optional.
+        this->createXpsThumbnail(page.get(), 0, &image);
+        
+        HRB(this->initXpsDocumentWriter(image.get()));
+    }
+    
+    HRBM(this->fPackageWriter->AddPage(page.get(),
+                                       &pageSize,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       NULL),
+         "Could not write the page.");
+    this->fCurrentXpsCanvas.reset();
+    
+    return true;
+}
+
+static HRESULT subset_typeface(SkXPSDevice::TypefaceUse* current) {
+    //CreateFontPackage wants unsigned short.
+    //Microsoft, Y U NO stdint.h?
+    SkTDArray<unsigned short> keepList;
+    current->glyphsUsed->exportTo(&keepList);
+    
+    //The following are declared with the types required by CreateFontPackage.
+    unsigned char *puchFontPackageBuffer;
+    unsigned long pulFontPackageBufferSize;
+    unsigned long pulBytesWritten;
+    unsigned long result = CreateFontPackage(
+        (unsigned char *) current->fontData->getMemoryBase(),
+        (unsigned long) current->fontData->getLength(),
+        &puchFontPackageBuffer,
+        &pulFontPackageBufferSize,
+        &pulBytesWritten,
+        TTFCFP_FLAGS_SUBSET | TTFCFP_FLAGS_GLYPHLIST,// | TTFCFP_FLAGS_TTC,
+        0,//TTC index
+        TTFCFP_SUBSET,
+        0,
+        0,
+        0,
+        keepList.begin(),
+        keepList.count(),
+        sk_malloc_throw,
+        sk_realloc_throw,
+        sk_free,
+        NULL);
+    if (result != NO_ERROR) {
+        SkDEBUGF(("CreateFontPackage Error %lu", result));
+        return E_UNEXPECTED;
+    }
+    
+    SkMemoryStream* newStream = new SkMemoryStream;
+    newStream->setMemoryOwned(puchFontPackageBuffer, pulBytesWritten);
+    SkTScopedComPtr<IStream> newIStream;
+    SkIStream::CreateFromSkStream(newStream, true, &newIStream);
+    
+    XPS_FONT_EMBEDDING embedding;
+    HRM(current->xpsFont->GetEmbeddingOption(&embedding),
+        "Could not get embedding option from font.");
+    
+    SkTScopedComPtr<IOpcPartUri> partUri;
+    HRM(current->xpsFont->GetPartName(&partUri),
+        "Could not get part uri from font.");
+    
+    HRM(current->xpsFont->SetContent(
+            newIStream.get(),
+            embedding,
+            partUri.get()),
+        "Could not set new stream for subsetted font.");
+    
+    return S_OK;
+}
+
+bool SkXPSDevice::endPortfolio() {
+    //Subset fonts
+    if (!this->fTypefaces.empty()) {
+        SkXPSDevice::TypefaceUse* current = &this->fTypefaces.front();
+        const TypefaceUse* last = &this->fTypefaces.back();
+        for (; current <= last; ++current) {
+            //Ignore return for now, if it didn't subset, let it be.
+            subset_typeface(current);
+        }
+    }
+    
+    HRBM(this->fPackageWriter->Close(), "Could not close writer.");
+    
+    return true;
+}
+
+static XPS_COLOR xps_color(const SkColor skColor) {
+    //XPS uses non-pre-multiplied alpha (XPS Spec 11.4).
+    XPS_COLOR xpsColor;
+    xpsColor.colorType = XPS_COLOR_TYPE_SRGB;
+    xpsColor.value.sRGB.alpha = SkColorGetA(skColor);
+    xpsColor.value.sRGB.red = SkColorGetR(skColor);
+    xpsColor.value.sRGB.green = SkColorGetG(skColor);
+    xpsColor.value.sRGB.blue = SkColorGetB(skColor);
+    
+    return xpsColor;
+}
+
+static XPS_POINT xps_point(const SkPoint& point) {
+    XPS_POINT xpsPoint = {
+        SkScalarToFLOAT(point.fX),
+        SkScalarToFLOAT(point.fY),
+    };
+    return xpsPoint;
+}
+
+static XPS_POINT xps_point(const SkPoint& point, const SkMatrix& matrix) {
+    SkPoint skTransformedPoint;
+    matrix.mapXY(point.fX, point.fY, &skTransformedPoint);
+    return xps_point(skTransformedPoint);
+}
+
+static XPS_SPREAD_METHOD xps_spread_method(SkShader::TileMode tileMode) {
+    switch (tileMode) {
+    case SkShader::kClamp_TileMode:
+        return XPS_SPREAD_METHOD_PAD;
+    case SkShader::kRepeat_TileMode:
+        return XPS_SPREAD_METHOD_REPEAT;
+    case SkShader::kMirror_TileMode:
+        return XPS_SPREAD_METHOD_REFLECT;
+    default:
+        SkASSERT(!"Unknown tile mode.");
+    }
+    return XPS_SPREAD_METHOD_PAD;
+}
+
+static void transform_offsets(SkScalar* stopOffsets, const int numOffsets,
+                              const SkPoint& start, const SkPoint& end,
+                              const SkMatrix& transform) {
+    SkPoint startTransformed;
+    transform.mapXY(start.fX, start.fY, &startTransformed);
+    SkPoint endTransformed;
+    transform.mapXY(end.fX, end.fY, &endTransformed);
+    
+    //Manhattan distance between transformed start and end.
+    SkScalar startToEnd = (endTransformed.fX - startTransformed.fX)
+                        + (endTransformed.fY - startTransformed.fY);
+    if (SkScalarNearlyZero(startToEnd)) {
+        for (int i = 0; i < numOffsets; ++i) {
+            stopOffsets[i] = 0;
+        }
+        return;
+    }
+    
+    for (int i = 0; i < numOffsets; ++i) {
+        SkPoint stop;
+        stop.fX = SkScalarMul(end.fX - start.fX, stopOffsets[i]);
+        stop.fY = SkScalarMul(end.fY - start.fY, stopOffsets[i]);
+        
+        SkPoint stopTransformed;
+        transform.mapXY(stop.fX, stop.fY, &stopTransformed);
+        
+        //Manhattan distance between transformed start and stop.
+        SkScalar startToStop = (stopTransformed.fX - startTransformed.fX)
+                             + (stopTransformed.fY - startTransformed.fY);
+        //Percentage along transformed line.
+        stopOffsets[i] = SkScalarDiv(startToStop, startToEnd);
+    }
+}
+
+HRESULT SkXPSDevice::createXpsTransform(const SkMatrix& matrix,
+                                        IXpsOMMatrixTransform** xpsTransform) {
+    SkScalar affine[6];
+    if (!matrix.asAffine(affine)) {
+        *xpsTransform = NULL;
+        return S_FALSE;
+    }
+    XPS_MATRIX rawXpsMatrix = {
+        SkScalarToFLOAT(affine[SkMatrix::kAScaleX]),
+        SkScalarToFLOAT(affine[SkMatrix::kASkewY]),
+        SkScalarToFLOAT(affine[SkMatrix::kASkewX]),
+        SkScalarToFLOAT(affine[SkMatrix::kAScaleY]),
+        SkScalarToFLOAT(affine[SkMatrix::kATransX]),
+        SkScalarToFLOAT(affine[SkMatrix::kATransY]),
+    };
+    HRM(this->fXpsFactory->CreateMatrixTransform(&rawXpsMatrix, xpsTransform),
+        "Could not create transform.");
+    
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::createPath(IXpsOMGeometryFigure* figure,
+                                IXpsOMVisualCollection* visuals,
+                                IXpsOMPath** path) {
+    SkTScopedComPtr<IXpsOMGeometry> geometry;
+    HRM(this->fXpsFactory->CreateGeometry(&geometry),
+        "Could not create geometry.");
+    
+    SkTScopedComPtr<IXpsOMGeometryFigureCollection> figureCollection;
+    HRM(geometry->GetFigures(&figureCollection), "Could not get figures.");
+    HRM(figureCollection->Append(figure), "Could not add figure.");
+    
+    HRM(this->fXpsFactory->CreatePath(path), "Could not create path.");
+    HRM((*path)->SetGeometryLocal(geometry.get()), "Could not set geometry");
+    
+    HRM(visuals->Append(*path), "Could not add path to visuals.");
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::createXpsSolidColorBrush(const SkColor skColor,
+                                              const SkAlpha alpha,
+                                              IXpsOMBrush** xpsBrush) {
+    XPS_COLOR xpsColor = xps_color(skColor);
+    SkTScopedComPtr<IXpsOMSolidColorBrush> solidBrush;
+    HRM(this->fXpsFactory->CreateSolidColorBrush(&xpsColor, NULL, &solidBrush),
+        "Could not create solid color brush.");
+    HRM(solidBrush->SetOpacity(alpha / 255.0f), "Could not set opacity.");
+    HRM(solidBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI Fail.");
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::sideOfClamp(const SkRect& areaToFill,
+                                 const XPS_RECT& imageViewBox,
+                                 IXpsOMImageResource* image,
+                                 IXpsOMVisualCollection* visuals) {
+    SkTScopedComPtr<IXpsOMGeometryFigure> areaToFillFigure;
+    HR(this->createXpsRect(areaToFill, FALSE, TRUE, &areaToFillFigure));
+    
+    SkTScopedComPtr<IXpsOMPath> areaToFillPath;
+    HR(this->createPath(areaToFillFigure.get(), visuals, &areaToFillPath));
+    
+    SkTScopedComPtr<IXpsOMImageBrush> areaToFillBrush;
+    HRM(this->fXpsFactory->CreateImageBrush(image,
+                                            &imageViewBox,
+                                            &imageViewBox,
+                                            &areaToFillBrush),
+        "Could not create brush for side of clamp.");
+    HRM(areaToFillBrush->SetTileMode(XPS_TILE_MODE_FLIPXY),
+        "Could not set tile mode for side of clamp.");
+    HRM(areaToFillPath->SetFillBrushLocal(areaToFillBrush.get()),
+        "Could not set brush for side of clamp");
+    
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::cornerOfClamp(const SkRect& areaToFill,
+                                   const SkColor color,
+                                   IXpsOMVisualCollection* visuals) {
+    SkTScopedComPtr<IXpsOMGeometryFigure> areaToFillFigure;
+    HR(this->createXpsRect(areaToFill, FALSE, TRUE, &areaToFillFigure));
+    
+    SkTScopedComPtr<IXpsOMPath> areaToFillPath;
+    HR(this->createPath(areaToFillFigure.get(), visuals, &areaToFillPath));
+    
+    SkTScopedComPtr<IXpsOMBrush> areaToFillBrush;
+    HR(this->createXpsSolidColorBrush(color, 0xFF, &areaToFillBrush));
+    HRM(areaToFillPath->SetFillBrushLocal(areaToFillBrush.get()),
+        "Could not set brush for corner of clamp.");
+    
+    return S_OK;
+}
+
+static const XPS_TILE_MODE XTM_N  = XPS_TILE_MODE_NONE;
+static const XPS_TILE_MODE XTM_T  = XPS_TILE_MODE_TILE;
+static const XPS_TILE_MODE XTM_X  = XPS_TILE_MODE_FLIPX;
+static const XPS_TILE_MODE XTM_Y  = XPS_TILE_MODE_FLIPY;
+static const XPS_TILE_MODE XTM_XY = XPS_TILE_MODE_FLIPXY;
+
+//TODO(bungeman): In the future, should skia add None,
+//handle None+Mirror and None+Repeat correctly.
+//None is currently an internal hack so masks don't repeat (None+None only).
+static XPS_TILE_MODE SkToXpsTileMode[SkShader::kTileModeCount+1]
+                                    [SkShader::kTileModeCount+1] = {
+           //Clamp //Repeat //Mirror //None
+/*Clamp */ XTM_N,  XTM_T,   XTM_Y,   XTM_N,
+/*Repeat*/ XTM_T,  XTM_T,   XTM_Y,   XTM_N,
+/*Mirror*/ XTM_X,  XTM_X,   XTM_XY,  XTM_X,
+/*None  */ XTM_N,  XTM_N,   XTM_Y,   XTM_N,
+};
+
+HRESULT SkXPSDevice::createXpsImageBrush(
+        const SkBitmap& bitmap,
+        const SkMatrix& localMatrix,
+        const SkShader::TileMode (&xy)[2],
+        const SkAlpha alpha,
+        IXpsOMTileBrush** xpsBrush) {
+    SkDynamicMemoryWStream write;
+    if (!SkImageEncoder::EncodeStream(&write, bitmap,
+                                      SkImageEncoder::kPNG_Type, 100)) {
+        HRM(E_FAIL, "Unable to encode bitmap as png.");
+    }
+    SkMemoryStream* read = new SkMemoryStream;
+    read->setData(write.copyToData())->unref();
+    SkTScopedComPtr<IStream> readWrapper;
+    HRM(SkIStream::CreateFromSkStream(read, true, &readWrapper),
+        "Could not create stream from png data.");
+    
+    const size_t size =
+        SK_ARRAY_COUNT(L"/Documents/1/Resources/Images/" L_GUID_ID L".png");
+    wchar_t buffer[size];
+    wchar_t id[GUID_ID_LEN];
+    HR(create_id(id, GUID_ID_LEN));
+    swprintf_s(buffer, size, L"/Documents/1/Resources/Images/%s.png", id);
+    
+    SkTScopedComPtr<IOpcPartUri> imagePartUri;
+    HRM(this->fXpsFactory->CreatePartUri(buffer, &imagePartUri),
+        "Could not create image part uri.");
+    
+    SkTScopedComPtr<IXpsOMImageResource> imageResource;
+    HRM(this->fXpsFactory->CreateImageResource(
+            readWrapper.get(),
+            XPS_IMAGE_TYPE_PNG,
+            imagePartUri.get(),
+            &imageResource),
+        "Could not create image resource.");
+    
+    XPS_RECT bitmapRect = {
+        0.0, 0.0,
+        static_cast<FLOAT>(bitmap.width()), static_cast<FLOAT>(bitmap.height())
+    };
+    SkTScopedComPtr<IXpsOMImageBrush> xpsImageBrush;
+    HRM(this->fXpsFactory->CreateImageBrush(imageResource.get(),
+                                            &bitmapRect, &bitmapRect,
+                                            &xpsImageBrush),
+        "Could not create image brush.");
+    
+    if (SkShader::kClamp_TileMode != xy[0] &&
+        SkShader::kClamp_TileMode != xy[1]) {
+        
+        HRM(xpsImageBrush->SetTileMode(SkToXpsTileMode[xy[0]][xy[1]]),
+            "Could not set image tile mode");
+        HRM(xpsImageBrush->SetOpacity(alpha / 255.0f),
+            "Could not set image opacity.");
+        HRM(xpsImageBrush->QueryInterface(xpsBrush), "QI failed.");
+    } else {
+        //TODO(bungeman): compute how big this really needs to be.
+        const SkScalar BIG = SkIntToScalar(1000); //SK_ScalarMax;
+        const FLOAT BIG_F = SkScalarToFLOAT(BIG);
+        const SkScalar bWidth = SkIntToScalar(bitmap.width());
+        const SkScalar bHeight = SkIntToScalar(bitmap.height());
+        
+        //create brush canvas
+        SkTScopedComPtr<IXpsOMCanvas> brushCanvas;
+        HRM(this->fXpsFactory->CreateCanvas(&brushCanvas),
+            "Could not create image brush canvas.");
+        SkTScopedComPtr<IXpsOMVisualCollection> brushVisuals;
+        HRM(brushCanvas->GetVisuals(&brushVisuals),
+            "Could not get image brush canvas visuals collection.");
+        
+        //create central figure
+        const SkRect bitmapPoints = SkRect::MakeLTRB(0, 0, bWidth, bHeight);
+        SkTScopedComPtr<IXpsOMGeometryFigure> centralFigure;
+        HR(this->createXpsRect(bitmapPoints, FALSE, TRUE, &centralFigure));
+        
+        SkTScopedComPtr<IXpsOMPath> centralPath;
+        HR(this->createPath(centralFigure.get(),
+                            brushVisuals.get(),
+                            &centralPath));
+        HRM(xpsImageBrush->SetTileMode(XPS_TILE_MODE_FLIPXY),
+            "Could not set tile mode for image brush central path.");
+        HRM(centralPath->SetFillBrushLocal(xpsImageBrush.get()),
+            "Could not set fill brush for image brush central path.");
+        
+        //add left/right
+        if (SkShader::kClamp_TileMode == xy[0]) {
+            SkRect leftArea = SkRect::MakeLTRB(-BIG, 0, 0, bHeight);
+            XPS_RECT leftImageViewBox = {
+                0.0, 0.0,
+                1.0, static_cast<FLOAT>(bitmap.height()),
+            };
+            HR(this->sideOfClamp(leftArea, leftImageViewBox,
+                                 imageResource.get(),
+                                 brushVisuals.get()));
+
+            SkRect rightArea = SkRect::MakeLTRB(bWidth, 0, BIG, bHeight);
+            XPS_RECT rightImageViewBox = {
+                bitmap.width() - 1.0f, 0.0f,
+                1.0f, static_cast<FLOAT>(bitmap.height()),
+            };
+            HR(this->sideOfClamp(rightArea, rightImageViewBox,
+                                 imageResource.get(),
+                                 brushVisuals.get()));
+        }
+        
+        //add top/bottom
+        if (SkShader::kClamp_TileMode == xy[1]) {
+            SkRect topArea = SkRect::MakeLTRB(0, -BIG, bWidth, 0);
+            XPS_RECT topImageViewBox = {
+                0.0, 0.0,
+                static_cast<FLOAT>(bitmap.width()), 1.0,
+            };
+            HR(this->sideOfClamp(topArea, topImageViewBox,
+                                 imageResource.get(),
+                                 brushVisuals.get()));
+            
+            SkRect bottomArea = SkRect::MakeLTRB(0, bHeight, bWidth, BIG);
+            XPS_RECT bottomImageViewBox = {
+                0.0f, bitmap.height() - 1.0f,
+                static_cast<FLOAT>(bitmap.width()), 1.0f,
+            };
+            HR(this->sideOfClamp(bottomArea, bottomImageViewBox,
+                                 imageResource.get(),
+                                 brushVisuals.get()));
+        }
+        
+        //add tl, tr, bl, br
+        if (SkShader::kClamp_TileMode == xy[0] &&
+            SkShader::kClamp_TileMode == xy[1]) {
+            
+            SkAutoLockPixels alp(bitmap);
+            
+            const SkColor tlColor = bitmap.getColor(0,0);
+            const SkRect tlArea = SkRect::MakeLTRB(-BIG, -BIG, 0, 0);
+            HR(this->cornerOfClamp(tlArea, tlColor, brushVisuals.get()));
+            
+            const SkColor trColor = bitmap.getColor(bitmap.width()-1,0);
+            const SkRect trArea = SkRect::MakeLTRB(bWidth, -BIG, BIG, 0);
+            HR(this->cornerOfClamp(trArea, trColor, brushVisuals.get()));
+            
+            const SkColor brColor = bitmap.getColor(bitmap.width()-1,
+                                                    bitmap.height()-1);
+            const SkRect brArea = SkRect::MakeLTRB(bWidth, bHeight, BIG, BIG);
+            HR(this->cornerOfClamp(brArea, brColor, brushVisuals.get()));
+            
+            const SkColor blColor = bitmap.getColor(0,bitmap.height()-1);
+            const SkRect blArea = SkRect::MakeLTRB(-BIG, bHeight, 0, BIG);
+            HR(this->cornerOfClamp(blArea, blColor, brushVisuals.get()));
+        }
+        
+        //create visual brush from canvas
+        XPS_RECT bound = {};
+        if (SkShader::kClamp_TileMode == xy[0] &&
+            SkShader::kClamp_TileMode == xy[1]) {
+            
+            bound.x = BIG_F / -2;
+            bound.y = BIG_F / -2;
+            bound.width = BIG_F;
+            bound.height = BIG_F;
+        } else if (SkShader::kClamp_TileMode == xy[0]) {
+            bound.x = BIG_F / -2;
+            bound.y = 0.0f;
+            bound.width = BIG_F;
+            bound.height = static_cast<FLOAT>(bitmap.height());
+        } else if (SkShader::kClamp_TileMode == xy[1]) {
+            bound.x = 0;
+            bound.y = BIG_F / -2;
+            bound.width = static_cast<FLOAT>(bitmap.width());
+            bound.height = BIG_F;
+        }
+        SkTScopedComPtr<IXpsOMVisualBrush> clampBrush;
+        HRM(this->fXpsFactory->CreateVisualBrush(&bound, &bound, &clampBrush),
+            "Could not create visual brush for image brush.");
+        HRM(clampBrush->SetVisualLocal(brushCanvas.get()),
+            "Could not set canvas on visual brush for image brush.");
+        HRM(clampBrush->SetTileMode(SkToXpsTileMode[xy[0]][xy[1]]),
+            "Could not set tile mode on visual brush for image brush.");
+        HRM(clampBrush->SetOpacity(alpha / 255.0f),
+            "Could not set opacity on visual brush for image brush.");
+        
+        HRM(clampBrush->QueryInterface(xpsBrush), "QI failed.");
+    }
+    
+    SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse;
+    HR(this->createXpsTransform(localMatrix, &xpsMatrixToUse));
+    if (NULL != xpsMatrixToUse.get()) {
+        HRM((*xpsBrush)->SetTransformLocal(xpsMatrixToUse.get()),
+            "Could not set transform for image brush.");
+    } else {
+        //TODO(bungeman): perspective bitmaps in general.
+    }
+    
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::createXpsGradientStop(const SkColor skColor,
+                                           const SkScalar offset,
+                                           IXpsOMGradientStop** xpsGradStop) {
+    XPS_COLOR gradStopXpsColor = xps_color(skColor);
+    HRM(this->fXpsFactory->CreateGradientStop(&gradStopXpsColor,
+                                              NULL,
+                                              SkScalarToFLOAT(offset),
+                                              xpsGradStop),
+        "Could not create gradient stop.");
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::createXpsLinearGradient(SkShader::GradientInfo info,
+                                             const SkAlpha alpha,
+                                             const SkMatrix& localMatrix,
+                                             IXpsOMMatrixTransform* xpsMatrix,
+                                             IXpsOMBrush** xpsBrush) {
+    XPS_POINT startPoint;
+    XPS_POINT endPoint;
+    if (NULL != xpsMatrix) {
+        startPoint = xps_point(info.fPoint[0]);
+        endPoint = xps_point(info.fPoint[1]);
+    } else {
+        transform_offsets(info.fColorOffsets, info.fColorCount,
+                          info.fPoint[0], info.fPoint[1],
+                          localMatrix);
+        startPoint = xps_point(info.fPoint[0], localMatrix);
+        endPoint = xps_point(info.fPoint[1], localMatrix);
+    }
+    
+    SkTScopedComPtr<IXpsOMGradientStop> gradStop0;
+    HR(createXpsGradientStop(info.fColors[0],
+                             info.fColorOffsets[0],
+                             &gradStop0));
+    
+    SkTScopedComPtr<IXpsOMGradientStop> gradStop1;
+    HR(createXpsGradientStop(info.fColors[1],
+                             info.fColorOffsets[1],
+                             &gradStop1));
+    
+    SkTScopedComPtr<IXpsOMLinearGradientBrush> gradientBrush;
+    HRM(this->fXpsFactory->CreateLinearGradientBrush(gradStop0.get(),
+                                                     gradStop1.get(),
+                                                     &startPoint,
+                                                     &endPoint,
+                                                     &gradientBrush),
+        "Could not create linear gradient brush.");
+    if (NULL != xpsMatrix) {
+        HRM(gradientBrush->SetTransformLocal(xpsMatrix),
+            "Could not set transform on linear gradient brush.");
+    }
+    
+    SkTScopedComPtr<IXpsOMGradientStopCollection> gradStopCollection;
+    HRM(gradientBrush->GetGradientStops(&gradStopCollection),
+        "Could not get linear gradient stop collection.");
+    for (int i = 2; i < info.fColorCount; ++i) {
+        SkTScopedComPtr<IXpsOMGradientStop> gradStop;
+        HR(createXpsGradientStop(info.fColors[i],
+                                 info.fColorOffsets[i],
+                                 &gradStop));
+        HRM(gradStopCollection->Append(gradStop.get()),
+            "Could not add linear gradient stop.");
+    }
+    
+    HRM(gradientBrush->SetSpreadMethod(xps_spread_method(info.fTileMode)),
+        "Could not set spread method of linear gradient.");
+    
+    HRM(gradientBrush->SetOpacity(alpha / 255.0f),
+        "Could not set opacity of linear gradient brush.");
+    HRM(gradientBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI failed");
+    
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::createXpsRadialGradient(SkShader::GradientInfo info,
+                                             const SkAlpha alpha,
+                                             const SkMatrix& localMatrix,
+                                             IXpsOMMatrixTransform* xpsMatrix,
+                                             IXpsOMBrush** xpsBrush) {
+    SkTScopedComPtr<IXpsOMGradientStop> gradStop0;
+    HR(createXpsGradientStop(info.fColors[0],
+                             info.fColorOffsets[0],
+                             &gradStop0));
+    
+    SkTScopedComPtr<IXpsOMGradientStop> gradStop1;
+    HR(createXpsGradientStop(info.fColors[1],
+                             info.fColorOffsets[1],
+                             &gradStop1));
+    
+    //TODO: figure out how to fake better if not affine
+    XPS_POINT centerPoint;
+    XPS_POINT gradientOrigin;
+    XPS_SIZE radiiSizes;
+    if (NULL != xpsMatrix) {
+        centerPoint = xps_point(info.fPoint[0]);
+        gradientOrigin = xps_point(info.fPoint[0]);
+        radiiSizes.width = SkScalarToFLOAT(info.fRadius[0]);
+        radiiSizes.height = SkScalarToFLOAT(info.fRadius[0]);
+    } else {
+        centerPoint = xps_point(info.fPoint[0], localMatrix);
+        gradientOrigin = xps_point(info.fPoint[0], localMatrix);
+        
+        SkScalar radius = info.fRadius[0];
+        SkVector vec[2];
+        
+        vec[0].set(radius, 0);
+        vec[1].set(0, radius);
+        localMatrix.mapVectors(vec, 2);
+        
+        SkScalar d0 = vec[0].length();
+        SkScalar d1 = vec[1].length();
+        
+        radiiSizes.width = SkScalarToFLOAT(d0);
+        radiiSizes.height = SkScalarToFLOAT(d1);
+    }
+    
+    SkTScopedComPtr<IXpsOMRadialGradientBrush> gradientBrush;
+    HRM(this->fXpsFactory->CreateRadialGradientBrush(gradStop0.get(),
+                                                     gradStop1.get(),
+                                                     &centerPoint,
+                                                     &gradientOrigin,
+                                                     &radiiSizes,
+                                                     &gradientBrush),
+        "Could not create radial gradient brush.");
+    if (NULL != xpsMatrix) {
+        HRM(gradientBrush->SetTransformLocal(xpsMatrix),
+            "Could not set transform on radial gradient brush.");
+    }
+    
+    SkTScopedComPtr<IXpsOMGradientStopCollection> gradStopCollection;
+    HRM(gradientBrush->GetGradientStops(&gradStopCollection),
+        "Could not get radial gradient stop collection.");
+    for (int i = 2; i < info.fColorCount; ++i) {
+        SkTScopedComPtr<IXpsOMGradientStop> gradStop;
+        HR(createXpsGradientStop(info.fColors[i],
+                                 info.fColorOffsets[i],
+                                 &gradStop));
+        HRM(gradStopCollection->Append(gradStop.get()),
+            "Could not add radial gradient stop.");
+    }
+    
+    HRM(gradientBrush->SetSpreadMethod(xps_spread_method(info.fTileMode)),
+        "Could not set spread method of radial gradient.");
+    
+    HRM(gradientBrush->SetOpacity(alpha / 255.0f),
+        "Could not set opacity of radial gradient brush.");
+    HRM(gradientBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI failed.");
+    
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::createXpsBrush(const SkPaint& skPaint,
+                                    IXpsOMBrush** brush,
+                                    const SkMatrix* parentTransform) {
+    const SkShader *shader = skPaint.getShader();
+    if (NULL == shader) {
+        HR(this->createXpsSolidColorBrush(skPaint.getColor(), 0xFF, brush));
+        return S_OK;
+    }
+    
+    //Gradient shaders.
+    SkShader::GradientInfo info;
+    info.fColorCount = 0;
+    info.fColors = NULL;
+    info.fColorOffsets = NULL;
+    SkShader::GradientType gradientType = shader->asAGradient(&info);
+    
+    if (SkShader::kNone_GradientType == gradientType) {
+        //Nothing to see, move along.
+        
+    } else if (SkShader::kColor_GradientType == gradientType) {
+        SkASSERT(1 == info.fColorCount);
+        SkColor color;
+        info.fColors = &color;
+        SkShader::GradientType gradientType = shader->asAGradient(&info);
+        SkAlpha alpha = skPaint.getAlpha();
+        HR(this->createXpsSolidColorBrush(color, alpha, brush));
+        return S_OK;
+        
+    } else {
+        if (info.fColorCount == 0) {
+            const SkColor color = skPaint.getColor();
+            HR(this->createXpsSolidColorBrush(color, 0xFF, brush));
+            return S_OK;
+        }
+        
+        SkAutoTArray<SkColor> colors(info.fColorCount);
+        SkAutoTArray<SkScalar> colorOffsets(info.fColorCount);
+        info.fColors = colors.get();
+        info.fColorOffsets = colorOffsets.get();
+        shader->asAGradient(&info);
+        
+        if (1 == info.fColorCount) {
+            SkColor color = info.fColors[0];
+            SkAlpha alpha = skPaint.getAlpha();
+            HR(this->createXpsSolidColorBrush(color, alpha, brush));
+            return S_OK;
+        }
+        
+        SkMatrix localMatrix;
+        shader->getLocalMatrix(&localMatrix);
+        if (NULL != parentTransform) {
+            localMatrix.preConcat(*parentTransform);
+        }
+        SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse;
+        HR(this->createXpsTransform(localMatrix, &xpsMatrixToUse));
+        
+        if (SkShader::kLinear_GradientType == gradientType) {
+            HR(this->createXpsLinearGradient(info,
+                                             skPaint.getAlpha(),
+                                             localMatrix,
+                                             xpsMatrixToUse.get(),
+                                             brush));
+            return S_OK;
+        }
+        
+        if (SkShader::kRadial_GradientType == gradientType) {
+            HR(this->createXpsRadialGradient(info,
+                                             skPaint.getAlpha(),
+                                             localMatrix,
+                                             xpsMatrixToUse.get(),
+                                             brush));
+            return S_OK;
+        }
+        
+        if (SkShader::kRadial2_GradientType == gradientType) {
+            //simple if affine and one is 0, otherwise will have to fake
+        }
+        
+        if (SkShader::kSweep_GradientType == gradientType) {
+            //have to fake
+        }
+    }
+    
+    SkBitmap outTexture;
+    SkMatrix outMatrix;
+    SkShader::TileMode xy[2];
+    SkScalar twoPointRadialParams[3];
+    SkShader::BitmapType bitmapType = shader->asABitmap(&outTexture,
+                                                        &outMatrix,
+                                                        xy,
+                                                        twoPointRadialParams);
+    switch (bitmapType) {
+        case SkShader::kNone_BitmapType:
+            break;
+        case SkShader::kDefault_BitmapType: {
+            //TODO: outMatrix??
+            SkMatrix localMatrix;
+            shader->getLocalMatrix(&localMatrix);
+            if (NULL != parentTransform) {
+                localMatrix.preConcat(*parentTransform);
+            }
+            
+            SkTScopedComPtr<IXpsOMTileBrush> tileBrush;
+            HR(this->createXpsImageBrush(outTexture,
+                                         localMatrix,
+                                         xy,
+                                         skPaint.getAlpha(),
+                                         &tileBrush));
+            
+            HRM(tileBrush->QueryInterface<IXpsOMBrush>(brush), "QI failed.");
+            
+            return S_OK;
+        }
+        case SkShader::kRadial_BitmapType:
+        case SkShader::kSweep_BitmapType:
+        case SkShader::kTwoPointRadial_BitmapType:
+        default:
+            break;
+    }
+    
+    HR(this->createXpsSolidColorBrush(skPaint.getColor(), 0xFF, brush));
+    return S_OK;
+}
+
+static bool rect_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) {
+    const bool zeroWidth = (0 == paint.getStrokeWidth());
+    const bool stroke = (SkPaint::kFill_Style != paint.getStyle());
+    
+    return paint.getPathEffect() ||
+           paint.getMaskFilter() ||
+           paint.getRasterizer() ||
+           (stroke && (
+               (matrix.hasPerspective() && !zeroWidth) ||
+               SkPaint::kMiter_Join != paint.getStrokeJoin() ||
+               (SkPaint::kMiter_Join == paint.getStrokeJoin() &&
+                paint.getStrokeMiter() < SK_ScalarSqrt2)
+           ))
+    ;
+}
+
+HRESULT SkXPSDevice::createXpsRect(const SkRect& rect, BOOL stroke, BOOL fill,
+                                   IXpsOMGeometryFigure** xpsRect) {
+    const SkPoint points[4] = {
+        { rect.fLeft, rect.fTop },
+        { rect.fRight, rect.fTop },
+        { rect.fRight, rect.fBottom },
+        { rect.fLeft, rect.fBottom },
+    };
+    return this->createXpsQuad(points, stroke, fill, xpsRect);
+}
+HRESULT SkXPSDevice::createXpsQuad(const SkPoint (&points)[4],
+                                   BOOL stroke, BOOL fill,
+                                   IXpsOMGeometryFigure** xpsQuad) {
+    // Define the start point.
+    XPS_POINT startPoint = xps_point(points[0]);
+    
+    // Create the figure.
+    HRM(this->fXpsFactory->CreateGeometryFigure(&startPoint, xpsQuad),
+        "Could not create quad geometry figure.");
+    
+    // Define the type of each segment.
+    XPS_SEGMENT_TYPE segmentTypes[3] = {
+        XPS_SEGMENT_TYPE_LINE,
+        XPS_SEGMENT_TYPE_LINE,
+        XPS_SEGMENT_TYPE_LINE,
+    };
+    
+    // Define the x and y coordinates of each corner of the figure.
+    FLOAT segmentData[6] = {
+        SkScalarToFLOAT(points[1].fX), SkScalarToFLOAT(points[1].fY),
+        SkScalarToFLOAT(points[2].fX), SkScalarToFLOAT(points[2].fY),
+        SkScalarToFLOAT(points[3].fX), SkScalarToFLOAT(points[3].fY),
+    };
+    
+    // Describe if the segments are stroked.
+    BOOL segmentStrokes[3] = {
+        stroke, stroke, stroke,
+    };
+    
+    // Add the segment data to the figure.
+    HRM((*xpsQuad)->SetSegments(
+            3, 6,
+            segmentTypes , segmentData, segmentStrokes),
+        "Could not add segment data to quad.");
+    
+    // Set the closed and filled properties of the figure.
+    HRM((*xpsQuad)->SetIsClosed(stroke), "Could not set quad close.");
+    HRM((*xpsQuad)->SetIsFilled(fill), "Could not set quad fill.");
+    
+    return S_OK;
+}
+
+void SkXPSDevice::clear(SkColor color) {
+    //TODO: override this for XPS
+    SkDEBUGF(("XPS clear not yet implemented."));
+}
+
+void SkXPSDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
+                             size_t count, const SkPoint points[],
+                             const SkPaint& paint) {
+    //This will call back into the device to do the drawing.
+    d.drawPoints(mode, count, points, paint, true);
+}
+
+void SkXPSDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode,
+                               int vertexCount, const SkPoint verts[],
+                               const SkPoint texs[], const SkColor colors[],
+                               SkXfermode* xmode, const uint16_t indices[],
+                               int indexCount, const SkPaint& paint) {
+    //TODO: override this for XPS
+    SkDEBUGF(("XPS drawVertices not yet implemented."));
+}
+
+void SkXPSDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
+    const SkRect r = SkRect::MakeSize(this->fCurrentCanvasSize);
+    
+    //If trying to paint with a stroke, ignore that and fill.
+    SkPaint* fillPaint = const_cast<SkPaint*>(&paint);
+    SkTLazy<SkPaint> modifiedPaint;
+    if (paint.getStyle() != SkPaint::kFill_Style) {
+        fillPaint = modifiedPaint.set(paint);
+        fillPaint->setStyle(SkPaint::kFill_Style);
+    }
+    
+    this->internalDrawRect(d, r, false, *fillPaint);
+}
+
+void SkXPSDevice::drawRect(const SkDraw& d,
+                           const SkRect& r,
+                           const SkPaint& paint) {
+    this->internalDrawRect(d, r, true, paint);
+}
+
+void SkXPSDevice::internalDrawRect(const SkDraw& d,
+                                   const SkRect& r,
+                                   bool transformRect,
+                                   const SkPaint& paint) {
+    //Exit early if there is nothing to draw.
+    if (d.fClip->isEmpty() ||
+        (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
+        return;
+    }
+    
+    //Path the rect if we can't optimize it.
+    if (rect_must_be_pathed(paint, *d.fMatrix)) {
+        SkPath tmp;
+        tmp.addRect(r);
+        tmp.setFillType(SkPath::kWinding_FillType);
+        this->drawPath(d, tmp, paint, NULL, true);
+        return;
+    }
+    
+    //Create the shaded path.
+    SkTScopedComPtr<IXpsOMPath> shadedPath;
+    HRVM(this->fXpsFactory->CreatePath(&shadedPath),
+         "Could not create shaded path for rect.");
+    
+    //Create the shaded geometry.
+    SkTScopedComPtr<IXpsOMGeometry> shadedGeometry;
+    HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry),
+         "Could not create shaded geometry for rect.");
+    
+    //Add the geometry to the shaded path.
+    HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()),
+         "Could not set shaded geometry for rect.");
+    
+    //Set the brushes.
+    BOOL fill = FALSE;
+    BOOL stroke = FALSE;
+    HRV(this->shadePath(shadedPath.get(), paint, *d.fMatrix, &fill, &stroke));
+    
+    bool xpsTransformsPath = true;
+    //Transform the geometry.
+    if (transformRect && xpsTransformsPath) {
+        SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
+        HRV(this->createXpsTransform(*d.fMatrix, &xpsTransform));
+        if (xpsTransform.get()) {
+            HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()),
+                 "Could not set transform for rect.");
+        } else {
+            xpsTransformsPath = false;
+        }
+    }
+    
+    //Create the figure.
+    SkTScopedComPtr<IXpsOMGeometryFigure> rectFigure;
+    {
+        SkPoint points[4] = {
+            { r.fLeft, r.fTop },
+            { r.fLeft, r.fBottom },
+            { r.fRight, r.fBottom },
+            { r.fRight, r.fTop },
+        };
+        if (!xpsTransformsPath && transformRect) {
+            d.fMatrix->mapPoints(points, SK_ARRAY_COUNT(points));
+        }
+        HRV(this->createXpsQuad(points, stroke, fill, &rectFigure));
+    }
+    
+    //Get the figures of the shaded geometry.
+    SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures;
+    HRVM(shadedGeometry->GetFigures(&shadedFigures),
+         "Could not get shaded figures for rect.");
+    
+    //Add the figure to the shaded geometry figures.
+    HRVM(shadedFigures->Append(rectFigure.get()),
+         "Could not add shaded figure for rect.");
+    
+    HRV(this->clip(shadedPath.get(), d));
+    
+    //Add the shaded path to the current visuals.
+    SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
+    HRVM(this->fCurrentXpsCanvas->GetVisuals(&currentVisuals),
+         "Could not get current visuals for rect.");
+    HRVM(currentVisuals->Append(shadedPath.get()),
+         "Could not add rect to current visuals.");
+}
+
+static HRESULT close_figure(const SkTDArray<XPS_SEGMENT_TYPE>& segmentTypes,
+                            const SkTDArray<BOOL>& segmentStrokes,
+                            const SkTDArray<FLOAT>& segmentData,
+                            BOOL stroke, BOOL fill,
+                            IXpsOMGeometryFigure* figure,
+                            IXpsOMGeometryFigureCollection* figures) {
+    // Add the segment data to the figure.
+    HRM(figure->SetSegments(segmentTypes.count(), segmentData.count(),
+                            segmentTypes.begin() , segmentData.begin(),
+                            segmentStrokes.begin()),
+        "Could not set path segments.");
+    
+    // Set the closed and filled properties of the figure.
+    HRM(figure->SetIsClosed(stroke), "Could not set path closed.");
+    HRM(figure->SetIsFilled(fill), "Could not set path fill.");
+    
+    // Add the figure created above to this geometry.
+    HRM(figures->Append(figure), "Could not add path to geometry.");
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::addXpsPathGeometry(
+        IXpsOMGeometryFigureCollection* xpsFigures,
+        BOOL stroke, BOOL fill, const SkPath& path) {
+    SkTDArray<XPS_SEGMENT_TYPE> segmentTypes;
+    SkTDArray<BOOL> segmentStrokes;
+    SkTDArray<FLOAT> segmentData;
+    
+    SkTScopedComPtr<IXpsOMGeometryFigure> xpsFigure;
+    SkPath::Iter iter(path, true);
+    SkPoint points[4];
+    SkPath::Verb verb;
+    while ((verb = iter.next(points)) != SkPath::kDone_Verb) {
+        switch (verb) {
+            case SkPath::kMove_Verb: {
+                if (NULL != xpsFigure.get()) {
+                    HR(close_figure(segmentTypes, segmentStrokes, segmentData,
+                                    stroke, fill,
+                                    xpsFigure.get() , xpsFigures));
+                    xpsFigure.reset();
+                    segmentTypes.rewind();
+                    segmentStrokes.rewind();
+                    segmentData.rewind();
+                }
+                // Define the start point.
+                XPS_POINT startPoint = xps_point(points[0]);
+                // Create the figure.
+                HRM(this->fXpsFactory->CreateGeometryFigure(&startPoint,
+                                                            &xpsFigure),
+                    "Could not create path geometry figure.");
+                break;
+            }
+            case SkPath::kLine_Verb:
+                if (iter.isCloseLine()) break; //ignore the line, auto-closed
+                segmentTypes.push(XPS_SEGMENT_TYPE_LINE);
+                segmentStrokes.push(stroke);
+                segmentData.push(SkScalarToFLOAT(points[1].fX));
+                segmentData.push(SkScalarToFLOAT(points[1].fY));
+                break;
+            case SkPath::kQuad_Verb:
+                segmentTypes.push(XPS_SEGMENT_TYPE_QUADRATIC_BEZIER);
+                segmentStrokes.push(stroke);
+                segmentData.push(SkScalarToFLOAT(points[1].fX));
+                segmentData.push(SkScalarToFLOAT(points[1].fY));
+                segmentData.push(SkScalarToFLOAT(points[2].fX));
+                segmentData.push(SkScalarToFLOAT(points[2].fY));
+                break;
+            case SkPath::kCubic_Verb:
+                segmentTypes.push(XPS_SEGMENT_TYPE_BEZIER);
+                segmentStrokes.push(stroke);
+                segmentData.push(SkScalarToFLOAT(points[1].fX));
+                segmentData.push(SkScalarToFLOAT(points[1].fY));
+                segmentData.push(SkScalarToFLOAT(points[2].fX));
+                segmentData.push(SkScalarToFLOAT(points[2].fY));
+                segmentData.push(SkScalarToFLOAT(points[3].fX));
+                segmentData.push(SkScalarToFLOAT(points[3].fY));
+                break;
+            case SkPath::kClose_Verb:
+                // we ignore these, and just get the whole segment from
+                // the corresponding line/quad/cubic verbs
+                break;
+            default:
+                SkASSERT(!"unexpected verb");
+                break;
+        }
+    }
+    if (NULL != xpsFigure.get()) {
+        HR(close_figure(segmentTypes, segmentStrokes, segmentData,
+                        stroke, fill,
+                        xpsFigure.get(), xpsFigures));
+    }
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::drawInverseWindingPath(const SkDraw& d,
+                                            const SkPath& devicePath,
+                                            IXpsOMPath* shadedPath) {
+    const SkRect universeRect = SkRect::MakeLTRB(0, 0,
+        this->fCurrentCanvasSize.fWidth, this->fCurrentCanvasSize.fHeight);
+    
+    const XPS_RECT universeRectXps = {
+        0.0f, 0.0f,
+        SkScalarToFLOAT(this->fCurrentCanvasSize.fWidth),
+        SkScalarToFLOAT(this->fCurrentCanvasSize.fHeight),
+    };
+    
+    //Get the geometry.
+    SkTScopedComPtr<IXpsOMGeometry> shadedGeometry;
+    HRM(shadedPath->GetGeometry(&shadedGeometry),
+        "Could not get shaded geometry for inverse path.");
+    
+    //Get the figures from the geometry.
+    SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures;
+    HRM(shadedGeometry->GetFigures(&shadedFigures),
+        "Could not get shaded figures for inverse path.");
+    
+    HRM(shadedGeometry->SetFillRule(XPS_FILL_RULE_NONZERO),
+        "Could not set shaded fill rule for inverse path.");
+    
+    //Take everything drawn so far, and make a shared resource out of it.
+    //Replace everything drawn so far with
+    //inverse canvas
+    //  old canvas of everything so far
+    //  world shaded figure, clipped to current clip
+    //  top canvas of everything so far, clipped to path
+    //Note: this is not quite right when there is nothing solid in the
+    //canvas of everything so far, as the bit on top will allow
+    //the world paint to show through.
+    
+    //Create new canvas.
+    SkTScopedComPtr<IXpsOMCanvas> newCanvas;
+    HRM(this->fXpsFactory->CreateCanvas(&newCanvas),
+        "Could not create inverse canvas.");
+    
+    //Save the old canvas to a dictionary on the new canvas.
+    SkTScopedComPtr<IXpsOMDictionary> newDictionary;
+    HRM(this->fXpsFactory->CreateDictionary(&newDictionary),
+        "Could not create inverse dictionary.");
+    HRM(newCanvas->SetDictionaryLocal(newDictionary.get()),
+        "Could not set inverse dictionary.");
+    
+    const size_t size = SK_ARRAY_COUNT(L"ID" L_GUID_ID);
+    wchar_t buffer[size];
+    wchar_t id[GUID_ID_LEN];
+    HR(create_id(id, GUID_ID_LEN, '_'));
+    swprintf_s(buffer, size, L"ID%s", id);
+    HRM(newDictionary->Append(buffer, this->fCurrentXpsCanvas.get()),
+        "Could not add canvas to inverse dictionary.");
+    
+    //Start drawing
+    SkTScopedComPtr<IXpsOMVisualCollection> newVisuals;
+    HRM(newCanvas->GetVisuals(&newVisuals),
+        "Could not get inverse canvas visuals.");
+    
+    //Draw old canvas from dictionary onto new canvas.
+    SkTScopedComPtr<IXpsOMGeometry> oldGeometry;
+    HRM(this->fXpsFactory->CreateGeometry(&oldGeometry),
+        "Could not create old inverse geometry.");
+    
+    SkTScopedComPtr<IXpsOMGeometryFigureCollection> oldFigures;
+    HRM(oldGeometry->GetFigures(&oldFigures),
+        "Could not get old inverse figures.");
+    
+    SkTScopedComPtr<IXpsOMGeometryFigure> oldFigure;
+    HR(this->createXpsRect(universeRect, FALSE, TRUE, &oldFigure));
+    HRM(oldFigures->Append(oldFigure.get()),
+        "Could not add old inverse figure.");
+    
+    SkTScopedComPtr<IXpsOMVisualBrush> oldBrush;
+    HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps,
+                                             &universeRectXps,
+                                             &oldBrush),
+        "Could not create old inverse brush.");
+    
+    SkTScopedComPtr<IXpsOMPath> oldPath;
+    HRM(this->fXpsFactory->CreatePath(&oldPath),
+        "Could not create old inverse path.");
+    HRM(oldPath->SetGeometryLocal(oldGeometry.get()),
+        "Could not set old inverse geometry.");
+    HRM(oldPath->SetFillBrushLocal(oldBrush.get()),
+        "Could not set old inverse fill brush.");
+    //the brush must be parented before setting the lookup.
+    HRM(newVisuals->Append(oldPath.get()),
+        "Could not add old inverse path to new canvas visuals.");
+    HRM(oldBrush->SetVisualLookup(buffer),
+        "Could not set old inverse brush visual lookup.");
+    
+    //Draw the clip filling shader.
+    SkTScopedComPtr<IXpsOMGeometryFigure> shadedFigure;
+    HR(this->createXpsRect(universeRect, FALSE, TRUE, &shadedFigure));
+    HRM(shadedFigures->Append(shadedFigure.get()),
+        "Could not add inverse shaded figure.");
+    //the geometry is already set
+    HR(this->clip(shadedPath, d));
+    HRM(newVisuals->Append(shadedPath),
+        "Could not add inverse shaded path to canvas visuals.");
+    
+    //Draw the old canvas on top, clipped to the original path.
+    SkTScopedComPtr<IXpsOMCanvas> topCanvas;
+    HRM(this->fXpsFactory->CreateCanvas(&topCanvas),
+        "Could not create top inverse canvas.");
+    //Clip the canvas to prevent alpha spill.
+    //This is the entire reason this canvas exists.
+    HR(this->clip(topCanvas.get(), d));
+    
+    SkTScopedComPtr<IXpsOMGeometry> topGeometry;
+    HRM(this->fXpsFactory->CreateGeometry(&topGeometry),
+        "Could not create top inverse geometry.");
+    
+    SkTScopedComPtr<IXpsOMGeometryFigureCollection> topFigures;
+    HRM(topGeometry->GetFigures(&topFigures),
+        "Could not get top inverse figures.");
+    
+    SkTScopedComPtr<IXpsOMGeometryFigure> topFigure;
+    HR(this->createXpsRect(universeRect, FALSE, TRUE, &topFigure));
+    HRM(topFigures->Append(topFigure.get()),
+        "Could not add old inverse figure.");
+    
+    SkTScopedComPtr<IXpsOMVisualBrush> topBrush;
+    HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps,
+                                             &universeRectXps,
+                                             &topBrush),
+        "Could not create top inverse brush.");
+    
+    SkTScopedComPtr<IXpsOMPath> topPath;
+    HRM(this->fXpsFactory->CreatePath(&topPath),
+        "Could not create top inverse path.");
+    HRM(topPath->SetGeometryLocal(topGeometry.get()),
+        "Could not set top inverse geometry.");
+    HRM(topPath->SetFillBrushLocal(topBrush.get()),
+        "Could not set top inverse fill brush.");
+    //the brush must be parented before setting the lookup.
+    HRM(newVisuals->Append(topCanvas.get()),
+        "Could not add top canvas to inverse canvas visuals.");
+    SkTScopedComPtr<IXpsOMVisualCollection> topVisuals;
+    HRM(topCanvas->GetVisuals(&topVisuals),
+        "Could not get top inverse canvas visuals.");
+    HRM(topVisuals->Append(topPath.get()),
+        "Could not add top inverse path to top canvas visuals.");
+    HRM(topBrush->SetVisualLookup(buffer),
+        "Could not set top inverse brush visual lookup.");
+    
+    HR(this->clipToPath(topPath.get(), devicePath, XPS_FILL_RULE_NONZERO));
+    
+    //swap current canvas to new canvas
+    this->fCurrentXpsCanvas.swap(newCanvas);
+    
+    return S_OK;
+}
+
+void SkXPSDevice::convertToPpm(const SkMaskFilter* filter,
+                               SkMatrix* matrix,
+                               SkVector* ppuScale,
+                               const SkIRect& clip, SkIRect* clipIRect) {
+    //TODO: currently ignoring the ppm if blur ignoring transform.
+    if (filter) {
+        SkMaskFilter::BlurInfo blurInfo;
+        SkMaskFilter::BlurType blurType = filter->asABlur(&blurInfo);
+        
+        if (SkMaskFilter::kNone_BlurType != blurType
+            && blurInfo.fIgnoreTransform) {
+
+            ppuScale->fX = SK_Scalar1;
+            ppuScale->fY = SK_Scalar1;
+            *clipIRect = clip;
+            return;
+        }
+    }
+    
+    //This action is in unit space, but the ppm is specified in physical space.
+    ppuScale->fX = SkScalarDiv(this->fCurrentPixelsPerMeter.fX,
+                               this->fCurrentUnitsPerMeter.fX);
+    ppuScale->fY = SkScalarDiv(this->fCurrentPixelsPerMeter.fY,
+                               this->fCurrentUnitsPerMeter.fY);
+    
+    matrix->postScale(ppuScale->fX, ppuScale->fY);
+    
+    const SkIRect& irect = clip;
+    SkRect clipRect = SkRect::MakeLTRB(
+        SkScalarMul(SkIntToScalar(irect.fLeft), ppuScale->fX),
+        SkScalarMul(SkIntToScalar(irect.fTop), ppuScale->fY),
+        SkScalarMul(SkIntToScalar(irect.fRight), ppuScale->fX),
+        SkScalarMul(SkIntToScalar(irect.fBottom), ppuScale->fY));
+    clipRect.roundOut(clipIRect);
+}
+
+HRESULT SkXPSDevice::applyMask(const SkDraw& d,
+                               const SkMask& mask,
+                               const SkVector& ppuScale,
+                               IXpsOMPath* shadedPath) {
+    //Get the geometry object.
+    SkTScopedComPtr<IXpsOMGeometry> shadedGeometry;
+    HRM(shadedPath->GetGeometry(&shadedGeometry),
+        "Could not get mask shaded geometry.");
+    
+    //Get the figures from the geometry.
+    SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures;
+    HRM(shadedGeometry->GetFigures(&shadedFigures),
+        "Could not get mask shaded figures.");
+    
+    SkMatrix m;
+    m.reset();
+    m.setTranslate(SkIntToScalar(mask.fBounds.fLeft),
+                   SkIntToScalar(mask.fBounds.fTop));
+    m.postScale(SkScalarInvert(ppuScale.fX), SkScalarInvert(ppuScale.fY));
+    
+    SkShader::TileMode xy[2];
+    xy[0] = (SkShader::TileMode)3;
+    xy[1] = (SkShader::TileMode)3;
+    
+    SkBitmap bm;
+    bm.setConfig(SkBitmap::kA8_Config,
+                 mask.fBounds.width(),
+                 mask.fBounds.height(),
+                 mask.fRowBytes);
+    bm.setPixels(mask.fImage);
+    
+    SkTScopedComPtr<IXpsOMTileBrush> maskBrush;
+    HR(this->createXpsImageBrush(bm, m, xy, 0xFF, &maskBrush));
+    HRM(shadedPath->SetOpacityMaskBrushLocal(maskBrush.get()),
+        "Could not set mask.");
+    
+    const SkRect universeRect = SkRect::MakeLTRB(0, 0,
+        this->fCurrentCanvasSize.fWidth, this->fCurrentCanvasSize.fHeight);
+    SkTScopedComPtr<IXpsOMGeometryFigure> shadedFigure;
+    HRM(this->createXpsRect(universeRect, FALSE, TRUE, &shadedFigure),
+        "Could not create mask shaded figure.");
+    HRM(shadedFigures->Append(shadedFigure.get()),
+        "Could not add mask shaded figure.");
+    
+    HR(this->clip(shadedPath, d));
+    
+    //Add the path to the active visual collection.
+    SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
+    HRM(this->fCurrentXpsCanvas->GetVisuals(&currentVisuals),
+        "Could not get mask current visuals.");
+    HRM(currentVisuals->Append(shadedPath),
+        "Could not add masked shaded path to current visuals.");
+    
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::shadePath(IXpsOMPath* shadedPath,
+                               const SkPaint& shaderPaint,
+                               const SkMatrix& matrix,
+                               BOOL* fill, BOOL* stroke) {
+    *fill = FALSE;
+    *stroke = FALSE;
+    
+    const SkPaint::Style style = shaderPaint.getStyle();
+    const bool hasFill = SkPaint::kFill_Style == style
+                      || SkPaint::kStrokeAndFill_Style == style;
+    const bool hasStroke = SkPaint::kStroke_Style == style
+                        || SkPaint::kStrokeAndFill_Style == style;
+    
+    //TODO(bungeman): use dictionaries and lookups.
+    if (hasFill) {
+        *fill = TRUE;
+        SkTScopedComPtr<IXpsOMBrush> fillBrush;
+        HR(this->createXpsBrush(shaderPaint, &fillBrush, &matrix));
+        HRM(shadedPath->SetFillBrushLocal(fillBrush.get()),
+            "Could not set fill for shaded path.");
+    }
+    
+    if (hasStroke) {
+        *stroke = TRUE;
+        SkTScopedComPtr<IXpsOMBrush> strokeBrush;
+        HR(this->createXpsBrush(shaderPaint, &strokeBrush, &matrix));
+        HRM(shadedPath->SetStrokeBrushLocal(strokeBrush.get()),
+            "Could not set stroke brush for shaded path.");
+        HRM(shadedPath->SetStrokeThickness(
+                SkScalarToFLOAT(shaderPaint.getStrokeWidth())),
+            "Could not set shaded path stroke thickness.");
+        
+        if (0 == shaderPaint.getStrokeWidth()) {
+            //XPS hair width is a hack. (XPS Spec 11.6.12).
+            SkTScopedComPtr<IXpsOMDashCollection> dashes;
+            HRM(shadedPath->GetStrokeDashes(&dashes),
+                "Could not set dashes for shaded path.");
+            XPS_DASH dash;
+            dash.length = 1.0;
+            dash.gap = 0.0;
+            HRM(dashes->Append(&dash), "Could not add dashes to shaded path.");
+            HRM(shadedPath->SetStrokeDashOffset(-2.0),
+                "Could not set dash offset for shaded path.");
+        }
+    }
+    return S_OK;
+}
+
+void SkXPSDevice::drawPath(const SkDraw& d,
+                           const SkPath& platonicPath,
+                           const SkPaint& paint,
+                           const SkMatrix* prePathMatrix,
+                           bool pathIsMutable) {
+    // nothing to draw
+    if (d.fClip->isEmpty() ||
+        (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
+        return;
+    }
+    
+    SkPath modifiedPath;
+    const bool paintHasPathEffect = paint.getPathEffect()
+                                 || paint.getStyle() != SkPaint::kFill_Style;
+    
+    //Apply pre-path matrix [Platonic-path -> Skeletal-path].
+    SkMatrix matrix = *d.fMatrix;
+    SkPath* skeletalPath = const_cast<SkPath*>(&platonicPath);
+    if (prePathMatrix) {
+        if (paintHasPathEffect || paint.getRasterizer()) {
+            if (!pathIsMutable) {
+                skeletalPath = &modifiedPath;
+                pathIsMutable = true;
+            }
+            platonicPath.transform(*prePathMatrix, skeletalPath);
+        } else {
+            if (!matrix.preConcat(*prePathMatrix)) {
+                return;
+            }
+        }
+    }
+    
+    SkTLazy<SkPaint> modifiedPaint;
+    SkPaint* shaderPaint = const_cast<SkPaint*>(&paint);
+    
+    //Apply path effect [Skeletal-path -> Fillable-path].
+    SkPath* fillablePath = skeletalPath;
+    if (paintHasPathEffect) {
+        if (!pathIsMutable) {
+            fillablePath = &modifiedPath;
+            pathIsMutable = true;
+        }
+        bool fill = paint.getFillPath(*skeletalPath, fillablePath);
+        
+        shaderPaint = modifiedPaint.set(paint);
+        shaderPaint->setPathEffect(NULL);
+        if (fill) {
+            shaderPaint->setStyle(SkPaint::kFill_Style);
+        } else {
+            shaderPaint->setStyle(SkPaint::kStroke_Style);
+            shaderPaint->setStrokeWidth(0);
+        }
+    }
+    
+    //Create the shaded path. This will be the path which is painted.
+    SkTScopedComPtr<IXpsOMPath> shadedPath;
+    HRVM(this->fXpsFactory->CreatePath(&shadedPath),
+         "Could not create shaded path for path.");
+    
+    //Create the geometry for the shaded path.
+    SkTScopedComPtr<IXpsOMGeometry> shadedGeometry;
+    HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry),
+         "Could not create shaded geometry for path.");
+    
+    //Add the geometry to the shaded path.
+    HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()),
+         "Could not add the shaded geometry to shaded path.");
+    
+    //Set the brushes.
+    BOOL fill;
+    BOOL stroke;
+    HRV(this->shadePath(shadedPath.get(),
+                        *shaderPaint,
+                        *d.fMatrix,
+                        &fill,
+                        &stroke));
+    
+    SkMaskFilter* filter = paint.getMaskFilter();
+    
+    //Rasterizer
+    if (paint.getRasterizer()) {
+        SkIRect clipIRect;
+        SkVector ppuScale;
+        this->convertToPpm(filter,
+                           &matrix,
+                           &ppuScale,
+                           d.fClip->getBounds(),
+                           &clipIRect);
+        
+        SkMask* mask = NULL;
+        
+        //[Fillable-path -> Mask]
+        SkMask rasteredMask;
+        if (paint.getRasterizer()->rasterize(
+                *fillablePath,
+                matrix,
+                &clipIRect,
+                filter,  //just to compute how much to draw.
+                &rasteredMask,
+                SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
+            
+            SkAutoMaskFreeImage rasteredAmi(rasteredMask.fImage);
+            mask = &rasteredMask;
+            
+            //[Mask -> Mask]
+            SkMask filteredMask;
+            if (filter &&
+                filter->filterMask(&filteredMask, *mask, *d.fMatrix, NULL)) {
+            
+                mask = &filteredMask;
+            } else {
+                filteredMask.fImage = NULL;
+            }
+            SkAutoMaskFreeImage filteredAmi(filteredMask.fImage);
+            
+            //Draw mask.
+            HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get()));
+        }
+        return;
+    }
+    
+    //Mask filter
+    if (filter) {
+        SkIRect clipIRect;
+        SkVector ppuScale;
+        this->convertToPpm(filter,
+                           &matrix,
+                           &ppuScale,
+                           d.fClip->getBounds(),
+                           &clipIRect);
+        
+        //[Fillable-path -> Pixel-path]
+        SkPath* pixelPath = pathIsMutable ? fillablePath : &modifiedPath;
+        fillablePath->transform(matrix, pixelPath);
+        
+        SkMask* mask = NULL;
+        
+        //[Pixel-path -> Mask]
+        SkMask rasteredMask;
+        if (SkDraw::DrawToMask(
+                        *pixelPath,
+                        &clipIRect,
+                        filter,  //just to compute how much to draw.
+                        &matrix,
+                        &rasteredMask,
+                        SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
+            
+            SkAutoMaskFreeImage rasteredAmi(rasteredMask.fImage);
+            mask = &rasteredMask;
+            
+            //[Mask -> Mask]
+            SkMask filteredMask;
+            if (filter->filterMask(&filteredMask,
+                                   rasteredMask,
+                                   matrix,
+                                   NULL)) {
+                mask = &filteredMask;
+            } else {
+                filteredMask.fImage = NULL;
+            }
+            SkAutoMaskFreeImage filteredAmi(filteredMask.fImage);
+            
+            //Draw mask.
+            HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get()));
+        }
+        return;
+    }
+    
+    //Get the figures from the shaded geometry.
+    SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures;
+    HRVM(shadedGeometry->GetFigures(&shadedFigures),
+         "Could not get shaded figures for shaded path.");
+    
+    bool xpsTransformsPath = true;
+    
+    //Set the fill rule.
+    XPS_FILL_RULE xpsFillRule;
+    switch (platonicPath.getFillType()) {
+        case SkPath::kWinding_FillType:
+            xpsFillRule = XPS_FILL_RULE_NONZERO;
+            break;
+        case SkPath::kEvenOdd_FillType:
+            xpsFillRule = XPS_FILL_RULE_EVENODD;
+            break;
+        case SkPath::kInverseWinding_FillType: {
+            //[Fillable-path -> Device-path]
+            SkPath* devicePath = pathIsMutable ? fillablePath : &modifiedPath;
+            fillablePath->transform(matrix, devicePath);
+            
+            HRV(this->drawInverseWindingPath(d,
+                                             *devicePath,
+                                             shadedPath.get()));
+            return;
+        }
+        case SkPath::kInverseEvenOdd_FillType: {
+            const SkRect universe = SkRect::MakeLTRB(
+                0, 0,
+                this->fCurrentCanvasSize.fWidth,
+                this->fCurrentCanvasSize.fHeight);
+            SkTScopedComPtr<IXpsOMGeometryFigure> addOneFigure;
+            HRV(this->createXpsRect(universe, FALSE, TRUE, &addOneFigure));
+            HRVM(shadedFigures->Append(addOneFigure.get()),
+                 "Could not add even-odd flip figure to shaded path.");
+            xpsTransformsPath = false;
+            xpsFillRule = XPS_FILL_RULE_EVENODD;
+            break;
+        }
+        default:
+            SkASSERT(!"Unknown SkPath::FillType.");
+    }
+    HRVM(shadedGeometry->SetFillRule(xpsFillRule),
+         "Could not set fill rule for shaded path.");
+    
+    //Create the XPS transform, if possible.
+    if (xpsTransformsPath) {
+        SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
+        HRV(this->createXpsTransform(matrix, &xpsTransform));
+        
+        if (xpsTransform.get()) {
+            HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()),
+                 "Could not set transform on shaded path.");
+        } else {
+            xpsTransformsPath = false;
+        }
+    }
+    
+    SkPath* devicePath = fillablePath;
+    if (!xpsTransformsPath) {
+        //[Fillable-path -> Device-path]
+        devicePath = pathIsMutable ? fillablePath : &modifiedPath;
+        fillablePath->transform(matrix, devicePath);
+    }
+    HRV(this->addXpsPathGeometry(shadedFigures.get(),
+                                 stroke, fill, *devicePath));
+    
+    HRV(this->clip(shadedPath.get(), d));
+    
+    //Add the path to the active visual collection.
+    SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
+    HRVM(this->fCurrentXpsCanvas->GetVisuals(&currentVisuals),
+         "Could not get current visuals for shaded path.");
+    HRVM(currentVisuals->Append(shadedPath.get()),
+         "Could not add shaded path to current visuals.");
+}
+
+HRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual, const SkDraw& d) {
+    SkPath clipPath;
+    SkAssertResult(d.fClip->getBoundaryPath(&clipPath));
+    
+    return this->clipToPath(xpsVisual, clipPath, XPS_FILL_RULE_EVENODD);
+}
+HRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual,
+                                const SkPath& clipPath,
+                                XPS_FILL_RULE fillRule) {
+    //Create the geometry.
+    SkTScopedComPtr<IXpsOMGeometry> clipGeometry;
+    HRM(this->fXpsFactory->CreateGeometry(&clipGeometry),
+        "Could not create clip geometry.");
+    
+    //Get the figure collection of the geometry.
+    SkTScopedComPtr<IXpsOMGeometryFigureCollection> clipFigures;
+    HRM(clipGeometry->GetFigures(&clipFigures),
+        "Could not get the clip figures.");
+    
+    //Create the figures into the geometry.
+    HR(this->addXpsPathGeometry(
+        clipFigures.get(),
+        FALSE, TRUE, clipPath));
+    
+    HRM(clipGeometry->SetFillRule(fillRule),
+        "Could not set fill rule.");
+    HRM(xpsVisual->SetClipGeometryLocal(clipGeometry.get()),
+        "Could not set clip geometry.");
+    
+    return S_OK;
+}
+
+void SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
+                             const SkIRect* srcRectOrNull,
+                             const SkMatrix& matrix, const SkPaint& paint) {
+    if (d.fClip->isEmpty()) {
+        return;
+    }
+    
+    SkIRect srcRect;
+    SkBitmap tmp;
+    const SkBitmap* bitmapPtr = &bitmap;
+    if (NULL == srcRectOrNull) {
+        srcRect.set(0, 0, bitmap.width(), bitmap.height());
+        bitmapPtr = &bitmap;
+    } else {
+        srcRect = *srcRectOrNull;
+        if (!bitmap.extractSubset(&tmp, srcRect)) {
+            return; // extraction failed
+        }
+        bitmapPtr = &tmp;
+    }
+    
+    //Create the new shaded path.
+    SkTScopedComPtr<IXpsOMPath> shadedPath;
+    HRVM(this->fXpsFactory->CreatePath(&shadedPath),
+         "Could not create path for bitmap.");
+    
+    //Create the shaded geometry.
+    SkTScopedComPtr<IXpsOMGeometry> shadedGeometry;
+    HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry),
+         "Could not create geometry for bitmap.");
+    
+    //Add the shaded geometry to the shaded path.
+    HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()),
+         "Could not set the geometry for bitmap.");
+    
+    //Get the shaded figures from the shaded geometry.
+    SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures;
+    HRVM(shadedGeometry->GetFigures(&shadedFigures),
+         "Could not get the figures for bitmap.");
+    
+    SkMatrix transform = matrix;
+    transform.postConcat(*d.fMatrix);
+    
+    SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
+    HRV(this->createXpsTransform(transform, &xpsTransform));
+    if (xpsTransform.get()) {
+        HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()),
+             "Could not set transform for bitmap.");
+    } else {
+        //TODO: perspective that bitmap!
+    }
+    
+    SkTScopedComPtr<IXpsOMGeometryFigure> rectFigure;
+    if (NULL != xpsTransform.get()) {
+        const SkShader::TileMode xy[2] = {
+            SkShader::kClamp_TileMode,
+            SkShader::kClamp_TileMode,
+        };
+        SkTScopedComPtr<IXpsOMTileBrush> xpsImageBrush;
+        HRV(this->createXpsImageBrush(*bitmapPtr,
+                                      transform,
+                                      xy,
+                                      paint.getAlpha(),
+                                      &xpsImageBrush));
+        HRVM(shadedPath->SetFillBrushLocal(xpsImageBrush.get()),
+             "Could not set bitmap brush.");
+        
+        const SkRect bitmapRect = SkRect::MakeLTRB(0, 0,
+            SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height()));
+        HRV(this->createXpsRect(bitmapRect, FALSE, TRUE, &rectFigure));
+    }
+    HRVM(shadedFigures->Append(rectFigure.get()),
+         "Could not add bitmap figure.");
+    
+    //Get the current visual collection and add the shaded path to it.
+    SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
+    HRVM(this->fCurrentXpsCanvas->GetVisuals(&currentVisuals),
+         "Could not get current visuals for bitmap");
+    HRVM(currentVisuals->Append(shadedPath.get()),
+         "Could not add bitmap to current visuals.");
+    
+    HRV(this->clip(shadedPath.get(), d));
+}
+
+void SkXPSDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap,
+                             int x, int y,
+                             const SkPaint& paint) {
+    //TODO: override this for XPS
+    SkDEBUGF(("XPS drawSprite not yet implemented."));
+}
+
+HRESULT SkXPSDevice::CreateTypefaceUse(const SkPaint& paint,
+                                       TypefaceUse** typefaceUse) {
+    const SkTypeface* typeface = paint.getTypeface();
+    
+    //Check cache.
+    const SkFontID typefaceID = SkTypeface::UniqueID(typeface);
+    if (!this->fTypefaces.empty()) {
+        TypefaceUse* current = &this->fTypefaces.front();
+        const TypefaceUse* last = &this->fTypefaces.back();
+        for (; current <= last; ++current) {
+            if (current->typefaceId == typefaceID) {
+                *typefaceUse = current;
+                return S_OK;
+            }
+        }
+    }
+    
+    //TODO: create glyph only fonts
+    //and let the host deal with what kind of font we're looking at.
+    XPS_FONT_EMBEDDING embedding = XPS_FONT_EMBEDDING_RESTRICTED;
+    
+    SkTScopedComPtr<IStream> fontStream;
+    SkStream* fontData = SkFontHost::OpenStream(typefaceID);
+    HRM(SkIStream::CreateFromSkStream(fontData,
+                                      true,
+                                      &fontStream),
+        "Could not create font stream.");
+    
+    const size_t size =
+        SK_ARRAY_COUNT(L"/Resources/Fonts/" L_GUID_ID L".odttf");
+    wchar_t buffer[size];
+    wchar_t id[GUID_ID_LEN];
+    HR(create_id(id, GUID_ID_LEN));
+    swprintf_s(buffer, size, L"/Resources/Fonts/%s.odttf", id);
+    
+    SkTScopedComPtr<IOpcPartUri> partUri;
+    HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri),
+        "Could not create font resource part uri.");
+    
+    SkTScopedComPtr<IXpsOMFontResource> xpsFontResource;
+    HRM(this->fXpsFactory->CreateFontResource(fontStream.get(),
+                                              embedding,
+                                              partUri.get(),
+                                              FALSE,
+                                              &xpsFontResource),
+        "Could not create font resource.");
+    
+    TypefaceUse& newTypefaceUse = this->fTypefaces.push_back();
+    newTypefaceUse.typefaceId = typefaceID;
+    newTypefaceUse.fontData = fontData;
+    newTypefaceUse.xpsFont = xpsFontResource.release();
+    
+    SkAutoGlyphCache agc = SkAutoGlyphCache(paint, &SkMatrix::I());
+    SkGlyphCache* glyphCache = agc.getCache();
+    unsigned int glyphCount = glyphCache->getGlyphCount();
+    newTypefaceUse.glyphsUsed = new SkBitSet(glyphCount);
+    
+    *typefaceUse = &newTypefaceUse;
+    return S_OK;
+}
+
+HRESULT SkXPSDevice::AddGlyphs(const SkDraw& d,
+                               IXpsOMObjectFactory* xpsFactory,
+                               IXpsOMCanvas* canvas,
+                               IXpsOMFontResource* font,
+                               LPCWSTR text,
+                               XPS_GLYPH_INDEX* xpsGlyphs,
+                               UINT32 xpsGlyphsLen,
+                               XPS_POINT *origin,
+                               FLOAT fontSize,
+                               XPS_STYLE_SIMULATION sims,
+                               const SkMatrix& transform,
+                               const SkPaint& paint) {
+    SkTScopedComPtr<IXpsOMGlyphs> glyphs;
+    HRM(xpsFactory->CreateGlyphs(font, &glyphs), "Could not create glyphs.");
+    
+    //XPS uses affine transformations for everything...
+    //...except positioning text.
+    bool useCanvasForClip;
+    if ((transform.getType() & ~SkMatrix::kTranslate_Mask) == 0) {
+        origin->x += SkScalarToFLOAT(transform.getTranslateX());
+        origin->y += SkScalarToFLOAT(transform.getTranslateY());
+        useCanvasForClip = false;
+    } else {
+        SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse;
+        HR(this->createXpsTransform(transform, &xpsMatrixToUse));
+        if (xpsMatrixToUse.get()) {
+            HRM(glyphs->SetTransformLocal(xpsMatrixToUse.get()),
+                "Could not set transform matrix.");
+            useCanvasForClip = true;
+        } else {
+            SkASSERT(!"Attempt to add glyphs in perspective.");
+            useCanvasForClip = false;
+        }
+    }
+    
+    SkTScopedComPtr<IXpsOMGlyphsEditor> glyphsEditor;
+    HRM(glyphs->GetGlyphsEditor(&glyphsEditor), "Could not get glyph editor.");
+    
+    if (NULL != text) {
+        HRM(glyphsEditor->SetUnicodeString(text),
+            "Could not set unicode string.");
+    }
+    
+    if (NULL != xpsGlyphs) {
+        HRM(glyphsEditor->SetGlyphIndices(xpsGlyphsLen, xpsGlyphs),
+            "Could not set glyphs.");
+    }
+    
+    HRM(glyphsEditor->ApplyEdits(), "Could not apply glyph edits.");
+    
+    SkTScopedComPtr<IXpsOMBrush> xpsFillBrush;
+    HR(this->createXpsBrush(
+            paint,
+            &xpsFillBrush,
+            useCanvasForClip ? NULL : &transform));
+    
+    HRM(glyphs->SetFillBrushLocal(xpsFillBrush.get()),
+        "Could not set fill brush.");
+    
+    HRM(glyphs->SetOrigin(origin), "Could not set glyph origin.");
+    
+    HRM(glyphs->SetFontRenderingEmSize(fontSize),
+        "Could not set font size.");
+    
+    HRM(glyphs->SetStyleSimulations(sims),
+        "Could not set style simulations.");
+    
+    SkTScopedComPtr<IXpsOMVisualCollection> visuals;
+    HRM(canvas->GetVisuals(&visuals), "Could not get glyph canvas visuals.");
+    
+    if (!useCanvasForClip) {
+        HR(this->clip(glyphs.get(), d));
+        HRM(visuals->Append(glyphs.get()), "Could not add glyphs to canvas.");
+    } else {
+        SkTScopedComPtr<IXpsOMCanvas> glyphCanvas;
+        HRM(this->fXpsFactory->CreateCanvas(&glyphCanvas),
+            "Could not create glyph canvas.");
+        
+        SkTScopedComPtr<IXpsOMVisualCollection> glyphCanvasVisuals;
+        HRM(glyphCanvas->GetVisuals(&glyphCanvasVisuals),
+            "Could not get glyph visuals collection.");
+        
+        HRM(glyphCanvasVisuals->Append(glyphs.get()),
+            "Could not add glyphs to page.");
+        HR(this->clip(glyphCanvas.get(), d));
+        
+        HRM(visuals->Append(glyphCanvas.get()),
+            "Could not add glyph canvas to page.");
+    }
+    
+    return S_OK;
+}
+
+struct SkXPSDrawProcs : public SkDrawProcs {
+public:
+    /** [in] Advance width and offsets for glyphs measured in
+    hundredths of the font em size (XPS Spec 5.1.3). */
+    FLOAT centemPerUnit;
+    /** [in,out] The accumulated glyphs used in the current typeface. */
+    SkBitSet* glyphUse;
+    /** [out] The glyphs to draw. */
+    SkTDArray<XPS_GLYPH_INDEX> xpsGlyphs;
+};
+
+static void xps_draw_1_glyph(const SkDraw1Glyph& state,
+                             SkFixed x, SkFixed y,
+                             const SkGlyph& skGlyph) {
+    SkASSERT(skGlyph.fWidth > 0 && skGlyph.fHeight > 0);
+    
+    SkXPSDrawProcs* procs = static_cast<SkXPSDrawProcs*>(state.fDraw->fProcs);
+    //Draw pre-adds half for floor rounding.
+    x -= SK_FixedHalf;
+    y -= SK_FixedHalf;
+    
+    XPS_GLYPH_INDEX* xpsGlyph = procs->xpsGlyphs.append();
+    uint16_t glyphID = skGlyph.getGlyphID();
+    procs->glyphUse->setBit(glyphID, true);
+    xpsGlyph->index = glyphID;
+    if (1 == procs->xpsGlyphs.count()) {
+        xpsGlyph->advanceWidth = 0.0f;
+        xpsGlyph->horizontalOffset = SkFixedToFloat(x) * procs->centemPerUnit;
+        xpsGlyph->verticalOffset = SkFixedToFloat(y) * -procs->centemPerUnit;
+    } else {
+        const XPS_GLYPH_INDEX& first = procs->xpsGlyphs[0];
+        xpsGlyph->advanceWidth = 0.0f;
+        xpsGlyph->horizontalOffset = (SkFixedToFloat(x) * procs->centemPerUnit)
+                                     - first.horizontalOffset;
+        xpsGlyph->verticalOffset = (SkFixedToFloat(y) * -procs->centemPerUnit)
+                                   - first.verticalOffset;
+    }
+}
+
+static void text_draw_init(const SkPaint& paint,
+                           const void* text, size_t byteLength,
+                           SkBitSet& glyphsUsed,
+                           SkDraw& myDraw, SkXPSDrawProcs& procs) {
+    procs.fD1GProc = xps_draw_1_glyph;
+    int numGlyphGuess;
+    switch (paint.getTextEncoding()) {
+        case SkPaint::kUTF8_TextEncoding:
+            numGlyphGuess = SkUTF8_CountUnichars(
+                static_cast<const char *>(text),
+                byteLength);
+            break;
+        case SkPaint::kUTF16_TextEncoding:
+            numGlyphGuess = SkUTF16_CountUnichars(
+                static_cast<const uint16_t *>(text),
+                byteLength);
+            break;
+        case SkPaint::kGlyphID_TextEncoding:
+            numGlyphGuess = byteLength / 2;
+            break;
+        default:
+            SK_DEBUGBREAK(true);
+    }
+    procs.xpsGlyphs.setReserve(numGlyphGuess);
+    procs.glyphUse = &glyphsUsed;
+    procs.centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize());
+    
+    myDraw.fProcs = &procs;
+    myDraw.fMVMatrix = &SkMatrix::I();
+    myDraw.fExtMatrix = &SkMatrix::I();
+}
+
+static bool text_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) {
+    const SkPaint::Style style = paint.getStyle();
+    return matrix.hasPerspective()
+        || SkPaint::kStroke_Style == style
+        || SkPaint::kStrokeAndFill_Style == style
+        || paint.getMaskFilter()
+        || paint.getRasterizer()
+    ;
+}
+
+void SkXPSDevice::drawText(const SkDraw& d,
+                           const void* text, size_t byteLen,
+                           SkScalar x, SkScalar y,
+                           const SkPaint& paint) {
+    if (byteLen < 1) return;
+    
+    if (text_must_be_pathed(paint, *d.fMatrix)) {
+        SkPath path;
+        paint.getTextPath(text, byteLen, x, y, &path);
+        this->drawPath(d, path, paint, NULL, true);
+        //TODO: add automation "text"
+        return;
+    }
+    
+    TypefaceUse* typeface;
+    HRV(CreateTypefaceUse(paint, &typeface));
+    
+    SkDraw myDraw(d);
+    SkXPSDrawProcs procs;
+    text_draw_init(paint, text, byteLen, *typeface->glyphsUsed, myDraw, procs);
+    
+    myDraw.drawText(static_cast<const char*>(text), byteLen, x, y, paint);
+    
+    XPS_POINT origin = {
+        procs.xpsGlyphs[0].horizontalOffset / procs.centemPerUnit,
+        procs.xpsGlyphs[0].verticalOffset / -procs.centemPerUnit,
+    };
+    procs.xpsGlyphs[0].horizontalOffset = 0.0f;
+    procs.xpsGlyphs[0].verticalOffset = 0.0f;
+    
+    HRV(AddGlyphs(d,
+                  this->fXpsFactory.get(),
+                  this->fCurrentXpsCanvas.get(),
+                  typeface->xpsFont,
+                  NULL,
+                  procs.xpsGlyphs.begin(), procs.xpsGlyphs.count(),
+                  &origin,
+                  SkScalarToFLOAT(paint.getTextSize()),
+                  XPS_STYLE_SIMULATION_NONE,
+                  *d.fMatrix,
+                  paint));
+}
+
+void SkXPSDevice::drawPosText(const SkDraw& d,
+                              const void* text, size_t byteLen,
+                              const SkScalar pos[],
+                              SkScalar constY, int scalarsPerPos,
+                              const SkPaint& paint) {
+    if (byteLen < 1) return;
+    
+    if (text_must_be_pathed(paint, *d.fMatrix)) {
+        SkPath path;
+        //TODO: make this work, Draw currently does not handle as well.
+        //paint.getTextPath(text, byteLength, x, y, &path);
+        //this->drawPath(d, path, paint, NULL, true);
+        //TODO: add automation "text"
+        return;
+    }
+    
+    TypefaceUse* typeface;
+    HRV(CreateTypefaceUse(paint, &typeface));
+    
+    SkDraw myDraw(d);
+    SkXPSDrawProcs procs;
+    text_draw_init(paint, text, byteLen, *typeface->glyphsUsed, myDraw, procs);
+    
+    myDraw.drawPosText(static_cast<const char*>(text), byteLen,
+                       pos, constY, scalarsPerPos,
+                       paint);
+    
+    XPS_POINT origin = {
+        procs.xpsGlyphs[0].horizontalOffset / procs.centemPerUnit,
+        procs.xpsGlyphs[0].verticalOffset / -procs.centemPerUnit,
+    };
+    procs.xpsGlyphs[0].horizontalOffset = 0.0f;
+    procs.xpsGlyphs[0].verticalOffset = 0.0f;
+    
+    HRV(AddGlyphs(d,
+                  this->fXpsFactory.get(),
+                  this->fCurrentXpsCanvas.get(),
+                  typeface->xpsFont,
+                  NULL,
+                  procs.xpsGlyphs.begin(), procs.xpsGlyphs.count(),
+                  &origin,
+                  SkScalarToFLOAT(paint.getTextSize()),
+                  XPS_STYLE_SIMULATION_NONE,
+                  *d.fMatrix,
+                  paint));
+}
+
+void SkXPSDevice::drawTextOnPath(const SkDraw& d, const void* text, size_t len,
+                                 const SkPath& path, const SkMatrix* matrix,
+                                 const SkPaint& paint) {
+    //This will call back into the device to do the drawing.
+     d.drawTextOnPath((const char*)text, len, path, matrix, paint);
+}
+
+void SkXPSDevice::drawDevice(const SkDraw& d, SkDevice* dev,
+                             int x, int y,
+                             const SkPaint&) {
+    SkXPSDevice* that = static_cast<SkXPSDevice*>(dev);
+    
+    SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
+    XPS_MATRIX rawTransform = {
+        1.0f,
+        0.0f,
+        0.0f,
+        1.0f,
+        static_cast<FLOAT>(x),
+        static_cast<FLOAT>(y),
+    };
+    HRVM(this->fXpsFactory->CreateMatrixTransform(&rawTransform, &xpsTransform),
+         "Could not create layer transform.");
+    HRVM(that->fCurrentXpsCanvas->SetTransformLocal(xpsTransform.get()),
+         "Could not set layer transform.");
+    
+    //Get the current visual collection and add the layer to it.
+    SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
+    HRVM(this->fCurrentXpsCanvas->GetVisuals(&currentVisuals),
+         "Could not get current visuals for layer.");
+    HRVM(currentVisuals->Append(that->fCurrentXpsCanvas.get()),
+         "Could not add layer to current visuals.");
+}
+
+SkDevice* SkXPSDevice::onCreateCompatibleDevice(SkBitmap::Config config,
+                                                int width, int height,
+                                                bool isOpaque,
+                                                Usage usage) {
+    if (SkDevice::kGeneral_Usage == usage) {
+        SK_CRASH();
+        //To what stream do we write?
+        //SkXPSDevice* dev = new SkXPSDevice(this);
+        //SkSize s = SkSize::Make(width, height);
+        //dev->BeginCanvas(s, s, SkMatrix::I());
+        //return dev;
+    }
+    
+    return new SkXPSDevice(this->fXpsFactory.get());
+}
+
+SkXPSDevice::SkXPSDevice(IXpsOMObjectFactory* xpsFactory)
+    : SkDevice(make_fake_bitmap(10000, 10000))
+    , fCurrentPage(0) {
+    
+    HRVM(CoCreateInstance(
+             CLSID_XpsOMObjectFactory,
+             NULL,
+             CLSCTX_INPROC_SERVER,
+             IID_PPV_ARGS(&this->fXpsFactory)),
+         "Could not create factory for layer.");
+    
+    HRVM(this->fXpsFactory->CreateCanvas(&this->fCurrentXpsCanvas),
+         "Could not create canvas for layer.");
+}
diff --git a/src/pdf/SkBitSet.cpp b/src/pdf/SkBitSet.cpp
index b47bce2..664c8cd 100755
--- a/src/pdf/SkBitSet.cpp
+++ b/src/pdf/SkBitSet.cpp
@@ -81,19 +81,3 @@
     }
     return true;
 }
-
-void SkBitSet::exportTo(SkTDArray<uint32_t>* array) const {
-    SkASSERT(array);
-    uint32_t* data = reinterpret_cast<uint32_t*>(fBitData.get());
-    for (unsigned int i = 0; i < fDwordCount; ++i) {
-        uint32_t value = data[i];
-        if (value) {  // There are set bits
-            unsigned int index = i * 32;
-            for (unsigned int j = 0; j < 32; ++j) {
-                if (0x1 & (value >> j)) {
-                    array->push(index + j);
-                }
-            }
-        }
-    }
-}
diff --git a/src/utils/win/SkHRESULT.cpp b/src/utils/win/SkHRESULT.cpp
new file mode 100644
index 0000000..740b8b8
--- /dev/null
+++ b/src/utils/win/SkHRESULT.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkTypes.h"
+
+#include "SKHRESULT.h"
+
+void SkTraceHR(const char* file, unsigned long line,
+               HRESULT hr, const char* msg) {
+    if (NULL != msg) SkDEBUGF(("%s\n", msg));
+    SkDEBUGF(("%s(%lu) : error 0x%x: ", file, line, hr));
+    
+    LPSTR errorText = NULL;
+    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                   FORMAT_MESSAGE_FROM_SYSTEM |
+                   FORMAT_MESSAGE_IGNORE_INSERTS,
+                   NULL,
+                   hr,
+                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                   (LPSTR) &errorText,
+                   0,
+                   NULL
+    );
+    
+    if (NULL == errorText) {
+        SkDEBUGF(("<unknown>\n"));
+    } else {
+        SkDEBUGF((errorText));
+        LocalFree(errorText);
+        errorText = NULL;
+    }
+}
