SkXPS: new document API.
authorHal Canary <halcanary@google.com>
Mon, 6 Feb 2017 14:51:42 +0000 (09:51 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Mon, 6 Feb 2017 19:00:28 +0000 (19:00 +0000)
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>

dm/DMSrcSink.cpp
gn/xps.gni
include/core/SkDocument.h
src/xps/SkDocument_XPS_None.cpp [deleted file]
src/xps/SkXPSDocument.cpp
src/xps/SkXPSDocument.h

index 75f5973..88b1963 100644 (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
 
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
index 570b573..eb6122c 100644 (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",
 ]
index 64291fb..6594511 100644 (file)
 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
diff --git a/src/xps/SkDocument_XPS_None.cpp b/src/xps/SkDocument_XPS_None.cpp
deleted file mode 100644 (file)
index b1c7ed4..0000000
+++ /dev/null
@@ -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)
index 6867227..80dd5ee 100644 (file)
 #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;
 }
 
index fbaf57b..726af8f 100644 (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: