| /* |
| * 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) |