147ef4d5d934bba86848aa238efab21f54a160c1ahalcanary/*
247ef4d5d934bba86848aa238efab21f54a160c1ahalcanary * Copyright 2015 Google Inc.
347ef4d5d934bba86848aa238efab21f54a160c1ahalcanary *
447ef4d5d934bba86848aa238efab21f54a160c1ahalcanary * Use of this source code is governed by a BSD-style license that can be
547ef4d5d934bba86848aa238efab21f54a160c1ahalcanary * found in the LICENSE file.
647ef4d5d934bba86848aa238efab21f54a160c1ahalcanary */
747ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary#include "SkDocument.h"
947ef4d5d934bba86848aa238efab21f54a160c1ahalcanary#include "SkXPSDevice.h"
1047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary#include "SkStream.h"
1147ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
1247ef4d5d934bba86848aa238efab21f54a160c1ahalcanaryclass SkDocument_XPS : public SkDocument {
1347ef4d5d934bba86848aa238efab21f54a160c1ahalcanarypublic:
1447ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    SkDocument_XPS(SkWStream* stream,
1547ef4d5d934bba86848aa238efab21f54a160c1ahalcanary                   void (*doneProc)(SkWStream*, bool),
1647ef4d5d934bba86848aa238efab21f54a160c1ahalcanary                   SkScalar dpi)
1747ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        : SkDocument(stream, doneProc) {
1847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        const SkScalar kPointsPerMeter = SkDoubleToScalar(360000.0 / 127.0);
1947ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fUnitsPerMeter.set(kPointsPerMeter, kPointsPerMeter);
2047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        SkScalar pixelsPerMeterScale = SkDoubleToScalar(dpi * 5000.0 / 127.0);
2147ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fPixelsPerMeter.set(pixelsPerMeterScale, pixelsPerMeterScale);
2247ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fDevice.beginPortfolio(stream);
2347ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    }
2447ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
2547ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    virtual ~SkDocument_XPS() {
2647ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        // subclasses must call close() in their destructors
2747ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        this->close();
2847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    }
2947ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
3047ef4d5d934bba86848aa238efab21f54a160c1ahalcanaryprotected:
31f4219ddf31b2171a5576ab98d1fd2deab4d816fdtfarina    SkCanvas* onBeginPage(SkScalar width,
32f4219ddf31b2171a5576ab98d1fd2deab4d816fdtfarina                          SkScalar height,
33f4219ddf31b2171a5576ab98d1fd2deab4d816fdtfarina                          const SkRect& trimBox) override {
3447ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fDevice.beginSheet(fUnitsPerMeter, fPixelsPerMeter,
3547ef4d5d934bba86848aa238efab21f54a160c1ahalcanary                           SkSize::Make(width, height));
3647ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fCanvas.reset(SkNEW_ARGS(SkCanvas, (&fDevice)));
3747ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fCanvas->clipRect(trimBox);
3847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fCanvas->translate(trimBox.x(), trimBox.y());
3947ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        return fCanvas.get();
4047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    }
4147ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
4236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onEndPage() override {
4347ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        SkASSERT(fCanvas.get());
4447ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fCanvas->flush();
4547ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fCanvas.reset(NULL);
4647ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        fDevice.endSheet();
4747ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    }
4847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
4936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onClose(SkWStream*) override {
5047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        SkASSERT(!fCanvas.get());
5147ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        return fDevice.endPortfolio();
5247ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    }
5347ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
5436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onAbort() override {}
5547ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
5647ef4d5d934bba86848aa238efab21f54a160c1ahalcanaryprivate:
5747ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    SkXPSDevice fDevice;
5847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    SkAutoTUnref<SkCanvas> fCanvas;
5947ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    SkVector fUnitsPerMeter;
6047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    SkVector fPixelsPerMeter;
6147ef4d5d934bba86848aa238efab21f54a160c1ahalcanary};
6247ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
6347ef4d5d934bba86848aa238efab21f54a160c1ahalcanary///////////////////////////////////////////////////////////////////////////////
6447ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
6547ef4d5d934bba86848aa238efab21f54a160c1ahalcanarySkDocument* SkDocument::CreateXPS(SkWStream* stream, SkScalar dpi) {
6647ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    return stream ? SkNEW_ARGS(SkDocument_XPS, (stream, NULL, dpi)) : NULL;
6747ef4d5d934bba86848aa238efab21f54a160c1ahalcanary}
6847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
6947ef4d5d934bba86848aa238efab21f54a160c1ahalcanarystatic void delete_wstream(SkWStream* stream, bool aborted) {
7047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    SkDELETE(stream);
7147ef4d5d934bba86848aa238efab21f54a160c1ahalcanary}
7247ef4d5d934bba86848aa238efab21f54a160c1ahalcanary
7347ef4d5d934bba86848aa238efab21f54a160c1ahalcanarySkDocument* SkDocument::CreateXPS(const char path[], SkScalar dpi) {
7447ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    SkAutoTDelete<SkFILEWStream> stream(SkNEW_ARGS(SkFILEWStream, (path)));
7547ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    if (!stream->isValid()) {
7647ef4d5d934bba86848aa238efab21f54a160c1ahalcanary        return NULL;
7747ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    }
7847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary    return SkNEW_ARGS(SkDocument_XPS, (stream.detach(), delete_wstream, dpi));
7947ef4d5d934bba86848aa238efab21f54a160c1ahalcanary}
80