diff options
author | Jeremias Maerki <jeremias@apache.org> | 2006-03-30 09:57:32 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2006-03-30 09:57:32 +0000 |
commit | fc889fb52f76f227a7ff8814dbe608a09394a971 (patch) | |
tree | b86c2ffc8b78a93300a1163f62f218e4eccfa140 /src/java/org/apache | |
parent | 1395c45d9d371d044795b526a07cee6bc3335075 (diff) | |
download | xmlgraphics-fop-fc889fb52f76f227a7ff8814dbe608a09394a971.tar.gz xmlgraphics-fop-fc889fb52f76f227a7ff8814dbe608a09394a971.zip |
Changed PDFText.escapeText() so it doesn't output 7bit ASCII texts in hex mode. This makes it easier to read the PDF in a text editor in most cases.
Fixed the property names for xmp:CreatorTool and xmp:CreateDate (case mistake on my side).
Changed XMP-generation to output the creation date including the time zone to keep Acrobat's preflight check for PDF/A-1b happy. Found that only after more than 3 hours of trial&error.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@390051 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache')
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFMetadata.java | 30 | ||||
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFObject.java | 4 | ||||
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFText.java | 51 |
3 files changed, 60 insertions, 25 deletions
diff --git a/src/java/org/apache/fop/pdf/PDFMetadata.java b/src/java/org/apache/fop/pdf/PDFMetadata.java index 13774c026..1dad2b5a5 100644 --- a/src/java/org/apache/fop/pdf/PDFMetadata.java +++ b/src/java/org/apache/fop/pdf/PDFMetadata.java @@ -23,7 +23,6 @@ import java.io.OutputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.TimeZone; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; @@ -35,6 +34,7 @@ import javax.xml.transform.stream.StreamResult; import org.apache.fop.fo.ElementMapping; import org.apache.fop.fo.extensions.xmp.XMPConstants; + import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -47,6 +47,9 @@ public class PDFMetadata extends PDFStream { private static final String XMLNS = "http://www.w3.org/2000/xmlns/"; + private static DateFormat pseudoISO8601DateFormat = new SimpleDateFormat( + "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"); + private Document xmpMetadata; private boolean readOnly = true; @@ -145,6 +148,16 @@ public class PDFMetadata extends PDFStream { return sb.toString(); } + private static String formatDate(Date dt) { + String s = pseudoISO8601DateFormat.format(dt); + + //Now insert the colon that's not possible using SimpleDateFormat + int tzpos = s.length() - 4; + String tz = s.substring(tzpos); + s = s.substring(0, tzpos) + tz.substring(0, 2) + ":" + tz.substring(2); + return s; + } + /** * Creates an XMP document based on the settings on the PDF Document. * @param pdfDoc the PDF Document @@ -159,15 +172,16 @@ public class PDFMetadata extends PDFStream { Element desc, el; PDFInfo info = pdfDoc.getInfo(); - DateFormat pseudoISO8601DateFormat = new SimpleDateFormat( - "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'"); - pseudoISO8601DateFormat.setTimeZone(TimeZone.getTimeZone("GMT+00")); //Set creation date if not available, yet if (info.getCreationDate() == null) { Date d = new Date(); info.setCreationDate(d); } + + //Important: Acrobat's preflight check for PDF/A-1b wants the creation date in the Info + //object and in the XMP metadata to have the same timezone or else it shows a validation + //error even if the times are essentially equal. //Dublin Core desc = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:Description"); @@ -195,18 +209,18 @@ public class PDFMetadata extends PDFStream { } el = doc.createElementNS(XMPConstants.DUBLIN_CORE_NAMESPACE, "dc:date"); desc.appendChild(el); - el.appendChild(doc.createTextNode(pseudoISO8601DateFormat.format(info.getCreationDate()))); + el.appendChild(doc.createTextNode(formatDate(info.getCreationDate()))); //XMP Basic Schema desc = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:Description"); desc.setAttributeNS(XMPConstants.RDF_NAMESPACE, "rdf:about", ""); desc.setAttributeNS(XMLNS, "xmlns:xmp", XMPConstants.XMP_BASIC_NAMESPACE); rdf.appendChild(desc); - el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:createDate"); + el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:CreateDate"); desc.appendChild(el); - el.appendChild(doc.createTextNode(pseudoISO8601DateFormat.format(info.getCreationDate()))); + el.appendChild(doc.createTextNode(formatDate(info.getCreationDate()))); if (info.getCreator() != null) { - el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:creatorTool"); + el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:CreatorTool"); desc.appendChild(el); el.appendChild(doc.createTextNode(info.getCreator())); } diff --git a/src/java/org/apache/fop/pdf/PDFObject.java b/src/java/org/apache/fop/pdf/PDFObject.java index 6d312b25f..9ccd59bfc 100644 --- a/src/java/org/apache/fop/pdf/PDFObject.java +++ b/src/java/org/apache/fop/pdf/PDFObject.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2004,2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -198,7 +198,7 @@ public abstract class PDFObject { return PDFText.escapeByteArray( getDocument().getEncryption().encrypt(buf, this)); } else { - return encode(PDFText.escapeText(text, true)); + return encode(PDFText.escapeText(text, false)); } } diff --git a/src/java/org/apache/fop/pdf/PDFText.java b/src/java/org/apache/fop/pdf/PDFText.java index e21b078a7..16fccb97e 100644 --- a/src/java/org/apache/fop/pdf/PDFText.java +++ b/src/java/org/apache/fop/pdf/PDFText.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2004,2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,20 +73,34 @@ public class PDFText extends PDFObject { * @return encoded text */ public static final String escapeText(final String text) { - return escapeText(text, true); + return escapeText(text, false); } /** * Escape text (see 4.4.1 in PDF 1.3 specs) * @param text the text to encode - * @param hexMode true if the output should follow the hex encoding rules + * @param forceHexMode true if the output should follow the hex encoding rules * @return encoded text */ - public static final String escapeText(final String text, boolean hexMode) { + public static final String escapeText(final String text, boolean forceHexMode) { if (text != null && text.length() > 0) { + boolean unicode = false; + boolean hexMode = false; + if (forceHexMode) { + hexMode = true; + } else { + for (int i = 0, c = text.length(); i < c; i++) { + if (text.charAt(i) >= 128) { + unicode = true; + hexMode = true; + break; + } + } + } + if (hexMode) { final byte[] uniBytes; try { - uniBytes = text.getBytes("UnicodeBig"); + uniBytes = text.getBytes("UTF-16"); } catch (java.io.UnsupportedEncodingException uee) { throw new CascadingRuntimeException("Incompatible VM", uee); } @@ -96,22 +110,29 @@ public class PDFText extends PDFObject { result.append("("); final int l = text.length(); - // byte order marker (0xfeff) - result.append("\\376\\377"); - - for (int i = 0; i < l; i++) { - final char ch = text.charAt(i); - //if (ch < 128) { - // result.append('\u0000'); - // result.append(ch); - //} else { + if (unicode) { + // byte order marker (0xfeff) + result.append("\\376\\377"); + + for (int i = 0; i < l; i++) { + final char ch = text.charAt(i); final int high = (ch & 0xff00) >>> 8; final int low = ch & 0xff; result.append("\\"); result.append(Integer.toOctalString(high)); result.append("\\"); result.append(Integer.toOctalString(low)); - //} + } + } else { + for (int i = 0; i < l; i++) { + final char ch = text.charAt(i); + if (ch < 256) { + escapeStringChar(ch, result); + } else { + throw new IllegalStateException( + "Can only treat text in 8-bit ASCII/PDFEncoding"); + } + } } result.append(")"); return result.toString(); |