📄 coswriter.java
字号:
{
addObjectToWrite( root );
}
if( info != null )
{
addObjectToWrite( info );
}
while( objectsToWrite.size() > 0 )
{
COSBase nextObject = (COSBase)objectsToWrite.remove( 0 );
doWriteObject( nextObject );
}
willEncrypt = false;
if( encrypt != null )
{
addObjectToWrite( encrypt );
}
while( objectsToWrite.size() > 0 )
{
COSBase nextObject = (COSBase)objectsToWrite.remove( 0 );
doWriteObject( nextObject );
}
// write all objects
/**
for (Iterator i = doc.getObjects().iterator(); i.hasNext();)
{
COSObject obj = (COSObject) i.next();
doWriteObject(obj);
}**/
}
private void addObjectToWrite( COSBase object )
{
COSBase actual = object;
if( actual instanceof COSObject )
{
actual = ((COSObject)actual).getObject();
}
if( !writtenObjects.contains( object ) &&
!objectsToWrite.contains( object ) &&
!actualsAdded.contains( actual ) )
{
objectsToWrite.add( object );
if( actual != null )
{
actualsAdded.add( actual );
}
}
}
/**
* This will write a COS object.
*
* @param obj The object to write.
*
* @throws COSVisitorException If there is an error visiting objects.
*/
public void doWriteObject( COSBase obj ) throws COSVisitorException
{
try
{
writtenObjects.add( obj );
// find the physical reference
currentObjectKey = getObjectKey( obj );
// add a x ref entry
addXRefEntry( new COSWriterXRefEntry(getStandardOutput().getPos(), obj, currentObjectKey));
// write the object
getStandardOutput().write(String.valueOf(currentObjectKey.getNumber()).getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(String.valueOf(currentObjectKey.getGeneration()).getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(OBJ);
getStandardOutput().writeEOL();
obj.accept( this );
getStandardOutput().writeEOL();
getStandardOutput().write(ENDOBJ);
getStandardOutput().writeEOL();
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
/**
* This will write the header to the PDF document.
*
* @param doc The document to get the data from.
*
* @throws IOException If there is an error writing to the stream.
*/
protected void doWriteHeader(COSDocument doc) throws IOException
{
getStandardOutput().write( doc.getHeaderString().getBytes() );
getStandardOutput().writeEOL();
getStandardOutput().write(COMMENT);
getStandardOutput().write(GARBAGE);
getStandardOutput().writeEOL();
}
/**
* This will write the trailer to the PDF document.
*
* @param doc The document to create the trailer for.
*
* @throws IOException If there is an IOError while writing the document.
* @throws COSVisitorException If there is an error while generating the data.
*/
protected void doWriteTrailer(COSDocument doc) throws IOException, COSVisitorException
{
getStandardOutput().write(TRAILER);
getStandardOutput().writeEOL();
COSDictionary trailer = doc.getTrailer();
//sort xref, needed only if object keys not regenerated
Collections.sort(getXRefEntries());
COSWriterXRefEntry lastEntry = (COSWriterXRefEntry)getXRefEntries().get( getXRefEntries().size()-1);
trailer.setInt(COSName.getPDFName("Size"), (int)lastEntry.getKey().getNumber()+1);
trailer.removeItem( COSName.PREV );
/**
COSObject catalog = doc.getCatalog();
if (catalog != null)
{
trailer.setItem(COSName.getPDFName("Root"), catalog);
}
*/
trailer.accept(this);
getStandardOutput().write(STARTXREF);
getStandardOutput().writeEOL();
getStandardOutput().write(String.valueOf(getStartxref()).getBytes());
getStandardOutput().writeEOL();
getStandardOutput().write(EOF);
}
/**
* write the x ref section for the pdf file
*
* currently, the pdf is reconstructed from the scratch, so we write a single section
*
* todo support for incremental writing?
*
* @param doc The document to write the xref from.
*
* @throws IOException If there is an error writing the data to the stream.
*/
protected void doWriteXRef(COSDocument doc) throws IOException
{
String offset;
String generation;
// sort xref, needed only if object keys not regenerated
Collections.sort(getXRefEntries());
COSWriterXRefEntry lastEntry = (COSWriterXRefEntry)getXRefEntries().get( getXRefEntries().size()-1 );
// remember the position where x ref is written
setStartxref(getStandardOutput().getPos());
//
getStandardOutput().write(XREF);
getStandardOutput().writeEOL();
// write start object number and object count for this x ref section
// we assume starting from scratch
getStandardOutput().write(String.valueOf(0).getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(String.valueOf(lastEntry.getKey().getNumber() + 1).getBytes());
getStandardOutput().writeEOL();
// write initial start object with ref to first deleted object and magic generation number
offset = formatXrefOffset.format(0);
generation = formatXrefGeneration.format(65535);
getStandardOutput().write(offset.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(generation.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(XREF_FREE);
getStandardOutput().writeCRLF();
// write entry for every object
long lastObjectNumber = 0;
for (Iterator i = getXRefEntries().iterator(); i.hasNext();)
{
COSWriterXRefEntry entry = (COSWriterXRefEntry) i.next();
while( lastObjectNumber<entry.getKey().getNumber()-1 )
{
offset = formatXrefOffset.format(0);
generation = formatXrefGeneration.format(65535);
getStandardOutput().write(offset.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(generation.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(XREF_FREE);
getStandardOutput().writeCRLF();
lastObjectNumber++;
}
lastObjectNumber = entry.getKey().getNumber();
offset = formatXrefOffset.format(entry.getOffset());
generation = formatXrefGeneration.format(entry.getKey().getGeneration());
getStandardOutput().write(offset.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(generation.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(entry.isFree() ? XREF_FREE : XREF_USED);
getStandardOutput().writeCRLF();
}
}
/**
* This will get the object key for the object.
*
* @param obj The object to get the key for.
*
* @return The object key for the object.
*/
private COSObjectKey getObjectKey( COSBase obj )
{
COSBase actual = obj;
if( actual instanceof COSObject )
{
actual = ((COSObject)obj).getObject();
}
COSObjectKey key = null;
if( actual != null )
{
key = (COSObjectKey)objectKeys.get(actual);
}
if( key == null )
{
key = (COSObjectKey)objectKeys.get(obj);
}
if (key == null)
{
setNumber(getNumber()+1);
key = new COSObjectKey(getNumber(),0);
objectKeys.put(obj, key);
if( actual != null )
{
objectKeys.put(actual, key);
}
}
return key;
}
/**
* visitFromArray method comment.
*
* @param obj The object that is being visited.
*
* @throws COSVisitorException If there is an exception while visiting this object.
*
* @return null
*/
public Object visitFromArray( COSArray obj ) throws COSVisitorException
{
try
{
int count = 0;
getStandardOutput().write(ARRAY_OPEN);
for (Iterator i = obj.iterator(); i.hasNext();)
{
COSBase current = (COSBase) i.next();
if( current instanceof COSDictionary )
{
addObjectToWrite( current );
writeReference( current );
}
else if( current instanceof COSObject )
{
COSBase subValue = ((COSObject)current).getObject();
if( subValue instanceof COSDictionary || subValue == null )
{
addObjectToWrite( current );
writeReference( current );
}
else
{
subValue.accept( this );
}
}
else if( current == null )
{
COSNull.NULL.accept( this );
}
else
{
current.accept(this);
}
count++;
if (i.hasNext())
{
if (count % 10 == 0)
{
getStandardOutput().writeEOL();
}
else
{
getStandardOutput().write(SPACE);
}
}
}
getStandardOutput().write(ARRAY_CLOSE);
getStandardOutput().writeEOL();
return null;
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
/**
* visitFromBoolean method comment.
*
* @param obj The object that is being visited.
*
* @throws COSVisitorException If there is an exception while visiting this object.
*
* @return null
*/
public Object visitFromBoolean(COSBoolean obj) throws COSVisitorException
{
try
{
obj.writePDF( getStandardOutput() );
return null;
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
/**
* visitFromDictionary method comment.
*
* @param obj The object that is being visited.
*
* @throws COSVisitorException If there is an exception while visiting this object.
*
* @return null
*/
public Object visitFromDictionary(COSDictionary obj) throws COSVisitorException
{
try
{
getStandardOutput().write(DICT_OPEN);
getStandardOutput().writeEOL();
for (Iterator i = obj.keyList().iterator(); i.hasNext();)
{
COSName name = (COSName) i.next();
COSBase value = obj.getItem(name);
if (value != null)
{
name.accept(this);
getStandardOutput().write(SPACE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -