[Podofo-svn] SF.net SVN: podofo: [358] podofo/trunk
A PDF parsing, modification and creation library.
Brought to you by:
domseichter
From: <dom...@us...> - 2007-01-23 14:38:59
|
Revision: 358 http://svn.sourceforge.net/podofo/?rev=358&view=rev Author: domseichter Date: 2007-01-23 06:38:57 -0800 (Tue, 23 Jan 2007) Log Message: ----------- Large patch to refactor PoDoFo's handling of XRef tables which was utterly broken. This patch first separates xref generation from writing the PDF file. PdfWriter is not responsible anymore for XRef generation. A new class PdfXRef handles this job now. This separation of concern will allow us to work more easily with problems in the XRef code. Additionally the XRef is build now when writing the XRef and not like before when writing the PdfObjects. This should fix issues when new free objects were added during loading of demand of objects during writing. This patch breaks linearization at the moment and XRef streams do not work correctly. As of now I do not yet understand why XRef streams do not work. PoDoFo is able to read the create XRef streams but poppler and Acrobat Reader refuse to do so. I will fix this ASAP. Modified Paths: -------------- podofo/trunk/ChangeLog podofo/trunk/src/CMakeLists.txt podofo/trunk/src/Makefile.am podofo/trunk/src/PdfDefines.h podofo/trunk/src/PdfDocument.cpp podofo/trunk/src/PdfDocument.h podofo/trunk/src/PdfHintStream.cpp podofo/trunk/src/PdfHintStream.h podofo/trunk/src/PdfParserObject.cpp podofo/trunk/src/PdfWriter.cpp podofo/trunk/src/PdfWriter.h podofo/trunk/src/podofo.h podofo/trunk/test/CreationTest/CreationTest.cpp podofo/trunk/test/LargeTest/LargeTest.cpp podofo/trunk/test/ParserTest/ParserTest.cpp Added Paths: ----------- podofo/trunk/src/PdfImmediateWriter.cpp podofo/trunk/src/PdfImmediateWriter.h podofo/trunk/src/PdfXRef.cpp podofo/trunk/src/PdfXRef.h podofo/trunk/src/PdfXRefStream.cpp podofo/trunk/src/PdfXRefStream.h Modified: podofo/trunk/ChangeLog =================================================================== --- podofo/trunk/ChangeLog 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/ChangeLog 2007-01-23 14:38:57 UTC (rev 358) @@ -9,7 +9,8 @@ Fixed reading PdfActions from PDF files Moved filter implementations to PdfFiltersPrivate.h Added PdfFilter::CanEncode and PdfFilter::CanDecode - + Simpliefid PoDoFos handling of XRef tables + Version 0.4 PdfImage now supports creating an image stream from a "raw bitmap" which can also be optionally Flate compressed Modified: podofo/trunk/src/CMakeLists.txt =================================================================== --- podofo/trunk/src/CMakeLists.txt 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/CMakeLists.txt 2007-01-23 14:38:57 UTC (rev 358) @@ -21,6 +21,7 @@ PdfFontMetrics.cpp PdfHintStream.cpp PdfImage.cpp + PdfImmediateWriter.cpp PdfInfo.cpp PdfInputDevice.cpp PdfInputStream.cpp @@ -47,6 +48,8 @@ PdfVecObjects.cpp PdfWriter.cpp PdfXObject.cpp + PdfXRef.cpp + PdfXRefStream.cpp ) SET(PODOFO_HEADERS @@ -73,6 +76,7 @@ PdfFontMetrics.h PdfHintStream.h PdfImage.h + PdfImmediateWriter.h PdfInfo.h PdfInputDevice.h PdfInputStream.h @@ -99,6 +103,8 @@ PdfVecObjects.h PdfWriter.h PdfXObject.h + PdfXRef.h + PdfXRefStream.h podofo.h podofoapi.h ) Modified: podofo/trunk/src/Makefile.am =================================================================== --- podofo/trunk/src/Makefile.am 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/Makefile.am 2007-01-23 14:38:57 UTC (rev 358) @@ -22,7 +22,7 @@ PdfEncrypt.h PdfNamesTree.h PdfInputDevice.h PdfHintStream.h \ PdfRefCountedInputDevice.h PdfInfo.h PdfFileSpec.h PdfExtGState.h \ PdfTokenizer.h PdfFiltersPrivate.h PdfInputStream.h PdfOutputStream.h \ - PdfFontCache.h + PdfFontCache.h PdfImmediateWriter.h PdfXRef.h PdfXRefStream.h # PdfSimpleWriter.cpp # PdfSimpleWriter.h libpodofo_la_SOURCES = PdfObject.cpp PdfParser.cpp PdfParserObject.cpp \ @@ -36,7 +36,7 @@ PdfEncrypt.cpp PdfNamesTree.cpp PdfInputDevice.cpp PdfHintStream.cpp \ PdfRefCountedInputDevice.cpp PdfInfo.cpp PdfFileSpec.cpp PdfExtGState.cpp \ PdfTokenizer.cpp PdfFiltersPrivate.cpp PdfInputStream.cpp PdfOutputStream.cpp \ - PdfFontCache.cpp + PdfFontCache.cpp PdfImmediateWriter.cpp PdfXRef.cpp PdfXRefStream.cpp # # Build a static library Modified: podofo/trunk/src/PdfDefines.h =================================================================== --- podofo/trunk/src/PdfDefines.h 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/PdfDefines.h 2007-01-23 14:38:57 UTC (rev 358) @@ -357,13 +357,13 @@ * \def PDF_MAX(x,y) * \returns the maximum of x and y */ -#define PDF_MAX(x,y) (x>y?x:y) +#define PDF_MAX(x,y) ((x)>(y)?(x):(y)) /** * \def PDF_MIN(x,y) * \returns the minimum of x and y */ -#define PDF_MIN(x,y) (x<y?x:y) +#define PDF_MIN(x,y) ((x)<(y)?(x):(y)) /* This is needed to enable compilation with VC++ on Windows Modified: podofo/trunk/src/PdfDocument.cpp =================================================================== --- podofo/trunk/src/PdfDocument.cpp 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/PdfDocument.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -29,6 +29,7 @@ #include "PdfFileSpec.h" #include "PdfFont.h" #include "PdfFontMetrics.h" +#include "PdfImmediateWriter.h" #include "PdfInfo.h" #include "PdfNamesTree.h" #include "PdfObject.h" @@ -43,7 +44,8 @@ using namespace std; PdfDocument::PdfDocument() - : m_pOutlines( NULL ), m_pNamesTree( NULL ), m_pPagesTree( NULL ), m_pTrailer( NULL ), m_fontCache( &m_vecObjects ) + : m_pOutlines( NULL ), m_pNamesTree( NULL ), m_pPagesTree( NULL ), + m_pTrailer( NULL ), m_fontCache( &m_vecObjects ), m_pImmediate( NULL ) { m_eVersion = ePdfVersion_1_3; m_bLinearized = false; @@ -62,7 +64,8 @@ } PdfDocument::PdfDocument( const char* pszFilename ) - : m_pInfo( NULL ), m_pOutlines( NULL ), m_pNamesTree( NULL ), m_pPagesTree( NULL ), m_pTrailer( NULL ), m_fontCache( &m_vecObjects ) + : m_pInfo( NULL ), m_pOutlines( NULL ), m_pNamesTree( NULL ), m_pPagesTree( NULL ), + m_pTrailer( NULL ), m_fontCache( &m_vecObjects ), m_pImmediate( NULL ) { m_vecObjects.SetParentDocument( this ); @@ -117,6 +120,12 @@ delete m_pTrailer; m_pTrailer = NULL; } + + if( m_pImmediate ) + { + delete m_pImmediate; + m_pImmediate = NULL; + } } void PdfDocument::InitFromParser( PdfParser* pParser ) @@ -202,6 +211,16 @@ writer.Write( pDevice ); } +void PdfDocument::WriteImmediately( PdfOutputDevice* pDevice ) +{ + if( m_pImmediate ) + { + RAISE_ERROR( ePdfError_InternalLogic ); + } + + m_pImmediate = new PdfImmediateWriter( pDevice, &m_vecObjects ); +} + PdfObject* PdfDocument::GetNamedObjectFromCatalog( const char* pszName ) const { return m_pCatalog->GetIndirectKey( PdfName( pszName ) ); @@ -261,7 +280,7 @@ } // append all pages now to our page tree - for(int i=0;i<rDoc.GetPageCount()-1;i++ ) + for(int i=0;i<rDoc.GetPageCount();i++ ) { PdfPage* pPage = rDoc.GetPage( i ); PdfObject* pObj = m_vecObjects.GetObject( PdfReference( pPage->GetObject()->Reference().ObjectNumber() + difference, 0 ) ); Modified: podofo/trunk/src/PdfDocument.h =================================================================== --- podofo/trunk/src/PdfDocument.h 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/PdfDocument.h 2007-01-23 14:38:57 UTC (rev 358) @@ -33,6 +33,7 @@ class PdfDictionary; class PdfFileSpec; class PdfFont; +class PdfImmediateWriter; class PdfInfo; class PdfNamesTree; class PdfOutlines; @@ -89,6 +90,18 @@ */ void Write( PdfOutputDevice* pDevice ); + /** Write the PDF immediately while all objects are + * created. This is much faster, if you are only + * creating PDF files and are not changing any objects + * after they have been created. + * + * This method may only be called once and should be + * the first method to call after constructing the PdfDocument. + * + * \param pDevice write to this device. + */ + void WriteImmediately( PdfOutputDevice* pDevice ); + /** Set the PDF Version of the document. Has to be called before Write() to * have an effect. * \param eVersion version of the pdf document @@ -362,6 +375,8 @@ EPdfVersion m_eVersion; PdfFontCache m_fontCache; + + PdfImmediateWriter* m_pImmediate; }; // ----------------------------------------------------- Modified: podofo/trunk/src/PdfHintStream.cpp =================================================================== --- podofo/trunk/src/PdfHintStream.cpp 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/PdfHintStream.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -239,6 +239,7 @@ } +/* void PdfHintStream::Create( TVecXRefTable* pXRef ) { this->CreatePageHintTable( pXRef ); @@ -350,6 +351,7 @@ } +*/ void PdfHintStream::WriteUInt16( pdf_uint16 val ) { Modified: podofo/trunk/src/PdfHintStream.h =================================================================== --- podofo/trunk/src/PdfHintStream.h 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/PdfHintStream.h 2007-01-23 14:38:57 UTC (rev 358) @@ -38,7 +38,7 @@ /** Create the hint stream * \param pXRef pointer to a valid XREF table structure */ - void Create( TVecXRefTable* pXRef ); + //void Create( TVecXRefTable* pXRef ); /** Write a pdf_uint16 to the stream in big endian format. * \param val the value to write to the stream @@ -51,7 +51,7 @@ void WriteUInt32( pdf_uint32 ); private: - void CreatePageHintTable( TVecXRefTable* pXRef ); + //void CreatePageHintTable( TVecXRefTable* pXRef ); void CreateSharedObjectHintTable(); private: Added: podofo/trunk/src/PdfImmediateWriter.cpp =================================================================== --- podofo/trunk/src/PdfImmediateWriter.cpp (rev 0) +++ podofo/trunk/src/PdfImmediateWriter.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2007 by Dominik Seichter * + * dom...@we... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "PdfImmediateWriter.h" + +#include "PdfObject.h" + +namespace PoDoFo { + +PdfImmediateWriter::PdfImmediateWriter( PdfOutputDevice* pDevice, PdfVecObjects* pVecObjects, EPdfVersion eVersion ) + : PdfWriter( pVecObjects ), m_pParent( pVecObjects ), m_pDevice( pDevice ) +{ + // register as observer for PdfVecObjects + + // start with writing the header + this->SetPdfVersion( eVersion ); + this->WritePdfHeader( m_pDevice ); +} + +PdfImmediateWriter::~PdfImmediateWriter() +{ + // calling here is too late, as the PdfVecObjects in PdfDocument + // is already cleared. + // + this->WriteOut(); +} + +void PdfImmediateWriter::WriteOut() +{ + TCIVecObjects itObjects = m_pParent->begin(); + + this->CompressObjects( *m_pParent ); + + while( itObjects != m_pParent->end() ) + { + this->WriteObject( *itObjects ); + ++itObjects; + } +} + +void PdfImmediateWriter::WriteObject( const PdfObject* pObject ) +{ + pObject->WriteObject( m_pDevice ); +} + +}; + Added: podofo/trunk/src/PdfImmediateWriter.h =================================================================== --- podofo/trunk/src/PdfImmediateWriter.h (rev 0) +++ podofo/trunk/src/PdfImmediateWriter.h 2007-01-23 14:38:57 UTC (rev 358) @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2007 by Dominik Seichter * + * dom...@we... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PDF_IMMEDIATE_WRITER_H_ +#define _PDF_IMMEDIATE_WRITER_H_ + +#include "PdfDefines.h" +#include "PdfWriter.h" + +namespace PoDoFo { + +class PdfOutputDevice; + +class PODOFO_API PdfImmediateWriter : private PdfWriter { + public: + PdfImmediateWriter( PdfOutputDevice* pDevice, PdfVecObjects* pVecObjects, EPdfVersion eVersion = ePdfVersion_1_5 ); + ~PdfImmediateWriter(); + + private: + void WriteOut(); + void WriteObject( const PdfObject* pObject ); + + private: + PdfVecObjects* m_pParent; + PdfOutputDevice* m_pDevice; +}; + +}; + +#endif /* _PDF_IMMEDIATE_WRITER_H_ */ + Modified: podofo/trunk/src/PdfParserObject.cpp =================================================================== --- podofo/trunk/src/PdfParserObject.cpp 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/PdfParserObject.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -115,6 +115,7 @@ #if defined(PODOFO_VERBOSE_DEBUG) std::cerr << "Parsing object number: " << m_reference.ObjectNumber() << " " << m_reference.GenerationNumber() << " obj" + << " " << m_lOffset << " offset" << " (DL: " << ( m_bLoadOnDemand ? "on" : "off" ) << ")" << endl; #endif // PODOFO_VERBOSE_DEBUG Modified: podofo/trunk/src/PdfWriter.cpp =================================================================== --- podofo/trunk/src/PdfWriter.cpp 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/PdfWriter.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -32,31 +32,18 @@ #include "PdfParser.h" #include "PdfStream.h" #include "PdfVariant.h" +#include "PdfXRef.h" +#include "PdfXRefStream.h" //#define PDF_MAGIC "%\xE2\xE3\xCF\xD3\n" //"%\0x25\0xe2\0xe3\0xcf\0xd3\0x0d" #define PDF_MAGIC "\xe2\xe3\xcf\xd3\n" -#define EMPTY_OBJECT_OFFSET 65535 #define XREF_ENTRY_SIZE 20 #define LINEARIZATION_PADDING 10 #include <iostream> -// for htonl -#ifdef _WIN32 -#include <winsock2.h> -#undef GetObject -#else -#include <arpa/inet.h> -#endif // _WIN32 - namespace PoDoFo { -bool podofo_is_little_endian() -{ - int _p = 1; - return ((reinterpret_cast<char*>(&_p))[0] == 1); -} - PdfWriter::PdfWriter( PdfParser* pParser ) : m_pPagesTree( NULL ), m_bCompress( true ), m_bLinearized( false ), m_bXRefStream( false ), m_lFirstInXRef( 0 ) @@ -100,6 +87,15 @@ m_vecObjects = pVecObjects; } +PdfWriter::PdfWriter( PdfVecObjects* pVecObjects ) + : m_pPagesTree( NULL ), m_bCompress( true ), m_bLinearized( false ), + m_bXRefStream( false ), m_lFirstInXRef( 0 ) +{ + m_eVersion = ePdfVersion_1_3; + m_pTrailer = NULL; + m_vecObjects = pVecObjects; +} + PdfWriter::~PdfWriter() { delete m_pTrailer; @@ -117,9 +113,6 @@ void PdfWriter::Write( PdfOutputDevice* pDevice ) { - TVecXRefTable vecXRef; - TVecXRefOffset vecXRefOffset; - if( !pDevice ) { RAISE_ERROR( ePdfError_InvalidHandle ); @@ -131,18 +124,41 @@ } else { - WritePdfHeader ( pDevice ); - WritePdfObjects ( pDevice, *m_vecObjects, &vecXRef ); + PdfXRef* pXRef = m_bXRefStream ? new PdfXRefStream( m_vecObjects, this ) : new PdfXRef(); - if( m_bXRefStream ) - WriteXRefStream( &vecXRef, pDevice ); - else - WritePdfTableOfContents( &vecXRef, pDevice, &vecXRefOffset, false, m_bLinearized ); + try { + WritePdfHeader ( pDevice ); + WritePdfObjects ( pDevice, *m_vecObjects, pXRef ); + + long lXRefOffset = pDevice->GetLength(); + pXRef->Write( pDevice ); + + // XRef streams contain the trailer in the XRef + if( !m_bXRefStream ) + { + PdfObject trailer; + + // if we have a dummy offset we write also a prev entry to the trailer + FillTrailerObject( &trailer, pXRef->GetSize(), false, false ); + + pDevice->Print("trailer\n"); + trailer.WriteObject( pDevice ); + } + + pDevice->Print( "startxref\n%li\n%%%%EOF\n", lXRefOffset ); + delete pXRef; + } catch( PdfError & e ) { + // Make sure pXRef is always deleted + delete pXRef; + e.AddToCallstack( __FILE__, __LINE__ ); + throw e; + } } } void PdfWriter::WriteLinearized( PdfOutputDevice* pDevice ) { + /* PdfObject* pLinearize = NULL; PdfPage* pPage; PdfObject* pLast; @@ -214,6 +230,7 @@ WritePdfTableOfContents( &vecXRef, pDevice, &vecXRefOffset, false, m_bLinearized ); this->FillLinearizationDictionary( pLinearize, pDevice, pPage, pLast, pHint, &vecXRefOffset ); + */ } void PdfWriter::WritePdfHeader( PdfOutputDevice* pDevice ) @@ -235,141 +252,29 @@ } } -void PdfWriter::WritePdfObjects( PdfOutputDevice* pDevice, const TVecObjects& vecObjects, TVecXRefTable* pVecXRef ) +void PdfWriter::WritePdfObjects( PdfOutputDevice* pDevice, const TVecObjects& vecObjects, PdfXRef* pXref ) { TCIVecObjects itObjects = vecObjects.begin(); - int index; - int written = 0; - TXRefTable tXRef; + TCIPdfReferenceList itFree = vecObjects.GetFreeObjects().begin(); this->CompressObjects( vecObjects ); - tXRef.nFirst = (*itObjects)->Reference().ObjectNumber(); - index = vecObjects.size() + vecObjects.GetFreeObjects().size(); - if( tXRef.nFirst == 1 ) - { - tXRef.nFirst--; - index++; - } - - tXRef.vecOffsets.resize( index ); - while( itObjects != vecObjects.end() ) { - index = (*itObjects)->Reference().ObjectNumber() - tXRef.nFirst; - - tXRef.vecOffsets[index].lOffset = pDevice->GetLength(); - tXRef.vecOffsets[index].lGeneration = (*itObjects)->Reference().GenerationNumber(); - tXRef.vecOffsets[index].cUsed = 'n'; - + pXref->AddObject( (*itObjects)->Reference(), pDevice->GetLength(), true ); (*itObjects)->WriteObject( pDevice ); - ++written; ++itObjects; } - TCIPdfReferenceList itFree = vecObjects.GetFreeObjects().begin(); - - // add the first free object - if( !tXRef.nFirst ) - { - tXRef.vecOffsets[0].lOffset = (itFree == vecObjects.GetFreeObjects().end() ? 0 : (*itFree).ObjectNumber()); - tXRef.vecOffsets[0].lGeneration = EMPTY_OBJECT_OFFSET; - tXRef.vecOffsets[0].cUsed = 'f'; - ++written; - } - while( itFree != vecObjects.GetFreeObjects().end() ) { - if( !((*itFree).ObjectNumber() > tXRef.nFirst && - (*itFree).ObjectNumber() < tXRef.nFirst + tXRef.nCount ) ) - { - ++itFree; - continue; - } - - index = (*itFree).ObjectNumber() - tXRef.nFirst; + pXref->AddObject( *itFree, 0, false ); ++itFree; - - if( index < static_cast<int>(tXRef.vecOffsets.size()) ) - { - // write empty entries into the table - tXRef.vecOffsets[index].lOffset = (itFree == vecObjects.GetFreeObjects().end() ? 0 : (*itFree).ObjectNumber()); - tXRef.vecOffsets[index].lGeneration = (itFree == vecObjects.GetFreeObjects().end() ? 1 : 0); - tXRef.vecOffsets[index].cUsed = 'f'; - ++written; - } } - - // This is still not really correct - //tXRef.vecOffsets.resize( written ); - tXRef.nCount = tXRef.vecOffsets.size(); - pVecXRef->push_back( tXRef ); } -void PdfWriter::WriteXRefEntries( PdfOutputDevice* pDevice, const TVecOffsets & vecOffsets ) -{ - TCIVecOffsets itOffsets = vecOffsets.begin(); - - if( !pDevice ) - { - RAISE_ERROR( ePdfError_InvalidHandle ); - } - - while( itOffsets != vecOffsets.end() ) - { - if( !(*itOffsets).cUsed ) - { - ++itOffsets; - continue; - // TODO: only here for debugging, - // remove as this will slow down stuff - //RAISE_ERROR( ePdfError_InternalLogic ); - } - - pDevice->Print( "%0.10i %0.5i %c \n", (*itOffsets).lOffset, (*itOffsets).lGeneration, (*itOffsets).cUsed ); - ++itOffsets; - } -} - -void PdfWriter::WritePdfTableOfContents( TVecXRefTable* pVecXRef, PdfOutputDevice* pDevice, TVecXRefOffset* pVecXRefOffset, bool bDummyOffset, bool bShortTrailer ) -{ - long lXRef = pDevice->GetLength();; - unsigned int nSize = 0; - TCIVecXRefTable it; - PdfObject trailer; - - pDevice->Print( "xref\n" ); - - it = pVecXRef->begin(); - while( it != pVecXRef->end() ) - { - nSize = ( nSize > (*it).nFirst + (*it).nCount ? nSize : (*it).nFirst + (*it).nCount ); - - // when there is only one, then we need to start with 0 and the bogus object... - pDevice->Print( "%u %u\n", (*it).nFirst, (*it).nCount ); - - if( it == pVecXRef->begin() ) - m_lFirstInXRef = pDevice->GetLength(); - - WriteXRefEntries( pDevice, (*it).vecOffsets ); - - ++it; - } - - // if we have a dummy offset we write also a prev entry to the trailer - FillTrailerObject( &trailer, nSize, bDummyOffset, bShortTrailer ); - - pDevice->Print("trailer\n"); - if( bDummyOffset ) - m_lTrailerOffset = pDevice->GetLength(); - - trailer.WriteObject( pDevice ); - pDevice->Print( "startxref\n%li\n%%%%EOF\n", pVecXRefOffset->size() ? pVecXRefOffset->back() : (bDummyOffset ? 0 : lXRef) ); - pVecXRefOffset->push_back( lXRef ); -} - void PdfWriter::GetByteOffset( PdfObject* pObject, unsigned long* pulOffset ) { TCIVecObjects it = m_vecObjects->begin(); @@ -529,86 +434,8 @@ } } -#ifdef WIN32 -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef signed short int16_t; -typedef unsigned short uint16_t; -typedef signed int int32_t; -typedef unsigned int uint32_t; -#endif - -#define STREAM_OFFSET_TYPE uint32_t - -void PdfWriter::WriteXRefStream( TVecXRefTable* pVecXRef, PdfOutputDevice* pDevice, bool bDummyOffset ) +void PdfWriter::FillTrailerObject( PdfObject* pTrailer, long lSize, bool bPrevEntry, bool bOnlySizeKey ) const { - long lXRef; - unsigned int nSize = 0; - TCIVecXRefTable it; - TCIVecOffsets itOffsets; - const size_t bufferLen = 2 + sizeof( STREAM_OFFSET_TYPE ); - char buffer[bufferLen]; - bool bLittle = podofo_is_little_endian(); - - STREAM_OFFSET_TYPE* pValue = reinterpret_cast<STREAM_OFFSET_TYPE*>(buffer+1); - - PdfObject object( PdfReference( m_vecObjects->m_nObjectCount, 0 ), "XRef" ); - PdfArray indeces; - PdfArray w; - - m_lFirstInXRef = 0; - - w.push_back( 1l ); - w.push_back( static_cast<long>(sizeof(STREAM_OFFSET_TYPE)) ); - w.push_back( 1l ); - - it = pVecXRef->begin(); - while( it != pVecXRef->end() ) - { - nSize = ( nSize > (*it).nFirst + (*it).nCount ? nSize : (*it).nFirst + (*it).nCount ); - - indeces.push_back( static_cast<long>((*it).nFirst) ); - indeces.push_back( static_cast<long>((*it).nCount) ); - - itOffsets = (*it).vecOffsets.begin(); - while( itOffsets != (*it).vecOffsets.end() ) - { - if( (*itOffsets).cUsed == 'n' ) - { - buffer[0] = static_cast<char>(1); - buffer[bufferLen] = static_cast<char>(0); - } - else if( (*itOffsets).cUsed == 'f' ) - { - buffer[0] = static_cast<char>(0); - buffer[bufferLen] = static_cast<char>(1); - } - - *pValue = static_cast<STREAM_OFFSET_TYPE>((*itOffsets).lOffset ); - - if( bLittle ) - *pValue = htonl( *pValue ); - - object.GetStream()->Append( buffer, bufferLen ); - ++itOffsets; - } - - ++it; - } - - FillTrailerObject( &object, nSize, false, false ); - - object.GetDictionary().AddKey( "Index", indeces ); - object.GetDictionary().AddKey( "W", w ); - object.FlateCompressStream(); - - lXRef = bDummyOffset ? 0 : pDevice->GetLength(); - object.WriteObject( pDevice ); - pDevice->Print( "startxref\n%li\n%%%%EOF\n", lXRef ); -} - -void PdfWriter::FillTrailerObject( PdfObject* pTrailer, long lSize, bool bPrevEntry, bool bOnlySizeKey ) -{ PdfVariant place_holder( 0l ); place_holder.SetPaddingLength( LINEARIZATION_PADDING ); @@ -657,6 +484,7 @@ } } +/* void PdfWriter::FillLinearizationDictionary( PdfObject* pLinearize, PdfOutputDevice* pDevice, PdfPage* pPage, PdfObject* pLast, PdfHintStream* pHint, TVecXRefOffset* pVecXRefOffset ) { @@ -694,8 +522,9 @@ trailer.WriteObject( pDevice ); pDevice->Seek( lFileSize ); } +*/ -void PdfWriter::CreateFileIdentifier( PdfObject* pTrailer ) +void PdfWriter::CreateFileIdentifier( PdfObject* pTrailer ) const { PdfOutputDevice length; PdfString identifier; Modified: podofo/trunk/src/PdfWriter.h =================================================================== --- podofo/trunk/src/PdfWriter.h 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/PdfWriter.h 2007-01-23 14:38:57 UTC (rev 358) @@ -36,31 +36,16 @@ class PdfPagesTree; class PdfParser; class PdfVecObjects; +class PdfXRef; -// FIXME CR: Should this be part of the exported API? -struct PODOFO_API TXRefTable { - unsigned int nFirst; - unsigned int nCount; - TVecOffsets vecOffsets; -}; - -typedef std::vector<TXRefTable> TVecXRefTable; -typedef TVecXRefTable::iterator TIVecXRefTable; -typedef TVecXRefTable::const_iterator TCIVecXRefTable; - -typedef std::vector<long> TVecXRefOffset; -typedef TVecXRefOffset::iterator TIVecXRefOffset; -typedef TVecXRefOffset::const_iterator TCIVecXRefOffset; - - /** The PdfWriter class writes a list of PdfObjects as PDF file. * The XRef section (which is the required table of contents for any * PDF file) is created automatically. * * It does not know about pages but only about PdfObjects. * - * Most users will want to use PdfSimpleWriter. + * Most users will want to use PdfDocument. */ class PODOFO_API PdfWriter { public: @@ -183,17 +168,32 @@ */ void WriteToBuffer( char** ppBuffer, unsigned long* pulLen ); - private: - /** Writes a linearized PDF file - * \param pDevice write to this output device - */ - void PODOFO_LOCAL WriteLinearized( PdfOutputDevice* pDevice ); + /** Add required keys to a trailer object + * \param pTrailer add keys to this object + * \param lSize number of objects in the PDF file + * \param bPrevEntry if true a prev entry is added to the trailer object with a value of 0 + * \param bOnlySizeKey write only the size key + */ + void FillTrailerObject( PdfObject* pTrailer, long lSize, bool bPrevEntry, bool bOnlySizeKey ) const; + protected: + /** + * Create a PdfWriter from a PdfVecObjects + */ + PdfWriter( PdfVecObjects* pVecObjects ); + /** Writes the pdf header to the current file. * \param pDevice write to this output device */ void PODOFO_LOCAL WritePdfHeader( PdfOutputDevice* pDevice ); + + private: + /** Writes a linearized PDF file + * \param pDevice write to this output device + */ + void PODOFO_LOCAL WriteLinearized( PdfOutputDevice* pDevice ); + /** Create a linearization dictionary for the current * document and return a pointer to it after inserting * it into the vector of PdfObjects @@ -218,38 +218,8 @@ * \param vecObjects write all objects in this vector to the file * \param pVecXRef add all written objects to this XRefTable */ - void WritePdfObjects( PdfOutputDevice* pDevice, const TVecObjects& vecObjects, TVecXRefTable* pVecXRef ) PODOFO_LOCAL; + void WritePdfObjects( PdfOutputDevice* pDevice, const TVecObjects& vecObjects, PdfXRef* pXref ) PODOFO_LOCAL; - /** Writes a list of xref entries to the current file - * \param pDevice write to this output device - * \param vecOffsets list of objects which will be written - */ - void WriteXRefEntries( PdfOutputDevice* pDevice, const TVecOffsets & vecOffsets ) PODOFO_LOCAL; - - /** Writes the xref table. - * \param pVecXRef write this XRef table - * \param pDevice write to this output device - * \param pVecXRefOffset add the offset of this XRef table to this vector - * \param bDummyOffset write a dummy startxref offset for linearized PDF files - * \param bShortTrailer write only the size key in the trailer - */ - void WritePdfTableOfContents( TVecXRefTable* pVecXRef, PdfOutputDevice* pDevice, TVecXRefOffset* pVecXRefOffset, bool bDummyOffset = false, bool bShortTrailer = true ) PODOFO_LOCAL; - - /** Writes the xref table as xref stream. - * \param pVecXRef write this XRef table - * \param pDevice write to this output device - * \param bDummyOffset write a dummy startxref offset for linearized PDF files - */ - void WriteXRefStream( TVecXRefTable* pVecXRef, PdfOutputDevice* pDevice, bool bDummyOffset = false ) PODOFO_LOCAL; - - /** Add required keys to a trailer object - * \param pTrailer add keys to this object - * \param lSize number of objects in the PDF file - * \param bPrevEntry if true a prev entry is added to the trailer object with a value of 0 - * \param bOnlySizeKey write only the size key - */ - void FillTrailerObject( PdfObject* pTrailer, long lSize, bool bPrevEntry, bool bOnlySizeKey ) PODOFO_LOCAL; - /** Initialize m_pPagesTree with its correct value * Always call this function befre accessing the pages tree. */ @@ -266,7 +236,7 @@ * \param pLast pointer of the last object belonging to the first page * \param pVecXRefOffset xref table entries for previous entry */ - void FillLinearizationDictionary( PdfObject* pLinearize, PdfOutputDevice* pDevice, PdfPage* pPage, PdfObject* pLast, PdfHintStream* pHint, TVecXRefOffset* pVecXRefOffset ) PODOFO_LOCAL; + // void FillLinearizationDictionary( PdfObject* pLinearize, PdfOutputDevice* pDevice, PdfPage* pPage, PdfObject* pLast, PdfHintStream* pHint, TVecXRefOffset* pVecXRefOffset ) PODOFO_LOCAL; /** Creates a file identifier which is required in several * PDF workflows. * All values from the files document information dictionary are @@ -274,7 +244,7 @@ * * \param pTrailer add the file identifier to this trailer dictionary */ - void CreateFileIdentifier( PdfObject* pTrailer ) PODOFO_LOCAL; + void CreateFileIdentifier( PdfObject* pTrailer ) const PODOFO_LOCAL; protected: PdfVecObjects* m_vecObjects; Added: podofo/trunk/src/PdfXRef.cpp =================================================================== --- podofo/trunk/src/PdfXRef.cpp (rev 0) +++ podofo/trunk/src/PdfXRef.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -0,0 +1,157 @@ +/*************************************************************************** + * Copyright (C) 2007 by Dominik Seichter * + * dom...@we... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "PdfXRef.h" + +#include <PdfOutputDevice.h> + +namespace PoDoFo { + +PdfXRef::PdfXRef() +{ + +} + +PdfXRef::~PdfXRef() +{ + +} + +void PdfXRef::AddObject( const PdfReference & rRef, long lOffset, bool bUsed ) +{ + bool bSort; + + if( bUsed ) + { + PdfXRef::TXRefItem item; + + item.reference = rRef; + item.lOffset = lOffset; + + bSort = m_vecXRef.size() ? item.reference < m_vecXRef.back().reference : false; + m_vecXRef.push_back( item ); + + if( bSort ) + { + // TODO: Maybe it is faster to sort, after all items have been added + std::sort( m_vecXRef.begin(), m_vecXRef.end() ); + } + } + else + { + bSort = m_vecFreeObjects.size() ? rRef < m_vecFreeObjects.back() : false; + m_vecFreeObjects.push_back( rRef ); + + if( bSort ) + { + // TODO: Maybe it is faster to sort, after all items have been added + std::sort( m_vecFreeObjects.begin(), m_vecFreeObjects.end() ); + } + } +} + +void PdfXRef::Write( PdfOutputDevice* pDevice ) +{ + PdfXRef::TCIVecXRefItems it = m_vecXRef.begin(); + PdfXRef::TCIVecReferences itFree = m_vecFreeObjects.begin(); + + int nFirst = 0; + int nCount = 0; + + pDevice->Print( "xref\n" ); + while( it != m_vecXRef.end() ) + { + nCount = GetItemCount( it, itFree ); + nFirst = PDF_MIN( it != m_vecXRef.end() ? (*it).reference.ObjectNumber() : EMPTY_OBJECT_OFFSET, + itFree != m_vecFreeObjects.end() ? (*itFree).ObjectNumber() : EMPTY_OBJECT_OFFSET ); + + if( nFirst == 1 ) + --nFirst; + + // when there is only one, then we need to start with 0 and the bogus object... + pDevice->Print( "%u %u\n", nFirst, nCount ); + if( !nFirst ) + { + //printf("Writing first free\n"); + pDevice->Print( "%0.10i %0.5i %c \n", + m_vecFreeObjects.size() ? m_vecFreeObjects.front().ObjectNumber() : 0, + EMPTY_OBJECT_OFFSET, 'f' ); + } + + while( --nCount && it != m_vecXRef.end() ) + { + while( itFree != m_vecFreeObjects.end() && + *itFree < (*it).reference && nCount ) + { + int nGen = (*itFree).GenerationNumber(); + //printf("Writing free %i\n", (*itFree).ObjectNumber() ); + ++itFree; + + // write free object + pDevice->Print( "%0.10i %0.5i f \n", + itFree != m_vecFreeObjects.end() ? (*itFree).ObjectNumber() : 0, + nGen ); + --nCount; + } + + //printf("Writing Object %i\n", (*it).reference.ObjectNumber() ); + pDevice->Print( "%0.10i %0.5i n \n", (*it).lOffset, (*it).reference.GenerationNumber() ); + ++it; + } + } +} + +int PdfXRef::GetItemCount( PdfXRef::TCIVecXRefItems it, PdfXRef::TCIVecReferences itFree ) const +{ + unsigned int nCur = (*it).reference.ObjectNumber(); + unsigned int nCnt = 1; + + ++it; + while( it != m_vecXRef.end() ) + { + while( itFree != m_vecFreeObjects.end() && + *itFree < (*it).reference ) + { + ++itFree; + ++nCnt; + ++nCur; + } + + if( (*it).reference.ObjectNumber() != ++nCur ) + break; + + ++nCnt; + ++it; + } + + return ++nCnt; +} + +unsigned int PdfXRef::GetSize() const +{ + // the list is assumed to be sorted + + if( !m_vecXRef.size() ) + return 0; + else + return m_vecXRef.back().reference.ObjectNumber() + 1; +} + +}; Added: podofo/trunk/src/PdfXRef.h =================================================================== --- podofo/trunk/src/PdfXRef.h (rev 0) +++ podofo/trunk/src/PdfXRef.h 2007-01-23 14:38:57 UTC (rev 358) @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2007 by Dominik Seichter * + * dom...@we... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PDF_XREF_H_ +#define _PDF_XREF_H_ + +#include "PdfDefines.h" + +#include "PdfReference.h" + +namespace PoDoFo { + +#define EMPTY_OBJECT_OFFSET 65535 + +class PdfOutputDevice; + +/** + * Creates an XRef table. + * + * This is an internal class of PoDoFo used by PdfWriter. + */ +class PdfXRef { + protected: + typedef struct TXRefItem { + PdfReference reference; + long lOffset; + + bool operator<( const TXRefItem & rhs ) const + { + return this->reference < rhs.reference; + } + }; + + typedef std::vector<TXRefItem> TVecXRefItems; + typedef TVecXRefItems::iterator TIVecXRefItems; + typedef TVecXRefItems::const_iterator TCIVecXRefItems; + + typedef std::vector<PdfReference> TVecReferences; + typedef TVecReferences::iterator TIVecReferences; + typedef TVecReferences::const_iterator TCIVecReferences; + + public: + /** Create a new XRef table + */ + PdfXRef(); + + /** Destruct the XRef table + */ + virtual ~PdfXRef(); + + /** Add an object to the XRef table. + * The object should have been written to an output device already. + * + * \param rRef reference of this object + * \param lOffset the offset where on the device the object was written + * \param bUsed specifies wether this is an used or free object. + * Set this value to true for all normal objects and to false + * for free object references. + */ + void AddObject( const PdfReference & rRef, long lOffset, bool bUsed ); + + /** Write the XRef table to an output device. + * + * \param pDevice an output device (usually a PDF file) + * + */ + virtual void Write( PdfOutputDevice* pDevice ); + + /** Get the size of the XRef table. + * I.e. the highest object number + 1. + * + * \returns the size of the xref table + */ + unsigned int GetSize() const; + + protected: + int GetItemCount( PdfXRef::TCIVecXRefItems it, PdfXRef::TCIVecReferences itFree ) const; + + protected: + TVecXRefItems m_vecXRef; + TVecReferences m_vecFreeObjects; +}; + +}; + +#endif /* _PDF_XREF_H_ */ Added: podofo/trunk/src/PdfXRefStream.cpp =================================================================== --- podofo/trunk/src/PdfXRefStream.cpp (rev 0) +++ podofo/trunk/src/PdfXRefStream.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -0,0 +1,138 @@ +/*************************************************************************** + * Copyright (C) 2007 by Dominik Seichter * + * dom...@we... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "PdfXRefStream.h" + +#include "PdfArray.h" +#include "PdfObject.h" +#include "PdfStream.h" +#include "PdfWriter.h" + +// for htonl +#ifdef _WIN32 +#include <winsock2.h> +#undef GetObject +#else +#include <arpa/inet.h> +#endif // _WIN32 + +namespace PoDoFo { + +#ifdef WIN32 +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +#endif + +#define STREAM_OFFSET_TYPE uint32_t + +bool podofo_is_little_endian() +{ + int _p = 1; + return ((reinterpret_cast<char*>(&_p))[0] == 1); +} + +PdfXRefStream::PdfXRefStream( PdfVecObjects* pParent, PdfWriter* pWriter ) + : m_pParent( pParent ), m_pWriter( pWriter ) +{ + +} + +PdfXRefStream::~PdfXRefStream() +{ + +} + +void PdfXRefStream::Write( PdfOutputDevice* pDevice ) +{ + const size_t bufferLen = 2 + sizeof( STREAM_OFFSET_TYPE ); + char buffer[bufferLen]; + bool bLittle = podofo_is_little_endian(); + + STREAM_OFFSET_TYPE* pValue = reinterpret_cast<STREAM_OFFSET_TYPE*>(buffer+1); + + // Make sure to not crash even for empty documents. + PdfReference reference( m_vecXRef.size() ? m_vecXRef.back().reference.ObjectNumber() + 1 : 0, 0 ); + PdfObject object( reference, "XRef" ); + PdfArray indeces; + PdfArray w; + + PdfXRef::TCIVecXRefItems it = m_vecXRef.begin(); + PdfXRef::TCIVecReferences itFree = m_vecFreeObjects.begin(); + + int nFirst = 0; + int nCount = 0; + + w.push_back( 1l ); + w.push_back( static_cast<long>(sizeof(STREAM_OFFSET_TYPE)) ); + w.push_back( 1l ); + + while( it != m_vecXRef.end() ) + { + nCount = GetItemCount( it, itFree ); + nFirst = PDF_MIN( it != m_vecXRef.end() ? (*it).reference.ObjectNumber() : EMPTY_OBJECT_OFFSET, + itFree != m_vecFreeObjects.end() ? (*itFree).ObjectNumber() : EMPTY_OBJECT_OFFSET ); + + indeces.push_back( static_cast<long>(nFirst) ); + indeces.push_back( static_cast<long>(nCount) ); + + while( --nCount && it != m_vecXRef.end() ) + { + while( itFree != m_vecFreeObjects.end() && + *itFree < (*it).reference && nCount ) + { + + ++itFree; + + // write free object + buffer[0] = static_cast<char>(0); + buffer[bufferLen] = static_cast<char>(1); + *pValue = static_cast<STREAM_OFFSET_TYPE>(itFree != m_vecFreeObjects.end() ? + (*itFree).ObjectNumber() : 0); + + object.GetStream()->Append( buffer, bufferLen ); + --nCount; + } + + buffer[0] = static_cast<char>(1); + buffer[bufferLen] = static_cast<char>(0); + *pValue = static_cast<STREAM_OFFSET_TYPE>((*it).lOffset ); + + if( bLittle ) + *pValue = htonl( *pValue ); + + object.GetStream()->Append( buffer, bufferLen ); + ++it; + } + } + + m_pWriter->FillTrailerObject( &object, this->GetSize(), false, false ); + + object.GetDictionary().AddKey( "Index", indeces ); + object.GetDictionary().AddKey( "W", w ); + object.FlateCompressStream(); + object.WriteObject( pDevice ); +} + +}; + Added: podofo/trunk/src/PdfXRefStream.h =================================================================== --- podofo/trunk/src/PdfXRefStream.h (rev 0) +++ podofo/trunk/src/PdfXRefStream.h 2007-01-23 14:38:57 UTC (rev 358) @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2007 by Dominik Seichter * + * dom...@we... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PDF_XREF_STREAM_H_ +#define _PDF_XREF_STREAM_H_ + +#include "PdfDefines.h" + +#include "PdfXRef.h" + +namespace PoDoFo { + +class PdfOutputDevice; +class PdfVecObjects; +class PdfWriter; + + +/** + * Creates an XRef table that is a stream object. + * Requires at least PDF 1.5. XRef streams are more + * compact than normal XRef tables. + * + * This is an internal class of PoDoFo used by PdfWriter. + */ +class PdfXRefStream : public PdfXRef { + public: + /** Create a new XRef table + * + * \param pParent a vector of PdfObject is required + * to create a PdfObject for the XRef + * \param pWriter is needed to fill the trailer directory + * correctly which is included into the XRef + */ + PdfXRefStream( PdfVecObjects* pParent, PdfWriter* pWriter ); + + /** Destruct the XRef table + */ + virtual ~PdfXRefStream(); + + /** Write the XRef table to an output device. + * + * \param pDevice an output device (usually a PDF file) + * + */ + virtual void Write( PdfOutputDevice* pDevice ); + + private: + PdfVecObjects* m_pParent; + PdfWriter* m_pWriter; +}; + +}; + +#endif /* _PDF_XREF_H_ */ Modified: podofo/trunk/src/podofo.h =================================================================== --- podofo/trunk/src/podofo.h 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/src/podofo.h 2007-01-23 14:38:57 UTC (rev 358) @@ -80,6 +80,8 @@ #include "PdfVecObjects.h" #include "PdfWriter.h" #include "PdfXObject.h" +#include "PdfXRef.h" +#include "PdfXRefStream.h" #if 0 #ifndef _PODOFO_NO_NAMESPACE_ Modified: podofo/trunk/test/CreationTest/CreationTest.cpp =================================================================== --- podofo/trunk/test/CreationTest/CreationTest.cpp 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/test/CreationTest/CreationTest.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -274,7 +274,7 @@ PdfXObject xObj( rect, &(pDocument->GetObjects()) ); PdfPainter pnt; // XObject painter - image.LoadFromFile( "./lena.jpg" ); + image.LoadFromFile( "../../../podofo/test/CreationTest/lena.jpg" ); pnt.SetPage( &xObj ); // Draw onto the XObject @@ -338,7 +338,7 @@ pPainter->SetColor( 1.0, 0.0, 0.0 ); pPainter->FillEllipse( dX, dY, 20000 * CONVERSION_CONSTANT, 20000 * CONVERSION_CONSTANT ); - PdfFileSpec file( "lena.jpg", true, &(pDocument->GetObjects()) ); + PdfFileSpec file( "../../../podofo/test/CreationTest/lena.jpg", true, &(pDocument->GetObjects()) ); pFileAnnotation = pPage->CreateAnnotation( ePdfAnnotation_FileAttachement, PdfRect( 300.0, 400.0, 250.0, 50.0 ) ); pFileAnnotation->SetContents( "A JPEG image of Lena" ); pFileAnnotation->SetFileAttachement( file ); @@ -454,7 +454,7 @@ TEST_SAFE_OP( writer.GetInfo()->SetSubject ( PdfString("Testing the PDF Library") ) ); TEST_SAFE_OP( writer.GetInfo()->SetKeywords( PdfString("Test;PDF;") ) ); - TEST_SAFE_OP( writer.AttachFile( PdfFileSpec("CreationTest.cpp", true, &(writer.GetObjects()) ) ) ); + TEST_SAFE_OP( writer.AttachFile( PdfFileSpec("../../../podofo/test/CreationTest/CreationTest.cpp", true, &(writer.GetObjects()) ) ) ); TEST_SAFE_OP( writer.Write( argv[1] ) ); Modified: podofo/trunk/test/LargeTest/LargeTest.cpp =================================================================== --- podofo/trunk/test/LargeTest/LargeTest.cpp 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/test/LargeTest/LargeTest.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -90,6 +90,9 @@ FcObjectSetDestroy( pObjectSet ); FcPatternDestroy( pPattern ); + PdfOutputDevice device( pszFilename ); + doc.WriteImmediately( &device ); + if( pFontSet ) { for( int i=0; i<pFontSet->nfont;i++ ) @@ -106,7 +109,7 @@ FcFontSetDestroy( pFontSet ); } - doc.Write( pszFilename ); + //doc.Write( pszFilename ); } int main( int argc, char* argv[] ) Modified: podofo/trunk/test/ParserTest/ParserTest.cpp =================================================================== --- podofo/trunk/test/ParserTest/ParserTest.cpp 2007-01-23 03:36:00 UTC (rev 357) +++ podofo/trunk/test/ParserTest/ParserTest.cpp 2007-01-23 14:38:57 UTC (rev 358) @@ -36,7 +36,7 @@ { PdfWriter writer( pParser ); - //writer.SetUseXRefStream( true ); + writer.SetUseXRefStream( true ); //writer.SetLinearized( true ); writer.SetPdfCompression( true ); writer.Write( pszFilename ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |