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 12class SkDocument_XPS : public SkDocument { 13public: 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 25 virtual ~SkDocument_XPS() { 26 // subclasses must call close() in their destructors 27 this->close(); 28 } 29 30protected: 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 42 void onEndPage() override { 43 SkASSERT(fCanvas.get()); 44 fCanvas->flush(); 45 fCanvas.reset(NULL); 46 fDevice.endSheet(); 47 } 48 49 bool onClose(SkWStream*) override { 50 SkASSERT(!fCanvas.get()); 51 return fDevice.endPortfolio(); 52 } 53 54 void onAbort() override {} 55 56private: 57 SkXPSDevice fDevice; 58 SkAutoTUnref<SkCanvas> fCanvas; 59 SkVector fUnitsPerMeter; 60 SkVector fPixelsPerMeter; 61}; 62 63/////////////////////////////////////////////////////////////////////////////// 64 65SkDocument* SkDocument::CreateXPS(SkWStream* stream, SkScalar dpi) { 66 return stream ? SkNEW_ARGS(SkDocument_XPS, (stream, NULL, dpi)) : NULL; 67} 68 69static void delete_wstream(SkWStream* stream, bool aborted) { 70 SkDELETE(stream); 71} 72 73SkDocument* 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