SkXPSDocument.cpp 2.6 KB

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