summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Storz <eduard.braun2@gmx.de>2019-07-07 18:18:30 +0000
committerPatrick Storz <eduard.braun2@gmx.de>2019-07-10 18:15:54 +0000
commit90b67c899f3a33f4ad8cf6e3d2da6ad57dd29e51 (patch)
treeb9cc15ddf5ad03533ab717da412ea87b7d60d71e
parentinkscape-version: offer variant without revision and date (diff)
downloadinkscape-90b67c899f3a33f4ad8cf6e3d2da6ad57dd29e51.tar.gz
inkscape-90b67c899f3a33f4ad8cf6e3d2da6ad57dd29e51.zip
cairo-renderer: set metadata in output
- metadata is taken from the SVG document; - fields that are compatible with the target format (and also supported by cairo) are set accordingly
-rw-r--r--src/extension/internal/cairo-render-context.cpp38
-rw-r--r--src/extension/internal/cairo-render-context.h18
-rw-r--r--src/extension/internal/cairo-renderer.cpp114
-rw-r--r--src/extension/internal/cairo-renderer.h4
4 files changed, 139 insertions, 35 deletions
diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp
index ab9f9e82f..2b4072336 100644
--- a/src/extension/internal/cairo-render-context.cpp
+++ b/src/extension/internal/cairo-render-context.cpp
@@ -885,6 +885,8 @@ CairoRenderContext::setupSurface(double width, double height)
break;
}
+ _setSurfaceMetadata(surface);
+
return _finishSurfaceSetup (surface, &ctm);
}
@@ -934,6 +936,42 @@ CairoRenderContext::_finishSurfaceSetup(cairo_surface_t *surface, cairo_matrix_t
return true;
}
+void
+CairoRenderContext::_setSurfaceMetadata(cairo_surface_t *surface)
+{
+ switch (_target) {
+#if defined CAIRO_HAS_PDF_SURFACE && CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 4)
+ case CAIRO_SURFACE_TYPE_PDF:
+ if (!_metadata.title.empty()) {
+ cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_TITLE, _metadata.title.c_str());
+ }
+ if (!_metadata.author.empty()) {
+ cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_AUTHOR, _metadata.author.c_str());
+ }
+ if (!_metadata.subject.empty()) {
+ cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_SUBJECT, _metadata.subject.c_str());
+ }
+ if (!_metadata.keywords.empty()) {
+ cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_KEYWORDS, _metadata.keywords.c_str());
+ }
+ if (!_metadata.creator.empty()) {
+ cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_CREATOR, _metadata.creator.c_str());
+ }
+ break;
+#endif
+#if defined CAIRO_HAS_PS_SURFACE
+ case CAIRO_SURFACE_TYPE_PS:
+ if (!_metadata.title.empty()) {
+ cairo_ps_surface_dsc_comment(surface, (Glib::ustring("%%Title: ") + _metadata.title).c_str());
+ }
+ if (!_metadata.copyright.empty()) {
+ cairo_ps_surface_dsc_comment(surface, (Glib::ustring("%%Copyright: ") + _metadata.copyright).c_str());
+ }
+ break;
+#endif
+ }
+}
+
bool
CairoRenderContext::finish(bool finish_surface)
{
diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h
index 12cdb522d..1ff5ddeec 100644
--- a/src/extension/internal/cairo-render-context.h
+++ b/src/extension/internal/cairo-render-context.h
@@ -64,6 +64,18 @@ struct CairoRenderState {
Geom::Affine transform; // the CTM
};
+// Metadata to set on the cairo surface (if the surface supports it)
+struct CairoRenderContextMetadata {
+ Glib::ustring title = "";
+ Glib::ustring author = "";
+ Glib::ustring subject = "";
+ Glib::ustring keywords = "";
+ Glib::ustring copyright = "";
+ Glib::ustring creator = "";
+ Glib::ustring cdate = ""; // currently unused
+ Glib::ustring mdate = ""; // currently unused
+};
+
class CairoRenderContext {
friend class CairoRenderer;
public:
@@ -105,7 +117,7 @@ public:
/** Creates the cairo_surface_t for the context with the
given width, height and with the currently set target
- surface type. */
+ surface type. Also sets supported metadata on the surface. */
bool setupSurface(double width, double height);
cairo_surface_t *getSurface();
@@ -208,6 +220,8 @@ protected:
CairoOmitTextPageState _omittext_state;
+ CairoRenderContextMetadata _metadata;
+
cairo_pattern_t *_createPatternForPaintServer(SPPaintServer const *const paintserver,
Geom::OptRect const &pbox, float alpha);
cairo_pattern_t *_createPatternPainter(SPPaintServer const *const paintserver, Geom::OptRect const &pbox);
@@ -216,6 +230,8 @@ protected:
unsigned int _showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoGlyphInfo> const &glyphtext, bool is_stroke);
bool _finishSurfaceSetup(cairo_surface_t *surface, cairo_matrix_t *ctm = nullptr);
+ void _setSurfaceMetadata(cairo_surface_t *surface);
+
void _setFillStyle(SPStyle const *style, Geom::OptRect const &pbox);
void _setStrokeStyle(SPStyle const *style, Geom::OptRect const &pbox);
diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp
index 27f024ca1..35531cb04 100644
--- a/src/extension/internal/cairo-renderer.cpp
+++ b/src/extension/internal/cairo-renderer.cpp
@@ -29,54 +29,59 @@
#include <csignal>
#include <cerrno>
-#include "libnrtype/Layout-TNG.h"
+
#include <2geom/transforms.h>
#include <2geom/pathvector.h>
-
+#include <cairo.h>
#include <glib.h>
-
#include <glibmm/i18n.h>
-#include "display/curve.h"
-#include "display/canvas-bpath.h"
+
+// include support for only the compiled-in surface types
+#ifdef CAIRO_HAS_PDF_SURFACE
+#include <cairo-pdf.h>
+#endif
+#ifdef CAIRO_HAS_PS_SURFACE
+#include <cairo-ps.h>
+#endif
+
+#include "cairo-render-context.h"
+#include "cairo-renderer.h"
+#include "document.h"
+#include "inkscape-version.h"
+#include "rdf.h"
+
#include "display/cairo-utils.h"
+#include "display/canvas-bpath.h"
+#include "display/curve.h"
+
+#include "extension/system.h"
+
+#include "helper/pixbuf-ops.h"
+#include "helper/png-write.h"
+
+#include "io/sys.h"
+
+#include "libnrtype/Layout-TNG.h"
+
#include "object/sp-anchor.h"
-#include "object/sp-item.h"
+#include "object/sp-clippath.h"
+#include "object/sp-flowtext.h"
+#include "object/sp-hatch-path.h"
+#include "object/sp-image.h"
#include "object/sp-item-group.h"
-#include "object/sp-marker.h"
+#include "object/sp-item.h"
#include "object/sp-linear-gradient.h"
+#include "object/sp-marker.h"
+#include "object/sp-mask.h"
+#include "object/sp-pattern.h"
#include "object/sp-radial-gradient.h"
#include "object/sp-root.h"
#include "object/sp-shape.h"
-#include "object/sp-use.h"
-#include "object/sp-text.h"
-#include "object/sp-flowtext.h"
-#include "object/sp-hatch-path.h"
-#include "object/sp-image.h"
#include "object/sp-symbol.h"
-#include "object/sp-pattern.h"
-#include "object/sp-mask.h"
-#include "object/sp-clippath.h"
+#include "object/sp-text.h"
+#include "object/sp-use.h"
#include "util/units.h"
-#include "helper/png-write.h"
-#include "helper/pixbuf-ops.h"
-
-#include "cairo-renderer.h"
-#include "cairo-render-context.h"
-#include "extension/system.h"
-
-#include "io/sys.h"
-
-#include <cairo.h>
-#include "document.h"
-
-// include support for only the compiled-in surface types
-#ifdef CAIRO_HAS_PDF_SURFACE
-#include <cairo-pdf.h>
-#endif
-#ifdef CAIRO_HAS_PS_SURFACE
-#include <cairo-ps.h>
-#endif
//#define TRACE(_args) g_printf _args
#define TRACE(_args)
@@ -657,6 +662,45 @@ void CairoRenderer::renderHatchPath(CairoRenderContext *ctx, SPHatchPath const &
ctx->popState();
}
+void CairoRenderer::setMetadata(CairoRenderContext *ctx, SPDocument *doc) {
+ // title
+ const gchar *title = rdf_get_work_entity(doc, rdf_find_entity("title"));
+ if (title) {
+ ctx->_metadata.title = title;
+ }
+
+ // author
+ const gchar *author = rdf_get_work_entity(doc, rdf_find_entity("creator"));
+ if (author) {
+ ctx->_metadata.author = author;
+ }
+
+ // subject
+ const gchar *subject = rdf_get_work_entity(doc, rdf_find_entity("description"));
+ if (subject) {
+ ctx->_metadata.subject = subject;
+ }
+
+ // keywords
+ const gchar *keywords = rdf_get_work_entity(doc, rdf_find_entity("subject"));
+ if (keywords) {
+ ctx->_metadata.keywords = keywords;
+ }
+
+ // copyright
+ const gchar *copyright = rdf_get_work_entity(doc, rdf_find_entity("rights"));
+ if (copyright) {
+ ctx->_metadata.copyright = copyright;
+ }
+
+ // creator
+ ctx->_metadata.creator = Glib::ustring::compose("Inkscape %1 (https://inkscape.org)",
+ Inkscape::version_string_without_revision);
+
+ // cdate / mdate
+ // (currently unused)
+}
+
bool
CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool pageBoundingBox, float bleedmargin_px, SPItem *base)
{
@@ -692,6 +736,8 @@ CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool page
TRACE(("setupDocument: %f x %f\n", ctx->_width, ctx->_height));
+ setMetadata(ctx, doc);
+
bool ret = ctx->setupSurface(ctx->_width, ctx->_height);
if (ret) {
diff --git a/src/extension/internal/cairo-renderer.h b/src/extension/internal/cairo-renderer.h
index a8eab52a8..26f2f414a 100644
--- a/src/extension/internal/cairo-renderer.h
+++ b/src/extension/internal/cairo-renderer.h
@@ -55,6 +55,10 @@ public:
/** Traverses the object tree and invokes the render methods. */
void renderItem(CairoRenderContext *ctx, SPItem *item);
void renderHatchPath(CairoRenderContext *ctx, SPHatchPath const &hatchPath, unsigned key);
+
+private:
+ /** Extract metadata from doc and set it on ctx. */
+ void setMetadata(CairoRenderContext *ctx, SPDocument *doc);
};
// FIXME: this should be a static method of CairoRenderer