Class Prawn::Document
In: lib/prawn/document/annotations.rb
lib/prawn/document/bounding_box.rb
lib/prawn/document/destinations.rb
lib/prawn/document/internals.rb
lib/prawn/document/page_geometry.rb
lib/prawn/document/span.rb
lib/prawn/document/text/box.rb
lib/prawn/document/text/wrapping.rb
lib/prawn/document/text.rb
lib/prawn/document.rb
lib/prawn/font.rb
Parent: Object

Methods

Included Modules

Text PageGeometry Internals Annotations Destinations Prawn::Graphics Prawn::Images

Classes and Modules

Module Prawn::Document::Annotations
Module Prawn::Document::Destinations
Module Prawn::Document::Internals
Module Prawn::Document::PageGeometry
Module Prawn::Document::Text
Class Prawn::Document::BoundingBox
Class Prawn::Document::LazyBoundingBox

Attributes

font_size  [W] 
margin_box  [RW] 
margins  [R] 
page_layout  [R] 
page_size  [R] 
y  [RW] 

Public Class methods

Creates and renders a PDF document.

When using the implicit block form, Prawn will evaluate the block within an instance of Prawn::Document, simplifying your syntax. However, please note that you will not be able to reference variables from the enclosing scope within this block.

  # Using implicit block form and rendering to a file
  Prawn::Document.generate "foo.pdf" do
    font "Times-Roman"
    text "Hello World", :at => [200,720], :size => 32
  end

If you need to access your local and instance variables, use the explicit block form shown below. In this case, Prawn yields an instance of PDF::Document and the block is an ordinary closure:

  # Using explicit block form and rendering to a file
  content = "Hello World"
  Prawn::Document.generate "foo.pdf" do |pdf|
    pdf.font "Times-Roman"
    pdf.text content, :at => [200,720], :size => 32
  end

Creates a new PDF Document. The following options are available:

:page_size:One of the Document::PageGeometry::SIZES [LETTER]
:page_layout:Either :portrait or :landscape
:left_margin:Sets the left margin in points [ 0.5 inch]
:right_margin:Sets the right margin in points [ 0.5 inch]
:top_margin:Sets the top margin in points [ 0.5 inch]
:bottom_margin:Sets the bottom margin in points [0.5 inch]
:skip_page_creation:Creates a document without starting the first page [false]
:compress:Compresses content streams before rendering them [false]
:background:An image path to be used as background on all pages [nil]

Usage:

  # New document, US Letter paper, portrait orientation
  pdf = Prawn::Document.new

  # New document, A4 paper, landscaped
  pdf = Prawn::Document.new(:page_size => "A4", :page_layout => :landscape)

  # New document, with background
  pdf = Prawn::Document.new(:background => "#{Prawn::BASEDIR}/data/images/pigs.jpg")

Public Instance methods

A bounding box serves two important purposes:

  • Provide bounds for flowing text, starting at a given point
  • Translate the origin (0,0) for graphics primitives, for the purposes

of simplifying coordinate math.

When flowing text, the usage of a bounding box is simple. Text will begin at the point specified, flowing the width of the bounding box. After the block exits, the cursor position will be moved to the bottom of the bounding box (y - height). If flowing text exceeds the height of the bounding box, the text will be continued on the next page, starting again at the top-left corner of the bounding box.

  pdf.bounding_box([100,500], :width => 100, :height => 300) do
    pdf.text "This text will flow in a very narrow box starting" +
     "from [100,500]. The pointer will then be moved to [100,200]" +
     "and return to the margin_box"
  end

When translating coordinates, the idea is to allow the user to draw relative to the origin, and then translate their drawing to a specified area of the document, rather than adjust all their drawing coordinates to match this new region.

Take for example two triangles which share one point, drawn from the origin:

  pdf.polygon [0,250], [0,0], [150,100]
  pdf.polygon [100,0], [150,100], [200,0]

It would be easy enough to translate these triangles to another point, e.g [200,200]

  pdf.polygon [200,450], [200,200], [350,300]
  pdf.polygon [300,200], [350,300], [400,200]

However, each time you want to move the drawing, you‘d need to alter every point in the drawing calls, which as you might imagine, can become tedious.

If instead, we think of the drawing as being bounded by a box, we can see that the image is 200 points wide by 250 points tall.

To translate it to a new origin, we simply select a point at (x,y+height)

Using the [200,200] example:

  pdf.bounding_box([200,450], :width => 200, :height => 250) do
    pdf.polygon [0,250], [0,0], [150,100]
    pdf.polygon [100,0], [150,100], [200,0]
  end

Notice that the drawing is still relative to the origin. If we want to move this drawing around the document, we simply need to recalculate the top-left corner of the rectangular bounding-box, and all of our graphics calls remain unmodified.

By default, bounding boxes are specified relative to the document‘s margin_box (which is itself a bounding box). You can also nest bounding boxes, allowing you to build components which are relative to each other

pdf.bouding_box([200,450], :width => 200, :height => 250) do

  pdf.bounding_box([50,200], :width => 50, :height => 50) do
    # a 50x50 bounding box that starts 50 pixels left and 50 pixels down
    # the parent bounding box.
  end

end

If you wish to position the bounding boxes at absolute coordinates rather than relative to the margins or other bounding boxes, you can use canvas()

  pdf.canvas do
    pdf.bounding_box([200,450], :width => 200, :height => 250) do
      # positioned at 'real' (200,450)
    end
  end

Of course, if you use canvas, you will be responsible for ensuring that you remain within the printable area of your document.

Returns the current BoundingBox object, which is by default the box represented by the margin box. When called from within a bounding_box block, the box defined by that call will be used.

Sets Document#bounds to the BoundingBox provided. If you don‘t know why you‘d need to do this, chances are, you can ignore this feature

A shortcut to produce a bounding box which is mapped to the document‘s absolute coordinates, regardless of how things are nested or margin sizes.

  pdf.canvas do
    pdf.line pdf.bounds.bottom_left, pdf.bounds.top_right
  end

Returns true if content streams will be compressed before rendering, false otherwise

The current y drawing position relative to the innermost bounding box, or to the page margins at the top level.

Without arguments, this returns the currently selected font. Otherwise, it sets the current font.

The single parameter must be a string. It can be one of the 14 built-in fonts supported by PDF, or the location of a TTF file. The Font::AFM::BUILT_INS array specifies the valid built in font values.

  pdf.font "Times-Roman"
  pdf.font "Chalkboard.ttf"

If a ttf font is specified, the glyphs necessary to render your document will be embedded in the rendered PDF. This should be your preferred option in most cases. It will increase the size of the resulting file, but also make it more portable.

Hash that maps font family names to their styled individual font names

To add support for another font family, append to this hash, e.g:

  pdf.font_families.update(
   "MyTrueTypeFamily" => { :bold        => "foo-bold.ttf",
                           :italic      => "foo-italic.ttf",
                           :bold_italic => "foo-bold-italic.ttf",
                           :normal      => "foo.ttf" })

This will then allow you to use the fonts like so:

  pdf.font("MyTrueTypeFamily", :style => :bold)
  pdf.text "Some bold text"
  pdf.font("MyTrueTypeFamily")
  pdf.text "Some normal text"

This assumes that you have appropriate TTF fonts for each style you wish to support.

When called with no argument, returns the current font size. When called with a single argument but no block, sets the current font size. When a block is used, the font size is applied transactionally and is rolled back when the block exits. You may still change the font size within a transactional block for individual text segments, or nested calls to font_size.

  Prawn::Document.generate("font_size.pdf") do
    font_size 16
    text "At size 16"

    font_size(10) do
      text "At size 10"
      text "At size 6", :size => 6
      text "At size 10"
    end

    text "At size 16"
  end

When called without an argument, this method returns the current font size.

A footer is a LazyBoundingBox drawn relative to the margins that can be repeated on every page of the document.

Unless :width or :height are specified, the margin_box width and height are used.

  footer [margin_box.left, margin_box.bottom + 25] do
    stroke_horizontal_rule
    text "And here's a sexy footer", :size => 16
  end

A header is a LazyBoundingBox drawn relative to the margins that can be repeated on every page of the document.

Unless :width or :height are specified, the margin_box width and height are used.

  header margin_box.top_left do
   text "Here's My Fancy Header", :size => 25, :align => :center
   stroke_horizontal_rule
 end

A LazyBoundingBox is simply a BoundingBox with an action tied to it to be executed later. The lazy_bounding_box method takes the same arguments as bounding_box, but returns a LazyBoundingBox object instead of executing the code block directly.

You can then call LazyBoundingBox#draw at any time (or multiple times if you wish), and the contents of the block will then be run. This can be useful for assembling repeating page elements or reusable components.

 file = "lazy_bounding_boxes.pdf"
 Prawn::Document.generate(file, :skip_page_creation => true) do
   point = [bounds.right-50, bounds.bottom + 25]
   page_counter = lazy_bounding_box(point, :width => 50) do
     text "Page: #{page_count}"
   end

   10.times do
    start_new_page
     text "Some text"
     page_counter.draw
   end
 end

Moves down the document by n point

Moves up the document by n points

Moves down the document by y, executes a block, then moves down the document by y again.

  pdf.text "some text"
  pdf.pad(100) do
    pdf.text "This is 100 points below the previous line of text"
  end
  pdf.text "This is 100 points below the previous line of text"

Executes a block then moves down the document

  pdf.text "some text"
  pdf.pad_bottom(100) do
    pdf.text "This text appears right below the previous line of text"
  end
  pdf.text "This is 100 points below the previous line of text"

Moves down the document and then executes a block.

  pdf.text "some text"
  pdf.pad_top(100) do
    pdf.text "This is 100 points below the previous line of text"
  end
  pdf.text "This text appears right below the previous line of text"

A bounding box with the same dimensions of its parents, minus a margin on all sides

Returns the number of pages in the document

  pdf = Prawn::Document.new
  pdf.page_count #=> 1
  3.times { pdf.start_new_page }
  pdf.page_count #=> 4

Renders the PDF document to string

Renders the PDF document to file.

  pdf.render_file "foo.pdf"

Saves the current font, and then yields. When the block finishes, the original font is restored.

A span is a special purpose bounding box that allows a column of elements to be positioned relative to the margin_box.

Arguments:

width:The width of the column in PDF points

Options:

:position:One of :left, :center, :right or an x offset

This method is typically used for flowing a column of text from one page to the next.

 span(350, :position => :center) do
   text "Here's some centered text in a 350 point column. " * 100
 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(:size => "LEGAL", :layout => :landscape)
  pdf.start_new_page(:left_margin => 50, :right_margin => 50)

Defines an invisible rectangle which you can flow text in. When the text overflows the box, you can either display :ellipses, :truncate the text, or allow it to :overflow the bottom boundary.

  text_box "Oh hai text box. " * 200,
    :width    => 300, :height => font.height * 5,
    :overflow => :ellipses,
    :at       => [100,bounds.top]

[Validate]