From dbf2bb187b8c28aafe7d4ea6a9911f955d581be3 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 26 Nov 2017 20:43:15 +1030 Subject: [PATCH 8/8] cairo: when interactive enabled, copy the metadata to the output Bug #103912 --- poppler/CairoOutputDev.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++--- poppler/CairoOutputDev.h | 7 ++++++ poppler/PDFDoc.h | 2 +- utils/pdftocairo.1 | 2 +- 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 30462cc5..dcba7a9a 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -46,9 +46,6 @@ #include #include #include -#if CAIRO_HAS_PDF_SURFACE -#include -#endif #include #include "goo/gfile.h" @@ -71,6 +68,7 @@ #include "UTF.h" #include "JBIG2Stream.h" #include "Outline.h" +#include "DateInfo.h" //------------------------------------------------------------------------ // #define LOG_CAIRO @@ -371,6 +369,48 @@ void CairoOutputDev::addOutlineNodes(GfxState *state, GooList *list, OutlineNode } } +#if defined(CAIRO_HAS_PDF_SURFACE) && CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 8) +void CairoOutputDev::setMetadataString(cairo_pdf_metadata_t metadata, const char *key) +{ + GooString *s; + char *utf8; + s = doc->getDocInfoStringEntry(key); + if (!s) + return; + utf8 = TextStringToUtf8(s); + cairo_pdf_surface_set_metadata (cairo_get_target (cairo), metadata, utf8); + gfree(utf8); + delete s; +} + +void CairoOutputDev::setMetadataDate(cairo_pdf_metadata_t metadata, const char *key) +{ + GooString *s; + int year, mon, day, hour, min, sec, tz_hour, tz_minute; + char tz; + + s = doc->getDocInfoStringEntry(key); + if (!s) + return; + + if ( parseDateString(s->getCString(), &year, &mon, &day, &hour, &min, &sec, &tz, &tz_hour, &tz_minute)) { + GooString d; + d.appendf("{0:04d}-{1:02d}-{2:02d}T{3:02d}:{4:02d}:{5:02d}", year, mon, day, hour, min, sec); + if (tz_hour == 0 && tz_minute == 0) { + d.append("Z"); + } else { + d.appendf("{0:c}{1:02d}", tz, tz_hour); + if (tz_minute) + d.appendf(":{0:02d}", tz_minute); + } + cairo_pdf_surface_set_metadata (cairo_get_target (cairo), metadata, d.getCString()); + } + delete s; +} + +#endif + + // Document setup that needs to be performed after setCairo() is called. void CairoOutputDev::startFirstPage(int pageNum, GfxState *state, XRef *xrefA) { @@ -410,6 +450,17 @@ void CairoOutputDev::startFirstPage(int pageNum, GfxState *state, XRef *xrefA) if (list) addOutlineNodes (state, list, nullptr); } + + // set metadata +#if defined(CAIRO_HAS_PDF_SURFACE) && CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 8) + setMetadataString(CAIRO_PDF_METADATA_TITLE, "Title"); + setMetadataString(CAIRO_PDF_METADATA_AUTHOR, "Author"); + setMetadataString(CAIRO_PDF_METADATA_SUBJECT, "Subject"); + setMetadataString(CAIRO_PDF_METADATA_KEYWORDS, "Keywords"); + setMetadataString(CAIRO_PDF_METADATA_CREATOR, "Creator"); + setMetadataDate(CAIRO_PDF_METADATA_CREATE_DATE, "CreationDate"); + setMetadataDate(CAIRO_PDF_METADATA_MOD_DATE, "ModDate"); +#endif } } diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index e0fb7b02..05d54b9b 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -41,6 +41,9 @@ #include "goo/gtypes.h" #include +#if CAIRO_HAS_PDF_SURFACE +#include +#endif #include "OutputDev.h" #include "TextOutputDev.h" #include "GfxState.h" @@ -315,6 +318,10 @@ protected: static void textStringToQuotedUtf8(GooString *text, GooString *s); GBool isPDF(); void startFirstPage(GfxState *state); +#if defined(CAIRO_HAS_PDF_SURFACE) && CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 8) + void setMetadataString(cairo_pdf_metadata_t metadata, const char *key); + void setMetadataDate(cairo_pdf_metadata_t metadata, const char *key); +#endif GfxRGB fill_color, stroke_color; cairo_pattern_t *fill_pattern, *stroke_pattern; diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 48d8dcf7..91d84906 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -257,7 +257,7 @@ public: // Get document's properties from document's Info dictionary. // Returns NULL on fail. - // Returned GooStrings should be freed by the caller. + // Returned GooStrings should be deleted by the caller. GooString *getDocInfoStringEntry(const char *key); GooString *getDocInfoTitle() { return getDocInfoStringEntry("Title"); } diff --git a/utils/pdftocairo.1 b/utils/pdftocairo.1 index 2f3b5e32..b6e3c6a4 100644 --- a/utils/pdftocairo.1 +++ b/utils/pdftocairo.1 @@ -224,7 +224,7 @@ write this information to the output file (PDF only). .B \-inter If the input file contains interactive features, where supported by cairo, write this information to the output file (PDF only). Currently supported -features: page labels, outline, thumbnail images. +features: page labels, outline, thumbnail images, and metadata. .TP .B \-origpagesizes This option is the same as "\-paper match". -- 2.11.0