Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Filling in the documentation gap. Bounding box may need to be made a …

…little clearer
  • Loading branch information...
commit a3a99869ebeb951c97a7c8acd27ed4216777a665 1 parent 7a2c295
sandal authored
View
30 lib/prawn/document.rb
@@ -18,8 +18,8 @@ class Document
attr_accessor :page_size, :page_layout, :y
- # Creates and renders a PDF document. If a filename is given, the output
- # will be rendered to file, otherwise the result will be turned as a string.
+ # Creates and renders a PDF document.
+ #
# The explicit receiver argument is necessary only when you need to make
# use of a closure.
#
@@ -29,19 +29,17 @@ class Document
# text "Hello World", :at => [200,720], :size => 32
# end
#
- # # Using explicit block form and rendering to a file
+ # # 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 "Hello World", :at => [200,720], :size => 32
+ # pdf.text content, :at => [200,720], :size => 32
# end
#
- # # Using implicit block form and rendering to string
- # output = Prawn::Document.generate { stroke_line [100,100], [200,200] }
- #
- def self.generate(filename=nil,&block)
- pdf = Prawn::Document.new
+ def self.generate(filename,options={},&block)
+ pdf = Prawn::Document.new(options)
block.arity < 1 ? pdf.instance_eval(&block) : yield(pdf)
- filename ? pdf.render_file(filename) : pdf.render
+ pdf.render_file(filename)
end
# Creates a new PDF Document. The following options are available:
@@ -49,7 +47,12 @@ def self.generate(filename=nil,&block)
# <tt>:page_size</tt>:: One of the Document::PageGeometry::SIZES (default: LETTER)
# <tt>:page_layout</tt>:: Either <tt>:portrait</tt> or <tt>:landscape</tt>
# <tt>:on_page_start</tt>:: Optional proc run at each page start
- # <tt>:on_page_stop</tt>:: Optional proc run at each page stop
+ # <tt>:on_page_stop</tt>:: Optional proc run at each page stop
+ # <tt>:left_margin</tt>:: Sets the left margin in points [default: 0.5 inch]
+ # <tt>:right_margin</tt>:: Sets the right margin in points [default: 0.5 inch]
+ # <tt>:top_margin</tt>:: Sets the top margin in points [default: 0.5 inch]
+ # <tt>:bottom_margin</tt>:: Sets the bottom margin in points [default: 0.5 inch]
+ #
#
# # New document, US Letter paper, portrait orientation
# pdf = Prawn::Document.new
@@ -143,6 +146,11 @@ def render_file(filename)
File.open(filename,"wb") { |f| f << render }
end
+ # Returns the current BoundingBox object, which is by default
+ # the box represented by the margin box. When called from within
+ # a <tt>bounding_box</tt> block, the box defined by that call will
+ # be used.
+ #
def bounds
@bounding_box
end
View
101 lib/prawn/document/bounding_box.rb
@@ -1,6 +1,63 @@
module Prawn
class Document
-
+
+ # 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 text drawing position will be moved to
+ # the bottom of the bounding box (y - height). Currently, Prawn allows
+ # text to overflow the bottom border of the bounding box, so it is up to
+ # the user to ensure the text provided will fit within the height 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.
+ #
def bounding_box(*args,&block)
@bounding_box = BoundingBox.new(*args)
self.y = @bounding_box.absolute_top
@@ -13,43 +70,53 @@ def bounding_box(*args,&block)
class BoundingBox
- def initialize(point,options={})
+ def initialize(point,options={}) #:nodoc:
@x,@y = point
@width, @height = options[:width], options[:height]
end
-
+
+ # The translated origin (x,y-height) which describes the location
+ # of the bottom left corner of the bounding box in absolute terms.
def anchor
[@x, @y - @height]
end
-
+
+ # Relative left x-coordinate of the bounding box. (Always 0)
def left
- 0
- end
-
+ 0
+ end
+
+ # Relative right x-coordinate of the bounding box. (Equal to the box width)
def right
@width
end
-
+
+ # Relative top y-coordinate of the bounding box. (Equal to the box height)
def top
@height
- end
-
+ end
+
+ # Relative bottom y-coordinate of the bounding box (Always 0)
def bottom
0
end
-
+
+ # Absolute left x-coordinate of the bounding box
def absolute_left
@x
- end
-
+ end
+
+ # Absolute right x-coordinate of the bounding box
def absolute_right
@x + @width
- end
-
+ end
+
+ # Absolute top y-coordinate of the bounding box
def absolute_top
@y
- end
-
+ end
+
+ # Absolute bottom y-coordinate of the bottom box
def absolute_bottom
@y - @height
end
View
14 lib/prawn/document/text.rb
@@ -14,10 +14,20 @@ module Text
Times-Roman Times-Bold Times-Italic Times-BoldItalic
Symbol ZapfDingbats ]
- # Draws text at a specified position on the page.
+ # Draws text on the page. If a point is specified via the <tt>:at</tt>
+ # option the text will begin exactly at that point, and the string is
+ # assumed to be pre-formatted to properly fit the page.
+ #
+ # When <tt>:at</tt> is not specified, Prawn attempts to wrap the text to
+ # fit within your current bounding box (or margin box if no bounding box
+ # is being used ). Text will flow onto the next page when it reaches
+ # the bottom of the margin_box. Text wrap in Prawn does not re-flow
+ # linebreaks, so if you want fully automated text wrapping, be sure to
+ # remove newlines before attempting to draw your string.
#
# pdf.text "Hello World", :at => [100,100]
- # pdf.text "Goodbye World", :at => [50,50], :size => 16
+ # pdf.text "Goodbye World", :at => [50,50], :size => 16
+ # pdf.text "This will be wrapped when it hits the edge of your bounding box"
#
def text(text,options={})
return wrapped_text(text,options) unless options[:at]
View
2  lib/prawn/font/afm.rb
@@ -9,7 +9,7 @@
module Prawn
module Font
- class AFM
+ class AFM #:nodoc:
ISOLatin1Encoding = %w[
.notdef .notdef .notdef .notdef .notdef .notdef .notdef .notdef
Please sign in to comment.
Something went wrong with that request. Please try again.