1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008 Henrik Tidefelt
25 #include "pdfstructure.h"
26 #include "simplepdfo.h"
27 #include "simplepdfi.h"
28 #include "autoonoff.h"
32 using namespace SimplePDF
;
36 SimplePDF::PDF_Object::PDF_Object( )
39 SimplePDF::PDF_Object::~PDF_Object( )
42 SimplePDF::PDF_Object::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
44 throw "This function, PDF_Object::writeTo, must not be called. It is practically purely virtual.";
46 RefCountPtr
< PDF_Object
>
47 SimplePDF::PDF_Object::deepCopy( RefCountPtr
< PDF_Object
> self
, size_t * indirectObjectCounter
, IndirectRemapType
* remap
)
56 SimplePDF::down_cast_follow( RefCountPtr
< PDF_Object
> maybeIndirect
)
59 const PDF_Indirect_in
* theIndirect( dynamic_cast< const PDF_Indirect_in
* >( maybeIndirect
.getPtr( ) ) );
60 if( theIndirect
!= 0 )
62 return theIndirect
->PDFin
->follow
< S
>( maybeIndirect
);
66 const PDF_Indirect_out
* theIndirect( dynamic_cast< const PDF_Indirect_out
* >( maybeIndirect
.getPtr( ) ) );
67 if( theIndirect
!= 0 )
69 return SimplePDF::down_cast_follow
< S
>( theIndirect
->obj
);
73 return maybeIndirect
.down_cast
< S
>( );
79 RefCountPtr
< SimplePDF::PDF_Float
>
80 down_cast_follow
< SimplePDF::PDF_Float
>( RefCountPtr
< PDF_Object
> maybeIndirect
)
83 const PDF_Indirect_in
* theIndirect( dynamic_cast< const PDF_Indirect_in
* >( maybeIndirect
.getPtr( ) ) );
84 if( theIndirect
!= 0 )
86 return theIndirect
->PDFin
->follow
< SimplePDF::PDF_Float
>( maybeIndirect
);
90 const PDF_Indirect_out
* theIndirect( dynamic_cast< const PDF_Indirect_out
* >( maybeIndirect
.getPtr( ) ) );
91 if( theIndirect
!= 0 )
93 return SimplePDF::down_cast_follow
< SimplePDF::PDF_Float
>( theIndirect
->obj
);
97 RefCountPtr
< PDF_Int
> res( maybeIndirect
.down_cast
< PDF_Int
>( ) );
98 if( res
!= NullPtr
< PDF_Int
>( ) )
100 return RefCountPtr
< PDF_Float
>( new PDF_Float( res
->value( ) ) );
103 return maybeIndirect
.down_cast
< SimplePDF::PDF_Float
>( );
109 template RefCountPtr
< SimplePDF::PDF_Vector
> down_cast_follow
< SimplePDF::PDF_Vector
>( RefCountPtr
< PDF_Object
> );
114 SimplePDF::PDF_Null::PDF_Null( )
116 SimplePDF::PDF_Null::~PDF_Null( )
120 SimplePDF::PDF_Null::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
127 SimplePDF::PDF_Boolean::PDF_Boolean( ValueType _value
)
130 SimplePDF::PDF_Boolean::~PDF_Boolean( )
133 SimplePDF::PDF_Boolean::ValueType
134 SimplePDF::PDF_Boolean::value( ) const
140 SimplePDF::PDF_Boolean::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
154 SimplePDF::PDF_Int::PDF_Int( PDF_Int::ValueType _value
)
157 SimplePDF::PDF_Int::PDF_Int( const char * strvalue
)
159 /* How can it be that end shall be non-const, while strvalue is const? */
162 my_value
= strtol( strvalue
, & end
, 10 );
165 throw "Internal error: Bad numeric int format";
168 SimplePDF::PDF_Int::~PDF_Int( )
172 SimplePDF::PDF_Int::value( ) const
178 SimplePDF::PDF_Int::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
185 SimplePDF::PDF_Float::PDF_Float( PDF_Float::ValueType _value
)
188 SimplePDF::PDF_Float::PDF_Float( const char * strvalue
)
190 /* How can it be that end shall be non-const, while strvalue is const? */
193 my_value
= strtod( strvalue
, & end
);
196 throw( "Internal error: Bad numeric float format" );
199 SimplePDF::PDF_Float::~PDF_Float( )
202 SimplePDF::PDF_Float::ValueType
PDF_Float::value( ) const
208 SimplePDF::PDF_Float::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
215 SimplePDF::PDF_String::PDF_String( )
217 SimplePDF::PDF_String::~PDF_String( )
222 SimplePDF::PDF_LiteralString::PDF_LiteralString( const string
& _str
)
225 SimplePDF::PDF_LiteralString::PDF_LiteralString( const char * _str
)
228 SimplePDF::PDF_LiteralString::PDF_LiteralString( const list
< RefCountPtr
< char > > & strs
)
231 typedef list
< RefCountPtr
< char > >::const_iterator I
;
232 for( I
i( strs
.begin( ) ); i
!= strs
.end( ); ++i
)
234 length
+= strlen( i
->getPtr( ) );
236 RefCountPtr
< char > mem( new char[ length
+ 1 ] );
237 char * dst
= mem
.getPtr( );
238 for( I
i( strs
.begin( ) ); i
!= strs
.end( ); ++i
)
240 strcpy( dst
, i
->getPtr( ) );
241 dst
+= strlen( i
->getPtr( ) );
244 my_str
= mem
.getPtr( );
246 SimplePDF::PDF_LiteralString::~PDF_LiteralString( )
250 SimplePDF::PDF_LiteralString::str( ) const
256 SimplePDF::PDF_LiteralString::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
259 for( const char * src
= my_str
.c_str( ); *src
!= '\0'; ++src
)
281 SimplePDF::PDF_HexString::PDF_HexString( const string
& _hexstr
)
282 : my_hexstr( _hexstr
)
284 SimplePDF::PDF_HexString::PDF_HexString( const char * _hexstr
)
285 : my_hexstr( _hexstr
)
287 SimplePDF::PDF_HexString::~PDF_HexString( )
291 SimplePDF::PDF_HexString::hexstr( ) const
297 SimplePDF::PDF_HexString::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
299 os
<< "<" << my_hexstr
<< ">" ;
304 SimplePDF::PDF_Name::PDF_Name( const string
& _name
)
307 SimplePDF::PDF_Name::~PDF_Name( )
311 SimplePDF::PDF_Name::name( ) const
317 SimplePDF::PDF_Name::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
319 os
<< "/" << my_name
;
322 ostream
& SimplePDF::operator << ( std::ostream
& os
, const PDF_Name
& self
)
324 return os
<< "/" << self
.my_name
;
330 SimplePDF::PDF_Vector::PDF_Vector( )
332 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType c
)
334 vec
.push_back( SimplePDF::newFloat( c
) );
336 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType c1
, PDF_Float::ValueType c2
)
338 vec
.push_back( SimplePDF::newFloat( c1
) );
339 vec
.push_back( SimplePDF::newFloat( c2
) );
341 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType c1
, PDF_Float::ValueType c2
, PDF_Float::ValueType c3
)
343 vec
.push_back( SimplePDF::newFloat( c1
) );
344 vec
.push_back( SimplePDF::newFloat( c2
) );
345 vec
.push_back( SimplePDF::newFloat( c3
) );
347 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType x1
, PDF_Float::ValueType y1
,
348 PDF_Float::ValueType x2
, PDF_Float::ValueType y2
)
350 vec
.push_back( SimplePDF::newFloat( x1
) );
351 vec
.push_back( SimplePDF::newFloat( y1
) );
352 vec
.push_back( SimplePDF::newFloat( x2
) );
353 vec
.push_back( SimplePDF::newFloat( y2
) );
355 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType a
, PDF_Float::ValueType b
,
356 PDF_Float::ValueType c
, PDF_Float::ValueType d
,
357 PDF_Float::ValueType e
, PDF_Float::ValueType f
)
359 vec
.push_back( SimplePDF::newFloat( a
) );
360 vec
.push_back( SimplePDF::newFloat( b
) );
361 vec
.push_back( SimplePDF::newFloat( c
) );
362 vec
.push_back( SimplePDF::newFloat( d
) );
363 vec
.push_back( SimplePDF::newFloat( e
) );
364 vec
.push_back( SimplePDF::newFloat( f
) );
366 SimplePDF::PDF_Vector::PDF_Vector( PDF_Int::ValueType x1
, PDF_Int::ValueType y1
,
367 PDF_Int::ValueType x2
, PDF_Int::ValueType y2
)
369 vec
.push_back( SimplePDF::newInt( x1
) );
370 vec
.push_back( SimplePDF::newInt( y1
) );
371 vec
.push_back( SimplePDF::newInt( x2
) );
372 vec
.push_back( SimplePDF::newInt( y2
) );
374 SimplePDF::PDF_Vector::~PDF_Vector( )
378 SimplePDF::PDF_Vector::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
381 for( VecType::const_iterator
i( vec
.begin( ) ); i
!= vec
.end( ); ++i
)
384 (*i
)->writeTo( os
, xref
, *i
);
389 RefCountPtr
< PDF_Object
>
390 SimplePDF::PDF_Vector::deepCopy( RefCountPtr
< PDF_Object
> self
, size_t * indirectObjectCounter
, IndirectRemapType
* remap
)
392 bool allSame( true );
393 RefCountPtr
< PDF_Vector
> res( new PDF_Vector
);
394 res
->vec
.reserve( vec
.size( ) );
395 for( VecType::iterator
i( vec
.begin( ) ); i
!= vec
.end( ); ++i
)
397 RefCountPtr
< PDF_Object
> copy( ::deepCopy( *i
, indirectObjectCounter
, remap
) );
398 res
->vec
.push_back( copy
);
399 if( allSame
&& copy
!= *i
)
411 RefCountPtr
< SimplePDF::PDF_Vector
>
412 SimplePDF::PDF_Vector::rectangleIntersection( const RefCountPtr
< SimplePDF::PDF_Vector
> & other
) const
414 if( vec
.size( ) != 4 )
416 throw "Internal error: PDF_Vector::rectangleIntersection: self size is not 4.";
418 if( other
->vec
.size( ) != 4 )
420 throw "Internal error: PDF_Vector::rectangleIntersection: self size is not 4.";
423 RefCountPtr
< PDF_Vector
> res( new PDF_Vector
);
424 res
->vec
.reserve( vec
.size( ) );
426 typedef typeof vec VectorType
;
427 typedef VectorType::const_iterator I
;
428 I src1
= vec
.begin( );
429 I src2
= other
->vec
.begin( );
430 res
->vec
.push_back( RefCountPtr
< PDF_Float
>( new PDF_Float( max( SimplePDF::down_cast_follow
< PDF_Float
>( *src1
)->value( ), SimplePDF::down_cast_follow
< PDF_Float
>( *src2
)->value( ) ) ) ) );
433 res
->vec
.push_back( RefCountPtr
< PDF_Float
>( new PDF_Float( max( SimplePDF::down_cast_follow
< PDF_Float
>( *src1
)->value( ), SimplePDF::down_cast_follow
< PDF_Float
>( *src2
)->value( ) ) ) ) );
436 res
->vec
.push_back( RefCountPtr
< PDF_Float
>( new PDF_Float( min( SimplePDF::down_cast_follow
< PDF_Float
>( *src1
)->value( ), SimplePDF::down_cast_follow
< PDF_Float
>( *src2
)->value( ) ) ) ) );
439 res
->vec
.push_back( RefCountPtr
< PDF_Float
>( new PDF_Float( min( SimplePDF::down_cast_follow
< PDF_Float
>( *src1
)->value( ), SimplePDF::down_cast_follow
< PDF_Float
>( *src2
)->value( ) ) ) ) );
447 SimplePDF::PDF_Dictionary::PDF_Dictionary( )
449 SimplePDF::PDF_Dictionary::PDF_Dictionary( const PDF_Dictionary
& orig
)
452 SimplePDF::PDF_Dictionary::~PDF_Dictionary( )
456 SimplePDF::PDF_Dictionary::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
459 for( DicType::const_iterator
i( dic
.begin( ) ); i
!= dic
.end( ); ++i
)
461 os
<< "/" << (i
->first
) << " " ;
462 (i
->second
)->writeTo( os
, xref
, i
->second
);
469 SimplePDF::PDF_Dictionary::writeToWithLength( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, size_t len
) const
472 os
<< "/Length " << len
<< endl
;
473 for( DicType::const_iterator
i( dic
.begin( ) ); i
!= dic
.end( ); ++i
)
475 os
<< "/" << (i
->first
) << " " ;
476 (i
->second
)->writeTo( os
, xref
, i
->second
);
483 SimplePDF::PDF_Dictionary::getLength( ) const
485 DicType::const_iterator
i( dic
.find( string( "Length" ) ) );
486 if( i
== dic
.end( ) )
488 throw( "Dictionary[Length]: /Length field missing" );
490 RefCountPtr
< const PDF_Int
> theInt
= SimplePDF::down_cast_follow
< const PDF_Int
>( i
->second
);
491 if( theInt
== NullPtr
< const PDF_Int
>( ) )
493 throw( "Dictionary[Length]: /Length is not a PDF_Int" );
495 return theInt
->value( );
499 SimplePDF::PDF_Dictionary::getCount( ) const
501 DicType::const_iterator
i( dic
.find( string( "Count" ) ) );
502 if( i
== dic
.end( ) )
504 throw( "Dictionary[Count]: /Count field missing" );
506 RefCountPtr
< const PDF_Int
> theInt
= SimplePDF::down_cast_follow
< const PDF_Int
>( i
->second
);
507 if( theInt
== NullPtr
< const PDF_Int
>( ) )
509 throw( "Dictionary[Count]: /Count is not a PDF_Int" );
511 return theInt
->value( );
515 SimplePDF::PDF_Dictionary::isPages( ) const
517 DicType::const_iterator
i( dic
.find( string( "Type" ) ) );
518 if( i
== dic
.end( ) )
520 throw( "PDF_Dictionary::isPages: /Type field missing" );
522 const PDF_Name
* theType( dynamic_cast< const PDF_Name
* >( i
->second
.getPtr( ) ) );
525 throw( "PDF_Dictionary::isPages: /Type is not a PDF_Name" );
527 return theType
->name( ) == "Pages";
530 RefCountPtr
< SimplePDF::PDF_Object
>
531 SimplePDF::PDF_Dictionary::getInheritable( const char * name
) const
534 DicType::const_iterator
i( dic
.find( string( name
) ) );
535 if( i
!= dic
.end( ) )
541 DicType::const_iterator
i( dic
.find( string( "Parent" ) ) );
542 if( i
!= dic
.end( ) )
544 return SimplePDF::down_cast_follow
< SimplePDF::PDF_Dictionary
>( i
->second
)->getInheritable( name
);
547 return RefCountPtr
< SimplePDF::PDF_Object
>( NullPtr
< SimplePDF::PDF_Object
>( ) );
551 RefCountPtr
< PDF_Object
> &
552 SimplePDF::PDF_Dictionary::operator [] ( const char * key
)
554 DicType::iterator
i( dic
.find( key
) );
555 if( i
== dic
.end( ) )
557 return ((dic
.insert(DicType::value_type( key
, RefCountPtr
< PDF_Object
>( new PDF_Null( ) ) ))).first
)->second
;
563 SimplePDF::PDF_Dictionary::hasKey( const char * key
) const
565 return dic
.find( key
) != dic
.end( );
568 RefCountPtr
< PDF_Object
>
569 SimplePDF::PDF_Dictionary::deepCopy( RefCountPtr
< PDF_Object
> self
, size_t * indirectObjectCounter
, IndirectRemapType
* remap
)
571 bool allSame( true );
572 RefCountPtr
< PDF_Dictionary
> res( new PDF_Dictionary
);
573 for( DicType::iterator
i( dic
.begin( ) ); i
!= dic
.end( ); ++i
)
575 RefCountPtr
< PDF_Object
> copy( ::deepCopy( i
->second
, indirectObjectCounter
, remap
) );
576 res
->dic
[ i
->first
] = copy
;
577 if( allSame
&& copy
!= i
->second
)
591 SimplePDF::PDF_Stream::PDF_Stream( )
593 SimplePDF::PDF_Stream::PDF_Stream( const PDF_Dictionary
& dic
)
594 : PDF_Dictionary( dic
)
596 SimplePDF::PDF_Stream::~PDF_Stream( )
600 SimplePDF::PDF_Stream::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
602 throw "PDF_Stream::writeTo called";
605 RefCountPtr
< PDF_Object
>
606 SimplePDF::PDF_Stream::deepCopy( RefCountPtr
< PDF_Object
> self
, size_t * indirectObjectCounter
, IndirectRemapType
* remap
)
608 throw "PDF_Stream::deepCopy must not be called. (However PDF_Stream_in::deepCopy may be called.)";
612 SimplePDF::PDF_Stream_out::PDF_Stream_out( )
614 data
<< std::setiosflags( std::ios_base::fixed
) ;
616 SimplePDF::PDF_Stream_out::~PDF_Stream_out( )
620 SimplePDF::PDF_Stream_out::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
622 const string
& dataStr( data
.str( ) );
623 PDF_Dictionary::writeToWithLength( os
, xref
, dataStr
.size( ) );
624 os
<< endl
<< "stream" << endl
;
625 os
<< dataStr
<< endl
;
631 SimplePDF::PDF_Stream_in::PDF_Stream_in( PDF_Dictionary
* dic
, istream
* _is
, streamoff _dataStart
)
632 : PDF_Stream( *dic
), is( _is
), dataStart( _dataStart
)
634 SimplePDF::PDF_Stream_in::PDF_Stream_in( istream
* _is
, streamoff _dataStart
)
635 : is( _is
), dataStart( _dataStart
)
637 SimplePDF::PDF_Stream_in::~PDF_Stream_in( )
641 SimplePDF::PDF_Stream_in::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
643 size_t length( PDF_Dictionary::getLength( ) );
644 PDF_Dictionary::writeTo( os
, xref
, self
);
645 os
<< endl
<< "stream" << endl
;
646 RefCountPtr
< char > buf( new char[ length
] );
647 is
->seekg( dataStart
, ios::beg
);
648 is
->read( buf
.getPtr( ), length
);
649 os
.write( buf
.getPtr( ), length
);
650 os
<< endl
<< "endstream " ;
653 SimplePDF::PDF_Stream_in::writeDataTo( std::ostream
& os
) const
655 size_t length( PDF_Dictionary::getLength( ) );
656 RefCountPtr
< char > buf( new char[ length
] );
657 is
->seekg( dataStart
, ios::beg
);
658 is
->read( buf
.getPtr( ), length
);
659 os
.write( buf
.getPtr( ), length
);
662 SimplePDF::PDF_Stream_in::writeDataDefilteredTo( std::ostream
& os
) const
664 if( dic
.find( "Filter" ) == dic
.end( ) )
670 RefCountPtr
< PDF_Object
> filterEntry
= RefCountPtr
< PDF_Object
>( new PDF_Null( ) );
671 typedef typeof dic DicType
;
672 DicType::const_iterator i
= dic
.find( "Filter" );
673 if( i
!= dic
.end( ) )
675 filterEntry
= i
->second
;
677 if( filterEntry
.down_cast
< PDF_Null
>( ) != NullPtr
< PDF_Null
>( ) )
683 RefCountPtr
< PDF_Name
> filterNameObj( filterEntry
.down_cast
< PDF_Name
>( ) );
684 if( filterNameObj
== NullPtr
< PDF_Name
>( ) )
686 throw( "The Filter entry was not a name (nor null) in the stream dictionary" );
688 const string
& filter( filterNameObj
->name( ) );
690 if( filter
== "FlateDecode" )
692 size_t inBufSize( PDF_Dictionary::getLength( ) );
693 RefCountPtr
< char > inBuf( new char[ inBufSize
] );
694 is
->seekg( dataStart
, ios::beg
);
695 is
->read( inBuf
.getPtr( ), inBufSize
);
697 const size_t BUFSIZE( 1024 );
698 RefCountPtr
< char > outBuf( new char[ BUFSIZE
] );
701 zs
.next_in
= reinterpret_cast< Bytef
* >( inBuf
.getPtr( ) );
702 zs
.avail_in
= inBufSize
;
703 zs
.next_out
= reinterpret_cast< Bytef
* >( outBuf
.getPtr( ) );
704 zs
.avail_out
= BUFSIZE
;
707 switch( inflateInit( & zs
) )
712 throw( "inflateInit failed" );
717 while( ( status
= inflate( & zs
, Z_NO_FLUSH
) ) == Z_OK
)
719 os
.write( outBuf
.getPtr( ), BUFSIZE
- zs
.avail_out
);
720 zs
.next_out
= reinterpret_cast< Bytef
* >( outBuf
.getPtr( ) );
721 zs
.avail_out
= BUFSIZE
;
726 os
.write( outBuf
.getPtr( ), BUFSIZE
- zs
.avail_out
);
729 throw( "The inflate cycle did not finish with Z_STREAM_END" );
733 switch( inflateEnd( & zs
) )
738 throw( "inflateEnd failed" );
743 throw( "The filter " + filter
+ " is not yet supported" );
747 RefCountPtr
< PDF_Object
>
748 SimplePDF::PDF_Stream_in::deepCopy( RefCountPtr
< PDF_Object
> self
, size_t * indirectObjectCounter
, IndirectRemapType
* remap
)
750 RefCountPtr
< PDF_Object
> dicCopy( PDF_Dictionary::deepCopy( self
, indirectObjectCounter
, remap
) );
751 if( dicCopy
.getPtr( ) == this )
755 /* By increasing the count by 1, we ensure that the memory is not destroyed when this function exits.
756 * We use that this object is newly created, so there are no other references to it.
758 if( *dicCopy
.getCounterPtr( ) != 1 )
760 throw "I expected to own the only reference to the new PDF_Dictionary";
762 ++(*dicCopy
.getCounterPtr( ));
763 return RefCountPtr
< PDF_Stream_in
>( new PDF_Stream_in( reinterpret_cast< PDF_Dictionary
* >( dicCopy
.getPtr( ) ), is
, dataStart
) );
767 SimplePDF::PDF_Indirect::PDF_Indirect( size_t _i
, size_t _v
)
770 SimplePDF::PDF_Indirect::~PDF_Indirect( )
773 SimplePDF::PDF_Indirect_in::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
775 throw "Internal error: PDF_Indirect_in::writeTo: This object is only good for reading, not for writing!";
776 // os << i << " " << v << " R" ;
778 bool SimplePDF::operator < ( const PDF_Indirect
& o1
, const PDF_Indirect
& o2
)
794 RefCountPtr
< PDF_Object
>
795 SimplePDF::PDF_Indirect::deepCopy( RefCountPtr
< PDF_Object
> self
, size_t * indirectObjectCounter
, IndirectRemapType
* remap
)
797 throw "PDF_Indirect::deepCopy must not be called. (However PDF_Indirect_in::deepCopy may be called.)";
801 SimplePDF::PDF_Indirect_out::PDF_Indirect_out( RefCountPtr
<PDF_Object
> _obj
, size_t _i
, size_t _v
)
802 : PDF_Indirect( _i
, _v
), inUse( true ), obj( _obj
)
804 SimplePDF::PDF_Indirect_out::~PDF_Indirect_out( )
807 SimplePDF::PDF_Indirect_out::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
809 xref
->enqueue( self
.down_cast
< const PDF_Indirect_out
>( ) ); /* This shall not fail! */
810 os
<< xref
->local( i
) << " " << v
<< " R" ; /* We must not call xref->local before xref->enqueue ! */
813 SimplePDF::PDF_Indirect_out::writeObject( std::ostream
& os
, SimplePDF::PDF_xref
* xref
) const
817 os
<< xref
->local( i
) << " " << v
<< " obj" << endl
;
818 obj
->writeTo( os
, xref
, obj
);
819 os
<< endl
<< "endobj" << endl
;
825 SimplePDF::PDF_Indirect_in::PDF_Indirect_in( size_t _i
, size_t _v
)
826 : PDF_Indirect( _i
, _v
), PDFin( 0 )
828 SimplePDF::PDF_Indirect_in::~PDF_Indirect_in( )
830 RefCountPtr
< PDF_Object
>
831 SimplePDF::PDF_Indirect_in::deref( )
835 throw( "PDF_Indirect_in::deref: PDFin is not assigned" );
837 return PDFin
->readObjectNumbered( i
, v
);
839 RefCountPtr
< PDF_Object
>
840 SimplePDF::PDF_Indirect_in::deepCopy( RefCountPtr
< PDF_Object
> self
, size_t * indirectObjectCounter
, IndirectRemapType
* remap
)
843 IndirectRemapType::iterator
i( remap
->find( *this ) );
844 if( i
!= remap
->end( ) )
849 return remap
->insert( IndirectRemapType::value_type( *this, SimplePDF::indirect( ::deepCopy( deref( ), indirectObjectCounter
, remap
),
850 indirectObjectCounter
) ) ).first
->second
;
855 SimplePDF::PDF_xref::PDF_xref( )
858 /* The first position in the xref table is special. */
859 localOrder_
.push_back( 0 ); /* The first object shall appear in the xref table. */
860 localNumbers_
.push_back( 0 ); /* It has number 0. */
861 byteOffsets_
.push_back( 0 ); /* This is interpreted as "not in use" */
862 generations_
.push_back( 65535 );
866 SimplePDF::PDF_xref::enqueue( const RefCountPtr
< const::PDF_Indirect_out
> & obj
)
868 /* Grow big enough */
869 while( byteOffsets_
.size( ) <= obj
->i
)
871 localNumbers_
.push_back( 0 );
872 byteOffsets_
.push_back( 0 );
873 generations_
.push_back( 0 );
876 if( byteOffsets_
[ obj
->i
] == 0 )
878 indirectQueue_
.push_back( obj
);
879 localNumbers_
[ obj
->i
] = localOrder_
.size( );
880 byteOffsets_
[ obj
->i
] = 1; /* We will change this later, this just indicates that the object has been put in queue. */
881 localOrder_
.push_back( obj
->i
);
886 SimplePDF::PDF_xref::writeRecursive( std::ostream
& os
)
888 std::streamoff os_start
;
890 std::streamoff tmp
= static_cast< streamoff
>( os
.tellp( ) );
892 os_start
= static_cast< streamoff
>( os
.tellp( ) ); /* Will this always be some kind of zero value? */
895 while( ! indirectQueue_
.empty( ) )
897 RefCountPtr
< const SimplePDF::PDF_Indirect_out
> i_obj
= indirectQueue_
.front( );
898 indirectQueue_
.pop_front( );
899 byteOffsets_
[ i_obj
->i
] = static_cast< streamoff
>( os
.tellp( ) ) - os_start
;
900 generations_
[ i_obj
->i
] = i_obj
->v
;
901 i_obj
->writeObject( os
, this );
906 SimplePDF::PDF_xref::local( size_t i
) const
908 return localNumbers_
[ i
];
912 SimplePDF::PDF_xref::writeTable( std::ostream
& os
) const
916 throw "Internal error: PDF_xref::writeTable: This table has already been written.";
918 size_
= localOrder_
.size( );
920 os
<< setfill( '0' ) ;
922 << 0 << " " << size_
<< endl
;
923 typedef typeof localOrder_ ListType
;
924 for( ListType::const_iterator i
= localOrder_
.begin( ); i
!= localOrder_
.end( ); ++i
)
926 size_t v
= generations_
[ *i
];
927 size_t o
= byteOffsets_
[ *i
];
928 os
<< setw( 10 ) << o
<< ' ' << setw( 5 ) << v
<< ' ' << 'n' << ' ' << static_cast< char >( 10 ) ;
933 SimplePDF::PDF_xref::size( ) const
937 throw "Internal error: PDF_xref::size: The size of the table is not determined yet. Call writeTable first.";
945 RefCountPtr
< PDF_Indirect_out
>
946 SimplePDF::indirect( RefCountPtr
< PDF_Object
> obj
, size_t * i
, size_t v
)
948 return RefCountPtr
< PDF_Indirect_out
>( new PDF_Indirect_out( obj
, (*i
)++, v
) );
951 RefCountPtr
< PDF_Object
>
952 SimplePDF::deepCopy( RefCountPtr
< PDF_Object
> obj
, size_t * indirectObjectCounter
, IndirectRemapType
* remap
)
954 return obj
->deepCopy( obj
, indirectObjectCounter
, remap
);