Newer
Older
Import / applications / MakePDF / 3rdParty / libharu-with-PRs / pr-patches / 0001-Update-src-hpdf_pdfa.c.patch
From 3c036616eb95d3a4ed6ba7c47f84a1557abf5c92 Mon Sep 17 00:00:00 2001
From: orouge <orouge@gmail.com>
Date: Wed, 16 May 2012 18:30:00 +0300
Subject: [PATCH] Update src/hpdf_pdfa.c

---
 src/hpdf_pdfa.c | 244 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 173 insertions(+), 71 deletions(-)

diff --git a/src/hpdf_pdfa.c b/src/hpdf_pdfa.c
index d76eee5..df06d1c 100644
--- a/src/hpdf_pdfa.c
+++ b/src/hpdf_pdfa.c
@@ -25,20 +25,33 @@
 #include <string.h>
 
 
-#define XMP_HEADER "<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?><?adobe-xap-filters esc=\"CRLF\"?><x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='XMP toolkit 2.9.1-13, framework 1.6'><rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'>"
-#define XMP_FOOTER "</rdf:RDF></x:xmpmeta><?xpacket end='w'?>"
-#define XMP_PDFA1A "<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/' pdfaid:part='1' pdfaid:conformance='A'/>"
-#define XMP_PDFA1B "<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/' pdfaid:part='1' pdfaid:conformance='B'/>"
-#define XMP_PRODUCER_STARTTAG "<rdf:Description rdf:about='' xmlns:pdf='http://ns.adobe.com/pdf/1.3/' pdf:Producer='"
-#define XMP_PRODUCER_ENDTAG "'/>"
-#define XMP_INFODATA_STARTTAG "<rdf:Description rdf:about='' xmlns:xmp='http://ns.adobe.com/xap/1.0/'>"
-#define XMP_INFODATA_ENDTAG "</rdf:Description>"
-#define XMP_CREATE_DATE_STARTTAG "<xmp:CreateDate>"
-#define XMP_CREATE_DATE_ENDTAG "</xmp:CreateDate>"
-#define XMP_MOD_DATE_STARTTAG "<xmp:ModifyDate>"
-#define XMP_MOD_DATE_ENDTAG "</xmp:ModifyDate>"
+#define HEADER                   "<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?><x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='XMP toolkit 2.9.1-13, framework 1.6'><rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'>"
+#define DC_HEADER                "<rdf:Description xmlns:dc='http://purl.org/dc/elements/1.1/' rdf:about=''>"
+#define DC_TITLE_STARTTAG        "<dc:title><rdf:Alt><rdf:li xml:lang=\"x-default\">"
+#define DC_TITLE_ENDTAG          "</rdf:li></rdf:Alt></dc:title>"
+#define DC_CREATOR_STARTTAG      "<dc:creator><rdf:Seq><rdf:li>"
+#define DC_CREATOR_ENDTAG        "</rdf:li></rdf:Seq></dc:creator>"
+#define DC_DESCRIPTION_STARTTAG  "<dc:description><rdf:Alt><rdf:li xml:lang=\"x-default\">"
+#define DC_DESCRIPTION_ENDTAG    "</rdf:li></rdf:Alt></dc:description>"
+#define DC_FOOTER                "</rdf:Description>"
+#define XMP_HEADER               "<rdf:Description xmlns:xmp='http://ns.adobe.com/xap/1.0/' rdf:about=''>"
 #define XMP_CREATORTOOL_STARTTAG "<xmp:CreatorTool>"
-#define XMP_CREATORTOOL_ENDTAG "</xmp:CreatorTool>"
+#define XMP_CREATORTOOL_ENDTAG   "</xmp:CreatorTool>"
+#define XMP_CREATE_DATE_STARTTAG "<xmp:CreateDate>"
+#define XMP_CREATE_DATE_ENDTAG   "</xmp:CreateDate>"
+#define XMP_MOD_DATE_STARTTAG    "<xmp:ModifyDate>"
+#define XMP_MOD_DATE_ENDTAG      "</xmp:ModifyDate>"
+#define XMP_FOOTER               "</rdf:Description>"
+#define PDF_HEADER               "<rdf:Description xmlns:pdf='http://ns.adobe.com/pdf/1.3/' rdf:about=''>"
+#define PDF_KEYWORDS_STARTTAG    "<pdf:Keywords>"
+#define PDF_KEYWORDS_ENDTAG      "</pdf:Keywords>"
+#define PDF_PRODUCER_STARTTAG    "<pdf:Producer>"
+#define PDF_PRODUCER_ENDTAG      "</pdf:Producer>"
+#define PDF_FOOTER               "</rdf:Description>"
+#define PDFAID_PDFA1A            "<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/' pdfaid:part='1' pdfaid:conformance='A'/>"
+#define PDFAID_PDFA1B            "<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/' pdfaid:part='1' pdfaid:conformance='B'/>"
+#define FOOTER                   "</rdf:RDF></x:xmpmeta><?xpacket end='w'?>"
+
 
 /*
  * Convert date in PDF specific format: D:YYYYMMDDHHmmSS
@@ -100,12 +113,21 @@ HPDF_STATUS ConvertDateToXMDate(HPDF_Stream stream, const char *pDate)
     pDate+=2;
     /* Write +... */
     if(pDate[0]==0) {
-        ret = HPDF_Stream_Write(stream, (const HPDF_BYTE*)"+0:00", 5);
+        ret = HPDF_Stream_Write(stream, (const HPDF_BYTE*)"Z", 1);
         return ret;
     }
     if(pDate[0]=='+'||pDate[0]=='-') {
-        ret = HPDF_Stream_Write(stream, (const HPDF_BYTE*)pDate, strlen(pDate));
-        return ret;        
+        ret = HPDF_Stream_Write(stream, (const HPDF_BYTE*)pDate, 3);
+        if (ret != HPDF_OK)
+            return ret;
+        pDate+=4;
+        ret = HPDF_Stream_Write(stream, (const HPDF_BYTE*)":", 1);
+        if (ret != HPDF_OK)
+            return ret;
+        ret = HPDF_Stream_Write(stream, (const HPDF_BYTE*)pDate, 2);
+        if (ret != HPDF_OK)
+            return ret;
+        return ret;
     }
     return HPDF_SetError (stream->error, HPDF_INVALID_PARAMETER, 0);
 }
@@ -117,68 +139,148 @@ HPDF_PDFA_SetPDFAConformance (HPDF_Doc pdf,HPDF_PDFAType pdfatype)
 {
     HPDF_OutputIntent xmp;
     HPDF_STATUS ret;
+
+    const char *dc_title       = NULL;
+    const char *dc_creator     = NULL;
+    const char *dc_description = NULL;
+
+    const char *xmp_CreatorTool = NULL;
+    const char *xmp_CreateDate  = NULL;
+    const char *xmp_ModifyDate  = NULL;
+
+    const char *pdf_Keywords    = NULL;
+    const char *pdf_Producer    = NULL;
+
     const char *info = NULL;
-    
+
     if (!HPDF_HasDoc(pdf)) {
       return HPDF_INVALID_DOCUMENT;
     }
-    
-    xmp = HPDF_DictStream_New(pdf->mmgr,pdf->xref);
-    if (!xmp) {
-      return HPDF_INVALID_STREAM;
-    }
-    
-    HPDF_Dict_AddName(xmp,"Type","Metadata");
-    HPDF_Dict_AddName(xmp,"SubType","XML");
 
-    ret = HPDF_OK;
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_HEADER);
-    
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_PRODUCER_STARTTAG);
-   
-    info = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_PRODUCER);
-    ret += HPDF_Stream_WriteStr(xmp->stream, info);
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_PRODUCER_ENDTAG);
-    
-    /* Add CreateDate, ModifyDate, and CreatorTool */
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_INFODATA_STARTTAG);    
-    info = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_CREATION_DATE);
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_CREATE_DATE_STARTTAG);    
-    /* Convert date to XMP compatible format */
-    ret += ConvertDateToXMDate(xmp->stream, info);
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_CREATE_DATE_ENDTAG);
-    
-    info = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_MOD_DATE);
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_MOD_DATE_STARTTAG);    
-    ret += ConvertDateToXMDate(xmp->stream, info);
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_MOD_DATE_ENDTAG);
-    
-    info = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_CREATOR);
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_CREATORTOOL_STARTTAG);    
-    ret += HPDF_Stream_WriteStr(xmp->stream, info);
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_CREATORTOOL_ENDTAG);
-    
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_INFODATA_ENDTAG);
-    
-    switch(pdfatype) {
-      case HPDF_PDFA_1A:
-        ret += HPDF_Stream_WriteStr(xmp->stream, XMP_PDFA1A);
-        break;
-      case HPDF_PDFA_1B:
-        ret += HPDF_Stream_WriteStr(xmp->stream, XMP_PDFA1B);
-        break;
-    }
-    ret += HPDF_Stream_WriteStr(xmp->stream, XMP_FOOTER);
+    dc_title       = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_TITLE);
+    dc_creator     = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_AUTHOR);
+    dc_description = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_SUBJECT);
 
-    if (ret != HPDF_OK) {
-      return HPDF_INVALID_STREAM;
-    }
-    
-    if ((ret = HPDF_Dict_Add(pdf->catalog, "Metadata", xmp)) != HPDF_OK) {
-      return ret;
+    xmp_CreateDate  = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_CREATION_DATE);
+    xmp_ModifyDate  = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_MOD_DATE);
+    xmp_CreatorTool = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_CREATOR);
+
+    pdf_Keywords = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_KEYWORDS);
+    pdf_Producer = (const char *)HPDF_GetInfoAttr(pdf, HPDF_INFO_PRODUCER);
+
+    if((dc_title != NULL) || (dc_creator != NULL) || (dc_description != NULL)
+       || (xmp_CreateDate != NULL) || (xmp_ModifyDate != NULL) || (xmp_CreatorTool != NULL)
+       || (pdf_Keywords != NULL)) {
+
+        xmp = HPDF_DictStream_New(pdf->mmgr,pdf->xref);
+        if (!xmp) {
+          return HPDF_INVALID_STREAM;
+        }
+
+        /* Update the PDF number version */
+        pdf->pdf_version = HPDF_VER_14;
+
+        HPDF_Dict_AddName(xmp,"Type","Metadata");
+        HPDF_Dict_AddName(xmp,"SubType","XML");
+
+        ret = HPDF_OK;
+        ret += HPDF_Stream_WriteStr(xmp->stream, HEADER);
+
+        /* Add the dc block */
+        if((dc_title != NULL) || (dc_creator != NULL) || (dc_description != NULL)) {
+            ret += HPDF_Stream_WriteStr(xmp->stream, DC_HEADER);
+
+            if(dc_title != NULL) {
+                ret += HPDF_Stream_WriteStr(xmp->stream, DC_TITLE_STARTTAG);
+                ret += HPDF_Stream_WriteStr(xmp->stream, dc_title);
+                ret += HPDF_Stream_WriteStr(xmp->stream, DC_TITLE_ENDTAG);
+            }
+
+            if(dc_creator != NULL) {
+                ret += HPDF_Stream_WriteStr(xmp->stream, DC_CREATOR_STARTTAG);
+                ret += HPDF_Stream_WriteStr(xmp->stream, dc_creator);
+                ret += HPDF_Stream_WriteStr(xmp->stream, DC_CREATOR_ENDTAG);
+            }
+
+            if(dc_description != NULL) {
+                ret += HPDF_Stream_WriteStr(xmp->stream, DC_DESCRIPTION_STARTTAG);
+                ret += HPDF_Stream_WriteStr(xmp->stream, dc_description);
+                ret += HPDF_Stream_WriteStr(xmp->stream, DC_DESCRIPTION_ENDTAG);
+            }
+
+            ret += HPDF_Stream_WriteStr(xmp->stream, DC_FOOTER);
+        }
+
+        /* Add the xmp block */
+        if((xmp_CreateDate != NULL) || (xmp_ModifyDate != NULL) || (xmp_CreatorTool != NULL)) {
+            ret += HPDF_Stream_WriteStr(xmp->stream, XMP_HEADER);
+
+            /* Add CreateDate, ModifyDate, and CreatorTool */
+            if(xmp_CreatorTool != NULL) {
+                ret += HPDF_Stream_WriteStr(xmp->stream, XMP_CREATORTOOL_STARTTAG);
+                ret += HPDF_Stream_WriteStr(xmp->stream, xmp_CreatorTool);
+                ret += HPDF_Stream_WriteStr(xmp->stream, XMP_CREATORTOOL_ENDTAG);
+            }
+
+            if(xmp_CreateDate != NULL) {
+                ret += HPDF_Stream_WriteStr(xmp->stream, XMP_CREATE_DATE_STARTTAG);
+                /* Convert date to XMP compatible format */
+                ret += ConvertDateToXMDate(xmp->stream, xmp_CreateDate);
+                ret += HPDF_Stream_WriteStr(xmp->stream, XMP_CREATE_DATE_ENDTAG);
+            }
+
+            if(xmp_ModifyDate != NULL) {
+                ret += HPDF_Stream_WriteStr(xmp->stream, XMP_MOD_DATE_STARTTAG);
+                ret += ConvertDateToXMDate(xmp->stream, xmp_ModifyDate);
+                ret += HPDF_Stream_WriteStr(xmp->stream, XMP_MOD_DATE_ENDTAG);
+            }
+
+            ret += HPDF_Stream_WriteStr(xmp->stream, XMP_FOOTER);
+        }
+
+        /* Add the pdf block */
+        if((pdf_Keywords != NULL) || (pdf_Producer != NULL)) {
+            ret += HPDF_Stream_WriteStr(xmp->stream, PDF_HEADER);
+
+            if(pdf_Keywords != NULL) {
+                ret += HPDF_Stream_WriteStr(xmp->stream, PDF_KEYWORDS_STARTTAG);
+                ret += HPDF_Stream_WriteStr(xmp->stream, pdf_Keywords);
+                ret += HPDF_Stream_WriteStr(xmp->stream, PDF_KEYWORDS_ENDTAG);
+            }
+
+            if(pdf_Producer != NULL) {
+                ret += HPDF_Stream_WriteStr(xmp->stream, PDF_PRODUCER_STARTTAG);
+                ret += HPDF_Stream_WriteStr(xmp->stream, pdf_Producer);
+                ret += HPDF_Stream_WriteStr(xmp->stream, PDF_PRODUCER_ENDTAG);
+            }
+
+            ret += HPDF_Stream_WriteStr(xmp->stream, PDF_FOOTER);
+        }
+
+        /* Add the pdfaid block */
+        switch(pdfatype) {
+          case HPDF_PDFA_1A:
+            ret += HPDF_Stream_WriteStr(xmp->stream, PDFAID_PDFA1A);
+            break;
+          case HPDF_PDFA_1B:
+            ret += HPDF_Stream_WriteStr(xmp->stream, PDFAID_PDFA1B);
+            break;
+        }
+
+        ret += HPDF_Stream_WriteStr(xmp->stream, FOOTER);
+
+        if (ret != HPDF_OK) {
+          return HPDF_INVALID_STREAM;
+        }
+
+        if ((ret = HPDF_Dict_Add(pdf->catalog, "Metadata", xmp)) != HPDF_OK) {
+          return ret;
+        }
+
+        return HPDF_PDFA_GenerateID(pdf);
     }
-    
-    return HPDF_PDFA_GenerateID(pdf);
+
+    return HPDF_OK;
 }
 
 /* Generate an ID for the trailer dict, PDF/A needs this. 
-- 
2.21.1 (Apple Git-122.3)