1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkDocument.h"
9 #include "SkXPSDevice.h"
10 #include "SkStream.h"
11 
12 class SkDocument_XPS : public SkDocument {
13 public:
SkDocument_XPS(SkWStream * stream,void (* doneProc)(SkWStream *,bool),SkScalar dpi)14     SkDocument_XPS(SkWStream* stream,
15                    void (*doneProc)(SkWStream*, bool),
16                    SkScalar dpi)
17         : SkDocument(stream, doneProc) {
18         const SkScalar kPointsPerMeter = SkDoubleToScalar(360000.0 / 127.0);
19         fUnitsPerMeter.set(kPointsPerMeter, kPointsPerMeter);
20         SkScalar pixelsPerMeterScale = SkDoubleToScalar(dpi * 5000.0 / 127.0);
21         fPixelsPerMeter.set(pixelsPerMeterScale, pixelsPerMeterScale);
22         fDevice.beginPortfolio(stream);
23     }
24 
~SkDocument_XPS()25     virtual ~SkDocument_XPS() {
26         // subclasses must call close() in their destructors
27         this->close();
28     }
29 
30 protected:
onBeginPage(SkScalar width,SkScalar height,const SkRect & trimBox)31     SkCanvas* onBeginPage(SkScalar width,
32                           SkScalar height,
33                           const SkRect& trimBox) override {
34         fDevice.beginSheet(fUnitsPerMeter, fPixelsPerMeter,
35                            SkSize::Make(width, height));
36         fCanvas.reset(SkNEW_ARGS(SkCanvas, (&fDevice)));
37         fCanvas->clipRect(trimBox);
38         fCanvas->translate(trimBox.x(), trimBox.y());
39         return fCanvas.get();
40     }
41 
onEndPage()42     void onEndPage() override {
43         SkASSERT(fCanvas.get());
44         fCanvas->flush();
45         fCanvas.reset(NULL);
46         fDevice.endSheet();
47     }
48 
onClose(SkWStream *)49     bool onClose(SkWStream*) override {
50         SkASSERT(!fCanvas.get());
51         return fDevice.endPortfolio();
52     }
53 
onAbort()54     void onAbort() override {}
55 
56 private:
57     SkXPSDevice fDevice;
58     SkAutoTUnref<SkCanvas> fCanvas;
59     SkVector fUnitsPerMeter;
60     SkVector fPixelsPerMeter;
61 };
62 
63 ///////////////////////////////////////////////////////////////////////////////
64 
CreateXPS(SkWStream * stream,SkScalar dpi)65 SkDocument* SkDocument::CreateXPS(SkWStream* stream, SkScalar dpi) {
66     return stream ? SkNEW_ARGS(SkDocument_XPS, (stream, NULL, dpi)) : NULL;
67 }
68 
delete_wstream(SkWStream * stream,bool aborted)69 static void delete_wstream(SkWStream* stream, bool aborted) {
70     SkDELETE(stream);
71 }
72 
CreateXPS(const char path[],SkScalar dpi)73 SkDocument* SkDocument::CreateXPS(const char path[], SkScalar dpi) {
74     SkAutoTDelete<SkFILEWStream> stream(SkNEW_ARGS(SkFILEWStream, (path)));
75     if (!stream->isValid()) {
76         return NULL;
77     }
78     return SkNEW_ARGS(SkDocument_XPS, (stream.detach(), delete_wstream, dpi));
79 }
80