|  | /* | 
|  | * Copyright 2015 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #include "SkDocument.h" | 
|  | #include "SkXPSDevice.h" | 
|  | #include "SkStream.h" | 
|  |  | 
|  | class SkDocument_XPS : public SkDocument { | 
|  | public: | 
|  | SkDocument_XPS(SkWStream* stream, | 
|  | void (*doneProc)(SkWStream*, bool), | 
|  | SkScalar dpi) | 
|  | : SkDocument(stream, doneProc) { | 
|  | const SkScalar kPointsPerMeter = SkDoubleToScalar(360000.0 / 127.0); | 
|  | fUnitsPerMeter.set(kPointsPerMeter, kPointsPerMeter); | 
|  | SkScalar pixelsPerMeterScale = SkDoubleToScalar(dpi * 5000.0 / 127.0); | 
|  | fPixelsPerMeter.set(pixelsPerMeterScale, pixelsPerMeterScale); | 
|  | fDevice.beginPortfolio(stream); | 
|  | } | 
|  |  | 
|  | virtual ~SkDocument_XPS() { | 
|  | // subclasses must call close() in their destructors | 
|  | this->close(); | 
|  | } | 
|  |  | 
|  | protected: | 
|  | SkCanvas* onBeginPage(SkScalar width, | 
|  | SkScalar height, | 
|  | const SkRect& trimBox) override { | 
|  | fDevice.beginSheet(fUnitsPerMeter, fPixelsPerMeter, | 
|  | SkSize::Make(width, height)); | 
|  | fCanvas.reset(SkNEW_ARGS(SkCanvas, (&fDevice))); | 
|  | fCanvas->clipRect(trimBox); | 
|  | fCanvas->translate(trimBox.x(), trimBox.y()); | 
|  | return fCanvas.get(); | 
|  | } | 
|  |  | 
|  | void onEndPage() override { | 
|  | SkASSERT(fCanvas.get()); | 
|  | fCanvas->flush(); | 
|  | fCanvas.reset(NULL); | 
|  | fDevice.endSheet(); | 
|  | } | 
|  |  | 
|  | bool onClose(SkWStream*) override { | 
|  | SkASSERT(!fCanvas.get()); | 
|  | return fDevice.endPortfolio(); | 
|  | } | 
|  |  | 
|  | void onAbort() override {} | 
|  |  | 
|  | private: | 
|  | SkXPSDevice fDevice; | 
|  | SkAutoTUnref<SkCanvas> fCanvas; | 
|  | SkVector fUnitsPerMeter; | 
|  | SkVector fPixelsPerMeter; | 
|  | }; | 
|  |  | 
|  | /////////////////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | SkDocument* SkDocument::CreateXPS(SkWStream* stream, SkScalar dpi) { | 
|  | return stream ? SkNEW_ARGS(SkDocument_XPS, (stream, NULL, dpi)) : NULL; | 
|  | } | 
|  |  | 
|  | static void delete_wstream(SkWStream* stream, bool aborted) { | 
|  | SkDELETE(stream); | 
|  | } | 
|  |  | 
|  | SkDocument* SkDocument::CreateXPS(const char path[], SkScalar dpi) { | 
|  | SkAutoTDelete<SkFILEWStream> stream(SkNEW_ARGS(SkFILEWStream, (path))); | 
|  | if (!stream->isValid()) { | 
|  | return NULL; | 
|  | } | 
|  | return SkNEW_ARGS(SkDocument_XPS, (stream.detach(), delete_wstream, dpi)); | 
|  | } |