Allow users to set custom producer in PDF metadata

Submitted by Guillaume Ayoub on Aug. 13, 2018, 4:19 p.m.

Details

Message ID 20180813161951.27719-1-guillaume.ayoub@kozea.fr
State New
Series "Allow users to set custom producer in PDF metadata"
Headers show

Commit Message

Guillaume Ayoub Aug. 13, 2018, 4:19 p.m.
External libraries using cairo may want	to edit	the Producer metadata tag
in generated PDF files.

This patch allows users	to edit	this tag as any other tag, and keeps the
previous cairo string as a fallback when no custom string is set.

---
 src/cairo-pdf-interchange.c     | 18 +++++++++++++++---
 src/cairo-pdf-surface-private.h |  1 +
 src/cairo-pdf.h                 |  2 ++
 test/pdf-tagged-text.c          |  1 +
 4 files changed, 19 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/cairo-pdf-interchange.c b/src/cairo-pdf-interchange.c
index 9aa6934dc..35b91dfba 100644
--- a/src/cairo-pdf-interchange.c
+++ b/src/cairo-pdf-interchange.c
@@ -1047,9 +1047,17 @@  cairo_pdf_interchange_write_docinfo (cairo_pdf_surface_t *surface)
 
     _cairo_output_stream_printf (surface->output,
 				 "%d 0 obj\n"
-				 "<< /Producer (cairo %s (http://cairographics.org))\n",
-				 surface->docinfo_res.id,
-				 cairo_version_string ());
+				 "<<",
+				 surface->docinfo_res.id);
+
+    if (ic->docinfo.producer)
+	_cairo_output_stream_printf (surface->output,
+				     " /Producer %s\n",
+				     ic->docinfo.producer);
+    else
+	_cairo_output_stream_printf (surface->output,
+				     " /Producer (cairo %s (http://cairographics.org))\n",
+				     cairo_version_string ());
 
     if (ic->docinfo.title)
 	_cairo_output_stream_printf (surface->output, "   /Title %s\n", ic->docinfo.title);
@@ -1722,6 +1730,10 @@  _cairo_pdf_interchange_set_metadata (cairo_pdf_surface_t  *surface,
 	    free (ic->docinfo.mod_date);
 	    ic->docinfo.mod_date = s;
 	    break;
+	case CAIRO_PDF_METADATA_PRODUCER:
+	    free (ic->docinfo.producer);
+	    ic->docinfo.producer = s;
+	    break;
     }
 
     return CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
index 3793332ce..51d7047b5 100644
--- a/src/cairo-pdf-surface-private.h
+++ b/src/cairo-pdf-surface-private.h
@@ -216,6 +216,7 @@  struct docinfo {
     char *creator;
     char *create_date;
     char *mod_date;
+    char *producer;
 };
 
 typedef struct _cairo_pdf_interchange {
diff --git a/src/cairo-pdf.h b/src/cairo-pdf.h
index 5be0b3f1b..ee8fb3dd4 100644
--- a/src/cairo-pdf.h
+++ b/src/cairo-pdf.h
@@ -122,6 +122,7 @@  cairo_pdf_surface_add_outline (cairo_surface_t	          *surface,
  * @CAIRO_PDF_METADATA_CREATOR: The document creator (Since 1.16)
  * @CAIRO_PDF_METADATA_CREATE_DATE: The document creation date (Since 1.16)
  * @CAIRO_PDF_METADATA_MOD_DATE: The document modification date (Since 1.16)
+ * @CAIRO_PDF_METADATA_PRODUCER: The document producer (Since 1.16)
  *
  * #cairo_pdf_metadata_t is used by the
  * cairo_pdf_surface_set_metadata() function specify the metadata to set.
@@ -136,6 +137,7 @@  typedef enum _cairo_pdf_metadata {
     CAIRO_PDF_METADATA_CREATOR,
     CAIRO_PDF_METADATA_CREATE_DATE,
     CAIRO_PDF_METADATA_MOD_DATE,
+    CAIRO_PDF_METADATA_PRODUCER,
 } cairo_pdf_metadata_t;
 
 cairo_public void
diff --git a/test/pdf-tagged-text.c b/test/pdf-tagged-text.c
index 5c1b82bc2..6f3f4e54f 100644
--- a/test/pdf-tagged-text.c
+++ b/test/pdf-tagged-text.c
@@ -325,6 +325,7 @@  create_document (cairo_surface_t *surface, cairo_t *cr)
     cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_CREATOR, "pdf-features");
     cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_CREATE_DATE, "2016-01-01T12:34:56+10:30");
     cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_MOD_DATE, "2016-06-21T05:43:21Z");
+    cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_PRODUCER, "cairo producer");
 
     cairo_tag_begin (cr, "Document", NULL);
 

Comments

Bryce Harrington Aug. 24, 2018, 5:59 p.m.
Hi Guillaume,

Thanks for looking into improving the pdf metadata support.

There has been interest from others in supporting custom producers in
PDFs, however it has been intended that list Cairo specifically, as the
actual library producing the PDF.  Applications are encouraged to
specify themselves as Creator instead.

See https://bugs.freedesktop.org/show_bug.cgi?id=99514 and feel free to
add more thoughts about this to that bug report, particularly if you
have use cases that haven't been thought of so far.

Bryce

On Mon, Aug 13, 2018 at 06:19:51PM +0200, Guillaume Ayoub wrote:
> External libraries using cairo may want to edit the Producer metadata
> tag in generated PDF files.
> 
> This patch allows users to edit this tag as any other tag, and keeps
> the previous cairo string as a fallback when no custom string is set.
> 
> ---
>  src/cairo-pdf-interchange.c     | 18 +++++++++++++++---
>  src/cairo-pdf-surface-private.h |  1 +
>  src/cairo-pdf.h                 |  2 ++
>  test/pdf-tagged-text.c          |  1 +
>  4 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/src/cairo-pdf-interchange.c b/src/cairo-pdf-interchange.c
> index 9aa6934dc..35b91dfba 100644
> --- a/src/cairo-pdf-interchange.c
> +++ b/src/cairo-pdf-interchange.c
> @@ -1047,9 +1047,17 @@ cairo_pdf_interchange_write_docinfo (cairo_pdf_surface_t *surface)
>  
>      _cairo_output_stream_printf (surface->output,
>  				 "%d 0 obj\n"
> -				 "<< /Producer (cairo %s (http://cairographics.org))\n",
> -				 surface->docinfo_res.id,
> -				 cairo_version_string ());
> +				 "<<",
> +				 surface->docinfo_res.id);
> +
> +    if (ic->docinfo.producer)
> +	_cairo_output_stream_printf (surface->output,
> +				     " /Producer %s\n",
> +				     ic->docinfo.producer);
> +    else
> +	_cairo_output_stream_printf (surface->output,
> +				     " /Producer (cairo %s (http://cairographics.org))\n",
> +				     cairo_version_string ());
>  
>      if (ic->docinfo.title)
>  	_cairo_output_stream_printf (surface->output, "   /Title %s\n", ic->docinfo.title);
> @@ -1722,6 +1730,10 @@ _cairo_pdf_interchange_set_metadata (cairo_pdf_surface_t  *surface,
>  	    free (ic->docinfo.mod_date);
>  	    ic->docinfo.mod_date = s;
>  	    break;
> +	case CAIRO_PDF_METADATA_PRODUCER:
> +	    free (ic->docinfo.producer);
> +	    ic->docinfo.producer = s;
> +	    break;
>      }
>  
>      return CAIRO_STATUS_SUCCESS;
> diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
> index 3793332ce..51d7047b5 100644
> --- a/src/cairo-pdf-surface-private.h
> +++ b/src/cairo-pdf-surface-private.h
> @@ -216,6 +216,7 @@ struct docinfo {
>      char *creator;
>      char *create_date;
>      char *mod_date;
> +    char *producer;
>  };
>  
>  typedef struct _cairo_pdf_interchange {
> diff --git a/src/cairo-pdf.h b/src/cairo-pdf.h
> index 5be0b3f1b..ee8fb3dd4 100644
> --- a/src/cairo-pdf.h
> +++ b/src/cairo-pdf.h
> @@ -122,6 +122,7 @@ cairo_pdf_surface_add_outline (cairo_surface_t	          *surface,
>   * @CAIRO_PDF_METADATA_CREATOR: The document creator (Since 1.16)
>   * @CAIRO_PDF_METADATA_CREATE_DATE: The document creation date (Since 1.16)
>   * @CAIRO_PDF_METADATA_MOD_DATE: The document modification date (Since 1.16)
> + * @CAIRO_PDF_METADATA_PRODUCER: The document producer (Since 1.16)
>   *
>   * #cairo_pdf_metadata_t is used by the
>   * cairo_pdf_surface_set_metadata() function specify the metadata to set.
> @@ -136,6 +137,7 @@ typedef enum _cairo_pdf_metadata {
>      CAIRO_PDF_METADATA_CREATOR,
>      CAIRO_PDF_METADATA_CREATE_DATE,
>      CAIRO_PDF_METADATA_MOD_DATE,
> +    CAIRO_PDF_METADATA_PRODUCER,
>  } cairo_pdf_metadata_t;
>  
>  cairo_public void
> diff --git a/test/pdf-tagged-text.c b/test/pdf-tagged-text.c
> index 5c1b82bc2..6f3f4e54f 100644
> --- a/test/pdf-tagged-text.c
> +++ b/test/pdf-tagged-text.c
> @@ -325,6 +325,7 @@ create_document (cairo_surface_t *surface, cairo_t *cr)
>      cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_CREATOR, "pdf-features");
>      cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_CREATE_DATE, "2016-01-01T12:34:56+10:30");
>      cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_MOD_DATE, "2016-06-21T05:43:21Z");
> +    cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_PRODUCER, "cairo producer");
>  
>      cairo_tag_begin (cr, "Document", NULL);
>  
> -- 
> 2.18.0
> 
> -- 
> cairo mailing list
> cairo@cairographics.org
> https://lists.cairographics.org/mailman/listinfo/cairo