aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Hal Canary <halcanary@google.com>2017-02-06 09:26:49 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-06 17:13:38 +0000
commitabc88d26365efa14b58d26ca3b8fbfb58a7dcbad (patch)
treefb67e60271b59650ff09dba4c4cfdce1fa8393e1
parentef46b2f8e44e45b6cb9723df09ddbc5493afd3e9 (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.cpp6
-rw-r--r--gn/xps.gni3
-rw-r--r--src/xps/SkDocument_XPS.cpp84
-rw-r--r--src/xps/SkXPSDevice.cpp60
-rw-r--r--src/xps/SkXPSDevice.h5
-rw-r--r--src/xps/SkXPSDocument.cpp104
-rw-r--r--src/xps/SkXPSDocument.h42
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