diff options
author | Hal Canary <halcanary@google.com> | 2017-02-06 09:26:49 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-06 17:13:38 +0000 |
commit | abc88d26365efa14b58d26ca3b8fbfb58a7dcbad (patch) | |
tree | fb67e60271b59650ff09dba4c4cfdce1fa8393e1 | |
parent | ef46b2f8e44e45b6cb9723df09ddbc5493afd3e9 (diff) |
SkXPS: Begin refactoring SkXPSDevice
A later CL will move all document-level fields and methods into
SkXPSDocument.
* SkXPSDocument cnstructor requires a xps factory ptr.
* All device layers share ownership of a single factory.
* renames SkDocument_XPS to the easier-to-say SkXPSDocument.
* Moves autocoinitialize to DM.
TODO: pipe the IXpsOMObjectFactory* into the SkDocument api.
No change in rendered documents.
Change-Id: I8a4680a3603951b1ce5f6c1de48714d4902061a9
Reviewed-on: https://skia-review.googlesource.com/7998
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
-rw-r--r-- | dm/DMSrcSink.cpp | 6 | ||||
-rw-r--r-- | gn/xps.gni | 3 | ||||
-rw-r--r-- | src/xps/SkDocument_XPS.cpp | 84 | ||||
-rw-r--r-- | src/xps/SkXPSDevice.cpp | 60 | ||||
-rw-r--r-- | src/xps/SkXPSDevice.h | 5 | ||||
-rw-r--r-- | src/xps/SkXPSDocument.cpp | 104 | ||||
-rw-r--r-- | src/xps/SkXPSDocument.h | 42 |
7 files changed, 174 insertions, 130 deletions
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 16ec5ca44a..75f59738e3 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -1333,6 +1333,12 @@ Error PDFSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const XPSSink::XPSSink() {} Error XPSSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const { +#ifdef SK_BUILD_FOR_WIN + SkAutoCoInitialize com; + if (!com.succeeded()) { + return "Could not initialize COM."; + } +#endif sk_sp<SkDocument> doc(SkDocument::MakeXPS(dst)); if (!doc) { return "SkDocument::MakeXPS() returned nullptr"; diff --git a/gn/xps.gni b/gn/xps.gni index d551f9f687..570b5730a1 100644 --- a/gn/xps.gni +++ b/gn/xps.gni @@ -7,7 +7,8 @@ _src = get_path_info("../src", "abspath") skia_xps_sources = [ - "$_src/xps/SkDocument_XPS.cpp", + "$_src/xps/SkXPSDocument.cpp", + "$_src/xps/SkXPSDocument.h", "$_src/xps/SkXPSDevice.cpp", "$_src/xps/SkXPSDevice.h", "$_src/xps/SkDocument_XPS_None.cpp", diff --git a/src/xps/SkDocument_XPS.cpp b/src/xps/SkDocument_XPS.cpp deleted file mode 100644 index 06fd06710c..0000000000 --- a/src/xps/SkDocument_XPS.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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 "SkTypes.h" -#if defined(SK_BUILD_FOR_WIN32) - -#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) - , 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); - 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(new SkCanvas(&fDevice)); - fCanvas->clipRect(trimBox); - fCanvas->translate(trimBox.x(), trimBox.y()); - return fCanvas.get(); - } - - void onEndPage() override { - SkASSERT(fCanvas.get()); - fCanvas->flush(); - fCanvas.reset(nullptr); - fDevice.endSheet(); - } - - void onClose(SkWStream*) override { - SkASSERT(!fCanvas.get()); - (void)fDevice.endPortfolio(); - } - - void onAbort() override {} - -private: - SkXPSDevice fDevice; - std::unique_ptr<SkCanvas> fCanvas; - SkVector fUnitsPerMeter; - SkVector fPixelsPerMeter; -}; - -/////////////////////////////////////////////////////////////////////////////// - -sk_sp<SkDocument> SkDocument::MakeXPS(SkWStream* stream, SkScalar dpi) { - return stream ? sk_make_sp<SkDocument_XPS>(stream, nullptr, dpi) : nullptr; -} - -static void delete_wstream(SkWStream* stream, bool aborted) { delete stream; } - -sk_sp<SkDocument> SkDocument::MakeXPS(const char path[], SkScalar dpi) { - std::unique_ptr<SkFILEWStream> stream(new SkFILEWStream(path)); - if (!stream->isValid()) { - return nullptr; - } - return sk_make_sp<SkDocument_XPS>(stream.release(), delete_wstream, dpi); -} - -#endif//defined(SK_BUILD_FOR_WIN32) diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp index aa6ec7cead..8dca7f0156 100644 --- a/src/xps/SkXPSDevice.cpp +++ b/src/xps/SkXPSDevice.cpp @@ -111,38 +111,18 @@ HRESULT SkXPSDevice::createId(wchar_t* buffer, size_t bufferSize, wchar_t sep) { return S_OK; } -// TODO: should inherit from SkBaseDevice instead of SkBitmapDevice... SkXPSDevice::SkXPSDevice(SkISize s) : INHERITED(SkImageInfo::MakeUnknown(s.width(), s.height()), SkSurfaceProps(0, kUnknown_SkPixelGeometry)) - , fCurrentPage(0) { -} - -SkXPSDevice::SkXPSDevice(SkISize s, IXpsOMObjectFactory* xpsFactory) - : INHERITED(SkImageInfo::MakeUnknown(s.width(), s.height()), - SkSurfaceProps(0, kUnknown_SkPixelGeometry)) - , fCurrentPage(0) { + , fCurrentPage(0) {} - HRVM(CoCreateInstance( - CLSID_XpsOMObjectFactory, - nullptr, - CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&this->fXpsFactory)), - "Could not create factory for layer."); - - HRVM(this->fXpsFactory->CreateCanvas(&this->fCurrentXpsCanvas), - "Could not create canvas for layer."); -} - -SkXPSDevice::~SkXPSDevice() { -} +SkXPSDevice::~SkXPSDevice() {} SkXPSDevice::TypefaceUse::TypefaceUse() : typefaceId(0xffffffff) , fontData(nullptr) , xpsFont(nullptr) - , glyphsUsed(nullptr) { -} + , glyphsUsed(nullptr) {} SkXPSDevice::TypefaceUse::~TypefaceUse() { //xpsFont owns fontData ref @@ -150,20 +130,10 @@ SkXPSDevice::TypefaceUse::~TypefaceUse() { delete this->glyphsUsed; } -bool SkXPSDevice::beginPortfolio(SkWStream* outputStream) { - if (!this->fAutoCo.succeeded()) return false; - - //Create XPS Factory. - HRBM(CoCreateInstance( - CLSID_XpsOMObjectFactory, - nullptr, - CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&this->fXpsFactory)), - "Could not create XPS factory."); - - HRBM(SkWIStream::CreateFromSkWStream(outputStream, &this->fOutputStream), - "Could not convert SkStream to IStream."); - +bool SkXPSDevice::beginPortfolio(SkWStream* outputStream, IXpsOMObjectFactory* factory) { + SkASSERT(factory); + fXpsFactory.reset(SkRefComPtr(factory)); + HRB(SkWIStream::CreateFromSkWStream(outputStream, &this->fOutputStream)); return true; } @@ -182,11 +152,13 @@ bool SkXPSDevice::beginSheet( this->fCurrentCanvasSize = trimSize; this->fCurrentUnitsPerMeter = unitsPerMeter; this->fCurrentPixelsPerMeter = pixelsPerMeter; + return this->createCanvasForLayer(); +} - this->fCurrentXpsCanvas.reset(); - HRBM(this->fXpsFactory->CreateCanvas(&this->fCurrentXpsCanvas), - "Could not create base canvas."); - +bool SkXPSDevice::createCanvasForLayer() { + SkASSERT(fXpsFactory); + fCurrentXpsCanvas.reset(); + HRB(fXpsFactory->CreateCanvas(&fCurrentXpsCanvas)); return true; } @@ -2278,7 +2250,11 @@ SkBaseDevice* SkXPSDevice::onCreateDevice(const CreateInfo& info, const SkPaint* //return dev; } #endif - return new SkXPSDevice(info.fInfo.dimensions(), this->fXpsFactory.get()); + SkXPSDevice* dev = new SkXPSDevice(info.fInfo.dimensions()); + // TODO(halcanary) implement copy constructor on SkTScopedCOmPtr + dev->fXpsFactory.reset(SkRefComPtr(fXpsFactory.get())); + SkAssertResult(dev->createCanvasForLayer()); + return dev; } void SkXPSDevice::drawOval(const SkDraw& d, const SkRect& o, const SkPaint& p) { diff --git a/src/xps/SkXPSDevice.h b/src/xps/SkXPSDevice.h index db8436d5e8..0ad9939509 100644 --- a/src/xps/SkXPSDevice.h +++ b/src/xps/SkXPSDevice.h @@ -40,7 +40,7 @@ public: SK_API SkXPSDevice(SkISize); SK_API virtual ~SkXPSDevice(); - bool beginPortfolio(SkWStream* outputStream); + bool beginPortfolio(SkWStream* outputStream, IXpsOMObjectFactory*); /** @param unitsPerMeter converts geometry units into physical units. @param pixelsPerMeter resolution to use when geometry must be rasterized. @@ -161,9 +161,8 @@ private: }; friend HRESULT subset_typeface(TypefaceUse* current); - SkXPSDevice(SkISize, IXpsOMObjectFactory*); + bool createCanvasForLayer(); - SkAutoCoInitialize fAutoCo; SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory; SkTScopedComPtr<IStream> fOutputStream; SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter; diff --git a/src/xps/SkXPSDocument.cpp b/src/xps/SkXPSDocument.cpp new file mode 100644 index 0000000000..68672271e8 --- /dev/null +++ b/src/xps/SkXPSDocument.cpp @@ -0,0 +1,104 @@ +/* + * 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 "SkTypes.h" +#if defined(SK_BUILD_FOR_WIN32) + +#include "SkXPSDocument.h" +#include "SkStream.h" +#include "SkHRESULT.h" + +SkXPSDocument::SkXPSDocument(SkWStream* stream, + void (*doneProc)(SkWStream*, bool), + SkScalar dpi, + SkTScopedComPtr<IXpsOMObjectFactory> xpsFactory) + : SkDocument(stream, doneProc) + , 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, + const SkRect& trimBox) { + fDevice.beginSheet(fUnitsPerMeter, fPixelsPerMeter, + SkSize::Make(width, height)); + fCanvas.reset(new SkCanvas(&fDevice)); + fCanvas->clipRect(trimBox); + fCanvas->translate(trimBox.x(), trimBox.y()); + return fCanvas.get(); +} + +void SkXPSDocument::onEndPage() { + SkASSERT(fCanvas.get()); + fCanvas->flush(); + fCanvas.reset(nullptr); + fDevice.endSheet(); +} + +void SkXPSDocument::onClose(SkWStream*) { + SkASSERT(!fCanvas.get()); + (void)fDevice.endPortfolio(); +} + +void SkXPSDocument::onAbort() {} + + +static SkTScopedComPtr<IXpsOMObjectFactory> make_xps_factory() { + IXpsOMObjectFactory* factory; + HRN(CoCreateInstance(CLSID_XpsOMObjectFactory, + nullptr, + CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&factory))); + return SkTScopedComPtr<IXpsOMObjectFactory>(factory); +} + + +/////////////////////////////////////////////////////////////////////////////// + +// TODO(halcanary, reed): modify the SkDocument API to take a IXpsOMObjectFactory* pointer. +/* +sk_sp<SkDocument> SkDocument::MakeXPS(SkWStream* stream, + IXpsOMObjectFactory* factoryPtr, + SkScalar dpi) { + SkTScopedComPtr<IXpsOMObjectFactory> factory(SkSafeRefComPtr(factoryPtr)); + return stream && factory + ? sk_make_sp<SkXPSDocument>(stream, nullptr, dpi, std::move(factory)) + : nullptr; +} +*/ + +sk_sp<SkDocument> SkDocument::MakeXPS(SkWStream* stream, SkScalar dpi) { + auto factory = make_xps_factory(); + return stream && factory + ? sk_make_sp<SkXPSDocument>(stream, nullptr, dpi, std::move(factory)) + : nullptr; +} + +sk_sp<SkDocument> SkDocument::MakeXPS(const char path[], SkScalar dpi) { + std::unique_ptr<SkFILEWStream> stream(new SkFILEWStream(path)); + auto factory = make_xps_factory(); + return stream->isValid() && factory + ? sk_make_sp<SkXPSDocument>(stream.release(), + [](SkWStream* s, bool) { delete s; }, + dpi, std::move(factory)) + : nullptr; +} + +#endif//defined(SK_BUILD_FOR_WIN32) diff --git a/src/xps/SkXPSDocument.h b/src/xps/SkXPSDocument.h new file mode 100644 index 0000000000..fbaf57b36f --- /dev/null +++ b/src/xps/SkXPSDocument.h @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkXPSDocument_DEFINED +#define SkXPSDocument_DEFINED + +#include "SkTypes.h" + +#ifdef SK_BUILD_FOR_WIN + +#include "SkDocument.h" +#include "SkXPSDevice.h" +#include "SkTScopedComPtr.h" + +#include <XpsObjectModel.h> + +class SkXPSDocument final : public SkDocument { +public: + SkXPSDocument(SkWStream*, void (*doneProc)(SkWStream*, bool abort), + SkScalar dpi, SkTScopedComPtr<IXpsOMObjectFactory>); + virtual ~SkXPSDocument(); + +protected: + SkCanvas* onBeginPage(SkScalar w, SkScalar h, const SkRect&) override; + void onEndPage() override; + void onClose(SkWStream*) override; + void onAbort() override; + +private: + SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory; + SkXPSDevice fDevice; + std::unique_ptr<SkCanvas> fCanvas; + SkVector fUnitsPerMeter; + SkVector fPixelsPerMeter; +}; + +#endif // SK_BUILD_FOR_WIN +#endif // SkXPSDocument_DEFINED |