SkXPS: new document API.

Now requires a IXpsOMObjectFactory pointer.  This will allow sandboxing
to be used in Chromium.  (Chrome will create a IXpsOMObjectFactory, then
go into sandbox mode, then call SkDocumenent::MakeXPS().)

Change-Id: Ic4b48d4b148c44e188d12a9481fb74735546528a
Reviewed-on: https://skia-review.googlesource.com/8052
Reviewed-by: Ben Wagner <bungeman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
Hal Canary 2017-02-06 09:51:42 -05:00 committed by Skia Commit-Bot
parent 604971e39a
commit 5e221e7ca2
6 changed files with 53 additions and 65 deletions

View File

@ -45,6 +45,9 @@
#if defined(SK_BUILD_FOR_WIN)
#include "SkAutoCoInitialize.h"
#include "SkHRESULT.h"
#include "SkTScopedComPtr.h"
#include <XpsObjectModel.h>
#endif
#if defined(SK_XML)
@ -1332,19 +1335,36 @@ 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
static SkTScopedComPtr<IXpsOMObjectFactory> make_xps_factory() {
IXpsOMObjectFactory* factory;
HRN(CoCreateInstance(CLSID_XpsOMObjectFactory,
nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&factory)));
return SkTScopedComPtr<IXpsOMObjectFactory>(factory);
}
Error XPSSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const {
SkAutoCoInitialize com;
if (!com.succeeded()) {
return "Could not initialize COM.";
}
#endif
sk_sp<SkDocument> doc(SkDocument::MakeXPS(dst));
SkTScopedComPtr<IXpsOMObjectFactory> factory = make_xps_factory();
if (!factory) {
return "Failed to create XPS Factory.";
}
sk_sp<SkDocument> doc(SkDocument::MakeXPS(dst, factory.get()));
if (!doc) {
return "SkDocument::MakeXPS() returned nullptr";
}
return draw_skdocument(src, doc.get(), dst);
}
#else
Error XPSSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const {
return "XPS not supported on this platform.";
}
#endif
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

View File

@ -11,5 +11,4 @@ skia_xps_sources = [
"$_src/xps/SkXPSDocument.h",
"$_src/xps/SkXPSDevice.cpp",
"$_src/xps/SkXPSDevice.h",
"$_src/xps/SkDocument_XPS_None.cpp",
]

View File

@ -19,6 +19,10 @@
class SkCanvas;
class SkWStream;
#ifdef SK_BUILD_FOR_WIN
struct IXpsOMObjectFactory;
#endif
/** SK_ScalarDefaultDPI is 72 DPI.
*/
#define SK_ScalarDefaultRasterDPI 72.0f
@ -141,19 +145,34 @@ public:
static sk_sp<SkDocument> MakePDF(const char outputFilePath[],
SkScalar dpi = SK_ScalarDefaultRasterDPI);
#ifdef SK_BUILD_FOR_WIN
/**
* Create a XPS-backed document, writing the results into the stream.
* Returns NULL if XPS is not supported.
*
* @param stream A XPS document will be written to this stream. The
* document may write to the stream at anytime during its
* lifetime, until either close() or abort() are called or
* the document is deleted.
* @param xpsFactory A pointer to a COM XPS factory. Must be non-null.
* The document will take a ref to the factory. See
* dm/DMSrcSink.cpp for an example.
* @param dpi The DPI (pixels-per-inch) at which features without
* native XPS support will be rasterized (e.g. draw image
* with perspective, draw text with perspective, ...) A
* larger DPI would create a XPS that reflects the
* original intent with better fidelity, but it can make
* for larger XPS files too, which would use more memory
* while rendering, and it would be slower to be processed
* or sent online or to printer.
*
* @returns nullptr if XPS is not supported.
*/
static sk_sp<SkDocument> MakeXPS(SkWStream* stream,
IXpsOMObjectFactory* xpsFactory,
SkScalar dpi = SK_ScalarDefaultRasterDPI);
/**
* Create a XPS-backed document, writing the results into a file.
* Returns NULL if XPS is not supported.
*/
static sk_sp<SkDocument> MakeXPS(const char path[],
SkScalar dpi = SK_ScalarDefaultRasterDPI);
#endif
// DEPRECATED; TODO(halcanary): remove this function after Chromium switches to new API.
static sk_sp<SkDocument> MakeXPS(SkWStream*) { return nullptr; }
/**
* Begin a new page for the document, returning the canvas that will draw

View File

@ -1,17 +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"
sk_sp<SkDocument> SkDocument::MakeXPS(SkWStream*, SkScalar) { return nullptr; }
sk_sp<SkDocument> SkDocument::MakeXPS(const char path[], SkScalar) {
return nullptr;
}
#endif//!defined(SK_BUILD_FOR_WIN32)

View File

@ -14,10 +14,9 @@
#include "SkHRESULT.h"
SkXPSDocument::SkXPSDocument(SkWStream* stream,
void (*doneProc)(SkWStream*, bool),
SkScalar dpi,
SkTScopedComPtr<IXpsOMObjectFactory> xpsFactory)
: SkDocument(stream, doneProc)
: SkDocument(stream, nullptr)
, fXpsFactory(std::move(xpsFactory))
, fDevice(SkISize{10000, 10000})
{
@ -59,45 +58,14 @@ void SkXPSDocument::onClose(SkWStream*) {
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))
? sk_make_sp<SkXPSDocument>(stream, dpi, std::move(factory))
: nullptr;
}

View File

@ -20,8 +20,7 @@
class SkXPSDocument final : public SkDocument {
public:
SkXPSDocument(SkWStream*, void (*doneProc)(SkWStream*, bool abort),
SkScalar dpi, SkTScopedComPtr<IXpsOMObjectFactory>);
SkXPSDocument(SkWStream*, SkScalar dpi, SkTScopedComPtr<IXpsOMObjectFactory>);
virtual ~SkXPSDocument();
protected: