lib/prawn/document.rb in prawn-0.11.1 vs lib/prawn/document.rb in prawn-0.12.0

- old
+ new

@@ -167,118 +167,127 @@ # # # New document, with background # pdf = Prawn::Document.new(:background => "#{Prawn::BASEDIR}/data/images/pigs.jpg") # def initialize(options={},&block) - Prawn.verify_options [:page_size, :page_layout, :margin, :left_margin, - :right_margin, :top_margin, :bottom_margin, :skip_page_creation, - :compress, :skip_encoding, :background, :info, - :optimize_objects, :template], options + options = options.dup - # need to fix, as the refactoring breaks this - # raise NotImplementedError if options[:skip_page_creation] + Prawn.verify_options [:page_size, :page_layout, :margin, :left_margin, + :right_margin, :top_margin, :bottom_margin, :skip_page_creation, + :compress, :skip_encoding, :background, :info, + :optimize_objects, :template], options - self.class.extensions.reverse_each { |e| extend e } - @internal_state = Prawn::Core::DocumentState.new(options) - @internal_state.populate_pages_from_store(self) - min_version(state.store.min_version) if state.store.min_version + # need to fix, as the refactoring breaks this + # raise NotImplementedError if options[:skip_page_creation] - @background = options[:background] - @font_size = 12 + self.class.extensions.reverse_each { |e| extend e } + @internal_state = Prawn::Core::DocumentState.new(options) + @internal_state.populate_pages_from_store(self) + min_version(state.store.min_version) if state.store.min_version - @bounding_box = nil - @margin_box = nil + @background = options[:background] + @font_size = 12 - @page_number = 0 + @bounding_box = nil + @margin_box = nil - options[:size] = options.delete(:page_size) - options[:layout] = options.delete(:page_layout) + @page_number = 0 - if options[:template] - fresh_content_streams(options) - go_to_page(1) - else - if options[:skip_page_creation] || options[:template] - start_new_page(options.merge(:orphan => true)) - else - start_new_page(options) - end - end + options[:size] = options.delete(:page_size) + options[:layout] = options.delete(:page_layout) - @bounding_box = @margin_box + if options[:template] + fresh_content_streams(options) + go_to_page(1) + else + if options[:skip_page_creation] || options[:template] + start_new_page(options.merge(:orphan => true)) + else + start_new_page(options) + end + end - if block - block.arity < 1 ? instance_eval(&block) : block[self] - end - end + @bounding_box = @margin_box - attr_accessor :margin_box - attr_reader :margins, :y - attr_writer :font_size - attr_accessor :page_number + if block + block.arity < 1 ? instance_eval(&block) : block[self] + end + end - def state - @internal_state - end + attr_accessor :margin_box + attr_reader :margins, :y + attr_writer :font_size + attr_accessor :page_number - def page - state.page - end + def state + @internal_state + end - # Creates and advances to a new page in the document. - # - # Page size, margins, and layout can also be set when generating a - # new page. These values will become the new defaults for page creation - # - # pdf.start_new_page #=> Starts new page keeping current values - # pdf.start_new_page(:size => "LEGAL", :layout => :landscape) - # pdf.start_new_page(:left_margin => 50, :right_margin => 50) - # pdf.start_new_page(:margin => 100) - # - # A template for a page can be specified by pointing to the path of and existing pdf. - # One can also specify which page of the template which defaults otherwise to 1. - # - # pdf.start_new_page(:template => multipage_template.pdf, :template_page => 2) - # - def start_new_page(options = {}) - if last_page = state.page - last_page_size = last_page.size - last_page_layout = last_page.layout - last_page_margins = last_page.margins - end + def page + state.page + end - page_options = {:size => options[:size] || last_page_size, - :layout => options[:layout] || last_page_layout, - :margins => last_page_margins} - if last_page - new_graphic_state = last_page.graphic_state.dup - #erase the color space so that it gets reset on new page for fussy pdf-readers - new_graphic_state.color_space = {} - page_options.merge!(:graphic_state => new_graphic_state) - end - merge_template_options(page_options, options) if options[:template] + # Creates and advances to a new page in the document. + # + # Page size, margins, and layout can also be set when generating a + # new page. These values will become the new defaults for page creation + # + # pdf.start_new_page #=> Starts new page keeping current values + # pdf.start_new_page(:size => "LEGAL", :layout => :landscape) + # pdf.start_new_page(:left_margin => 50, :right_margin => 50) + # pdf.start_new_page(:margin => 100) + # + # A template for a page can be specified by pointing to the path of and existing pdf. + # One can also specify which page of the template which defaults otherwise to 1. + # + # pdf.start_new_page(:template => multipage_template.pdf, :template_page => 2) + # + def start_new_page(options = {}) + if last_page = state.page + last_page_size = last_page.size + last_page_layout = last_page.layout + last_page_margins = last_page.margins + end - state.page = Prawn::Core::Page.new(self, page_options) + page_options = {:size => options[:size] || last_page_size, + :layout => options[:layout] || last_page_layout, + :margins => last_page_margins} + if last_page + new_graphic_state = last_page.graphic_state.dup + #erase the color space so that it gets reset on new page for fussy pdf-readers + new_graphic_state.color_space = {} + page_options.merge!(:graphic_state => new_graphic_state) + end + merge_template_options(page_options, options) if options[:template] - apply_margin_options(options) - state.page.new_content_stream if options[:template] - use_graphic_settings(options[:template]) + state.page = Prawn::Core::Page.new(self, page_options) - unless options[:orphan] - state.insert_page(state.page, @page_number) - @page_number += 1 + apply_margin_options(options) + generate_margin_box - canvas { image(@background, :at => bounds.top_left) } if @background - @y = @bounding_box.absolute_top + # Reset the bounding box if the new page has different size or layout + if last_page && (last_page.size != state.page.size || + last_page.layout != state.page.layout) + @bounding_box = @margin_box + end - float do - state.on_page_create_action(self) - end - end + state.page.new_content_stream if options[:template] + use_graphic_settings(options[:template]) - end + unless options[:orphan] + state.insert_page(state.page, @page_number) + @page_number += 1 + canvas { image(@background, :at => bounds.top_left) } if @background + @y = @bounding_box.absolute_top + + float do + state.on_page_create_action(self) + end + end + end + # Returns the number of pages in the document # # pdf = Prawn::Document.new # pdf.page_count #=> 1 # 3.times { pdf.start_new_page } @@ -316,11 +325,13 @@ # def move_cursor_to(new_y) self.y = new_y + bounds.absolute_bottom end - # Executes a block and then restores the original y position + # Executes a block and then restores the original y position. If new pages + # were created during this block, it will teleport back to the original + # page when done. # # pdf.text "A" # # pdf.float do # pdf.move_down 100 @@ -328,11 +339,15 @@ # end # # pdf.text "B" # def float - mask(:y) { yield } + original_page = page_number + original_y = y + yield + go_to_page(original_page) unless page_number == original_page + self.y = original_y end # Renders the PDF document to string # def render @@ -386,10 +401,16 @@ # def bounds @bounding_box end + # Returns the innermost non-stretchy bounding box. + # + def reference_bounds + @bounding_box.reference_bounds + end + # Sets Document#bounds to the BoundingBox provided. See above for a brief # description of what a bounding box is. This function is useful if you # really need to change the bounding box manually, but usually, just entering # and exiting bounding box code blocks is good enough. # @@ -546,11 +567,15 @@ # end # def number_pages(string, options={}) opts = options.dup start_count_at = opts.delete(:start_count_at).to_i - page_filter = opts.delete(:page_filter) + page_filter = if opts.has_key?(:page_filter) + opts.delete(:page_filter) + else + :all + end total_pages = opts.delete(:total_pages) txtcolor = opts.delete(:color) # An explicit height so that we can draw page numbers in the margins opts[:height] = 50 @@ -640,11 +665,11 @@ :width => page.dimensions[-2] - (page.margins[:left] + page.margins[:right]), :height => page.dimensions[-1] - (page.margins[:top] + page.margins[:bottom]) ) # This check maintains indentation settings across page breaks - if (old_margin_box) + if old_margin_box @margin_box.add_left_padding(old_margin_box.total_left_padding) @margin_box.add_right_padding(old_margin_box.total_right_padding) end # we must update bounding box if not flowing from the previous page @@ -669,10 +694,8 @@ [:left,:right,:top,:bottom].each do |side| if margin = options[:"#{side}_margin"] state.page.margins[side] = margin end end - - generate_margin_box end end end