Class: PDF::Core::Renderer
- Inherits:
- 
      Object
      
        - Object
- PDF::Core::Renderer
 
- Defined in:
- lib/pdf/core/renderer.rb
Overview
Document renderer serializes document into its binary representation.
Instance Attribute Summary collapse
- 
  
    
      #state  ⇒ PDF::Core::DocumentState 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Document state. 
Instance Method Summary collapse
- 
  
    
      #add_content(str)  ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Appends a raw string to the current page content. 
- 
  
    
      #before_render {|document_state| ... } ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Defines a block to be called just before the document is rendered. 
- 
  
    
      #close_graphics_state  ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Close current graphic state (restore previous) in the content stream. 
- 
  
    
      #compression_enabled?  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    Returns true if content streams will be compressed before rendering, false otherwise. 
- 
  
    
      #deref(obj)  ⇒ any 
    
    
  
  
  
  
  
  
  
  
  
    At any stage in the object tree an object can be replaced with an indirect reference. 
- 
  
    
      #finalize_all_page_contents  ⇒ void 
    
    
  
  
  
  
  
  
  
  private
  
    Finalize all pages. 
- 
  
    
      #go_to_page(page_number)  ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Re-opens the page with the given (1-based) page number so that you can draw on it. 
- 
  
    
      #graphic_stack  ⇒ PDF::Core::GraphicStateStack 
    
    
  
  
  
  
  
  
  
  
  
    Graphic state stack of the current document. 
- 
  
    
      #graphic_state  ⇒ PDF::Core::GraphicState 
    
    
  
  
  
  
  
  
  
  
  
    Current graphic state. 
- 
  
    
      #initialize(state)  ⇒ Renderer 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    A new instance of Renderer. 
- 
  
    
      #min_version(min)  ⇒ void 
    
    
  
  
  
  
  
  
  
  private
  
    Raise the PDF version of the file we’re going to generate. 
- 
  
    
      #names  ⇒ PDF::Core::Reference<Hash> 
    
    
  
  
  
  
  
  
  
  
  
    The Name dictionary for this document. 
- 
  
    
      #names?  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    Returns true if the Names dictionary is in use for this document. 
- 
  
    
      #on_page_create {|document_state| ... } ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Defines a block to be called just before a new page is started. 
- 
  
    
      #open_graphics_state  ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Open (save) current graphic state in the content stream. 
- 
  
    
      #page_count  ⇒ Integer 
    
    
  
  
  
  
  
  
  
  
  
    Number of pages in the document. 
- 
  
    
      #ref(data)  ⇒ Integer 
    
    
  
  
  
  
  
  
  
  
  
    Creates a new Reference and adds it to the Document’s object list. 
- 
  
    
      #ref!(data)  ⇒ PDF::Core::Reference 
    
    
  
  
  
  
  
  
  
  
  
    Like #ref, but returns the actual reference instead of its identifier. 
- 
  
    
      #render(output = nil)  ⇒ String 
    
    
  
  
  
  
  
  
  
  
  
    Renders the PDF document to string. 
- 
  
    
      #render_body(output)  ⇒ void 
    
    
  
  
  
  
  
  
  
  private
  
    Write out the PDF Body, as per spec 3.4.2. 
- 
  
    
      #render_file(filename)  ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Renders the PDF document to file. 
- 
  
    
      #render_header(output)  ⇒ void 
    
    
  
  
  
  
  
  
  
  private
  
    Write out the PDF Header, as per spec 3.4.1. 
- 
  
    
      #render_trailer(output)  ⇒ void 
    
    
  
  
  
  
  
  
  
  private
  
    Write out the PDF Trailer, as per spec 3.4.4. 
- 
  
    
      #render_xref(output)  ⇒ void 
    
    
  
  
  
  
  
  
  
  private
  
    Write out the PDF Cross Reference Table, as per spec 3.4.3. 
- 
  
    
      #restore_graphics_state  ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Pops the last saved graphics state off the graphics state stack and restores the state to those values. 
- 
  
    
      #save_graphics_state(graphic_state = nil) { ... } ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Save surrent graphic state both in the graphic state stack and in the page content stream. 
- 
  
    
      #start_new_page(options = {})  ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Create a new page and set it current. 
Constructor Details
#initialize(state) ⇒ Renderer
Returns a new instance of Renderer.
Source Code
| 10 | def initialize(state) | 
| 11 | @state = state | 
| 12 | @state.populate_pages_from_store(self) | 
| 13 | |
| 14 | min_version(state.store.min_version) if state.store.min_version | 
| 15 | |
| 16 | @page_number = 0 | 
| 17 | end
 | 
Instance Attribute Details
#state ⇒ PDF::Core::DocumentState (readonly)
Document state
Source Code
| 21 | def state | 
| 22 |   @state
 | 
| 23 | end
 | 
Instance Method Details
#add_content(str) ⇒ void
This method returns an undefined value.
Appends a raw string to the current page content.
Source Code
| 66 | def add_content(str) | 
| 67 | save_graphics_state if graphic_state.nil? | 
| 68 | state.page.content << str << "\n" | 
| 69 | end
 | 
#before_render {|document_state| ... } ⇒ void
This method returns an undefined value.
Defines a block to be called just before the document is rendered.
Source Code
| 92 | def before_render(&block) | 
| 93 | state.before_render_callbacks << block | 
| 94 | end
 | 
#close_graphics_state ⇒ void
This method returns an undefined value.
Close current graphic state (restore previous) in the content stream.
Source Code
| 290 | def close_graphics_state | 
| 291 | add_content('Q') | 
| 292 | end
 | 
#compression_enabled? ⇒ Boolean
Returns true if content streams will be compressed before rendering, false otherwise
Source Code
| 316 | def compression_enabled? | 
| 317 | state.compress | 
| 318 | end
 | 
#deref(obj) ⇒ any
At any stage in the object tree an object can be replaced with an
indirect reference. To get access to the object safely, regardless
of if it’s hidden behind a PDF::Core::Reference, wrap it in deref().
Source Code
| 51 | def deref(obj) | 
| 52 | obj.is_a?(PDF::Core::Reference) ? obj.data : obj | 
| 53 | end
 | 
#finalize_all_page_contents ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Finalize all pages
Source Code
| 166 | def finalize_all_page_contents | 
| 167 | (1..page_count).each do |i| | 
| 168 | go_to_page(i) | 
| 169 | while graphic_stack.present? | 
| 170 |       restore_graphics_state
 | 
| 171 |     end
 | 
| 172 | state.page.finalize | 
| 173 |   end
 | 
| 174 | end
 | 
#go_to_page(page_number) ⇒ void
This method returns an undefined value.
Re-opens the page with the given (1-based) page number so that you can draw on it.
Source Code
| 157 | def go_to_page(page_number) | 
| 158 | @page_number = page_number | 
| 159 | state.page = state.pages[page_number - 1] | 
| 160 | end
 | 
#graphic_stack ⇒ PDF::Core::GraphicStateStack
Graphic state stack of the current document.
Source Code
| 336 | def graphic_stack | 
| 337 | state.page.stack | 
| 338 | end
 | 
#graphic_state ⇒ PDF::Core::GraphicState
Current graphic state
Source Code
| 343 | def graphic_state | 
| 344 | save_graphics_state unless graphic_stack.current_state | 
| 345 | graphic_stack.current_state | 
| 346 | end
 | 
#min_version(min) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Raise the PDF version of the file we’re going to generate. A private method, designed for internal use when the user adds a feature to their document that requires a particular version.
Source Code
| 183 | def min_version(min) | 
| 184 | state.version = min if min > state.version | 
| 185 | end
 | 
#names ⇒ PDF::Core::Reference<Hash>
The Name dictionary for this document. It is lazily initialized, so that documents that do not need a name dictionary do not incur the additional overhead.
Source Code
| 77 | def names | 
| 78 | state.store.root.data[:Names] ||= ref!(Type: :Names) | 
| 79 | end
 | 
#names? ⇒ Boolean
Returns true if the Names dictionary is in use for this document.
Source Code
| 84 | def names? | 
| 85 | state.store.root.data.key?(:Names) | 
| 86 | end
 | 
#on_page_create {|document_state| ... } ⇒ void
This method returns an undefined value.
Defines a block to be called just before a new page is started.
Source Code
| 100 | def on_page_create(&block) | 
| 101 | state.on_page_create_callback = block | 
| 102 | end
 | 
#open_graphics_state ⇒ void
This method returns an undefined value.
Open (save) current graphic state in the content stream.
Source Code
| 283 | def open_graphics_state | 
| 284 | add_content('q') | 
| 285 | end
 | 
#page_count ⇒ Integer
Number of pages in the document.
Source Code
| 147 | def page_count | 
| 148 | state.page_count | 
| 149 | end
 | 
#ref(data) ⇒ Integer
Creates a new Reference and adds it to the Document’s object list.
Source Code
| 27 | def ref(data) | 
| 28 | ref!(data).identifier | 
| 29 | end
 | 
#ref!(data) ⇒ PDF::Core::Reference
Like #ref, but returns the actual reference instead of its identifier.
While you can use this to build up nested references within the object
tree, it is recommended to persist only identifiers, and then provide
helper methods to look up the actual references in the ObjectStore if
needed. If you take this approach, Document::Snapshot will probably
work with your extension.
Source Code
| 41 | def ref!(data) | 
| 42 | state.store.ref(data) | 
| 43 | end
 | 
#render(output = nil) ⇒ String
Renders the PDF document to string. Pass an open file descriptor to render to file.
Source Code
| 192 | def render(output = nil) | 
| 193 | buffer = StringIO.new.binmode | 
| 194 | |
| 195 |   finalize_all_page_contents
 | 
| 196 | |
| 197 | render_header(buffer) | 
| 198 | render_body(buffer) | 
| 199 | render_xref(buffer) | 
| 200 | render_trailer(buffer) | 
| 201 | |
| 202 | if output.respond_to?(:<<) | 
| 203 | output << buffer.string | 
| 204 |   end
 | 
| 205 | |
| 206 | buffer.string | 
| 207 | end
 | 
#render_body(output) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Write out the PDF Body, as per spec 3.4.2
Source Code
| 240 | def render_body(output) | 
| 241 | state.render_body(output) | 
| 242 | end
 | 
#render_file(filename) ⇒ void
This method returns an undefined value.
Renders the PDF document to file.
Source Code
| 216 | def render_file(filename) | 
| 217 | File.open(filename, 'wb') { |f| render(f) } | 
| 218 | end
 | 
#render_header(output) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Write out the PDF Header, as per spec 3.4.1
Source Code
| 225 | def render_header(output) | 
| 226 | state.before_render_actions(self) | 
| 227 | |
| 228 |   # pdf version
 | 
| 229 | output << "%PDF-#{state.version}\n" | 
| 230 | |
| 231 |   # 4 binary chars, as recommended by the spec
 | 
| 232 | output << "%\xFF\xFF\xFF\xFF\n" | 
| 233 | end
 | 
#render_trailer(output) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Write out the PDF Trailer, as per spec 3.4.4
Source Code
| 265 | def render_trailer(output) | 
| 266 | trailer_hash = { | 
| 267 | Size: state.store.size + 1, | 
| 268 | Root: state.store.root, | 
| 269 | Info: state.store.info, | 
| 270 |   }
 | 
| 271 | trailer_hash.merge!(state.trailer) if state.trailer | 
| 272 | |
| 273 | output << "trailer\n" | 
| 274 | output << PDF::Core.pdf_object(trailer_hash) << "\n" | 
| 275 | output << "startxref\n" | 
| 276 | output << @xref_offset << "\n" | 
| 277 | output << '%%EOF' << "\n" | 
| 278 | end
 | 
#render_xref(output) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Write out the PDF Cross Reference Table, as per spec 3.4.3
Source Code
| 249 | def render_xref(output) | 
| 250 | @xref_offset = output.size | 
| 251 | output << "xref\n" | 
| 252 | output << "0 #{state.store.size + 1}\n" | 
| 253 | output << "0000000000 65535 f \n" | 
| 254 | state.store.each do |ref| | 
| 255 | output.printf('%<offset>010d', offset: ref.offset) | 
| 256 | output << " 00000 n \n" | 
| 257 |   end
 | 
| 258 | end
 | 
#restore_graphics_state ⇒ void
This method returns an undefined value.
Pops the last saved graphics state off the graphics state stack and restores the state to those values
Source Code
| 324 | def restore_graphics_state | 
| 325 | if graphic_stack.empty? | 
| 326 | raise PDF::Core::Errors::EmptyGraphicStateStack, | 
| 327 | "\n You have reached the end of the graphic state stack" | 
| 328 |   end
 | 
| 329 |   close_graphics_state
 | 
| 330 | graphic_stack.restore_graphic_state | 
| 331 | end
 | 
#save_graphics_state(graphic_state = nil) { ... } ⇒ void
This method returns an undefined value.
Save surrent graphic state both in the graphic state stack and in the page content stream.
If a block is given graphic state is automatically restored after the block execution.
Source Code
| 303 | def save_graphics_state(graphic_state = nil) | 
| 304 | graphic_stack.save_graphic_state(graphic_state) | 
| 305 |   open_graphics_state
 | 
| 306 | if block_given? | 
| 307 |     yield
 | 
| 308 |     restore_graphics_state
 | 
| 309 |   end
 | 
| 310 | end
 | 
#start_new_page(options = {}) ⇒ void
This method returns an undefined value.
Create a new page and set it current.
Source Code
| 110 | def start_new_page(options = {}) | 
| 111 | last_page = state.page | 
| 112 | if last_page | 
| 113 | last_page_size = last_page.size | 
| 114 | last_page_layout = last_page.layout | 
| 115 | last_page_margins = last_page.margins | 
| 116 |   end
 | 
| 117 | |
| 118 | page_options = { | 
| 119 | size: options[:size] || last_page_size, | 
| 120 | layout: options[:layout] || last_page_layout, | 
| 121 | margins: last_page_margins, | 
| 122 |   }
 | 
| 123 | if last_page | 
| 124 | if last_page.graphic_state | 
| 125 | new_graphic_state = last_page.graphic_state.dup | 
| 126 |     end
 | 
| 127 | |
| 128 |     # Erase the color space so that it gets reset on new page for fussy
 | 
| 129 |     # pdf-readers
 | 
| 130 | if new_graphic_state | 
| 131 | new_graphic_state.color_space = {} | 
| 132 |     end
 | 
| 133 | page_options[:graphic_state] = new_graphic_state | 
| 134 |   end
 | 
| 135 | |
| 136 | state.page = PDF::Core::Page.new(self, page_options) | 
| 137 | |
| 138 | state.insert_page(state.page, @page_number) | 
| 139 | @page_number += 1 | 
| 140 | |
| 141 | state.on_page_create_action(self) | 
| 142 | end
 |