module Prawn::Graphics
Implements the drawing facilities for Prawn::Document. Use this to draw the most beautiful imaginable things.
This file lifts and modifies several of PDF::Writer's graphics functions ruby-pdf.rubyforge.org
Constants
- KAPPA
This constant is used to approximate a symmetrical arc using a cubic Bezier curve.
Public Instance Methods
Draws a circle of radius radius
with the centre-point at
point
as a complete subpath. The drawing point will be moved
to the centre-point upon completion of the drawing the circle.
pdf.circle [100,100], 25
# File lib/prawn/graphics.rb, line 194 def circle(center, radius) ellipse(center, radius, radius) end
Closes and strokes the current path. If a block is provided, yields to the block before closing the path. See Graphics::Color for color details.
# File lib/prawn/graphics.rb, line 285 def close_and_stroke yield if block_given? renderer.add_content "s" end
Closes the current path.
# File lib/prawn/graphics.rb, line 386 def close_path renderer.add_content "h" end
Draws a Bezier curve between two points, bounded by two additional points
pdf.curve [50,100], [100,100], :bounds => [[90,90],[75,75]]
# File lib/prawn/graphics.rb, line 178 def curve(origin, dest, options = {}) move_to(*origin) curve_to(dest, options) end
Draws a Bezier curve from the current drawing position to the specified point, bounded by two additional points.
pdf.curve_to [100,100], :bounds => [[90,90],[75,75]]
# File lib/prawn/graphics.rb, line 67 def curve_to(dest, options = {}) options[:bounds] or fail Prawn::Errors::InvalidGraphicsPath, "Bounding points for bezier curve must be specified " \ "as :bounds => [[x1,y1],[x2,y2]]" curve_points = PDF::Core.real_params( (options[:bounds] << dest).flat_map { |e| map_to_absolute(e) } ) renderer.add_content("#{curve_points} c") end
Draws an ellipse of x
radius r1
and
y
radius r2
with the centre-point at
point
as a complete subpath. The drawing point will be moved
to the centre-point upon completion of the drawing the ellipse.
# draws an ellipse with x-radius 25 and y-radius 50 pdf.ellipse [100,100], 25, 50
# File lib/prawn/graphics.rb, line 206 def ellipse(point, r1, r2 = r1) x, y = point l1 = r1 * KAPPA l2 = r2 * KAPPA move_to(x + r1, y) # Upper right hand corner curve_to [x, y + r2], :bounds => [[x + r1, y + l2], [x + l1, y + r2]] # Upper left hand corner curve_to [x - r1, y], :bounds => [[x - l1, y + r2], [x - r1, y + l2]] # Lower left hand corner curve_to [x, y - r2], :bounds => [[x - r1, y - l2], [x - l1, y - r2]] # Lower right hand corner curve_to [x + r1, y], :bounds => [[x + l1, y - r2], [x + r1, y - l2]] move_to(x, y) end
Closes and fills the current path. See Graphics::Color for color details.
If the option :fill_rule => :even_odd is specified, Prawn will use the even-odd rule to fill the path. Otherwise, the nonzero winding number rule will be used. See the PDF reference, “Graphics -> Path Construction and Painting -> Clipping Path Operators” for details on the difference.
# File lib/prawn/graphics.rb, line 365 def fill(options = {}) yield if block_given? renderer.add_content(options[:fill_rule] == :even_odd ? "f*" : "f") end
Closes, fills, and strokes the current path. If a block is provided, yields to the block before closing the path. See Graphics::Color for color details.
If the option :fill_rule => :even_odd is specified, Prawn will use the even-odd rule to fill the path. Otherwise, the nonzero winding number rule will be used. See the PDF reference, “Graphics -> Path Construction and Painting -> Clipping Path Operators” for details on the difference.
# File lib/prawn/graphics.rb, line 379 def fill_and_stroke(options = {}) yield if block_given? renderer.add_content(options[:fill_rule] == :even_odd ? "b*" : "b") end
Draws, strokes, and fills a circle of radius radius
with the
centre-point at point
.
# File lib/prawn/graphics.rb, line 518
Draws, strokes, and fills an ellipse of x radius r1
and y
radius r2
with the centre-point at point
.
# File lib/prawn/graphics.rb, line 545
Draws, strokes, and fills a polygon from the specified points.
# File lib/prawn/graphics.rb, line 569
Draws, fills, and strokes a rectangle given point
,
width
and height
. The rectangle is bounded by its
upper-left corner.
# File lib/prawn/graphics.rb, line 417
Draws, strokes, and fills a rounded polygon from specified points, using
radius
to define Bezier curves.
# File lib/prawn/graphics.rb, line 596 ops = %w{fill stroke fill_and_stroke}
Draws and fills a circle of radius radius
with the
centre-point at point
.
# File lib/prawn/graphics.rb, line 509
Draws and fills an ellipse of x radius r1
and y radius
r2
with the centre-point at point
.
# File lib/prawn/graphics.rb, line 536
Draws and fills a polygon from the specified points.
# File lib/prawn/graphics.rb, line 561
Draws and fills ills a rectangle given point
,
width
and height
. The rectangle is bounded by its
upper-left corner.
# File lib/prawn/graphics.rb, line 408
Draws and fills a rounded polygon from specified points, using
radius
to define Bezier curves.
# File lib/prawn/graphics.rb, line 587
Draws and fills a rounded rectangle given point
,
width
and height
and radius
for the
rounded corner. The rectangle is bounded by its upper-left corner.
# File lib/prawn/graphics.rb, line 437
Draws a horizontal line from x1
to x2
at the
current y
position, or the position specified by the :at
option.
# draw a line from [25, 75] to [100, 75] horizontal_line 25, 100, :at => 75
# File lib/prawn/graphics.rb, line 147 def horizontal_line(x1, x2, options = {}) if options[:at] y1 = options[:at] else y1 = y - bounds.absolute_bottom end line(x1, y1, x2, y1) end
Draws a horizontal line from the left border to the right border of the
bounding box at the current y
position.
# File lib/prawn/graphics.rb, line 160 def horizontal_rule horizontal_line(bounds.left, bounds.right) end
Draws a line from one point to another. Points may be specified as tuples or flattened argument list:
pdf.line [100,100], [200,250] pdf.line(100,100,200,250)
# File lib/prawn/graphics.rb, line 135 def line(*points) x0, y0, x1, y1 = points.flatten move_to(x0, y0) line_to(x1, y1) end
Draws a line from the current drawing position to the specified point. The destination may be described as a tuple or a flattened list:
pdf.line_to [50,50] pdf.line_to(50,50)
# File lib/prawn/graphics.rb, line 57 def line_to(*point) xy = PDF::Core.real_params(map_to_absolute(point)) renderer.add_content("#{xy} l") end
When called without an argument, returns the current line thickness. When called with an argument, sets the line thickness to the specified value (in PDF points)
pdf.line_width #=> 1 pdf.line_width(5) pdf.line_width #=> 5
# File lib/prawn/graphics.rb, line 121 def line_width(width = nil) if width self.line_width = width else current_line_width end end
Sets line thickness to the width
specified.
# File lib/prawn/graphics.rb, line 108 def line_width=(width) self.current_line_width = width write_line_width end
Moves the drawing position to a given point. The point can be specified as a tuple or a flattened argument list
pdf.move_to [100,50] pdf.move_to(100,50)
# File lib/prawn/graphics.rb, line 46 def move_to(*point) xy = PDF::Core.real_params(map_to_absolute(point)) renderer.add_content("#{xy} m") end
Draws a polygon from the specified points.
# draws a snazzy triangle pdf.polygon [100,100], [100,200], [200,200]
# File lib/prawn/graphics.rb, line 237 def polygon(*points) move_to points[0] (points[1..-1] << points[0]).each do |point| line_to(*point) end # close the path renderer.add_content "h" end
Draws a rectangle given point
, width
and
height
. The rectangle is bounded by its upper-left corner.
pdf.rectangle [300,300], 100, 200
# File lib/prawn/graphics.rb, line 84 def rectangle(point, width, height) x, y = map_to_absolute(point) box = PDF::Core.real_params([x, y - height, width, height]) renderer.add_content("#{box} re") end
Draws a rounded polygon from specified points using the radius to define bezier curves
# draws a rounded filled in polygon pdf.fill_and_stroke_rounded_polygon(10, [100, 250], [200, 300], [300, 250], [300, 150], [200, 100], [100, 150])
# File lib/prawn/graphics.rb, line 251 def rounded_polygon(radius, *points) move_to point_on_line(radius, points[1], points[0]) sides = points.size points << points[0] << points[1] (sides).times do |i| rounded_vertex(radius, points[i], points[i + 1], points[i + 2]) end # close the path renderer.add_content "h" end
Draws a rounded rectangle given point
, width
and
height
and radius
for the rounded corner. The
rectangle is bounded by its upper-left corner.
pdf.rounded_rectangle [300,300], 100, 200, 10
# File lib/prawn/graphics.rb, line 97 def rounded_rectangle(point, width, height, radius) x, y = point rounded_polygon(radius, point, [x + width, y], [x + width, y - height], [x, y - height]) end
Creates a rounded vertex for a line segment used for building a rounded polygon requires a radius to define bezier curve and three points. The first two points define the line segment and the third point helps define the curve for the vertex.
# File lib/prawn/graphics.rb, line 265 def rounded_vertex(radius, *points) radial_point_1 = point_on_line(radius, points[0], points[1]) bezier_point_1 = point_on_line((radius - radius * KAPPA), points[0], points[1]) radial_point_2 = point_on_line(radius, points[2], points[1]) bezier_point_2 = point_on_line((radius - radius * KAPPA), points[2], points[1]) line_to(radial_point_1) curve_to(radial_point_2, :bounds => [bezier_point_1, bezier_point_2]) end
Strokes the current path. If a block is provided, yields to the block before closing the path. See Graphics::Color for color details.
# File lib/prawn/graphics.rb, line 277 def stroke yield if block_given? renderer.add_content "S" end
Draws, fills, and strokes a rounded rectangle given point
,
width
and height
and radius
for the
rounded corner. The rectangle is bounded by its upper-left corner.
# File lib/prawn/graphics.rb, line 447
Draws and strokes X and Y axes rulers beginning at the current bounding box origin (or at a custom location).
Options¶ ↑
:at
-
Origin of the X and Y axes (default: [0, 0] = origin of the bounding box)
:width
-
Length of the X axis (default: width of the bounding box)
:height
-
Length of the Y axis (default: height of the bounding box)
:step_length
-
Length of the step between markers (default: 100)
:negative_axes_length
-
Length of the negative parts of the axes (default: 20)
:color
:
The color of the axes and the text.
# File lib/prawn/graphics.rb, line 320 def stroke_axis(options = {}) options = { :at => [0, 0], :height => bounds.height.to_i - (options[:at] || [0, 0])[1], :width => bounds.width.to_i - (options[:at] || [0, 0])[0], :step_length => 100, :negative_axes_length => 20, :color => "000000" }.merge(options) Prawn.verify_options([:at, :width, :height, :step_length, :negative_axes_length, :color], options) save_graphics_state do fill_color(options[:color]) stroke_color(options[:color]) dash(1, :space => 4) stroke_horizontal_line(options[:at][0] - options[:negative_axes_length], options[:at][0] + options[:width], :at => options[:at][1]) stroke_vertical_line(options[:at][1] - options[:negative_axes_length], options[:at][1] + options[:height], :at => options[:at][0]) undash fill_circle(options[:at], 1) (options[:step_length]..options[:width]).step(options[:step_length]) do |point| fill_circle([options[:at][0] + point, options[:at][1]], 1) draw_text(point, :at => [options[:at][0] + point - 5, options[:at][1] - 10], :size => 7) end (options[:step_length]..options[:height]).step(options[:step_length]) do |point| fill_circle([options[:at][0], options[:at][1] + point], 1) draw_text(point, :at => [options[:at][0] - 17, options[:at][1] + point - 2], :size => 7) end end end
Draws and strokes a rectangle represented by the current bounding box
# File lib/prawn/graphics.rb, line 292 def stroke_bounds stroke_rectangle bounds.top_left, bounds.width, bounds.height end
Draws and strokes a circle of radius radius
with the
centre-point at point
.
# File lib/prawn/graphics.rb, line 500
Strokes a Bezier curve between two points, bounded by two additional points.
# File lib/prawn/graphics.rb, line 491
Draws and strokes an ellipse of x radius r1
and y radius
r2
with the centre-point at point
.
# File lib/prawn/graphics.rb, line 527
Strokes a horizontal line from x1
to x2
at the
current y position, or the position specified by the :at option.
# File lib/prawn/graphics.rb, line 465
Strokes a horizontal line from the left border to the right border of the bounding box at the current y position.
# File lib/prawn/graphics.rb, line 474
Strokes a line from one point to another. Points may be specified as tuples or flattened argument list.
# File lib/prawn/graphics.rb, line 456
Draws and strokes a polygon from the specified points.
# File lib/prawn/graphics.rb, line 553
Draws and strokes a rectangle given point
, width
and height
. The rectangle is bounded by its upper-left corner.
# File lib/prawn/graphics.rb, line 399
Draws and strokes a rounded polygon from specified points, using
radius
to define Bezier curves.
# File lib/prawn/graphics.rb, line 578
Draws and strokes a rounded rectangle given point
,
width
and height
and radius
for the
rounded corner. The rectangle is bounded by its upper-left corner.
# File lib/prawn/graphics.rb, line 427
Strokes a vertical line at the x coordinate given by :at from y1 to y2.
# File lib/prawn/graphics.rb, line 482
Draws a vertical line at the x cooordinate given by :at from y1 to y2.
# draw a line from [25, 100] to [25, 300] vertical_line 100, 300, :at => 25
# File lib/prawn/graphics.rb, line 169 def vertical_line(y1, y2, params) line(params[:at], y1, params[:at], y2) end
Private Instance Methods
# File lib/prawn/graphics.rb, line 606 def current_line_width graphic_state.line_width end
# File lib/prawn/graphics.rb, line 610 def current_line_width=(width) graphic_state.line_width = width end
# File lib/prawn/graphics.rb, line 627 def degree_to_rad(angle) angle * Math::PI / 180 end
# File lib/prawn/graphics.rb, line 618 def map_to_absolute(*point) x, y = point.flatten [@bounding_box.absolute_left + x, @bounding_box.absolute_bottom + y] end
# File lib/prawn/graphics.rb, line 623 def map_to_absolute!(point) point.replace(map_to_absolute(point)) end
Returns the coordinates for a point on a line that is a given distance away from the second point defining the line segement
# File lib/prawn/graphics.rb, line 633 def point_on_line(distance_from_end, *points) x0, y0, x1, y1 = points.flatten length = Math.sqrt((x1 - x0)**2 + (y1 - y0)**2) p = (length - distance_from_end) / length xr = x0 + p * (x1 - x0) yr = y0 + p * (y1 - y0) [xr, yr] end
# File lib/prawn/graphics.rb, line 614 def write_line_width renderer.add_content("#{current_line_width} w") end