giga-fast-kit 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/giga-fast-kit.gemspec +12 -0
- data/prawn-2.5.0/COPYING +2 -0
- data/prawn-2.5.0/GPLv2 +339 -0
- data/prawn-2.5.0/GPLv3 +674 -0
- data/prawn-2.5.0/LICENSE +56 -0
- data/prawn-2.5.0/data/fonts/Courier-Bold.afm +342 -0
- data/prawn-2.5.0/data/fonts/Courier-BoldOblique.afm +342 -0
- data/prawn-2.5.0/data/fonts/Courier-Oblique.afm +342 -0
- data/prawn-2.5.0/data/fonts/Courier.afm +342 -0
- data/prawn-2.5.0/data/fonts/Helvetica-Bold.afm +2827 -0
- data/prawn-2.5.0/data/fonts/Helvetica-BoldOblique.afm +2827 -0
- data/prawn-2.5.0/data/fonts/Helvetica-Oblique.afm +3051 -0
- data/prawn-2.5.0/data/fonts/Helvetica.afm +3051 -0
- data/prawn-2.5.0/data/fonts/MustRead.html +19 -0
- data/prawn-2.5.0/data/fonts/Symbol.afm +213 -0
- data/prawn-2.5.0/data/fonts/Times-Bold.afm +2588 -0
- data/prawn-2.5.0/data/fonts/Times-BoldItalic.afm +2384 -0
- data/prawn-2.5.0/data/fonts/Times-Italic.afm +2667 -0
- data/prawn-2.5.0/data/fonts/Times-Roman.afm +2419 -0
- data/prawn-2.5.0/data/fonts/ZapfDingbats.afm +225 -0
- data/prawn-2.5.0/lib/prawn/document/bounding_box.rb +625 -0
- data/prawn-2.5.0/lib/prawn/document/column_box.rb +177 -0
- data/prawn-2.5.0/lib/prawn/document/internals.rb +76 -0
- data/prawn-2.5.0/lib/prawn/document/span.rb +65 -0
- data/prawn-2.5.0/lib/prawn/document.rb +846 -0
- data/prawn-2.5.0/lib/prawn/encoding.rb +85 -0
- data/prawn-2.5.0/lib/prawn/errors.rb +73 -0
- data/prawn-2.5.0/lib/prawn/font.rb +567 -0
- data/prawn-2.5.0/lib/prawn/font_metric_cache.rb +50 -0
- data/prawn-2.5.0/lib/prawn/fonts/afm.rb +332 -0
- data/prawn-2.5.0/lib/prawn/fonts/dfont.rb +42 -0
- data/prawn-2.5.0/lib/prawn/fonts/otf.rb +14 -0
- data/prawn-2.5.0/lib/prawn/fonts/to_unicode_cmap.rb +151 -0
- data/prawn-2.5.0/lib/prawn/fonts/ttc.rb +41 -0
- data/prawn-2.5.0/lib/prawn/fonts/ttf.rb +615 -0
- data/prawn-2.5.0/lib/prawn/fonts.rb +14 -0
- data/prawn-2.5.0/lib/prawn/graphics/blend_mode.rb +62 -0
- data/prawn-2.5.0/lib/prawn/graphics/cap_style.rb +44 -0
- data/prawn-2.5.0/lib/prawn/graphics/color.rb +257 -0
- data/prawn-2.5.0/lib/prawn/graphics/dash.rb +123 -0
- data/prawn-2.5.0/lib/prawn/graphics/join_style.rb +60 -0
- data/prawn-2.5.0/lib/prawn/graphics/patterns.rb +389 -0
- data/prawn-2.5.0/lib/prawn/graphics/transformation.rb +172 -0
- data/prawn-2.5.0/lib/prawn/graphics/transparency.rb +79 -0
- data/prawn-2.5.0/lib/prawn/graphics.rb +791 -0
- data/prawn-2.5.0/lib/prawn/grid.rb +449 -0
- data/prawn-2.5.0/lib/prawn/image_handler.rb +61 -0
- data/prawn-2.5.0/lib/prawn/images/image.rb +48 -0
- data/prawn-2.5.0/lib/prawn/images/jpg.rb +121 -0
- data/prawn-2.5.0/lib/prawn/images/png.rb +383 -0
- data/prawn-2.5.0/lib/prawn/images.rb +195 -0
- data/prawn-2.5.0/lib/prawn/measurement_extensions.rb +82 -0
- data/prawn-2.5.0/lib/prawn/measurements.rb +129 -0
- data/prawn-2.5.0/lib/prawn/outline.rb +316 -0
- data/prawn-2.5.0/lib/prawn/repeater.rb +140 -0
- data/prawn-2.5.0/lib/prawn/security/arcfour.rb +54 -0
- data/prawn-2.5.0/lib/prawn/security.rb +308 -0
- data/prawn-2.5.0/lib/prawn/soft_mask.rb +105 -0
- data/prawn-2.5.0/lib/prawn/stamp.rb +147 -0
- data/prawn-2.5.0/lib/prawn/text/box.rb +192 -0
- data/prawn-2.5.0/lib/prawn/text/formatted/arranger.rb +396 -0
- data/prawn-2.5.0/lib/prawn/text/formatted/box.rb +725 -0
- data/prawn-2.5.0/lib/prawn/text/formatted/fragment.rb +373 -0
- data/prawn-2.5.0/lib/prawn/text/formatted/line_wrap.rb +335 -0
- data/prawn-2.5.0/lib/prawn/text/formatted/parser.rb +284 -0
- data/prawn-2.5.0/lib/prawn/text/formatted/wrap.rb +166 -0
- data/prawn-2.5.0/lib/prawn/text/formatted.rb +82 -0
- data/prawn-2.5.0/lib/prawn/text.rb +701 -0
- data/prawn-2.5.0/lib/prawn/transformation_stack.rb +63 -0
- data/prawn-2.5.0/lib/prawn/utilities.rb +34 -0
- data/prawn-2.5.0/lib/prawn/version.rb +6 -0
- data/prawn-2.5.0/lib/prawn/view.rb +116 -0
- data/prawn-2.5.0/lib/prawn.rb +83 -0
- metadata +114 -0
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# graphics.rb : Implements PDF drawing primitives
|
|
4
|
+
#
|
|
5
|
+
# Copyright April 2008, Gregory Brown. All Rights Reserved.
|
|
6
|
+
#
|
|
7
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
|
8
|
+
|
|
9
|
+
require_relative 'graphics/blend_mode'
|
|
10
|
+
require_relative 'graphics/color'
|
|
11
|
+
require_relative 'graphics/dash'
|
|
12
|
+
require_relative 'graphics/cap_style'
|
|
13
|
+
require_relative 'graphics/join_style'
|
|
14
|
+
require_relative 'graphics/transparency'
|
|
15
|
+
require_relative 'graphics/transformation'
|
|
16
|
+
require_relative 'graphics/patterns'
|
|
17
|
+
|
|
18
|
+
module Prawn
|
|
19
|
+
# Implements the drawing facilities for {Prawn::Document}.
|
|
20
|
+
# Use this to draw the most beautiful imaginable things.
|
|
21
|
+
module Graphics
|
|
22
|
+
include BlendMode
|
|
23
|
+
include Color
|
|
24
|
+
include Dash
|
|
25
|
+
include CapStyle
|
|
26
|
+
include JoinStyle
|
|
27
|
+
include Transparency
|
|
28
|
+
include Transformation
|
|
29
|
+
include Patterns
|
|
30
|
+
|
|
31
|
+
# @group Stable API
|
|
32
|
+
|
|
33
|
+
#######################################################################
|
|
34
|
+
# Low level drawing operations must map the point to absolute coords! #
|
|
35
|
+
#######################################################################
|
|
36
|
+
|
|
37
|
+
# Moves the drawing position to a given point. The point can be specified as
|
|
38
|
+
# a tuple or a flattened argument list.
|
|
39
|
+
#
|
|
40
|
+
# @example
|
|
41
|
+
# pdf.move_to [100, 50]
|
|
42
|
+
# pdf.move_to(100, 50)
|
|
43
|
+
#
|
|
44
|
+
# @overload move_to(point)
|
|
45
|
+
# @param point [Array(Number, Number)]
|
|
46
|
+
# @return [void]
|
|
47
|
+
# @overload move_to(x, y)
|
|
48
|
+
# @param x [Number]
|
|
49
|
+
# @param y [Number]
|
|
50
|
+
# @return [void]
|
|
51
|
+
def move_to(*point)
|
|
52
|
+
xy = PDF::Core.real_params(map_to_absolute(point))
|
|
53
|
+
renderer.add_content("#{xy} m")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Draws a line from the current drawing position to the specified point.
|
|
57
|
+
# The destination may be described as a tuple or a flattened list:
|
|
58
|
+
#
|
|
59
|
+
# @example
|
|
60
|
+
# pdf.line_to [50, 50]
|
|
61
|
+
# pdf.line_to(50, 50)
|
|
62
|
+
#
|
|
63
|
+
# @overload line_to(point)
|
|
64
|
+
# @param point [Array(Number, Number)]
|
|
65
|
+
# @return [void]
|
|
66
|
+
# @overload line_to(x, y)
|
|
67
|
+
# @param x [Number]
|
|
68
|
+
# @param y [Number]
|
|
69
|
+
# @return [void]
|
|
70
|
+
def line_to(*point)
|
|
71
|
+
xy = PDF::Core.real_params(map_to_absolute(point))
|
|
72
|
+
renderer.add_content("#{xy} l")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Draws a Bezier curve from the current drawing position to the
|
|
76
|
+
# specified point, bounded by two additional points.
|
|
77
|
+
#
|
|
78
|
+
# @example
|
|
79
|
+
# pdf.curve_to [100, 100], bounds: [[90, 90], [75, 75]]
|
|
80
|
+
#
|
|
81
|
+
# @param dest [Array(Number, Number)]
|
|
82
|
+
# @param options [Hash]
|
|
83
|
+
# @option options :bounds [Array(Array(Number, Number), Array(Number, Number))]
|
|
84
|
+
# @return [void]
|
|
85
|
+
def curve_to(dest, options = {})
|
|
86
|
+
options[:bounds] || raise(
|
|
87
|
+
Prawn::Errors::InvalidGraphicsPath,
|
|
88
|
+
'Bounding points for bezier curve must be specified as :bounds => [[x1,y1],[x2,y2]]',
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
curve_points = PDF::Core.real_params(
|
|
92
|
+
(options[:bounds] << dest).flat_map { |e| map_to_absolute(e) },
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
renderer.add_content("#{curve_points} c")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Draws a rectangle given `point`, `width and `height`. The rectangle is
|
|
99
|
+
# bounded by its upper-left corner.
|
|
100
|
+
#
|
|
101
|
+
# @example
|
|
102
|
+
# pdf.rectangle [300, 300], 100, 200
|
|
103
|
+
#
|
|
104
|
+
# @param point [Array(Number, Number)]
|
|
105
|
+
# @param width [Number]
|
|
106
|
+
# @param height [Number]
|
|
107
|
+
# @return [void]
|
|
108
|
+
def rectangle(point, width, height)
|
|
109
|
+
x, y = map_to_absolute(point)
|
|
110
|
+
box = PDF::Core.real_params([x, y - height, width, height])
|
|
111
|
+
|
|
112
|
+
renderer.add_content("#{box} re")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Draws a rounded rectangle given `point`, `width`, `height`, and `radius`
|
|
116
|
+
# for the rounded corner. The rectangle is bounded by its upper-left corner.
|
|
117
|
+
#
|
|
118
|
+
# @example
|
|
119
|
+
# pdf.rounded_rectangle [300, 300], 100, 200, 10
|
|
120
|
+
#
|
|
121
|
+
# @param point [Array(Number, Number)]
|
|
122
|
+
# @param width [Number]
|
|
123
|
+
# @param height [Number]
|
|
124
|
+
# @param radius [Number]
|
|
125
|
+
# @return [void]
|
|
126
|
+
def rounded_rectangle(point, width, height, radius)
|
|
127
|
+
x, y = point
|
|
128
|
+
rounded_polygon(
|
|
129
|
+
radius, point, [x + width, y], [x + width, y - height], [x, y - height],
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
###########################################################
|
|
134
|
+
# Higher level functions: May use relative coords #
|
|
135
|
+
###########################################################
|
|
136
|
+
|
|
137
|
+
# Sets line thickness to the `width` specified.
|
|
138
|
+
#
|
|
139
|
+
# @param width [Number]
|
|
140
|
+
# @return [void]
|
|
141
|
+
def line_width=(width)
|
|
142
|
+
self.current_line_width = width
|
|
143
|
+
write_line_width
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# When called without an argument, returns the current line thickness.
|
|
147
|
+
# When called with an argument, sets the line thickness to the specified
|
|
148
|
+
# value (in PDF points).
|
|
149
|
+
#
|
|
150
|
+
# @example
|
|
151
|
+
# pdf.line_width #=> 1
|
|
152
|
+
# pdf.line_width(5)
|
|
153
|
+
# pdf.line_width #=> 5
|
|
154
|
+
#
|
|
155
|
+
# @overload line_width()
|
|
156
|
+
# @return [Number]
|
|
157
|
+
# @overload line_width(width)
|
|
158
|
+
# @param width [Number]
|
|
159
|
+
# @return [void]
|
|
160
|
+
def line_width(width = nil)
|
|
161
|
+
if width
|
|
162
|
+
self.line_width = width
|
|
163
|
+
else
|
|
164
|
+
current_line_width
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Draws a line from one point to another. Points may be specified as
|
|
169
|
+
# tuples or flattened argument list.
|
|
170
|
+
#
|
|
171
|
+
# @example
|
|
172
|
+
# pdf.line [100, 100], [200, 250]
|
|
173
|
+
# pdf.line(100, 100, 200, 250)
|
|
174
|
+
#
|
|
175
|
+
# @overload line(point1, point2)
|
|
176
|
+
# @param point1 [Array(Number, Number)]
|
|
177
|
+
# @param point2 [Array(Number, Number)]
|
|
178
|
+
# @return [void]
|
|
179
|
+
# @overload line(x1, y1, x2, y2)
|
|
180
|
+
# @param x1 [Number]
|
|
181
|
+
# @param y1 [Number]
|
|
182
|
+
# @param x2 [Number]
|
|
183
|
+
# @param y2 [Number]
|
|
184
|
+
# @return [void]
|
|
185
|
+
def line(*points)
|
|
186
|
+
x0, y0, x1, y1 = points.flatten
|
|
187
|
+
move_to(x0, y0)
|
|
188
|
+
line_to(x1, y1)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Draws a horizontal line from `x1` to `x2` at the current {Document#y}
|
|
192
|
+
# position, or the position specified by the `:at` option.
|
|
193
|
+
#
|
|
194
|
+
# @example Draw a line from `[25, 75]` to `[100, 75]`
|
|
195
|
+
# horizontal_line 25, 100, at: 75
|
|
196
|
+
#
|
|
197
|
+
# @param x1 [Number]
|
|
198
|
+
# @param x2 [Number]
|
|
199
|
+
# @param options [Hash]
|
|
200
|
+
# @option options :at [Number]
|
|
201
|
+
# @return [void]
|
|
202
|
+
def horizontal_line(x1, x2, options = {})
|
|
203
|
+
y1 = options[:at] || (y - bounds.absolute_bottom)
|
|
204
|
+
|
|
205
|
+
line(x1, y1, x2, y1)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Draws a horizontal line from the left border to the right border of the
|
|
209
|
+
# bounding box at the current {Document#y} position.
|
|
210
|
+
#
|
|
211
|
+
# @return [void]
|
|
212
|
+
def horizontal_rule
|
|
213
|
+
horizontal_line(bounds.left, bounds.right)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Draws a vertical line at the x coordinate given by `:at` from `y1` to
|
|
217
|
+
# `y2`.
|
|
218
|
+
#
|
|
219
|
+
# @example Draw a line from `[25, 100]` to `[25, 300]`
|
|
220
|
+
# vertical_line 100, 300, at: 25
|
|
221
|
+
#
|
|
222
|
+
# @param y1 [Number]
|
|
223
|
+
# @param y2 [Number]
|
|
224
|
+
# @param params [Hash]
|
|
225
|
+
# @option params :at [Number]
|
|
226
|
+
# @return [void]
|
|
227
|
+
def vertical_line(y1, y2, params)
|
|
228
|
+
line(params[:at], y1, params[:at], y2)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Draws a Bezier curve between two points, bounded by two additional
|
|
232
|
+
# points
|
|
233
|
+
#
|
|
234
|
+
# @example
|
|
235
|
+
# pdf.curve [50, 100], [100, 100], bounds: [[90, 90], [75, 75]]
|
|
236
|
+
#
|
|
237
|
+
# @param origin [Array(Number, Number)]
|
|
238
|
+
# @param dest [Array(Number, Number)]
|
|
239
|
+
# @param options [Hash]
|
|
240
|
+
# @option options :bounds [Array(Array(Number, Number), Array(Number, Number))]
|
|
241
|
+
# @return [void]
|
|
242
|
+
def curve(origin, dest, options = {})
|
|
243
|
+
move_to(*origin)
|
|
244
|
+
curve_to(dest, options)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# This constant is used to approximate a symmetrical arc using a cubic
|
|
248
|
+
# Bezier curve.
|
|
249
|
+
KAPPA = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0)
|
|
250
|
+
|
|
251
|
+
# Draws a circle of radius `radius` with the centre-point at
|
|
252
|
+
# `point` as a complete subpath. The drawing point will be moved to
|
|
253
|
+
# the centre-point upon completion of the drawing the circle.
|
|
254
|
+
#
|
|
255
|
+
# @example
|
|
256
|
+
# pdf.circle [100, 100], 25
|
|
257
|
+
#
|
|
258
|
+
# @param center [Array(Number, Number)]
|
|
259
|
+
# @param radius [Number]
|
|
260
|
+
# @return [void]
|
|
261
|
+
def circle(center, radius)
|
|
262
|
+
ellipse(center, radius, radius)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# Draws an ellipse of `x` radius `radius1` and `y` radius `radius2` with the
|
|
266
|
+
# centre-point at `point` as a complete subpath. The drawing point will be
|
|
267
|
+
# moved to the centre-point upon completion of the drawing the ellipse.
|
|
268
|
+
#
|
|
269
|
+
# @example Draws an ellipse with x-radius 25 and y-radius 50
|
|
270
|
+
# pdf.ellipse [100, 100], 25, 50
|
|
271
|
+
#
|
|
272
|
+
# @param point [Array(Number, Number)]
|
|
273
|
+
# @param radius1 [Number]
|
|
274
|
+
# @param radius2 [Number]
|
|
275
|
+
# @return [void]
|
|
276
|
+
def ellipse(point, radius1, radius2 = radius1)
|
|
277
|
+
x, y = point
|
|
278
|
+
l1 = radius1 * KAPPA
|
|
279
|
+
l2 = radius2 * KAPPA
|
|
280
|
+
|
|
281
|
+
move_to(x + radius1, y)
|
|
282
|
+
|
|
283
|
+
# Upper right hand corner
|
|
284
|
+
curve_to(
|
|
285
|
+
[x, y + radius2],
|
|
286
|
+
bounds: [[x + radius1, y + l2], [x + l1, y + radius2]],
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
# Upper left hand corner
|
|
290
|
+
curve_to(
|
|
291
|
+
[x - radius1, y],
|
|
292
|
+
bounds: [[x - l1, y + radius2], [x - radius1, y + l2]],
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# Lower left hand corner
|
|
296
|
+
curve_to(
|
|
297
|
+
[x, y - radius2],
|
|
298
|
+
bounds: [[x - radius1, y - l2], [x - l1, y - radius2]],
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
# Lower right hand corner
|
|
302
|
+
curve_to(
|
|
303
|
+
[x + radius1, y],
|
|
304
|
+
bounds: [[x + l1, y - radius2], [x + radius1, y - l2]],
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
move_to(x, y)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# Draws a polygon from the specified points.
|
|
311
|
+
#
|
|
312
|
+
# @example Draws a snazzy triangle
|
|
313
|
+
# pdf.polygon [100,100], [100,200], [200,200]
|
|
314
|
+
#
|
|
315
|
+
# @param points [Array<Array(Number, Number)>]
|
|
316
|
+
# @return [void]
|
|
317
|
+
def polygon(*points)
|
|
318
|
+
move_to(points[0])
|
|
319
|
+
(points[1..] << points[0]).each do |point|
|
|
320
|
+
line_to(*point)
|
|
321
|
+
end
|
|
322
|
+
# close the path
|
|
323
|
+
renderer.add_content('h')
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
# Draws a rounded polygon from specified points using the radius to define
|
|
327
|
+
# bezier curves.
|
|
328
|
+
#
|
|
329
|
+
# @example Draws a rounded filled in polygon
|
|
330
|
+
# pdf.fill_and_stroke_rounded_polygon(
|
|
331
|
+
# 10, [100, 250], [200, 300], [300, 250], [300, 150], [200, 100],
|
|
332
|
+
# [100, 150]
|
|
333
|
+
# )
|
|
334
|
+
#
|
|
335
|
+
# @param radius [Number]
|
|
336
|
+
# @param points [Array<Array(Number, Number)>]
|
|
337
|
+
# @return [void]
|
|
338
|
+
def rounded_polygon(radius, *points)
|
|
339
|
+
move_to(point_on_line(radius, points[1], points[0]))
|
|
340
|
+
sides = points.size
|
|
341
|
+
points << points[0] << points[1]
|
|
342
|
+
sides.times do |i|
|
|
343
|
+
rounded_vertex(radius, points[i], points[i + 1], points[i + 2])
|
|
344
|
+
end
|
|
345
|
+
# close the path
|
|
346
|
+
renderer.add_content('h')
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# Creates a rounded vertex for a line segment used for building a rounded
|
|
350
|
+
# polygon requires a radius to define bezier curve and three points. The
|
|
351
|
+
# first two points define the line segment and the third point helps define
|
|
352
|
+
# the curve for the vertex.
|
|
353
|
+
#
|
|
354
|
+
# @param radius [Number]
|
|
355
|
+
# @param points [Array(Array(Number, Number), Array(Number, Number), Array(Number, Number))]
|
|
356
|
+
# @return [void]
|
|
357
|
+
def rounded_vertex(radius, *points)
|
|
358
|
+
radial_point1 = point_on_line(radius, points[0], points[1])
|
|
359
|
+
bezier_point1 = point_on_line(
|
|
360
|
+
(radius - (radius * KAPPA)),
|
|
361
|
+
points[0],
|
|
362
|
+
points[1],
|
|
363
|
+
)
|
|
364
|
+
radial_point2 = point_on_line(radius, points[2], points[1])
|
|
365
|
+
bezier_point2 = point_on_line(
|
|
366
|
+
(radius - (radius * KAPPA)),
|
|
367
|
+
points[2],
|
|
368
|
+
points[1],
|
|
369
|
+
)
|
|
370
|
+
line_to(radial_point1)
|
|
371
|
+
curve_to(radial_point2, bounds: [bezier_point1, bezier_point2])
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# Strokes the current path. If a block is provided, yields to the block
|
|
375
|
+
# before closing the path. See {Graphics::Color} for color details.
|
|
376
|
+
#
|
|
377
|
+
# @yield
|
|
378
|
+
# @return [void]
|
|
379
|
+
def stroke
|
|
380
|
+
yield if block_given?
|
|
381
|
+
renderer.add_content('S')
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
# Closes and strokes the current path. If a block is provided, yields to the
|
|
385
|
+
# block before closing the path. See {Graphics::Color} for color details.
|
|
386
|
+
#
|
|
387
|
+
# @yield
|
|
388
|
+
# @return [void]
|
|
389
|
+
def close_and_stroke
|
|
390
|
+
yield if block_given?
|
|
391
|
+
renderer.add_content('s')
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Draws and strokes a rectangle represented by the current bounding box.
|
|
395
|
+
#
|
|
396
|
+
# @return [void]
|
|
397
|
+
def stroke_bounds
|
|
398
|
+
stroke_rectangle(bounds.top_left, bounds.width, bounds.height)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
# Draws and strokes X and Y axes rulers beginning at the current bounding
|
|
402
|
+
# box origin (or at a custom location).
|
|
403
|
+
#
|
|
404
|
+
# @param options [Hash]
|
|
405
|
+
# @option options :at [Array(Number, Number)] ([0, 0], origin of the bounding box)
|
|
406
|
+
# Origin of the X and Y axes.
|
|
407
|
+
# @option options :width [Number] (width of the bounding box)
|
|
408
|
+
# Length of the X axis.
|
|
409
|
+
# @option options :height [Number] (height of the bounding box)
|
|
410
|
+
# Length of the Y axis.
|
|
411
|
+
# @option options :step_length [Number] (100)
|
|
412
|
+
# Length of the step between markers.
|
|
413
|
+
# @option options :negative_axes_length [Number] (20)
|
|
414
|
+
# Length of the negative parts of the axes.
|
|
415
|
+
# @option options :color [String, Array<Number>]
|
|
416
|
+
# The color of the axes and the text.
|
|
417
|
+
# @return [void]
|
|
418
|
+
def stroke_axis(options = {})
|
|
419
|
+
options = {
|
|
420
|
+
at: [0, 0],
|
|
421
|
+
height: bounds.height - (options[:at] || [0, 0])[1],
|
|
422
|
+
width: bounds.width - (options[:at] || [0, 0])[0],
|
|
423
|
+
step_length: 100,
|
|
424
|
+
negative_axes_length: 20,
|
|
425
|
+
color: '000000',
|
|
426
|
+
}.merge(options)
|
|
427
|
+
|
|
428
|
+
Prawn.verify_options(
|
|
429
|
+
%i[at width height step_length negative_axes_length color],
|
|
430
|
+
options,
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
save_graphics_state do
|
|
434
|
+
fill_color(options[:color])
|
|
435
|
+
stroke_color(options[:color])
|
|
436
|
+
|
|
437
|
+
dash(1, space: 4)
|
|
438
|
+
stroke_horizontal_line(
|
|
439
|
+
options[:at][0] - options[:negative_axes_length],
|
|
440
|
+
options[:at][0] + options[:width],
|
|
441
|
+
at: options[:at][1],
|
|
442
|
+
)
|
|
443
|
+
stroke_vertical_line(
|
|
444
|
+
options[:at][1] - options[:negative_axes_length],
|
|
445
|
+
options[:at][1] + options[:height],
|
|
446
|
+
at: options[:at][0],
|
|
447
|
+
)
|
|
448
|
+
undash
|
|
449
|
+
|
|
450
|
+
fill_circle(options[:at], 1)
|
|
451
|
+
|
|
452
|
+
(options[:step_length]..options[:width])
|
|
453
|
+
.step(options[:step_length]) do |point|
|
|
454
|
+
fill_circle([options[:at][0] + point, options[:at][1]], 1)
|
|
455
|
+
draw_text(
|
|
456
|
+
point,
|
|
457
|
+
at: [options[:at][0] + point - 5, options[:at][1] - 10],
|
|
458
|
+
size: 7,
|
|
459
|
+
)
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
(options[:step_length]..options[:height])
|
|
463
|
+
.step(options[:step_length]) do |point|
|
|
464
|
+
fill_circle([options[:at][0], options[:at][1] + point], 1)
|
|
465
|
+
draw_text(
|
|
466
|
+
point,
|
|
467
|
+
at: [options[:at][0] - 17, options[:at][1] + point - 2],
|
|
468
|
+
size: 7,
|
|
469
|
+
)
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
# Closes and fills the current path. See {Graphics::Color} for color details.
|
|
475
|
+
#
|
|
476
|
+
# If the option `fill_rule: :even_odd` is specified, Prawn will use the
|
|
477
|
+
# even-odd rule to fill the path. Otherwise, the nonzero winding number rule
|
|
478
|
+
# will be used. See the PDF reference, "Graphics -> Path Construction and
|
|
479
|
+
# Painting -> Clipping Path Operators" for details on the difference.
|
|
480
|
+
#
|
|
481
|
+
# @param options [Hash]
|
|
482
|
+
# @option options :fill_rule [Symbol]
|
|
483
|
+
# @yield
|
|
484
|
+
# @return [void]
|
|
485
|
+
def fill(options = {})
|
|
486
|
+
yield if block_given?
|
|
487
|
+
renderer.add_content(options[:fill_rule] == :even_odd ? 'f*' : 'f')
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
# Closes, fills, and strokes the current path. If a block is provided,
|
|
491
|
+
# yields to the block before closing the path. See {Graphics::Color} for
|
|
492
|
+
# color details.
|
|
493
|
+
#
|
|
494
|
+
# If the option `fill_rule: :even_odd` is specified, Prawn will use the
|
|
495
|
+
# even-odd rule to fill the path. Otherwise, the nonzero winding number rule
|
|
496
|
+
# will be used. See the PDF reference, "Graphics -> Path Construction and
|
|
497
|
+
# Painting -> Clipping Path Operators" for details on the difference.
|
|
498
|
+
#
|
|
499
|
+
# @param options [Hash]
|
|
500
|
+
# @option options :fill_rule [Symbol]
|
|
501
|
+
# @yield
|
|
502
|
+
# @return [void]
|
|
503
|
+
def fill_and_stroke(options = {})
|
|
504
|
+
yield if block_given?
|
|
505
|
+
renderer.add_content(options[:fill_rule] == :even_odd ? 'b*' : 'b')
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
# Closes the current path.
|
|
509
|
+
#
|
|
510
|
+
def close_path
|
|
511
|
+
renderer.add_content('h')
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
# @!method fill_rectangle(point, width, height)
|
|
515
|
+
# Draws and fills a rectangle given `point`, `width`, and `height`. The
|
|
516
|
+
# rectangle is bounded by its upper-left corner.
|
|
517
|
+
#
|
|
518
|
+
# @param point [Array(Number, Number)]
|
|
519
|
+
# @param width [Number]
|
|
520
|
+
# @param height [Number]
|
|
521
|
+
# @return [void]
|
|
522
|
+
|
|
523
|
+
# @!method stroke_rectangle(point, width, height)
|
|
524
|
+
# Draws and strokes a rectangle given `point`, `width`, and `height`. The
|
|
525
|
+
# rectangle is bounded by its upper-left corner.
|
|
526
|
+
#
|
|
527
|
+
# @param point [Array(Number, Number)]
|
|
528
|
+
# @param width [Number]
|
|
529
|
+
# @param height [Number]
|
|
530
|
+
# @return [void]
|
|
531
|
+
|
|
532
|
+
# @!method fill_and_stroke_rectangle(point, width, height)
|
|
533
|
+
# Draws, fills, and strokes a rectangle given `point`, `width`, and
|
|
534
|
+
# `height`. The rectangle is bounded by its upper-left corner.
|
|
535
|
+
#
|
|
536
|
+
# @param point [Array(Number, Number)]
|
|
537
|
+
# @param width [Number]
|
|
538
|
+
# @param height [Number]
|
|
539
|
+
# @return [void]
|
|
540
|
+
|
|
541
|
+
# @!method fill_rounded_rectangle(point, width, height, radius)
|
|
542
|
+
#
|
|
543
|
+
# Draws and fills a rounded rectangle given `point`, `width` and `height`,
|
|
544
|
+
# and `radius` for the rounded corner. The rectangle is bounded by its
|
|
545
|
+
# upper-left corner.
|
|
546
|
+
#
|
|
547
|
+
# @param point [Array(Number, Number)]
|
|
548
|
+
# @param width [Number]
|
|
549
|
+
# @param height [Number]
|
|
550
|
+
# @param radius [Number]
|
|
551
|
+
# @return [void]
|
|
552
|
+
|
|
553
|
+
# @!method stroke_rounded_rectangle(point, width, height, radius)
|
|
554
|
+
# Draws and strokes a rounded rectangle given `point`, `width` and
|
|
555
|
+
# `height`, and `radius` for the rounded corner. The rectangle is bounded
|
|
556
|
+
# by its upper-left corner.
|
|
557
|
+
#
|
|
558
|
+
# @param point [Array(Number, Number)]
|
|
559
|
+
# @param width [Number]
|
|
560
|
+
# @param height [Number]
|
|
561
|
+
# @param radius [Number]
|
|
562
|
+
# @return [void]
|
|
563
|
+
|
|
564
|
+
# @!method fill_and_stroke_rounded_rectangle(point, width, height, radius)
|
|
565
|
+
#
|
|
566
|
+
# Draws, fills, and strokes a rounded rectangle given `point`, `width`,
|
|
567
|
+
# and `height` and `radius` for the rounded corner. The rectangle is
|
|
568
|
+
# bounded by its upper-left corner.
|
|
569
|
+
#
|
|
570
|
+
# @param point [Array(Number, Number)]
|
|
571
|
+
# @param width [Number]
|
|
572
|
+
# @param height [Number]
|
|
573
|
+
# @param radius [Number]
|
|
574
|
+
# @return [void]
|
|
575
|
+
|
|
576
|
+
# @!method stroke_line(*points)
|
|
577
|
+
#
|
|
578
|
+
# Strokes a line from one point to another. Points may be specified as
|
|
579
|
+
# tuples or flattened argument list.
|
|
580
|
+
#
|
|
581
|
+
# @overload line(point1, point2)
|
|
582
|
+
# @param point1 [Array(Number, Number)]
|
|
583
|
+
# @param point2 [Array(Number, Number)]
|
|
584
|
+
# @return [void]
|
|
585
|
+
# @overload line(x1, y1, x2, y2)
|
|
586
|
+
# @param x1 [Number]
|
|
587
|
+
# @param y1 [Number]
|
|
588
|
+
# @param x2 [Number]
|
|
589
|
+
# @param y2 [Number]
|
|
590
|
+
# @return [void]
|
|
591
|
+
|
|
592
|
+
# @!method stroke_horizontal_line(x1, x2, options = {})
|
|
593
|
+
#
|
|
594
|
+
# Strokes a horizontal line from `x1` to `x2` at the current y position,
|
|
595
|
+
# or the position specified by the :at option.
|
|
596
|
+
#
|
|
597
|
+
# @param x1 [Number]
|
|
598
|
+
# @param x2 [Number]
|
|
599
|
+
# @param options [Hash]
|
|
600
|
+
# @option options :at [Number]
|
|
601
|
+
# @return [void]
|
|
602
|
+
|
|
603
|
+
# @!method stroke_horizontal_rule
|
|
604
|
+
#
|
|
605
|
+
# Strokes a horizontal line from the left border to the right border of
|
|
606
|
+
# the bounding box at the current y position.
|
|
607
|
+
#
|
|
608
|
+
# @return [void]
|
|
609
|
+
|
|
610
|
+
# @!method stroke_vertical_line(y1, y2, params)
|
|
611
|
+
#
|
|
612
|
+
# Strokes a vertical line at the x coordinate given by `:at` from `y1` to
|
|
613
|
+
# `y2`.
|
|
614
|
+
#
|
|
615
|
+
# @param y1 [Number]
|
|
616
|
+
# @param y2 [Number]
|
|
617
|
+
# @param params [Hash]
|
|
618
|
+
# @option params :at [Number]
|
|
619
|
+
# @return [void]
|
|
620
|
+
|
|
621
|
+
# @!method stroke_curve(origin, dest, options = {})
|
|
622
|
+
#
|
|
623
|
+
# Strokes a Bezier curve between two points, bounded by two additional
|
|
624
|
+
# points.
|
|
625
|
+
#
|
|
626
|
+
# @param origin [Array(Number, Number)]
|
|
627
|
+
# @param dest [Array(Number, Number)]
|
|
628
|
+
# @param options [Hash]
|
|
629
|
+
# @option options :bounds [Array(Array(Number, Number), Array(Number, Number))]
|
|
630
|
+
# @return [void]
|
|
631
|
+
|
|
632
|
+
# @!method: stroke_circle(center, radius)
|
|
633
|
+
#
|
|
634
|
+
# Draws and strokes a circle of radius `radius` with the centre-point at
|
|
635
|
+
# `point`.
|
|
636
|
+
#
|
|
637
|
+
# @param center [Array(Number, Number)]
|
|
638
|
+
# @param radius [Number]
|
|
639
|
+
# @return [void]
|
|
640
|
+
|
|
641
|
+
# @!method fill_circle(center, radius)
|
|
642
|
+
#
|
|
643
|
+
# Draws and fills a circle of radius `radius` with the centre-point at
|
|
644
|
+
# `point`.
|
|
645
|
+
#
|
|
646
|
+
# @param center [Array(Number, Number)]
|
|
647
|
+
# @param radius [Number]
|
|
648
|
+
# @return [void]
|
|
649
|
+
|
|
650
|
+
# @!method fill_and_stroke_circle(center, radius)
|
|
651
|
+
#
|
|
652
|
+
# Draws, strokes, and fills a circle of radius `radius` with the
|
|
653
|
+
# centre-point at `point`.
|
|
654
|
+
#
|
|
655
|
+
# @param center [Array(Number, Number)]
|
|
656
|
+
# @param radius [Number]
|
|
657
|
+
# @return [void]
|
|
658
|
+
|
|
659
|
+
# @!method stroke_ellipse(point, radius1, radius2 = radius1)
|
|
660
|
+
#
|
|
661
|
+
# Draws and strokes an ellipse of x radius `r1` and y radius `r2` with the
|
|
662
|
+
# centre-point at `point`.
|
|
663
|
+
#
|
|
664
|
+
# @param point [Array(Number, Number)]
|
|
665
|
+
# @param radius1 [Number]
|
|
666
|
+
# @param radius2 [Number]
|
|
667
|
+
# @return [void]
|
|
668
|
+
|
|
669
|
+
# @!method fill_ellipse(point, radius1, radius2 = radius1)
|
|
670
|
+
#
|
|
671
|
+
# Draws and fills an ellipse of x radius `r1` and y radius `r2` with the
|
|
672
|
+
# centre-point at `point`.
|
|
673
|
+
#
|
|
674
|
+
# @param point [Array(Number, Number)]
|
|
675
|
+
# @param radius1 [Number]
|
|
676
|
+
# @param radius2 [Number]
|
|
677
|
+
# @return [void]
|
|
678
|
+
|
|
679
|
+
# @!method fill_and_stroke_ellipse(point, radius1, radius2 = radius1)
|
|
680
|
+
#
|
|
681
|
+
# Draws, strokes, and fills an ellipse of x radius `r1` and y radius `r2`
|
|
682
|
+
# with the centre-point at `point`.
|
|
683
|
+
#
|
|
684
|
+
# @param point [Array(Number, Number)]
|
|
685
|
+
# @param radius1 [Number]
|
|
686
|
+
# @param radius2 [Number]
|
|
687
|
+
# @return [void]
|
|
688
|
+
|
|
689
|
+
# @!method stroke_polygon(*points)
|
|
690
|
+
#
|
|
691
|
+
# Draws and strokes a polygon from the specified points.
|
|
692
|
+
#
|
|
693
|
+
# @param points [Array<Array(Number, Number)>]
|
|
694
|
+
# @return [void]
|
|
695
|
+
|
|
696
|
+
# @!method fill_polygon(*points)
|
|
697
|
+
#
|
|
698
|
+
# Draws and fills a polygon from the specified points.
|
|
699
|
+
#
|
|
700
|
+
# @param points [Array<Array(Number, Number)>]
|
|
701
|
+
# @return [void]
|
|
702
|
+
|
|
703
|
+
# @!method fill_and_stroke_polygon(*points)
|
|
704
|
+
#
|
|
705
|
+
# Draws, strokes, and fills a polygon from the specified points.
|
|
706
|
+
#
|
|
707
|
+
# @param points [Array<Array(Number, Number)>]
|
|
708
|
+
# @return [void]
|
|
709
|
+
|
|
710
|
+
# @!method stroke_rounded_polygon(radius, *points)
|
|
711
|
+
#
|
|
712
|
+
# Draws and strokes a rounded polygon from specified points, using
|
|
713
|
+
# `radius` to define Bezier curves.
|
|
714
|
+
#
|
|
715
|
+
# @param radius [Number]
|
|
716
|
+
# @param points [Array<Array(Number, Number)>]
|
|
717
|
+
# @return [void]
|
|
718
|
+
|
|
719
|
+
# @!method fill_rounded_polygon(radius, *points)
|
|
720
|
+
#
|
|
721
|
+
# Draws and fills a rounded polygon from specified points, using `radius`
|
|
722
|
+
# to define Bezier curves.
|
|
723
|
+
#
|
|
724
|
+
# @param radius [Number]
|
|
725
|
+
# @param points [Array<Array(Number, Number)>]
|
|
726
|
+
# @return [void]
|
|
727
|
+
|
|
728
|
+
# @!method fill_and_stroke_rounded_polygon(radius, *points)
|
|
729
|
+
#
|
|
730
|
+
# Draws, strokes, and fills a rounded polygon from specified points, using
|
|
731
|
+
# `radius` to define Bezier curves.
|
|
732
|
+
#
|
|
733
|
+
# @param radius [Number]
|
|
734
|
+
# @param points [Array<Array(Number, Number)>]
|
|
735
|
+
# @return [void]
|
|
736
|
+
|
|
737
|
+
ops = %w[fill stroke fill_and_stroke]
|
|
738
|
+
shapes = %w[
|
|
739
|
+
line_to curve_to rectangle rounded_rectangle line horizontal_line
|
|
740
|
+
horizontal_rule vertical_line curve circle_at circle ellipse_at ellipse
|
|
741
|
+
polygon rounded_polygon rounded_vertex
|
|
742
|
+
]
|
|
743
|
+
|
|
744
|
+
ops.product(shapes).each do |operation, shape|
|
|
745
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
|
746
|
+
def #{operation}_#{shape}(*args) # def fill_polygon(*args)
|
|
747
|
+
#{shape}(*args) # polygon(*args)
|
|
748
|
+
#{operation} # fill
|
|
749
|
+
end # end
|
|
750
|
+
METHOD
|
|
751
|
+
end
|
|
752
|
+
|
|
753
|
+
private
|
|
754
|
+
|
|
755
|
+
def current_line_width
|
|
756
|
+
graphic_state.line_width
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
def current_line_width=(width)
|
|
760
|
+
graphic_state.line_width = width
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
def write_line_width
|
|
764
|
+
renderer.add_content("#{current_line_width} w")
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
def map_to_absolute(*point)
|
|
768
|
+
x, y = point.flatten
|
|
769
|
+
[@bounding_box.absolute_left + x, @bounding_box.absolute_bottom + y]
|
|
770
|
+
end
|
|
771
|
+
|
|
772
|
+
def map_to_absolute!(point)
|
|
773
|
+
point.replace(map_to_absolute(point))
|
|
774
|
+
end
|
|
775
|
+
|
|
776
|
+
def degree_to_rad(angle)
|
|
777
|
+
angle * Math::PI / 180
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
# Returns the coordinates for a point on a line that is a given distance
|
|
781
|
+
# away from the second point defining the line segement
|
|
782
|
+
def point_on_line(distance_from_end, *points)
|
|
783
|
+
x0, y0, x1, y1 = points.flatten
|
|
784
|
+
length = Math.sqrt(((x1 - x0)**2) + ((y1 - y0)**2))
|
|
785
|
+
p = (length - distance_from_end) / length
|
|
786
|
+
xr = x0 + (p * (x1 - x0))
|
|
787
|
+
yr = y0 + (p * (y1 - y0))
|
|
788
|
+
[xr, yr]
|
|
789
|
+
end
|
|
790
|
+
end
|
|
791
|
+
end
|