aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2006-03-30 09:57:32 +0000
committerJeremias Maerki <jeremias@apache.org>2006-03-30 09:57:32 +0000
commitfc889fb52f76f227a7ff8814dbe608a09394a971 (patch)
treeb86c2ffc8b78a93300a1163f62f218e4eccfa140 /src/java/org
parent1395c45d9d371d044795b526a07cee6bc3335075 (diff)
downloadxmlgraphics-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')
-rw-r--r--src/java/org/apache/fop/pdf/PDFMetadata.java30
-rw-r--r--src/java/org/apache/fop/pdf/PDFObject.java4
-rw-r--r--src/java/org/apache/fop/pdf/PDFText.java51
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();