Module: Prawn::Graphics

Includes:
CapStyle, Color, Dash, JoinStyle, Transformation, Transparency
Included in:
Document
Defined in:
lib/prawn/graphics.rb,
lib/prawn/graphics/dash.rb,
lib/prawn/graphics/color.rb,
lib/prawn/graphics/cap_style.rb,
lib/prawn/graphics/join_style.rb,
lib/prawn/graphics/transparency.rb,
lib/prawn/graphics/transformation.rb

Overview

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

Defined Under Namespace

Modules: CapStyle, Color, Dash, JoinStyle, Transformation, Transparency

Constant Summary collapse

KAPPA =

This constant is used to approximate a symmetrical arc using a cubic Bezier curve.

4.0 * ((Math.sqrt(2) - 1.0) / 3.0)

Constants included from JoinStyle

JoinStyle::JOIN_STYLES

Constants included from CapStyle

CapStyle::CAP_STYLES

Instance Method Summary collapse

Methods included from Transformation

#rotate, #scale, #transformation_matrix, #translate

Methods included from Transparency

#transparent

Methods included from JoinStyle

#join_style

Methods included from CapStyle

#cap_style

Methods included from Dash

#dash, #dashed?, #undash

Methods included from Color

#fill_color, hex2rgb, #method_missing, rgb2hex, #stroke_color

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Prawn::Graphics::Color

Instance Method Details

#circle_at(point, options) ⇒ Object

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_at [100,100], :radius => 25

188
189
190
191
# File 'lib/prawn/graphics.rb', line 188

def circle_at(point, options)
  x,y = point
  ellipse_at [x, y], options[:radius]
end

#curve(origin, dest, options = {}) ⇒ Object

Draws a Bezier curve between two points, bounded by two additional points

pdf.curve [50,100], [100,100], :bounds => [[90,90],[75,75]]

172
173
174
175
# File 'lib/prawn/graphics.rb', line 172

def curve(origin,dest, options={})
  move_to(*origin)
  curve_to(dest,options)
end

#curve_to(dest, options = {}) ⇒ Object

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]]

64
65
66
67
68
69
70
71
72
# File 'lib/prawn/graphics.rb', line 64

def curve_to(dest,options={})
   options[:bounds] or raise Prawn::Errors::InvalidGraphicsPath,
     "Bounding points for bezier curve must be specified "+
     "as :bounds => [[x1,y1],[x2,y2]]"

   curve_points = (options[:bounds] << dest).map { |e| map_to_absolute(e) }
   add_content("%.3f %.3f %.3f %.3f %.3f %.3f c" %
                 curve_points.flatten )
end

#ellipse_at(point, r1, r2 = r1) ⇒ Object

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_at [100,100], 25, 50

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/prawn/graphics.rb', line 201

def ellipse_at(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 + l1], [x + l2, y + r2]]

  # Upper left hand corner
  curve_to [x - r1, y],
    :bounds => [[x - l2, y + r2], [x - r1, y + l1]]

  # Lower left hand corner
  curve_to [x, y - r2],
    :bounds => [[x - r1, y - l1], [x - l2, y - r2]]

  # Lower right hand corner
  curve_to [x + r1, y],
    :bounds => [[x + l2, y - r2], [x + r1, y - l1]]

  move_to(x, y)
end

#fillObject

Fills and closes the current path. See Graphic::Color for color details


286
287
288
289
# File 'lib/prawn/graphics.rb', line 286

def fill
  yield if block_given?
  add_content "f"
end

#fill_and_strokeObject

Fills, strokes, and closes the current path. See Graphic::Color for color details


293
294
295
296
# File 'lib/prawn/graphics.rb', line 293

def fill_and_stroke
  yield if block_given?
  add_content "b"
end

#horizontal_line(x1, x2, options = {}) ⇒ Object

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

141
142
143
144
145
146
147
148
149
# File 'lib/prawn/graphics.rb', line 141

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

#horizontal_ruleObject

Draws a horizontal line from the left border to the right border of the bounding box at the current y position.


154
155
156
# File 'lib/prawn/graphics.rb', line 154

def horizontal_rule
  horizontal_line(bounds.left, bounds.right)
end

#line(*points) ⇒ Object

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)

129
130
131
132
133
# File 'lib/prawn/graphics.rb', line 129

def line(*points)
  x0,y0,x1,y1 = points.flatten
  move_to(x0, y0)
  line_to(x1, y1)
end

#line_to(*point) ⇒ Object

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)

54
55
56
57
# File 'lib/prawn/graphics.rb', line 54

def line_to(*point)
  x,y = map_to_absolute(point)
  add_content("%.3f %.3f l" % [ x, y ])
end

#line_width(width = nil) ⇒ Object

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

115
116
117
118
119
120
121
# File 'lib/prawn/graphics.rb', line 115

def line_width(width=nil)
  if width
    self.line_width = width
  else
    (defined?(@line_width) && @line_width) || 1
  end
end

#line_width=(width) ⇒ Object

Sets line thickness to the width specified.


102
103
104
105
# File 'lib/prawn/graphics.rb', line 102

def line_width=(width)
  @line_width = width
  add_content("#{width} w")
end

#move_to(*point) ⇒ Object

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)

43
44
45
46
# File 'lib/prawn/graphics.rb', line 43

def move_to(*point)
  x,y = map_to_absolute(point)
  add_content("%.3f %.3f m" % [ x, y ])
end

#polygon(*points) ⇒ Object

Draws a polygon from the specified points.

# draws a snazzy triangle
pdf.polygon [100,100], [100,200], [200,200]

232
233
234
235
236
237
238
239
# File 'lib/prawn/graphics.rb', line 232

def polygon(*points)
  move_to points[0]
  (points[1..-1] << points[0]).each do |point|
    line_to(*point)
  end
  # close the path
  add_content "h"
end

#rectangle(point, width, height) ⇒ Object

Draws a rectangle given point, width and height. The rectangle is bounded by its upper-left corner.

pdf.rectangle [300,300], 100, 200

79
80
81
82
# File 'lib/prawn/graphics.rb', line 79

def rectangle(point,width,height)
  x,y = map_to_absolute(point)
  add_content("%.3f %.3f %.3f %.3f re" % [ x, y - height, width, height ])
end

#rounded_polygon(radius, *points) ⇒ Object

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])

246
247
248
249
250
251
252
253
254
255
# File 'lib/prawn/graphics.rb', line 246

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
  add_content "h"
end

#rounded_rectangle(point, width, height, radius) ⇒ Object

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

90
91
92
93
# File 'lib/prawn/graphics.rb', line 90

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

#rounded_vertex(radius, *points) ⇒ Object

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.


261
262
263
264
265
266
267
268
269
# File 'lib/prawn/graphics.rb', line 261

def rounded_vertex(radius, *points)
  x0,y0,x1,y1,x2,y2 = points.flatten
  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

#strokeObject

Strokes and closes the current path. See Graphic::Color for color details


273
274
275
276
# File 'lib/prawn/graphics.rb', line 273

def stroke
  yield if block_given?
  add_content "S"
end

#stroke_boundsObject

Draws and strokes a rectangle represented by the current bounding box


280
281
282
# File 'lib/prawn/graphics.rb', line 280

def stroke_bounds
  stroke_rectangle bounds.top_left, bounds.width, bounds.height
end

#vertical_line(y1, y2, params) ⇒ Object

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

163
164
165
# File 'lib/prawn/graphics.rb', line 163

def vertical_line(y1,y2,params)
  line(params[:at],y1,params[:at],y2)
end