/*
 * 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"
#if defined(SK_BUILD_FOR_WIN)

#include "SkLeanWindows.h"

#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#include <ObjBase.h>
#include <XpsObjectModel.h>
#include <T2EmbApi.h>
#include <FontSub.h>
#include <limits>

#include "SkColor.h"
#include "SkData.h"
#include "SkDraw.h"
#include "SkEndian.h"
#include "SkFindAndPlaceGlyph.h"
#include "SkGeometry.h"
#include "SkGlyphCache.h"
#include "SkHRESULT.h"
#include "SkIStream.h"
#include "SkImage.h"
#include "SkImageEncoder.h"
#include "SkImagePriv.h"
#include "SkMaskFilterBase.h"
#include "SkPaint.h"
#include "SkPathEffect.h"
#include "SkPathOps.h"
#include "SkPoint.h"
#include "SkRasterClip.h"
#include "SkSFNTHeader.h"
#include "SkShader.h"
#include "SkSize.h"
#include "SkStream.h"
#include "SkStrikeCache.h"
#include "SkTDArray.h"
#include "SkTLazy.h"
#include "SkTScopedComPtr.h"
#include "SkTTCFHeader.h"
#include "SkTo.h"
#include "SkTypefacePriv.h"
#include "SkUtils.h"
#include "SkVertices.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 createId.
#define L_GUID_ID L"XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX"
//Length of GUID representation from createId, including nullptr 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]);
}

HRESULT SkXPSDevice::createId(wchar_t* buffer, size_t bufferSize, wchar_t sep) {
    GUID guid = {};
#ifdef SK_XPS_USE_DETERMINISTIC_IDS
    guid.Data1 = fNextId++;
    // The following make this a valid Type4 UUID.
    guid.Data3 = 0x4000;
    guid.Data4[0] = 0x80;
#else
    HRM(CoCreateGuid(&guid), "Could not create GUID for id.");
#endif

    if (format_guid(guid, buffer, bufferSize, sep) == -1) {
        HRM(E_UNEXPECTED, "Could not format GUID into id.");
    }

    return S_OK;
}

SkXPSDevice::SkXPSDevice(SkISize s)
    : INHERITED(SkImageInfo::MakeUnknown(s.width(), s.height()),
                SkSurfaceProps(0, kUnknown_SkPixelGeometry))
    , fCurrentPage(0) {}

SkXPSDevice::~SkXPSDevice() {}

SkXPSDevice::TypefaceUse::TypefaceUse()
    : typefaceId(0xffffffff)
    , fontData(nullptr)
    , xpsFont(nullptr)
    , glyphsUsed(nullptr) {}

SkXPSDevice::TypefaceUse::~TypefaceUse() {
    //xpsFont owns fontData ref
    this->xpsFont->Release();
    delete this->glyphsUsed;
}

bool SkXPSDevice::beginPortfolio(SkWStream* outputStream, IXpsOMObjectFactory* factory) {
    SkASSERT(factory);
    fXpsFactory.reset(SkRefComPtr(factory));
    HRB(SkWIStream::CreateFromSkWStream(outputStream, &this->fOutputStream));
    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;
    return this->createCanvasForLayer();
}

bool SkXPSDevice::createCanvasForLayer() {
    SkASSERT(fXpsFactory);
    fCurrentXpsCanvas.reset();
    HRB(fXpsFactory->CreateCanvas(&fCurrentXpsCanvas));
    return true;
}

template <typename T> static constexpr size_t sk_digits_in() {
    return static_cast<size_t>(std::numeric_limits<T>::digits10 + 1);
}

HRESULT SkXPSDevice::createXpsThumbnail(IXpsOMPage* page,
                                        const unsigned int pageNum,
                                        IXpsOMImageResource** image) {
    SkTScopedComPtr<IXpsOMThumbnailGenerator> thumbnailGenerator;
    HRM(CoCreateInstance(
            CLSID_XpsOMThumbnailGenerator,
            nullptr,
            CLSCTX_INPROC_SERVER,
            IID_PPV_ARGS(&thumbnailGenerator)),
        "Could not create thumbnail generator.");

    SkTScopedComPtr<IOpcPartUri> partUri;
    constexpr size_t size = SkTMax(
            SK_ARRAY_COUNT(L"/Documents/1/Metadata/.png") + sk_digits_in<decltype(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(this->createId(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) {
    constexpr size_t size =
        SK_ARRAY_COUNT(L"/Documents/1/Pages/.fpage")
        + sk_digits_in<decltype(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(),
                nullptr,
                image,
                nullptr,
                nullptr,
                &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(),
                                                   nullptr,
                                                   nullptr,
                                                   nullptr,
                                                   nullptr),
            "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 (nullptr == 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,
                                       nullptr,
                                       nullptr,
                                       nullptr,
                                       nullptr),
         "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?
    std::vector<unsigned short> keepList;
    current->glyphsUsed->exportTo(&keepList);

    int ttcCount = (current->ttcIndex + 1);

    //The following are declared with the types required by CreateFontPackage.
    unsigned char *fontPackageBufferRaw = nullptr;
    unsigned long fontPackageBufferSize;
    unsigned long bytesWritten;
    unsigned long result = CreateFontPackage(
        (unsigned char *) current->fontData->getMemoryBase(),
        (unsigned long) current->fontData->getLength(),
        &fontPackageBufferRaw,
        &fontPackageBufferSize,
        &bytesWritten,
        TTFCFP_FLAGS_SUBSET | TTFCFP_FLAGS_GLYPHLIST | (ttcCount > 0 ? TTFCFP_FLAGS_TTC : 0),
        current->ttcIndex,
        TTFCFP_SUBSET,
        0,
        0,
        0,
        keepList.data(),
        SkTo<unsigned short>(keepList.size()),
        sk_malloc_throw,
        sk_realloc_throw,
        sk_free,
        nullptr);
    SkAutoTMalloc<unsigned char> fontPackageBuffer(fontPackageBufferRaw);
    if (result != NO_ERROR) {
        SkDEBUGF("CreateFontPackage Error %lu", result);
        return E_UNEXPECTED;
    }

    // If it was originally a ttc, keep it a ttc.
    // CreateFontPackage over-allocates, realloc usually decreases the size substantially.
    size_t extra;
    if (ttcCount > 0) {
        // Create space for a ttc header.
        extra = sizeof(SkTTCFHeader) + (ttcCount * sizeof(SK_OT_ULONG));
        fontPackageBuffer.realloc(bytesWritten + extra);
        //overlap is certain, use memmove
        memmove(fontPackageBuffer.get() + extra, fontPackageBuffer.get(), bytesWritten);

        // Write the ttc header.
        SkTTCFHeader* ttcfHeader = reinterpret_cast<SkTTCFHeader*>(fontPackageBuffer.get());
        ttcfHeader->ttcTag = SkTTCFHeader::TAG;
        ttcfHeader->version = SkTTCFHeader::version_1;
        ttcfHeader->numOffsets = SkEndian_SwapBE32(ttcCount);
        SK_OT_ULONG* offsetPtr = SkTAfter<SK_OT_ULONG>(ttcfHeader);
        for (int i = 0; i < ttcCount; ++i, ++offsetPtr) {
            *offsetPtr = SkEndian_SwapBE32(SkToU32(extra));
        }

        // Fix up offsets in sfnt table entries.
        SkSFNTHeader* sfntHeader = SkTAddOffset<SkSFNTHeader>(fontPackageBuffer.get(), extra);
        int numTables = SkEndian_SwapBE16(sfntHeader->numTables);
        SkSFNTHeader::TableDirectoryEntry* tableDirectory =
            SkTAfter<SkSFNTHeader::TableDirectoryEntry>(sfntHeader);
        for (int i = 0; i < numTables; ++i, ++tableDirectory) {
            tableDirectory->offset = SkEndian_SwapBE32(
                SkToU32(SkEndian_SwapBE32(SkToU32(tableDirectory->offset)) + extra));
        }
    } else {
        extra = 0;
        fontPackageBuffer.realloc(bytesWritten);
    }

    std::unique_ptr<SkMemoryStream> newStream(new SkMemoryStream());
    newStream->setMemoryOwned(fontPackageBuffer.release(), bytesWritten + extra);

    SkTScopedComPtr<IStream> newIStream;
    SkIStream::CreateFromSkStream(newStream.release(), 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:
        SkDEBUGFAIL("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 = (end.fX - start.fX) * stopOffsets[i];
        stop.fY = (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] = startToStop / startToEnd;
    }
}

HRESULT SkXPSDevice::createXpsTransform(const SkMatrix& matrix,
                                        IXpsOMMatrixTransform** xpsTransform) {
    SkScalar affine[6];
    if (!matrix.asAffine(affine)) {
        *xpsTransform = nullptr;
        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, nullptr, &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 (!SkEncodeImage(&write, bitmap, SkEncodedImageFormat::kPNG, 100)) {
        HRM(E_FAIL, "Unable to encode bitmap as png.");
    }
    SkMemoryStream* read = new SkMemoryStream;
    read->setData(write.detachAsData());
    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(this->createId(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]) {

            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 (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,
                                              nullptr,
                                              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 (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 (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 (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 (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 (nullptr == shader) {
        HR(this->createXpsSolidColorBrush(skPaint.getColor(), 0xFF, brush));
        return S_OK;
    }

    //Gradient shaders.
    SkShader::GradientInfo info;
    info.fColorCount = 0;
    info.fColors = nullptr;
    info.fColorOffsets = nullptr;
    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;
        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();
        if (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::kConical_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];
    SkImage* image = shader->isAImage(&outMatrix, xy);
    if (image && image->asLegacyBitmap(&outTexture)) {
        //TODO: outMatrix??
        SkMatrix localMatrix = shader->getLocalMatrix();
        if (parentTransform) {
            localMatrix.postConcat(*parentTransform);
        }

        SkTScopedComPtr<IXpsOMTileBrush> tileBrush;
        HR(this->createXpsImageBrush(outTexture,
                                     localMatrix,
                                     xy,
                                     skPaint.getAlpha(),
                                     &tileBrush));

        HRM(tileBrush->QueryInterface<IXpsOMBrush>(brush), "QI failed.");
    } else {
        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() ||
           (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;
}

template <typename F, typename... Args>
void draw(SkClipStackDevice* dev, F f, Args&&... args) {
    SkIRect r = dev->devClipBounds();
    SkRasterClip rc(r);
    SkDraw draw;
    draw.fMatrix = &dev->ctm();
    draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(r.right(), r.bottom()), nullptr, 0);
    draw.fRC = &rc;
    (draw.*f)(std::forward<Args>(args)...);
}


void SkXPSDevice::drawPoints(SkCanvas::PointMode mode,
                             size_t count, const SkPoint points[],
                             const SkPaint& paint) {
    draw(this, &SkDraw::drawPoints, mode, count, points, paint, this);
}

void SkXPSDevice::drawVertices(const SkVertices* v, const SkVertices::Bone bones[], int boneCount,
                               SkBlendMode blendMode, const SkPaint& paint) {
    draw(this, &SkDraw::drawVertices, v->mode(), v->vertexCount(), v->positions(), v->texCoords(),
         v->colors(), v->boneIndices(), v->boneWeights(), blendMode, v->indices(), v->indexCount(),
         paint, bones, boneCount);
}

void SkXPSDevice::drawPaint(const SkPaint& origPaint) {
    const SkRect r = SkRect::MakeSize(this->fCurrentCanvasSize);

    //If trying to paint with a stroke, ignore that and fill.
    SkPaint* fillPaint = const_cast<SkPaint*>(&origPaint);
    SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
    if (paint->getStyle() != SkPaint::kFill_Style) {
        paint.writable()->setStyle(SkPaint::kFill_Style);
    }

    this->internalDrawRect(r, false, *fillPaint);
}

void SkXPSDevice::drawRect(const SkRect& r,
                           const SkPaint& paint) {
    this->internalDrawRect(r, true, paint);
}

void SkXPSDevice::drawRRect(const SkRRect& rr,
                            const SkPaint& paint) {
    SkPath path;
    path.addRRect(rr);
    this->drawPath(path, paint, true);
}

static SkIRect size(const SkBaseDevice& dev) { return {0, 0, dev.width(), dev.height()}; }

void SkXPSDevice::internalDrawRect(const SkRect& r,
                                   bool transformRect,
                                   const SkPaint& paint) {
    //Exit early if there is nothing to draw.
    if (this->cs().isEmpty(size(*this)) ||
        (paint.getAlpha() == 0 && paint.isSrcOver())) {
        return;
    }

    //Path the rect if we can't optimize it.
    if (rect_must_be_pathed(paint, this->ctm())) {
        SkPath tmp;
        tmp.addRect(r);
        tmp.setFillType(SkPath::kWinding_FillType);
        this->drawPath(tmp, paint, 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, this->ctm(), &fill, &stroke));

    bool xpsTransformsPath = true;
    //Transform the geometry.
    if (transformRect && xpsTransformsPath) {
        SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
        HRV(this->createXpsTransform(this->ctm(), &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) {
            this->ctm().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()));

    //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 (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_back(XPS_SEGMENT_TYPE_LINE);
                segmentStrokes.push_back(stroke);
                segmentData.push_back(SkScalarToFLOAT(points[1].fX));
                segmentData.push_back(SkScalarToFLOAT(points[1].fY));
                break;
            case SkPath::kQuad_Verb:
                segmentTypes.push_back(XPS_SEGMENT_TYPE_QUADRATIC_BEZIER);
                segmentStrokes.push_back(stroke);
                segmentData.push_back(SkScalarToFLOAT(points[1].fX));
                segmentData.push_back(SkScalarToFLOAT(points[1].fY));
                segmentData.push_back(SkScalarToFLOAT(points[2].fX));
                segmentData.push_back(SkScalarToFLOAT(points[2].fY));
                break;
            case SkPath::kCubic_Verb:
                segmentTypes.push_back(XPS_SEGMENT_TYPE_BEZIER);
                segmentStrokes.push_back(stroke);
                segmentData.push_back(SkScalarToFLOAT(points[1].fX));
                segmentData.push_back(SkScalarToFLOAT(points[1].fY));
                segmentData.push_back(SkScalarToFLOAT(points[2].fX));
                segmentData.push_back(SkScalarToFLOAT(points[2].fY));
                segmentData.push_back(SkScalarToFLOAT(points[3].fX));
                segmentData.push_back(SkScalarToFLOAT(points[3].fY));
                break;
            case SkPath::kConic_Verb: {
                const SkScalar tol = SK_Scalar1 / 4;
                SkAutoConicToQuads converter;
                const SkPoint* quads =
                    converter.computeQuads(points, iter.conicWeight(), tol);
                for (int i = 0; i < converter.countQuads(); ++i) {
                    segmentTypes.push_back(XPS_SEGMENT_TYPE_QUADRATIC_BEZIER);
                    segmentStrokes.push_back(stroke);
                    segmentData.push_back(SkScalarToFLOAT(quads[2 * i + 1].fX));
                    segmentData.push_back(SkScalarToFLOAT(quads[2 * i + 1].fY));
                    segmentData.push_back(SkScalarToFLOAT(quads[2 * i + 2].fX));
                    segmentData.push_back(SkScalarToFLOAT(quads[2 * i + 2].fY));
                }
                break;
            }
            case SkPath::kClose_Verb:
                // we ignore these, and just get the whole segment from
                // the corresponding line/quad/cubic verbs
                break;
            default:
                SkDEBUGFAIL("unexpected verb");
                break;
        }
    }
    if (xpsFigure.get()) {
        HR(close_figure(segmentTypes, segmentStrokes, segmentData,
                        stroke, fill,
                        xpsFigure.get(), xpsFigures));
    }
    return S_OK;
}

void SkXPSDevice::convertToPpm(const SkMaskFilter* filter,
                               SkMatrix* matrix,
                               SkVector* ppuScale,
                               const SkIRect& clip, SkIRect* clipIRect) {
    //This action is in unit space, but the ppm is specified in physical space.
    ppuScale->set(fCurrentPixelsPerMeter.fX / fCurrentUnitsPerMeter.fX,
                  fCurrentPixelsPerMeter.fY / fCurrentUnitsPerMeter.fY);

    matrix->postScale(ppuScale->fX, ppuScale->fY);

    const SkIRect& irect = clip;
    SkRect clipRect = SkRect::MakeLTRB(SkIntToScalar(irect.fLeft) * ppuScale->fX,
                                       SkIntToScalar(irect.fTop) * ppuScale->fY,
                                       SkIntToScalar(irect.fRight) * ppuScale->fX,
                                       SkIntToScalar(irect.fBottom) * ppuScale->fY);
    clipRect.roundOut(clipIRect);
}

HRESULT SkXPSDevice::applyMask(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.installMaskPixels(mask);

    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));

    //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 SkPath& platonicPath,
                           const SkPaint& origPaint,
                           bool pathIsMutable) {
    SkTCopyOnFirstWrite<SkPaint> paint(origPaint);

    // nothing to draw
    if (this->cs().isEmpty(size(*this)) ||
        (paint->getAlpha() == 0 && paint->isSrcOver())) {
        return;
    }

    SkPath modifiedPath;
    const bool paintHasPathEffect = paint->getPathEffect()
                                 || paint->getStyle() != SkPaint::kFill_Style;

    //Apply pre-path matrix [Platonic-path -> Skeletal-path].
    SkMatrix matrix = this->ctm();
    SkPath* skeletalPath = const_cast<SkPath*>(&platonicPath);

    //Apply path effect [Skeletal-path -> Fillable-path].
    SkPath* fillablePath = skeletalPath;
    if (paintHasPathEffect) {
        if (!pathIsMutable) {
            fillablePath = &modifiedPath;
            pathIsMutable = true;
        }
        bool fill = paint->getFillPath(*skeletalPath, fillablePath);

        SkPaint* writablePaint = paint.writable();
        writablePaint->setPathEffect(nullptr);
        if (fill) {
            writablePaint->setStyle(SkPaint::kFill_Style);
        } else {
            writablePaint->setStyle(SkPaint::kStroke_Style);
            writablePaint->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.");

    SkMaskFilter* filter = paint->getMaskFilter();

    //Determine if we will draw or shade and mask.
    if (filter) {
        if (paint->getStyle() != SkPaint::kFill_Style) {
            paint.writable()->setStyle(SkPaint::kFill_Style);
        }
    }

    //Set the brushes.
    BOOL fill;
    BOOL stroke;
    HRV(this->shadePath(shadedPath.get(),
                        *paint,
                        this->ctm(),
                        &fill,
                        &stroke));

    //Mask filter
    if (filter) {
        SkIRect clipIRect;
        SkVector ppuScale;
        this->convertToPpm(filter,
                           &matrix,
                           &ppuScale,
                           this->cs().bounds(size(*this)).roundOut(),
                           &clipIRect);

        //[Fillable-path -> Pixel-path]
        SkPath* pixelPath = pathIsMutable ? fillablePath : &modifiedPath;
        fillablePath->transform(matrix, pixelPath);

        SkMask* mask = nullptr;

        SkASSERT(SkPaint::kFill_Style == paint->getStyle() ||
                 (SkPaint::kStroke_Style == paint->getStyle() && 0 == paint->getStrokeWidth()));
        SkStrokeRec::InitStyle style = (SkPaint::kFill_Style == paint->getStyle())
                                            ? SkStrokeRec::kFill_InitStyle
                                            : SkStrokeRec::kHairline_InitStyle;
        //[Pixel-path -> Mask]
        SkMask rasteredMask;
        if (SkDraw::DrawToMask(
                        *pixelPath,
                        &clipIRect,
                        filter,  //just to compute how much to draw.
                        &matrix,
                        &rasteredMask,
                        SkMask::kComputeBoundsAndRenderImage_CreateMode,
                        style)) {

            SkAutoMaskFreeImage rasteredAmi(rasteredMask.fImage);
            mask = &rasteredMask;

            //[Mask -> Mask]
            SkMask filteredMask;
            if (as_MFB(filter)->filterMask(&filteredMask, rasteredMask, matrix, nullptr)) {
                mask = &filteredMask;
            }
            SkAutoMaskFreeImage filteredAmi(filteredMask.fImage);

            //Draw mask.
            HRV(this->applyMask(*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.
    SkPath* xpsCompatiblePath = fillablePath;
    XPS_FILL_RULE xpsFillRule;
    switch (fillablePath->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 (inverse winding) -> XPS-path (inverse even odd)]
            if (!pathIsMutable) {
                xpsCompatiblePath = &modifiedPath;
                pathIsMutable = true;
            }
            if (!Simplify(*fillablePath, xpsCompatiblePath)) {
                SkDEBUGF("Could not simplify inverse winding path.");
                return;
            }
        }
        // The xpsCompatiblePath is noW inverse even odd, so fall through.
        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:
            SkDEBUGFAIL("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 = xpsCompatiblePath;
    if (!xpsTransformsPath) {
        //[Fillable-path -> Device-path]
        devicePath = pathIsMutable ? xpsCompatiblePath : &modifiedPath;
        xpsCompatiblePath->transform(matrix, devicePath);
    }
    HRV(this->addXpsPathGeometry(shadedFigures.get(),
                                 stroke, fill, *devicePath));

    HRV(this->clip(shadedPath.get()));

    //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) {
    SkPath clipPath;
    // clipPath.addRect(this->cs().bounds(size(*this)));
    (void)this->cs().asPath(&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 SkBitmap& bitmap,
                             SkScalar x,
                             SkScalar y,
                             const SkPaint& paint) {
    if (this->cs().isEmpty(size(*this))) {
        return;
    }

    SkIRect srcRect;
    srcRect.set(0, 0, bitmap.width(), bitmap.height());

    //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 = SkMatrix::MakeTrans(x, y);
    transform.postConcat(this->ctm());

    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 (xpsTransform.get()) {
        const SkShader::TileMode xy[2] = {
            SkShader::kClamp_TileMode,
            SkShader::kClamp_TileMode,
        };
        SkTScopedComPtr<IXpsOMTileBrush> xpsImageBrush;
        HRV(this->createXpsImageBrush(bitmap,
                                      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()));
}

void SkXPSDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& paint) {
    //TODO: override this for XPS
    SkDEBUGF("XPS drawSprite not yet implemented.");
}

#if 0

HRESULT SkXPSDevice::CreateTypefaceUse(const SkPaint& paint,
                                       TypefaceUse** typefaceUse) {
    SkAutoResolveDefaultTypeface typeface(paint.getTypeface());

    //Check cache.
    const SkFontID typefaceID = typeface->uniqueID();
    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;
    int ttcIndex;
    SkStream* fontData = typeface->openStream(&ttcIndex);
    //TODO: cannot handle FON fonts.
    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(this->createId(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.");

    //TODO: change openStream to return -1 for non-ttc, get rid of this.
    uint8_t* data = (uint8_t*)fontData->getMemoryBase();
    bool isTTC = (data &&
                  fontData->getLength() >= sizeof(SkTTCFHeader) &&
                  ((SkTTCFHeader*)data)->ttcTag == SkTTCFHeader::TAG);

    TypefaceUse& newTypefaceUse = this->fTypefaces.push_back();
    newTypefaceUse.typefaceId = typefaceID;
    newTypefaceUse.ttcIndex = isTTC ? ttcIndex : -1;
    newTypefaceUse.fontData = fontData;
    newTypefaceUse.xpsFont = xpsFontResource.release();
    auto glyphCache =
        SkStrikeCache::FindOrCreateStrikeExclusive(
            paint, &this->surfaceProps(),
            SkScalerContextFlags::kNone, nullptr);
    unsigned int glyphCount = glyphCache->getGlyphCount();
    newTypefaceUse.glyphsUsed = new SkBitSet(glyphCount);

    *typefaceUse = &newTypefaceUse;
    return S_OK;
}

HRESULT SkXPSDevice::AddGlyphs(IXpsOMObjectFactory* xpsFactory,
                               IXpsOMCanvas* canvas,
                               TypefaceUse* 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->xpsFont, &glyphs), "Could not create glyphs.");
    HRM(glyphs->SetFontFaceIndex(font->ttcIndex), "Could not set glyph font face index.");

    //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 {
            SkDEBUGFAIL("Attempt to add glyphs in perspective.");
            useCanvasForClip = false;
        }
    }

    SkTScopedComPtr<IXpsOMGlyphsEditor> glyphsEditor;
    HRM(glyphs->GetGlyphsEditor(&glyphsEditor), "Could not get glyph editor.");

    if (text) {
        HRM(glyphsEditor->SetUnicodeString(text),
            "Could not set unicode string.");
    }

    if (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 ? nullptr : &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()));
        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()));

        HRM(visuals->Append(glyphCanvas.get()),
            "Could not add glyph canvas to page.");
    }

    return S_OK;
}

static int num_glyph_guess(SkPaint::TextEncoding encoding, const void* text, size_t byteLength) {
    static_assert((int)SkTypeface::kUTF8_Encoding  == (int)SkPaint::kUTF8_TextEncoding,  "");
    static_assert((int)SkTypeface::kUTF16_Encoding == (int)SkPaint::kUTF16_TextEncoding, "");
    static_assert((int)SkTypeface::kUTF32_Encoding == (int)SkPaint::kUTF32_TextEncoding, "");
    if (encoding == SkPaint::kGlyphID_TextEncoding) {
        return SkToInt(byteLength / 2);
    }
    return SkUTFN_CountUnichars((SkTypeface::Encoding)encoding, text, byteLength);
}

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()
    ;
}

typedef SkTDArray<XPS_GLYPH_INDEX> GlyphRun;

class ProcessOneGlyph {
public:
    ProcessOneGlyph(FLOAT centemPerUnit, SkBitSet* glyphUse, GlyphRun* xpsGlyphs)
        : fCentemPerUnit(centemPerUnit)
        , fGlyphUse(glyphUse)
        , fXpsGlyphs(xpsGlyphs) { }

    void operator()(const SkGlyph& glyph, SkPoint position, SkPoint) {
        SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);

        SkScalar x = position.fX;
        SkScalar y = position.fY;

        XPS_GLYPH_INDEX* xpsGlyph = fXpsGlyphs->append();
        uint16_t glyphID = glyph.getGlyphID();
        fGlyphUse->set(glyphID);
        xpsGlyph->index = glyphID;
        if (1 == fXpsGlyphs->count()) {
            xpsGlyph->advanceWidth = 0.0f;
            xpsGlyph->horizontalOffset = SkScalarToFloat(x) * fCentemPerUnit;
            xpsGlyph->verticalOffset = SkScalarToFloat(y) * -fCentemPerUnit;
        }
        else {
            const XPS_GLYPH_INDEX& first = (*fXpsGlyphs)[0];
            xpsGlyph->advanceWidth = 0.0f;
            xpsGlyph->horizontalOffset = (SkScalarToFloat(x) * fCentemPerUnit)
                - first.horizontalOffset;
            xpsGlyph->verticalOffset = (SkScalarToFloat(y) * -fCentemPerUnit)
                - first.verticalOffset;
        }
    }

private:
    /** [in] Advance width and offsets for glyphs measured in
    hundredths of the font em size (XPS Spec 5.1.3). */
    const FLOAT fCentemPerUnit;
    /** [in,out] The accumulated glyphs used in the current typeface. */
    SkBitSet* const fGlyphUse;
    /** [out] The glyphs to draw. */
    GlyphRun* const fXpsGlyphs;
};

void SkXPSDevice::drawPosText(const void* text, size_t byteLen,
                              const SkScalar pos[], int scalarsPerPos,
                              const SkPoint& offset, const SkPaint& paint) {
    if (byteLen < 1) return;

    if (text_must_be_pathed(paint, this->ctm())) {
        SkPath path;
        //TODO: make this work, Draw currently does not handle as well.
        //paint.getTextPath(text, byteLength, x, y, &path);
        //this->drawPath(path, paint, nullptr, true);
        //TODO: add automation "text"
        return;
    }

    TypefaceUse* typeface;
    HRV(CreateTypefaceUse(paint, &typeface));

    auto cache =
        SkStrikeCache::FindOrCreateStrikeExclusive(
            paint, &this->surfaceProps(),
            SkScalerContextFlags::kNone, nullptr);

    // Advance width and offsets for glyphs measured in hundredths of the font em size
    // (XPS Spec 5.1.3).
    FLOAT centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize());
    GlyphRun xpsGlyphs;
    xpsGlyphs.setReserve(num_glyph_guess(paint.getTextEncoding(),
        static_cast<const char*>(text), byteLen));

    ProcessOneGlyph processOneGlyph(centemPerUnit, typeface->glyphsUsed, &xpsGlyphs);

    SkFindAndPlaceGlyph::ProcessPosText(
        paint.getTextEncoding(), static_cast<const char*>(text), byteLen,
        offset, SkMatrix::I(), pos, scalarsPerPos, cache.get(), processOneGlyph);

    if (xpsGlyphs.count() == 0) {
        return;
    }

    XPS_POINT origin = {
        xpsGlyphs[0].horizontalOffset / centemPerUnit,
        xpsGlyphs[0].verticalOffset / -centemPerUnit,
    };
    xpsGlyphs[0].horizontalOffset = 0.0f;
    xpsGlyphs[0].verticalOffset = 0.0f;

    HRV(AddGlyphs(this->fXpsFactory.get(),
                  this->fCurrentXpsCanvas.get(),
                  typeface,
                  nullptr,
                  xpsGlyphs.begin(), xpsGlyphs.count(),
                  &origin,
                  SkScalarToFLOAT(paint.getTextSize()),
                  XPS_STYLE_SIMULATION_NONE,
                  this->ctm(),
                  paint));
}
#endif
void SkXPSDevice::drawDevice( SkBaseDevice* dev,
                             int x, int y,
                             const SkPaint&) {
    SkXPSDevice* that = static_cast<SkXPSDevice*>(dev);

    SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
    // TODO(halcanary): assert that current transform is identity rather than calling setter.
    XPS_MATRIX rawTransform = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};
    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.");
}

SkBaseDevice* SkXPSDevice::onCreateDevice(const CreateInfo& info, const SkPaint*) {
//Conditional for bug compatibility with PDF device.
#if 0
    if (SkBaseDevice::kGeneral_Usage == info.fUsage) {
        return nullptr;
        //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;
    }
#endif
    SkXPSDevice* dev = new SkXPSDevice(info.fInfo.dimensions());
    // TODO(halcanary) implement copy constructor on SkTScopedCOmPtr
    dev->fXpsFactory.reset(SkRefComPtr(fXpsFactory.get()));
    SkAssertResult(dev->createCanvasForLayer());
    return dev;
}

void SkXPSDevice::drawOval( const SkRect& o, const SkPaint& p) {
    SkPath path;
    path.addOval(o);
    this->drawPath(path, p, true);
}

void SkXPSDevice::drawBitmapRect(const SkBitmap& bitmap,
                                 const SkRect* src,
                                 const SkRect& dst,
                                 const SkPaint& paint,
                                 SkCanvas::SrcRectConstraint constraint) {
    SkRect bitmapBounds = SkRect::Make(bitmap.bounds());
    SkRect srcBounds = src ? *src : bitmapBounds;
    SkMatrix matrix = SkMatrix::MakeRectToRect(srcBounds, dst, SkMatrix::kFill_ScaleToFit);
    SkRect actualDst;
    if (!src || bitmapBounds.contains(*src)) {
        actualDst = dst;
    } else {
        if (!srcBounds.intersect(bitmapBounds)) {
            return;
        }
        matrix.mapRect(&actualDst, srcBounds);
    }
    auto bitmapShader = SkMakeBitmapShader(bitmap, SkShader::kClamp_TileMode,
                                           SkShader::kClamp_TileMode, &matrix,
                                           kNever_SkCopyPixelsMode);
    SkASSERT(bitmapShader);
    if (!bitmapShader) { return; }
    SkPaint paintWithShader(paint);
    paintWithShader.setStyle(SkPaint::kFill_Style);
    paintWithShader.setShader(std::move(bitmapShader));
    this->drawRect(actualDst, paintWithShader);
}
#endif//defined(SK_BUILD_FOR_WIN)
