• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/core/SkTypes.h"
9 #if defined(SK_BUILD_FOR_WIN)
10 
11 #include "include/docs/SkXPSDocument.h"
12 
13 #include "include/core/SkStream.h"
14 #include "src/utils/win/SkHRESULT.h"
15 #include "src/utils/win/SkTScopedComPtr.h"
16 #include "src/xps/SkXPSDevice.h"
17 
18 // #include <XpsObjectModel.h>
19 #include <xpsobjectmodel.h>
20 
21 namespace {
22 struct SkXPSDocument final : public SkDocument {
23     SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory;
24     SkXPSDevice fDevice;
25     std::unique_ptr<SkCanvas> fCanvas;
26     SkVector fUnitsPerMeter;
27     SkVector fPixelsPerMeter;
28 
29     SkXPSDocument(SkWStream*, SkScalar dpi, SkTScopedComPtr<IXpsOMObjectFactory>);
30     ~SkXPSDocument() override;
31     SkCanvas* onBeginPage(SkScalar w, SkScalar h) override;
32     void onEndPage() override;
33     void onClose(SkWStream*) override;
34     void onAbort() override;
35 };
36 }
37 
SkXPSDocument(SkWStream * stream,SkScalar dpi,SkTScopedComPtr<IXpsOMObjectFactory> xpsFactory)38 SkXPSDocument::SkXPSDocument(SkWStream* stream,
39                    SkScalar dpi,
40                    SkTScopedComPtr<IXpsOMObjectFactory> xpsFactory)
41         : SkDocument(stream)
42         , fXpsFactory(std::move(xpsFactory))
43         , fDevice(SkISize{10000, 10000})
44 {
45     const SkScalar kPointsPerMeter = SkDoubleToScalar(360000.0 / 127.0);
46     fUnitsPerMeter.set(kPointsPerMeter, kPointsPerMeter);
47     SkScalar pixelsPerMeterScale = SkDoubleToScalar(dpi * 5000.0 / 127.0);
48     fPixelsPerMeter.set(pixelsPerMeterScale, pixelsPerMeterScale);
49     SkASSERT(fXpsFactory);
50     fDevice.beginPortfolio(stream, fXpsFactory.get());
51 }
52 
~SkXPSDocument()53 SkXPSDocument::~SkXPSDocument() {
54     // subclasses must call close() in their destructors
55     this->close();
56 }
57 
onBeginPage(SkScalar width,SkScalar height)58 SkCanvas* SkXPSDocument::onBeginPage(SkScalar width, SkScalar height) {
59     fDevice.beginSheet(fUnitsPerMeter, fPixelsPerMeter, {width, height});
60     fCanvas.reset(new SkCanvas(sk_ref_sp(&fDevice)));
61     return fCanvas.get();
62 }
63 
onEndPage()64 void SkXPSDocument::onEndPage() {
65     SkASSERT(fCanvas.get());
66     fCanvas.reset(nullptr);
67     fDevice.endSheet();
68 }
69 
onClose(SkWStream *)70 void SkXPSDocument::onClose(SkWStream*) {
71     SkASSERT(!fCanvas.get());
72     (void)fDevice.endPortfolio();
73 }
74 
onAbort()75 void SkXPSDocument::onAbort() {}
76 
77 ///////////////////////////////////////////////////////////////////////////////
78 
MakeDocument(SkWStream * stream,IXpsOMObjectFactory * factoryPtr,SkScalar dpi)79 sk_sp<SkDocument> SkXPS::MakeDocument(SkWStream* stream,
80                                       IXpsOMObjectFactory* factoryPtr,
81                                       SkScalar dpi) {
82     SkTScopedComPtr<IXpsOMObjectFactory> factory(SkSafeRefComPtr(factoryPtr));
83     return stream && factory
84            ? sk_make_sp<SkXPSDocument>(stream, dpi, std::move(factory))
85            : nullptr;
86 }
87 #endif  // defined(SK_BUILD_FOR_WIN)
88