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 "SkTypes.h" 9 #if defined(SK_BUILD_FOR_WIN32) 10 11 #include "SkDocument.h" 12 #include "SkXPSDevice.h" 13 #include "SkStream.h" 14 15 class SkDocument_XPS : public SkDocument { 16 public: 17 SkDocument_XPS(SkWStream* stream, 18 void (*doneProc)(SkWStream*, bool), 19 SkScalar dpi) 20 : SkDocument(stream, doneProc) { 21 const SkScalar kPointsPerMeter = SkDoubleToScalar(360000.0 / 127.0); 22 fUnitsPerMeter.set(kPointsPerMeter, kPointsPerMeter); 23 SkScalar pixelsPerMeterScale = SkDoubleToScalar(dpi * 5000.0 / 127.0); 24 fPixelsPerMeter.set(pixelsPerMeterScale, pixelsPerMeterScale); 25 fDevice.beginPortfolio(stream); 26 } 27 28 virtual ~SkDocument_XPS() { 29 // subclasses must call close() in their destructors 30 this->close(); 31 } 32 33 protected: 34 SkCanvas* onBeginPage(SkScalar width, 35 SkScalar height, 36 const SkRect& trimBox) override { 37 fDevice.beginSheet(fUnitsPerMeter, fPixelsPerMeter, 38 SkSize::Make(width, height)); 39 fCanvas.reset(new SkCanvas(&fDevice)); 40 fCanvas->clipRect(trimBox); 41 fCanvas->translate(trimBox.x(), trimBox.y()); 42 return fCanvas.get(); 43 } 44 45 void onEndPage() override { 46 SkASSERT(fCanvas.get()); 47 fCanvas->flush(); 48 fCanvas.reset(nullptr); 49 fDevice.endSheet(); 50 } 51 52 bool onClose(SkWStream*) override { 53 SkASSERT(!fCanvas.get()); 54 return fDevice.endPortfolio(); 55 } 56 57 void onAbort() override {} 58 59 private: 60 SkXPSDevice fDevice; 61 SkAutoTUnref<SkCanvas> fCanvas; 62 SkVector fUnitsPerMeter; 63 SkVector fPixelsPerMeter; 64 }; 65 66 /////////////////////////////////////////////////////////////////////////////// 67 68 SkDocument* SkDocument::CreateXPS(SkWStream* stream, SkScalar dpi) { 69 return stream ? new SkDocument_XPS(stream, nullptr, dpi) : nullptr; 70 } 71 72 static void delete_wstream(SkWStream* stream, bool aborted) { delete stream; } 73 74 SkDocument* SkDocument::CreateXPS(const char path[], SkScalar dpi) { 75 SkAutoTDelete<SkFILEWStream> stream(new SkFILEWStream(path)); 76 if (!stream->isValid()) { 77 return nullptr; 78 } 79 return new SkDocument_XPS(stream.detach(), delete_wstream, dpi); 80 } 81 82 #endif//defined(SK_BUILD_FOR_WIN32) 83