Porting update.

git-svn-id: svn://svn.code.sf.net/p/itextsharp/code/trunk@30 820d3149-562b-4f88-9aa4-a8e61a3485cf
master
psoares33 2009-06-14 10:26:24 +00:00
parent 5b3065c1df
commit 167fa81408
7 changed files with 517 additions and 31 deletions

View File

@ -1,6 +1,8 @@
using System;
using System.Collections;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.exceptions;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.intern;
@ -175,6 +177,9 @@ namespace iTextSharp.text.pdf {
*/
protected int separator = '\n';
private int mcDepth = 0;
private bool inText = false;
private static Hashtable abrev = new Hashtable();
static PdfContentByte() {
@ -234,6 +239,7 @@ namespace iTextSharp.text.pdf {
*/
public byte[] ToPdf(PdfWriter writer) {
SanityCheck();
return content.ToByteArray();
}
@ -1169,6 +1175,14 @@ namespace iTextSharp.text.pdf {
if (inlineImage) {
content.Append("\nBI\n");
PdfImage pimage = new PdfImage(image, "", null);
if (image is ImgJBIG2) {
byte[] globals = ((ImgJBIG2)image).GlobalBytes;
if (globals != null) {
PdfDictionary decodeparms = new PdfDictionary();
decodeparms.Put(PdfName.JBIG2GLOBALS, writer.GetReferenceJBIG2Globals(globals));
pimage.Put(PdfName.DECODEPARMS, decodeparms);
}
}
foreach (PdfName key in pimage.Keys) {
PdfObject value = pimage.Get(key);
String s = (String)abrev[key];
@ -1177,12 +1191,12 @@ namespace iTextSharp.text.pdf {
content.Append(s);
bool check = true;
if (key.Equals(PdfName.COLORSPACE) && value.IsArray()) {
ArrayList ar = ((PdfArray)value).ArrayList;
if (ar.Count == 4
&& PdfName.INDEXED.Equals(ar[0])
&& ((PdfObject)ar[1]).IsName()
&& ((PdfObject)ar[2]).IsNumber()
&& ((PdfObject)ar[3]).IsString()
PdfArray ar = (PdfArray)value;
if (ar.Size == 4
&& PdfName.INDEXED.Equals(ar.GetAsName(0))
&& ar[1].IsName()
&& ar[2].IsNumber()
&& ar[3].IsString()
) {
check = false;
}
@ -1251,11 +1265,23 @@ namespace iTextSharp.text.pdf {
}
/**
* Makes this <CODE>PdfContentByte</CODE> empty.
*/
* Makes this <CODE>PdfContentByte</CODE> empty.
* Calls <code>reset( true )</code>
*/
public void Reset() {
Reset( true );
}
/**
* Makes this <CODE>PdfContentByte</CODE> empty.
* @param validateContent will call <code>sanityCheck()</code> if true.
* @since 2.1.6
*/
public void Reset( bool validateContent ) {
content.Reset();
stateList.Clear();
if (validateContent) {
SanityCheck();
}
state = new GraphicState();
}
@ -1263,6 +1289,10 @@ namespace iTextSharp.text.pdf {
* Starts the writing of text.
*/
public void BeginText() {
if (inText) {
throw new IllegalPdfSyntaxException("Unbalanced begin/end text operators." );
}
inText = true;
state.xTLM = 0;
state.yTLM = 0;
content.Append("BT").Append_i(separator);
@ -1272,6 +1302,10 @@ namespace iTextSharp.text.pdf {
* Ends the writing of text and makes the current font invalid.
*/
public void EndText() {
if (!inText) {
throw new IllegalPdfSyntaxException("Unbalanced begin/end text operators." );
}
inText = false;
content.Append("ET").Append_i(separator);
}
@ -1292,7 +1326,7 @@ namespace iTextSharp.text.pdf {
content.Append('Q').Append_i(separator);
int idx = stateList.Count - 1;
if (idx < 0)
throw new Exception("Unbalanced save/restore state operators.");
throw new IllegalPdfSyntaxException("Unbalanced save/restore state operators.");
state = (GraphicState)stateList[idx];
stateList.RemoveAt(idx);
}
@ -2788,6 +2822,8 @@ namespace iTextSharp.text.pdf {
if (layerDepth != null && layerDepth.Count > 0) {
n = (int)layerDepth[layerDepth.Count - 1];
layerDepth.RemoveAt(layerDepth.Count - 1);
} else {
throw new IllegalPdfSyntaxException("Unbalanced layer operators." );
}
while (n-- > 0)
content.Append("EMC").Append_i(separator);
@ -2831,7 +2867,7 @@ namespace iTextSharp.text.pdf {
}
else if (obj.IsArray()) {
ar = (PdfArray)obj;
if (!((PdfObject)ar.ArrayList[0]).IsNumber())
if (!ar[0].IsNumber())
throw new ArgumentException("The structure has kids.");
}
else
@ -2847,6 +2883,7 @@ namespace iTextSharp.text.pdf {
struc.Put(PdfName.PG, writer.CurrentPage);
}
pdf.IncMarkPoint();
mcDepth++;
content.Append(struc.Get(PdfName.S).GetBytes()).Append(" <</MCID ").Append(mark).Append(">> BDC").Append_i(separator);
}
@ -2854,6 +2891,10 @@ namespace iTextSharp.text.pdf {
* Ends a marked content sequence
*/
public void EndMarkedContentSequence() {
if (mcDepth == 0) {
throw new IllegalPdfSyntaxException("Unbalanced begin/end marked content operators." );
}
--mcDepth;
content.Append("EMC").Append_i(separator);
}
@ -2885,6 +2926,7 @@ namespace iTextSharp.text.pdf {
content.Append(name.GetBytes());
}
content.Append(" BDC").Append_i(separator);
++mcDepth;
}
/**
@ -2894,5 +2936,31 @@ namespace iTextSharp.text.pdf {
public void BeginMarkedContentSequence(PdfName tag) {
BeginMarkedContentSequence(tag, null, false);
}
/**
* Checks for any dangling state: Mismatched save/restore state, begin/end text,
* begin/end layer, or begin/end marked content sequence.
* If found, this function will throw. This function is called automatically
* during a reset() (from Document.newPage() for example), and before writing
* itself out in toPdf().
* One possible cause: not calling myPdfGraphics2D.dispose() will leave dangling
* saveState() calls.
* @since 2.1.6
* @throws IllegalPdfSyntaxException (a runtime exception)
*/
public void SanityCheck() {
if (mcDepth != 0) {
throw new IllegalPdfSyntaxException("Unbalanced marked content operators." );
}
if (inText) {
throw new IllegalPdfSyntaxException("Unbalanced begin/end text operators." );
}
if (layerDepth != null && layerDepth.Count > 0) {
throw new IllegalPdfSyntaxException("Unbalanced layer operators." );
}
if (stateList.Count > 0) {
throw new IllegalPdfSyntaxException("Unbalanced save/restore state operators." );
}
}
}
}

View File

@ -0,0 +1,171 @@
using System;
using System.IO;
using System.Collections;
using System.util.zlib;
/*
* $Id: PdfEFStream.java 3735 2009-02-26 01:44:03Z xlv $
*
* Copyright (c) 2008 by Bruno Lowagie
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or under the terms of the GNU
* Library General Public License as published by the Free Software Foundation;
* either version 2 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
* details.
*
* If you didn't download this code from the following link, you should check if
* you aren't using an obsolete version:
* http://www.lowagie.com/iText/
*/
namespace iTextSharp.text.pdf {
/**
* Extends PdfStream and should be used to create Streams for Embedded Files
* (file attachments).
* @since 2.1.3
*/
public class PdfEFStream : PdfStream {
/**
* Creates a Stream object using an InputStream and a PdfWriter object
* @param in the InputStream that will be read to get the Stream object
* @param writer the writer to which the stream will be added
*/
public PdfEFStream(Stream inp, PdfWriter writer) : base (inp, writer) {
}
/**
* Creates a Stream object using a byte array
* @param fileStore the bytes for the stream
*/
public PdfEFStream(byte[] fileStore) : base(fileStore) {
}
/**
* @see com.lowagie.text.pdf.PdfDictionary#toPdf(com.lowagie.text.pdf.PdfWriter, java.io.OutputStream)
*/
public override void ToPdf(PdfWriter writer, Stream os) {
if (inputStream != null && compressed)
Put(PdfName.FILTER, PdfName.FLATEDECODE);
PdfEncryption crypto = null;
if (writer != null)
crypto = writer.Encryption;
if (crypto != null) {
PdfObject filter = Get(PdfName.FILTER);
if (filter != null) {
if (PdfName.CRYPT.Equals(filter))
crypto = null;
else if (filter.IsArray()) {
PdfArray a = (PdfArray)filter;
if (!a.IsEmpty() && PdfName.CRYPT.Equals(a[0]))
crypto = null;
}
}
}
if (crypto != null && crypto.IsEmbeddedFilesOnly()) {
PdfArray filter = new PdfArray();
PdfArray decodeparms = new PdfArray();
PdfDictionary crypt = new PdfDictionary();
crypt.Put(PdfName.NAME, PdfName.STDCF);
filter.Add(PdfName.CRYPT);
decodeparms.Add(crypt);
if (compressed) {
filter.Add(PdfName.FLATEDECODE);
decodeparms.Add(new PdfNull());
}
Put(PdfName.FILTER, filter);
Put(PdfName.DECODEPARMS, decodeparms);
}
PdfObject nn = Get(PdfName.LENGTH);
if (crypto != null && nn != null && nn.IsNumber()) {
int sz = ((PdfNumber)nn).IntValue;
Put(PdfName.LENGTH, new PdfNumber(crypto.CalculateStreamSize(sz)));
SuperToPdf(writer, os);
Put(PdfName.LENGTH, nn);
}
else
SuperToPdf(writer, os);
os.Write(STARTSTREAM, 0, STARTSTREAM.Length);
if (inputStream != null) {
rawLength = 0;
ZDeflaterOutputStream def = null;
OutputStreamCounter osc = new OutputStreamCounter(os);
OutputStreamEncryption ose = null;
Stream fout = osc;
if (crypto != null)
fout = ose = crypto.GetEncryptionStream(fout);
if (compressed)
fout = def = new ZDeflaterOutputStream(fout, compressionLevel);
byte[] buf = new byte[4192];
while (true) {
int n = inputStream.Read(buf, 0, buf.Length);
if (n <= 0)
break;
fout.Write(buf, 0, n);
rawLength += n;
}
if (def != null)
def.Finish();
if (ose != null)
ose.Finish();
inputStreamLength = osc.Counter;
}
else {
if (crypto == null) {
if (streamBytes != null)
streamBytes.WriteTo(os);
else
os.Write(bytes, 0, bytes.Length);
}
else {
byte[] b;
if (streamBytes != null) {
b = crypto.EncryptByteArray(streamBytes.ToArray());
}
else {
b = crypto.EncryptByteArray(bytes);
}
os.Write(b, 0, b.Length);
}
}
os.Write(ENDSTREAM, 0, ENDSTREAM.Length);
}
}
}

View File

@ -3013,7 +3013,7 @@ namespace iTextSharp.text.pdf {
* @param content a byte array that may already been added to the writer inside a stream object.
* @since 2.1.5
*/
protected PdfIndirectReference GetReferenceJBIG2Globals(byte[] content) {
protected internal PdfIndirectReference GetReferenceJBIG2Globals(byte[] content) {
if (content == null) return null;
foreach (PdfStream str in JBIG2Globals.Keys) {
if (Org.BouncyCastle.Utilities.Arrays.AreEqual(content, str.GetBytes())) {

View File

@ -4,7 +4,7 @@ using System.Text;
using System.IO;
using System.Xml;
/*
* $Id: XfaForm.cs,v 1.9 2008/06/28 18:48:46 psoares33 Exp $
* $Id: XfaForm.cs,v 1.8 2008/06/06 14:57:18 psoares33 Exp $
*
* Copyright 2006 Paulo Soares
*
@ -61,6 +61,7 @@ namespace iTextSharp.text.pdf {
public class XfaForm {
private Xml2SomTemplate templateSom;
private XmlNode templateNode;
private Xml2SomDatasets datasetsSom;
private AcroFieldsSearch acroFieldsSom;
private PdfReader reader;
@ -76,6 +77,21 @@ namespace iTextSharp.text.pdf {
public XfaForm() {
}
/**
* Return the XFA Object, could be an array, could be a Stream.
* Returns null f no XFA Object is present.
* @param reader a PdfReader instance
* @return the XFA object
* @since 2.1.3
*/
public static PdfObject GetXfaObject(PdfReader reader) {
PdfDictionary af = (PdfDictionary)PdfReader.GetPdfObjectRelease(reader.Catalog.Get(PdfName.ACROFORM));
if (af == null) {
return null;
}
return PdfReader.GetPdfObjectRelease(af.Get(PdfName.XFA));
}
/**
* A constructor from a <CODE>PdfReader</CODE>. It basically does everything
* from finding the XFA stream to the XML parsing.
@ -86,12 +102,7 @@ namespace iTextSharp.text.pdf {
*/
public XfaForm(PdfReader reader) {
this.reader = reader;
PdfDictionary af = (PdfDictionary)PdfReader.GetPdfObjectRelease(reader.Catalog.Get(PdfName.ACROFORM));
if (af == null) {
xfaPresent = false;
return;
}
PdfObject xfa = PdfReader.GetPdfObjectRelease(af.Get(PdfName.XFA));
PdfObject xfa = GetXfaObject(reader);
if (xfa == null) {
xfaPresent = false;
return;
@ -99,9 +110,9 @@ namespace iTextSharp.text.pdf {
xfaPresent = true;
MemoryStream bout = new MemoryStream();
if (xfa.IsArray()) {
ArrayList ar = ((PdfArray)xfa).ArrayList;
for (int k = 1; k < ar.Count; k += 2) {
PdfObject ob = PdfReader.GetPdfObject((PdfObject)ar[k]);
PdfArray ar = (PdfArray)xfa;
for (int k = 1; k < ar.Size; k += 2) {
PdfObject ob = ar.GetDirectObject(k);
if (ob is PRStream) {
byte[] b = PdfReader.GetStreamBytes((PRStream)ob);
bout.Write(b, 0, b.Length);
@ -117,6 +128,14 @@ namespace iTextSharp.text.pdf {
domDocument = new XmlDocument();
domDocument.PreserveWhitespace = true;
domDocument.Load(xtr);
ExtractNodes();
}
/**
* Extracts the nodes from the domDocument.
* @since 2.1.5
*/
private void ExtractNodes() {
XmlNode n = domDocument.FirstChild;
while (n.NodeType != XmlNodeType.Element || n.ChildNodes.Count == 0)
n = n.NextSibling;
@ -125,6 +144,7 @@ namespace iTextSharp.text.pdf {
if (n.NodeType == XmlNodeType.Element) {
String s = n.LocalName;
if (s.Equals("template")) {
templateNode = n;
templateSom = new Xml2SomTemplate(n);
}
else if (s.Equals("datasets")) {
@ -138,19 +158,46 @@ namespace iTextSharp.text.pdf {
/**
* Sets the XFA key from a byte array. The old XFA is erased.
* @param xfaData the data
* @param form the data
* @param reader the reader
* @param writer the writer
* @throws java.io.IOException on error
*/
public static void SetXfa(byte[] xfaData, PdfReader reader, PdfWriter writer) {
public static void SetXfa(XfaForm form, PdfReader reader, PdfWriter writer) {
PdfDictionary af = (PdfDictionary)PdfReader.GetPdfObjectRelease(reader.Catalog.Get(PdfName.ACROFORM));
if (af == null) {
return;
}
PdfObject xfa = GetXfaObject(reader);
if (xfa.IsArray()) {
PdfArray ar = (PdfArray)xfa;
int t = -1;
int d = -1;
for (int k = 0; k < ar.Size; k += 2) {
PdfString s = ar.GetAsString(k);
if ("template".Equals(s.ToString())) {
t = k + 1;
}
if ("datasets".Equals(s.ToString())) {
d = k + 1;
}
}
if (t > -1 && d > -1) {
reader.KillXref(ar.GetAsIndirectObject(t));
reader.KillXref(ar.GetAsIndirectObject(d));
PdfStream tStream = new PdfStream(SerializeDoc(form.templateNode));
tStream.FlateCompress(writer.CompressionLevel);
ar[t] = writer.AddToBody(tStream).IndirectReference;
PdfStream dStream = new PdfStream(SerializeDoc(form.datasetsNode));
dStream.FlateCompress(writer.CompressionLevel);
ar[d] = writer.AddToBody(dStream).IndirectReference;
af.Put(PdfName.XFA, new PdfArray(ar));
return;
}
}
reader.KillXref(af.Get(PdfName.XFA));
PdfStream str = new PdfStream(xfaData);
str.FlateCompress();
PdfStream str = new PdfStream(SerializeDoc(form.domDocument));
str.FlateCompress(writer.CompressionLevel);
PdfIndirectReference refe = writer.AddToBody(str).IndirectReference;
af.Put(PdfName.XFA, refe);
}
@ -161,7 +208,7 @@ namespace iTextSharp.text.pdf {
* @throws java.io.IOException on error
*/
public void SetXfa(PdfWriter writer) {
SetXfa(SerializeDoc(domDocument), reader, writer);
SetXfa(this, reader, writer);
}
/**
@ -201,6 +248,7 @@ namespace iTextSharp.text.pdf {
}
set {
domDocument = value;
ExtractNodes();
}
}
@ -217,7 +265,10 @@ namespace iTextSharp.text.pdf {
if (items.ContainsKey(name))
return name;
if (acroFieldsSom == null) {
acroFieldsSom = new AcroFieldsSearch(items.Keys);
if (items.Count == 0 && xfaPresent)
acroFieldsSom = new AcroFieldsSearch(datasetsSom.Name2Node.Keys);
else
acroFieldsSom = new AcroFieldsSearch(items.Keys);
}
if (acroFieldsSom.AcroShort2LongName.ContainsKey(name))
return (String)acroFieldsSom.AcroShort2LongName[name];

View File

@ -0,0 +1,168 @@
using System;
using System.IO;
using System.Xml;
using System.Text;
/*
* Copyright 2008 by Bruno Lowagie
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2008 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or under the terms of the GNU
* Library General Public License as published by the Free Software Foundation;
* either version 2 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
* details.
*
* If you didn't download this code from the following link, you should check if
* you aren't using an obsolete version:
* http://www.lowagie.com/iText/
*/
namespace iTextSharp.text.xml.xmp {
/**
* Reads an XMP stream into an org.w3c.dom.Document objects.
* Allows you to replace the contents of a specific tag.
* @since 2.1.3
*/
public class XmpReader {
private XmlDocument domDocument;
/**
* Constructs an XMP reader
* @param bytes the XMP content
* @throws ExceptionConverter
* @throws IOException
* @throws SAXException
*/
public XmpReader(byte[] bytes) {
MemoryStream bout = new MemoryStream();
bout.Write(bytes, 0, bytes.Length);
bout.Seek(0, SeekOrigin.Begin);
XmlTextReader xtr = new XmlTextReader(bout);
domDocument = new XmlDocument();
domDocument.PreserveWhitespace = true;
domDocument.Load(xtr);
}
/**
* Replaces the content of a tag.
* @param namespaceURI the URI of the namespace
* @param localName the tag name
* @param value the new content for the tag
* @return true if the content was successfully replaced
* @since 2.1.6 the return type has changed from void to boolean
*/
public bool Replace(String namespaceURI, String localName, String value) {
XmlNodeList nodes = domDocument.GetElementsByTagName(localName, namespaceURI);
XmlNode node;
if (nodes.Count == 0)
return false;
for (int i = 0; i < nodes.Count; i++) {
node = nodes[i];
SetNodeText(domDocument, node, value);
}
return true;
}
/**
* Adds a tag.
* @param namespaceURI the URI of the namespace
* @param parent the tag name of the parent
* @param localName the name of the tag to add
* @param value the new content for the tag
* @return true if the content was successfully added
* @since 2.1.6
*/
public bool Add(String parent, String namespaceURI, String localName, String value) {
XmlNodeList nodes = domDocument.GetElementsByTagName(parent);
if (nodes.Count == 0)
return false;
XmlNode pNode;
XmlNode node;
for (int i = 0; i < nodes.Count; i++) {
pNode = nodes[i];
XmlAttributeCollection attrs = pNode.Attributes;
for (int j = 0; j < attrs.Count; j++) {
node = attrs[j];
if (namespaceURI.Equals(node.Value)) {
node = domDocument.CreateElement(localName);
node.AppendChild(domDocument.CreateTextNode(value));
pNode.AppendChild(node);
return true;
}
}
}
return false;
}
/**
* Sets the text of this node. All the child's node are deleted and a new
* child text node is created.
* @param domDocument the <CODE>Document</CODE> that contains the node
* @param n the <CODE>Node</CODE> to add the text to
* @param value the text to add
*/
public bool SetNodeText(XmlDocument domDocument, XmlNode n, String value) {
if (n == null)
return false;
XmlNode nc = null;
while ((nc = n.FirstChild) != null) {
n.RemoveChild(nc);
}
n.AppendChild(domDocument.CreateTextNode(value));
return true;
}
/**
* Writes the document to a byte array.
*/
public byte[] SerializeDoc() {
MemoryStream fout = new MemoryStream();
byte[] b = new UTF8Encoding(false).GetBytes(XmpWriter.XPACKET_PI_BEGIN);
fout.Write(b, 0, b.Length);
fout.Flush();
XmlNodeList xmpmeta = domDocument.GetElementsByTagName("x:xmpmeta");
XmlTextWriter xw = new XmlTextWriter(fout, new UTF8Encoding(false));
xw.WriteNode(new XmlNodeReader(xmpmeta[0]), true);
xw.Flush();
b = new UTF8Encoding(false).GetBytes(XmpWriter.XPACKET_PI_END_W);
fout.Write(b, 0, b.Length);
fout.Close();
return fout.ToArray();
}
}
}

View File

@ -83,6 +83,24 @@ namespace iTextSharp.text.xml.xmp {
/** The about string that goes into the rdf:Description tags. */
protected String about;
/**
* Processing Instruction required at the start of an XMP stream
* @since iText 2.1.6
*/
public const String XPACKET_PI_BEGIN = "<?xpacket begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n";
/**
* Processing Instruction required at the end of an XMP stream for XMP streams that can be updated
* @since iText 2.1.6
*/
public const String XPACKET_PI_END_W = "<?xpacket end=\"w\"?>";
/**
* Processing Instruction required at the end of an XMP stream for XMP streams that are read only
* @since iText 2.1.6
*/
public const String XPACKET_PI_END_R = "<?xpacket end=\"r\"?>";
/** The end attribute. */
protected char end = 'w';
@ -96,7 +114,7 @@ namespace iTextSharp.text.xml.xmp {
public XmpWriter(Stream os, string utfEncoding, int extraSpace) {
this.extraSpace = extraSpace;
writer = new StreamWriter(os, new EncodingNoPreamble(IanaEncodings.GetEncodingEncoding(utfEncoding)));
writer.Write("<?xpacket begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n");
writer.Write(XPACKET_PI_BEGIN);
writer.Write("<x:xmpmeta xmlns:x=\"adobe:ns:meta/\">\n");
writer.Write("<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n");
about = "";
@ -165,7 +183,7 @@ namespace iTextSharp.text.xml.xmp {
for (int i = 0; i < extraSpace; i++) {
writer.Write(EXTRASPACE);
}
writer.Write("<?xpacket end=\"" + end + "\"?>");
writer.Write(end == 'r' ? XPACKET_PI_END_R : XPACKET_PI_END_W);
writer.Flush();
writer.Close();
}

View File

@ -872,6 +872,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "iTextSharp\text\pdf\PdfEFStream.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "iTextSharp\text\pdf\PdfEncodings.cs"
SubType = "Code"
@ -2222,6 +2227,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "iTextSharp\text\xml\xmp\XmpReader.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "iTextSharp\text\xml\xmp\XmpSchema.cs"
SubType = "Code"
@ -5364,7 +5374,7 @@
/>
<File
RelPath = "srcbc\crypto\parameters\DSAKeyParameters.cs"
SubType = "Code"
SubType = ""
BuildAction = "Compile"
/>
<File