#include <Page.hh>
Inheritance diagram for pdf::page::CPage:
this class represent a page in the PDF document. it is the container of other visual elements that will appear in the page, such as text segments, vector graphics and image pixels. normal usage of this class is to construct it, add the visual elements, then add the page to the document object.
|
list of page elements
|
|
enum for each of the page element type
00089 { path_type, xobject_type, text_type } ; |
|
construct a page with the given dimension.
00057 : m_info( new CInfo( width, height ) ) 00058 { 00059 } |
|
copy constructor. it was not need if I didn't use auto_ptr. it will deep copy the page info object.
00065 : m_texts( page.m_texts ), m_paths( page.m_paths ), 00066 m_xobj_inst( page.m_xobj_inst ), 00067 m_info( page.m_info.get( ) != 0 ? new CInfo( *page.m_info ) : 0 ), 00068 m_elements( page.m_elements ) 00069 { 00070 } |
|
destructor has nothing to do.
00075 { 00076 } |
|
assignment operator uses the copy-swap idiom.
00081 { 00082 CPage temp( page ) ; 00083 Swap( temp ) ; 00084 return *this ; 00085 } |
|
call swap on every members. used by copy-swap idiom in operator=
00090 { 00091 m_texts.swap( page.m_texts ) ; 00092 m_paths.swap( page.m_paths ) ; 00093 m_xobj_inst.swap( page.m_xobj_inst ) ; 00094 00095 // swapping the auto_ptrs should work. I have tested it with gcc 00096 std::swap( m_info, page.m_info ) ; 00097 00098 m_elements.swap( page.m_elements ) ; 00099 } |
|
this function will add the text element to the page. the text element object is copied to the internal list.
|
|
this function will add a path object (a line segment) to the page.
|
|
this function will draw an xobject on the page. xobjects are object appear in the page but not stored inside its content stream. it is stored elsewhere external to the page such that it can be shared by multiple pages. this function will only draw the xobject, but not copy the whole content of the object to the page's content. the xobject will appear in the page, in the position and transformation stored in the xobject instance. a single xobject can appear in a single page multiple times, usually with different position (otherwise they will overlap). the xobject must be added to the page's resource dictionary first, by calling CNodeBase::AddXObj(). if the page's resource dictionary is empty, it will inherit the resource dictionary from its parent node in the page tree.
00143 { 00144 assert( !ResDict( ).HasXObj( ) || FindXObj( object ) ) ; 00145 00146 m_xobj_inst.push_back( CXObjInst( object, x, y, width, height ) ) ; 00147 m_elements.push_back( std::make_pair( xobject_type, 00148 m_xobj_inst.size( ) - 1 ) ) ; 00149 } |
|
this function write the page object into a PDF file, given the parent object of this page. the parent object should be a page tree object.
00161 { 00162 using namespace core ; 00163 00164 00165 CDictionary *dict = new CDictionary ; 00166 dict->AddPair( CName( "Type" ), new CName( "Page" ) ) ; 00167 dict->AddPair( CName( "Parent" ), parent.Dup( ) ) ; 00168 00169 // write content stream 00170 CObjRef content = WriteContent( file ) ; 00171 dict->AddPair( CName( "Contents" ), content.Dup( ) ) ; 00172 00173 // should check if it is different from parent first 00174 if ( m_info.get( ) != 0 ) 00175 m_info->Write( dict, default_info ) ; 00176 00177 return file.AddObj( dict ) ; 00178 } |
|
this function will write the content stream of the page. it is called by Write(). it will iterate all page elements and write them out.
00187 { 00188 using namespace common ; 00189 using namespace core ; 00190 using namespace std ; 00191 00192 // the content stream 00193 stringstream os ; 00194 00195 for ( CElementIt i = m_elements.begin( ) ; i != m_elements.end( ) ; ) 00196 { 00197 switch ( i->first ) 00198 { 00199 case text_type : i = WriteText( os, i ) ; break ; 00200 case path_type : i = WritePaths( os, i ) ; break ; 00201 case xobject_type : i = WriteXObjs( os, i ) ; break ; 00202 00203 #ifdef _DEBUG 00204 default: assert( false ) ; 00205 #endif 00206 } 00207 } 00208 00209 CStream *stream = new CFlateStream( istreambuf_iterator<char>( os ), 00210 istreambuf_iterator<char>( ) ) ; 00211 return file.AddObj( stream ) ; 00212 } |
|
helper function to write all text segment objects to the output stream.
00222 { 00223 assert( i != m_elements.end( ) ) ; 00224 assert( i->first == text_type ) ; 00225 00226 // since BT will reset the text state, we create a new state object. 00227 // a default constructed state object represent the initial state. 00228 text::CState state ; 00229 os << "q\nBT\n" ; 00230 00231 // use the state object until we meet a non-text element. 00232 while ( i != m_elements.end( ) && i->first == text_type ) 00233 { 00234 assert( i->second >= 0 ) ; 00235 assert( i->second < (int)m_texts.size( ) ) ; 00236 m_texts[i->second].Write( os, state ) ; 00237 00238 state = m_texts[i->second].State( ) ; 00239 00240 ++i ; 00241 } 00242 os << "ET\nQ\n" ; 00243 00244 return i ; 00245 } |
|
helper function to write all path objects to the output stream.
00255 { 00256 assert( i != m_elements.end( ) ) ; 00257 00258 graph::CState state ; 00259 os << "q\n" ; 00260 while ( i != m_elements.end( ) && i->first == path_type ) 00261 { 00262 assert( i->second >= 0 ) ; 00263 assert( i->second < (int)m_paths.size( ) ) ; 00264 m_paths[i->second].Write( os, state ) ; 00265 00266 state = m_paths[i->second].State( ) ; 00267 00268 ++i ; 00269 } 00270 os << "Q\n" ; 00271 return i ; 00272 } |
|
helper function to write all xobjects to the output stream.
00282 { 00283 assert( i != m_elements.end( ) ) ; 00284 00285 while ( i != m_elements.end( ) && i->first == xobject_type ) 00286 { 00287 assert( i->second >= 0 ) ; 00288 assert( i->second < (int)m_xobj_inst.size( ) ) ; 00289 m_xobj_inst[i->second].Write( os ) ; 00290 00291 ++i ; 00292 } 00293 return i ; 00294 } |
|
the internal list of text segments
|
|
the list of paths (line segments)
|
|
the list of xobjects (e.g. images)
|
|
optional page info object
|