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 15class SkDocument_XPS : public SkDocument { 16public: 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 33protected: 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 59private: 60 SkXPSDevice fDevice; 61 SkAutoTUnref<SkCanvas> fCanvas; 62 SkVector fUnitsPerMeter; 63 SkVector fPixelsPerMeter; 64}; 65 66/////////////////////////////////////////////////////////////////////////////// 67 68SkDocument* SkDocument::CreateXPS(SkWStream* stream, SkScalar dpi) { 69 return stream ? new SkDocument_XPS(stream, nullptr, dpi) : nullptr; 70} 71 72static void delete_wstream(SkWStream* stream, bool aborted) { delete stream; } 73 74SkDocument* 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