| /* | 
 |  * 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 "include/core/SkTypes.h" | 
 | #if defined(SK_BUILD_FOR_WIN) | 
 |  | 
 | #include "include/docs/SkXPSDocument.h" | 
 |  | 
 | #include "include/core/SkStream.h" | 
 | #include "src/utils/win/SkHRESULT.h" | 
 | #include "src/utils/win/SkTScopedComPtr.h" | 
 | #include "src/xps/SkXPSDevice.h" | 
 |  | 
 | #include <XpsObjectModel.h> | 
 |  | 
 | namespace { | 
 | struct SkXPSDocument final : public SkDocument { | 
 |     SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory; | 
 |     SkXPSDevice fDevice; | 
 |     std::unique_ptr<SkCanvas> fCanvas; | 
 |     SkVector fUnitsPerMeter; | 
 |     SkVector fPixelsPerMeter; | 
 |  | 
 |     SkXPSDocument(SkWStream*, SkScalar dpi, SkTScopedComPtr<IXpsOMObjectFactory>); | 
 |     ~SkXPSDocument() override; | 
 |     SkCanvas* onBeginPage(SkScalar w, SkScalar h) override; | 
 |     void onEndPage() override; | 
 |     void onClose(SkWStream*) override; | 
 |     void onAbort() override; | 
 | }; | 
 | } | 
 |  | 
 | SkXPSDocument::SkXPSDocument(SkWStream* stream, | 
 |                    SkScalar dpi, | 
 |                    SkTScopedComPtr<IXpsOMObjectFactory> xpsFactory) | 
 |         : SkDocument(stream) | 
 |         , fXpsFactory(std::move(xpsFactory)) | 
 |         , fDevice(SkISize{10000, 10000}) | 
 | { | 
 |     const SkScalar kPointsPerMeter = SkDoubleToScalar(360000.0 / 127.0); | 
 |     fUnitsPerMeter.set(kPointsPerMeter, kPointsPerMeter); | 
 |     SkScalar pixelsPerMeterScale = SkDoubleToScalar(dpi * 5000.0 / 127.0); | 
 |     fPixelsPerMeter.set(pixelsPerMeterScale, pixelsPerMeterScale); | 
 |     SkASSERT(fXpsFactory); | 
 |     fDevice.beginPortfolio(stream, fXpsFactory.get()); | 
 | } | 
 |  | 
 | SkXPSDocument::~SkXPSDocument() { | 
 |     // subclasses must call close() in their destructors | 
 |     this->close(); | 
 | } | 
 |  | 
 | SkCanvas* SkXPSDocument::onBeginPage(SkScalar width, SkScalar height) { | 
 |     fDevice.beginSheet(fUnitsPerMeter, fPixelsPerMeter, {width, height}); | 
 |     fCanvas.reset(new SkCanvas(sk_ref_sp(&fDevice))); | 
 |     return fCanvas.get(); | 
 | } | 
 |  | 
 | void SkXPSDocument::onEndPage() { | 
 |     SkASSERT(fCanvas.get()); | 
 |     fCanvas.reset(nullptr); | 
 |     fDevice.endSheet(); | 
 | } | 
 |  | 
 | void SkXPSDocument::onClose(SkWStream*) { | 
 |     SkASSERT(!fCanvas.get()); | 
 |     (void)fDevice.endPortfolio(); | 
 | } | 
 |  | 
 | void SkXPSDocument::onAbort() {} | 
 |  | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | sk_sp<SkDocument> SkXPS::MakeDocument(SkWStream* stream, | 
 |                                       IXpsOMObjectFactory* factoryPtr, | 
 |                                       SkScalar dpi) { | 
 |     SkTScopedComPtr<IXpsOMObjectFactory> factory(SkSafeRefComPtr(factoryPtr)); | 
 |     return stream && factory | 
 |            ? sk_make_sp<SkXPSDocument>(stream, dpi, std::move(factory)) | 
 |            : nullptr; | 
 | } | 
 | #endif  // defined(SK_BUILD_FOR_WIN) |