diff options
| author | Patrick Storz <eduard.braun2@gmx.de> | 2019-07-07 18:18:30 +0000 |
|---|---|---|
| committer | Patrick Storz <eduard.braun2@gmx.de> | 2019-07-10 18:15:54 +0000 |
| commit | 90b67c899f3a33f4ad8cf6e3d2da6ad57dd29e51 (patch) | |
| tree | b9cc15ddf5ad03533ab717da412ea87b7d60d71e | |
| parent | inkscape-version: offer variant without revision and date (diff) | |
| download | inkscape-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.cpp | 38 | ||||
| -rw-r--r-- | src/extension/internal/cairo-render-context.h | 18 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer.cpp | 114 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer.h | 4 |
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 |
