Hi All,
Here are some fixes to embedded attachment handling in iTextSharp.
PdfEncodings.cs: Changed behavior of loading attachment object names.
Might have side effects elsewhere. In my opinion Unicode should be used
internally to process all strings. Raw version can be kept handy if needed.
Anyway. This was needed when embedded attachment object name was in
Unicode and iTextSharp saved new attachment with Ascii version. Now
Acrobat Reader 9.1 failed to handle files properly.
PdfFileSpecification.cs: Contains bugfixes to wrapper functions. Also
removes the need to make indirect object for data. Generates smaller PDF
file and smaller catalog.
PdfName.cs: Couple of new tokens.
PdfStamperImp.cs: If attachments were added, it would generate new
EmbeddedFiles entry in the written PDF file. This fixes it so that
previous EmbeddedFiles entry is removed.
PdfStream.cs: Keeps track of original attachment size in DL.
Documentation fixes.
PdfSignatureAppearance.cs: Documentation fixes.
Thanks,
Vesa Jääskeläinen
Index: iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfEncodings.cs
===================================================================
--- iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfEncodings.cs (revision 80)
+++ iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfEncodings.cs (working copy)
@@ -233,10 +233,22 @@
if (bytes == null)
return PdfObject.NOTHING;
if (encoding == null || encoding.Length == 0) {
- char[] c = new char[bytes.Length];
- for (int k = 0; k < bytes.Length; ++k)
- c[k] = (char)(bytes[k] & 0xff);
- return new String(c);
+ // If encoding wasn't specified, try to autodetect Unicode encoding
+ if (bytes.Length >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE)
+ {
+ encoding = "UNICODELITTLEUNMARKED";
+ }
+ else if (bytes.Length >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF)
+ {
+ encoding = "UNICODEBIGUNMARKED";
+ }
+ else
+ {
+ char[] c = new char[bytes.Length];
+ for (int k = 0; k < bytes.Length; ++k)
+ c[k] = (char)(bytes[k] & 0xff);
+ return new String(c);
+ }
}
IExtraEncoding extra =
(IExtraEncoding)extraEncodings[encoding.ToLower(System.Globalization.CultureInfo.InvariantCulture)];
if (extra != null) {
Index: iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfFileSpecification.cs
===================================================================
--- iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfFileSpecification.cs
(revision 80)
+++ iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfFileSpecification.cs
(working copy)
@@ -144,7 +144,7 @@
* @return the file specification
*/
public static PdfFileSpecification FileEmbedded(PdfWriter writer,
String filePath, String fileDisplay, byte[] fileStore, bool compress, String
mimeType, PdfDictionary fileParameter) {
- return FileEmbedded(writer, filePath, fileDisplay, fileStore,
null, null, compress ? PdfStream.BEST_COMPRESSION : PdfStream.NO_COMPRESSION);
+ return FileEmbedded(writer, filePath, fileDisplay, fileStore,
mimeType, fileParameter, compress ? PdfStream.BEST_COMPRESSION :
PdfStream.NO_COMPRESSION);
}
/**
@@ -169,11 +169,12 @@
PdfEFStream stream;
Stream inp = null;
PdfIndirectReference refi;
- PdfIndirectReference refFileLength;
+ PdfIndirectReference refFileLength = null;
try {
- refFileLength = writer.PdfIndirectReference;
if (fileStore == null) {
- if (File.Exists(filePath)) {
+ refFileLength = writer.PdfIndirectReference;
+ if (File.Exists(filePath))
+ {
inp = new FileStream(filePath, FileMode.Open,
FileAccess.Read);
}
else {
@@ -193,18 +194,30 @@
stream = new PdfEFStream(fileStore);
stream.Put(PdfName.TYPE, PdfName.EMBEDDEDFILE);
stream.FlateCompress(compressionLevel);
- stream.Put(PdfName.PARAMS, refFileLength);
+
+ PdfDictionary param = new PdfDictionary();
+ if (fileParameter != null)
+ param.Merge(fileParameter);
+
+ if (fileStore != null)
+ {
+ param.Put(PdfName.SIZE, new PdfNumber(stream.RawLength));
+ stream.Put(PdfName.PARAMS, param);
+ }
+ else
+ {
+ stream.Put(PdfName.PARAMS, refFileLength);
+ }
+
if (mimeType != null)
stream.Put(PdfName.SUBTYPE, new PdfName(mimeType));
+
refi = writer.AddToBody(stream).IndirectReference;
if (fileStore == null) {
stream.WriteLength();
+ param.Put(PdfName.SIZE, new PdfNumber(stream.RawLength));
+ writer.AddToBody(param, refFileLength);
}
- PdfDictionary param = new PdfDictionary();
- if (fileParameter != null)
- param.Merge(fileParameter);
- param.Put(PdfName.SIZE, new PdfNumber(stream.RawLength));
- writer.AddToBody(param, refFileLength);
}
finally {
if (inp != null)
Index: iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfName.cs
===================================================================
--- iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfName.cs (revision 80)
+++ iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfName.cs (working copy)
@@ -293,6 +293,8 @@
/** A name */
public static readonly PdfName CH = new PdfName("Ch");
/** A name */
+ public static readonly PdfName CHECKSUM = new PdfName("CheckSum");
+ /** A name */
public static readonly PdfName CHARPROCS = new PdfName("CharProcs");
/** A name */
public static readonly PdfName CI = new PdfName("CI");
@@ -406,6 +408,8 @@
public static readonly PdfName DC = new PdfName("DC");
/** A name */
public static readonly PdfName DCTDECODE = new PdfName("DCTDecode");
+ /** A name */
+ public static readonly PdfName DL = new PdfName("DL");
/**
* A name.
* @since 2.1.6
Index: iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfSignatureAppearance.cs
===================================================================
--- iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfSignatureAppearance.cs
(revision 80)
+++ iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfSignatureAppearance.cs
(working copy)
@@ -337,6 +337,7 @@
* <p>
* Consult <A
HREF="http://partners.adobe.com/asn/developer/pdfs/tn/PPKAppearances.pdf">PPKAppearances.pdf</A>
* for further details.
+ * </p>
* @return the main appearance layer
* @throws DocumentException on error
* @throws IOException on error
Index: iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfStamperImp.cs
===================================================================
--- iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfStamperImp.cs
(revision 80)
+++ iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfStamperImp.cs
(working copy)
@@ -1279,6 +1279,15 @@
old[nn] = entry.Value;
}
PdfDictionary tree = PdfNameTree.WriteTree(old, this);
+
+ // Remove old EmbeddedFiles object if preset
+ PdfObject oldEmbeddedFiles = names.Get(PdfName.EMBEDDEDFILES);
+ if (oldEmbeddedFiles != null)
+ {
+ PdfReader.KillIndirect(oldEmbeddedFiles);
+ }
+
+ // Add new EmbeddedFiles object
names.Put(PdfName.EMBEDDEDFILES,
AddToBody(tree).IndirectReference);
}
Index: iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfStream.cs
===================================================================
--- iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfStream.cs (revision 80)
+++ iTextSharp/svn/src/core/iTextSharp/text/pdf/PdfStream.cs (working copy)
@@ -72,6 +72,7 @@
* Remark: In this version only the FLATEDECODE-filter is supported.<BR>
* This object is described in the 'Portable Document Format Reference
Manual version 1.3'
* section 4.8 (page 41-53).<BR>
+ * </P>
*
* @see PdfObject
* @see PdfDictionary
@@ -141,7 +142,6 @@
/**
* Creates an efficient stream. No temporary array is ever created.
The <CODE>InputStream</CODE>
* is totally consumed but is not closed. The general usage is:
- * <p>
* <pre>
* InputStream in = ...;
* PdfStream stream = new PdfStream(in, writer);
@@ -176,6 +176,7 @@
* <p>
* This method must be called and can only be called if the contructor
{...@link #PdfStream(InputStream,PdfWriter)}
* is used to create the stream.
+ * </p>
* @throws IOException on error
* @see #PdfStream(InputStream,PdfWriter)
*/
@@ -210,7 +211,7 @@
public void FlateCompress(int compressionLevel) {
if (!Document.Compress)
return;
- // check if the flateCompress-method has allready been
+ // check if the flateCompress-method has already been
if (compressed) {
return;
}
@@ -219,7 +220,7 @@
compressed = true;
return;
}
- // check if a filter allready exists
+ // check if a filter already exists
PdfObject filter = PdfReader.GetPdfObject(Get(PdfName.FILTER));
if (filter != null) {
if (filter.IsName()) {
@@ -238,13 +239,21 @@
MemoryStream stream = new MemoryStream();
ZDeflaterOutputStream zip = new ZDeflaterOutputStream(stream,
compressionLevel);
if (streamBytes != null)
+ {
streamBytes.WriteTo(zip);
+ }
else
+ {
zip.Write(bytes, 0, bytes.Length);
+
+ // Keep track of original data length
+ Put(PdfName.DL, new PdfNumber(bytes.Length));
+ }
//zip.Close();
zip.Finish();
// update the object
streamBytes = stream;
+
bytes = null;
Put(PdfName.LENGTH, new PdfNumber(streamBytes.Length));
if (filter == null) {
------------------------------------------------------------------------------
Come build with us! The BlackBerry® Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9-12, 2009. Register now!
http://p.sf.net/sfu/devconf
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://www.1t3xt.com/docs/book.php
Check the site with examples before you ask questions:
http://www.1t3xt.info/examples/
You can also search the keywords list: http://1t3xt.info/tutorials/keywords/