From abc88d26365efa14b58d26ca3b8fbfb58a7dcbad Mon Sep 17 00:00:00 2001 From: Hal Canary Date: Mon, 6 Feb 2017 09:26:49 -0500 Subject: 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 Commit-Queue: Hal Canary --- src/xps/SkDocument_XPS.cpp | 84 ------------------------------------ src/xps/SkXPSDevice.cpp | 60 ++++++++------------------ src/xps/SkXPSDevice.h | 5 +-- src/xps/SkXPSDocument.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++++ src/xps/SkXPSDocument.h | 42 ++++++++++++++++++ 5 files changed, 166 insertions(+), 129 deletions(-) delete mode 100644 src/xps/SkDocument_XPS.cpp create mode 100644 src/xps/SkXPSDocument.cpp create mode 100644 src/xps/SkXPSDocument.h (limited to 'src/xps') 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 fCanvas; - SkVector fUnitsPerMeter; - SkVector fPixelsPerMeter; -}; - -/////////////////////////////////////////////////////////////////////////////// - -sk_sp SkDocument::MakeXPS(SkWStream* stream, SkScalar dpi) { - return stream ? sk_make_sp(stream, nullptr, dpi) : nullptr; -} - -static void delete_wstream(SkWStream* stream, bool aborted) { delete stream; } - -sk_sp SkDocument::MakeXPS(const char path[], SkScalar dpi) { - std::unique_ptr stream(new SkFILEWStream(path)); - if (!stream->isValid()) { - return nullptr; - } - return sk_make_sp(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 fXpsFactory; SkTScopedComPtr fOutputStream; SkTScopedComPtr 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 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 make_xps_factory() { + IXpsOMObjectFactory* factory; + HRN(CoCreateInstance(CLSID_XpsOMObjectFactory, + nullptr, + CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&factory))); + return SkTScopedComPtr(factory); +} + + +/////////////////////////////////////////////////////////////////////////////// + +// TODO(halcanary, reed): modify the SkDocument API to take a IXpsOMObjectFactory* pointer. +/* +sk_sp SkDocument::MakeXPS(SkWStream* stream, + IXpsOMObjectFactory* factoryPtr, + SkScalar dpi) { + SkTScopedComPtr factory(SkSafeRefComPtr(factoryPtr)); + return stream && factory + ? sk_make_sp(stream, nullptr, dpi, std::move(factory)) + : nullptr; +} +*/ + +sk_sp SkDocument::MakeXPS(SkWStream* stream, SkScalar dpi) { + auto factory = make_xps_factory(); + return stream && factory + ? sk_make_sp(stream, nullptr, dpi, std::move(factory)) + : nullptr; +} + +sk_sp SkDocument::MakeXPS(const char path[], SkScalar dpi) { + std::unique_ptr stream(new SkFILEWStream(path)); + auto factory = make_xps_factory(); + return stream->isValid() && factory + ? sk_make_sp(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 + +class SkXPSDocument final : public SkDocument { +public: + SkXPSDocument(SkWStream*, void (*doneProc)(SkWStream*, bool abort), + SkScalar dpi, SkTScopedComPtr); + virtual ~SkXPSDocument(); + +protected: + SkCanvas* onBeginPage(SkScalar w, SkScalar h, const SkRect&) override; + void onEndPage() override; + void onClose(SkWStream*) override; + void onAbort() override; + +private: + SkTScopedComPtr fXpsFactory; + SkXPSDevice fDevice; + std::unique_ptr fCanvas; + SkVector fUnitsPerMeter; + SkVector fPixelsPerMeter; +}; + +#endif // SK_BUILD_FOR_WIN +#endif // SkXPSDocument_DEFINED -- cgit v1.2.3