prawn 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +2 -31
- data/lib/prawn.rb +1 -0
- data/lib/prawn/document.rb +20 -15
- data/lib/prawn/document/bounding_box.rb +10 -2
- data/lib/prawn/document/span.rb +2 -1
- data/lib/prawn/font.rb +6 -4
- data/lib/prawn/font_metric_cache.rb +7 -6
- data/lib/prawn/fonts/afm.rb +18 -16
- data/lib/prawn/fonts/ttf.rb +55 -29
- data/lib/prawn/graphics.rb +11 -11
- data/lib/prawn/graphics/color.rb +18 -16
- data/lib/prawn/graphics/join_style.rb +1 -1
- data/lib/prawn/graphics/patterns.rb +57 -49
- data/lib/prawn/graphics/transformation.rb +3 -3
- data/lib/prawn/grid.rb +36 -1
- data/lib/prawn/images.rb +29 -27
- data/lib/prawn/images/jpg.rb +4 -1
- data/lib/prawn/images/png.rb +2 -1
- data/lib/prawn/outline.rb +6 -5
- data/lib/prawn/repeater.rb +1 -1
- data/lib/prawn/security.rb +39 -36
- data/lib/prawn/text.rb +18 -18
- data/lib/prawn/text/box.rb +10 -9
- data/lib/prawn/text/formatted/arranger.rb +38 -19
- data/lib/prawn/text/formatted/box.rb +20 -15
- data/lib/prawn/text/formatted/line_wrap.rb +18 -16
- data/lib/prawn/text/formatted/parser.rb +28 -26
- data/lib/prawn/text/formatted/wrap.rb +15 -11
- data/lib/prawn/version.rb +1 -1
- data/lib/prawn/view.rb +2 -2
- data/manual/basic_concepts/measurement.rb +1 -1
- data/manual/bounding_box/canvas.rb +3 -3
- data/manual/bounding_box/nesting.rb +1 -1
- data/manual/document_and_page_options/background.rb +6 -2
- data/manual/document_and_page_options/document_and_page_options.rb +3 -3
- data/manual/document_and_page_options/print_scaling.rb +2 -1
- data/manual/graphics/common_lines.rb +1 -1
- data/manual/graphics/fill_and_stroke.rb +1 -1
- data/manual/graphics/fill_rules.rb +4 -3
- data/manual/graphics/helper.rb +11 -4
- data/manual/graphics/lines_and_curves.rb +1 -1
- data/manual/graphics/stroke_dash.rb +5 -5
- data/manual/graphics/translate.rb +2 -1
- data/manual/images/horizontal.rb +2 -2
- data/manual/images/scale.rb +3 -3
- data/manual/images/vertical.rb +6 -3
- data/manual/images/width_and_height.rb +3 -3
- data/manual/layout/content.rb +2 -2
- data/manual/outline/outline.rb +1 -1
- data/manual/security/permissions.rb +4 -2
- data/manual/security/security.rb +1 -1
- data/manual/text/alignment.rb +2 -2
- data/manual/text/column_box.rb +2 -2
- data/manual/text/font_style.rb +5 -2
- data/manual/text/formatted_callbacks.rb +17 -12
- data/manual/text/formatted_text.rb +7 -4
- data/manual/text/free_flowing_text.rb +3 -3
- data/manual/text/kerning_and_character_spacing.rb +4 -4
- data/manual/text/paragraph_indentation.rb +4 -5
- data/manual/text/rendering_and_color.rb +1 -1
- data/manual/text/right_to_left_text.rb +6 -6
- data/manual/text/rotation.rb +8 -3
- data/manual/text/text_box_extensions.rb +1 -1
- data/manual/text/text_box_overflow.rb +11 -9
- data/manual/text/win_ansi_charset.rb +9 -9
- data/prawn.gemspec +4 -10
- data/spec/prawn/document/bounding_box_spec.rb +82 -78
- data/spec/prawn/document/security_spec.rb +1 -1
- data/spec/prawn/document_span_spec.rb +14 -6
- data/spec/prawn/document_spec.rb +29 -26
- data/spec/prawn/font_spec.rb +16 -14
- data/spec/prawn/graphics_spec.rb +79 -44
- data/spec/prawn/images_spec.rb +13 -8
- data/spec/prawn/outline_spec.rb +127 -27
- data/spec/prawn/repeater_spec.rb +9 -8
- data/spec/prawn/soft_mask_spec.rb +1 -1
- data/spec/prawn/stamp_spec.rb +3 -2
- data/spec/prawn/text/box_spec.rb +57 -59
- data/spec/prawn/text/formatted/arranger_spec.rb +10 -10
- data/spec/prawn/text/formatted/box_spec.rb +8 -5
- data/spec/prawn/text/formatted/line_wrap_spec.rb +2 -1
- data/spec/prawn/text_draw_text_spec.rb +9 -8
- data/spec/prawn/text_spacing_spec.rb +2 -2
- data/spec/prawn/text_spec.rb +9 -9
- data/spec/prawn/text_with_inline_formatting_spec.rb +1 -1
- data/spec/prawn_manual_spec.rb +4 -4
- metadata +14 -98
- metadata.gz.sig +0 -0
data/lib/prawn/graphics.rb
CHANGED
@@ -212,7 +212,7 @@ module Prawn
|
|
212
212
|
move_to(x + radius1, y)
|
213
213
|
|
214
214
|
# Upper right hand corner
|
215
|
-
curve_to [x,
|
215
|
+
curve_to [x, y + radius2],
|
216
216
|
bounds: [[x + radius1, y + l2], [x + l1, y + radius2]]
|
217
217
|
|
218
218
|
# Upper left hand corner
|
@@ -341,10 +341,8 @@ module Prawn
|
|
341
341
|
}.merge(options)
|
342
342
|
|
343
343
|
Prawn.verify_options(
|
344
|
-
%i[
|
345
|
-
|
346
|
-
negative_axes_length color
|
347
|
-
], options
|
344
|
+
%i[at width height step_length negative_axes_length color],
|
345
|
+
options
|
348
346
|
)
|
349
347
|
|
350
348
|
save_graphics_state do
|
@@ -354,11 +352,13 @@ module Prawn
|
|
354
352
|
dash(1, space: 4)
|
355
353
|
stroke_horizontal_line(
|
356
354
|
options[:at][0] - options[:negative_axes_length],
|
357
|
-
options[:at][0] + options[:width],
|
355
|
+
options[:at][0] + options[:width],
|
356
|
+
at: options[:at][1]
|
358
357
|
)
|
359
358
|
stroke_vertical_line(
|
360
359
|
options[:at][1] - options[:negative_axes_length],
|
361
|
-
options[:at][1] + options[:height],
|
360
|
+
options[:at][1] + options[:height],
|
361
|
+
at: options[:at][0]
|
362
362
|
)
|
363
363
|
undash
|
364
364
|
|
@@ -633,10 +633,10 @@ module Prawn
|
|
633
633
|
|
634
634
|
ops.product(shapes).each do |operation, shape|
|
635
635
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
636
|
-
def #{operation}_#{shape}(*args)
|
637
|
-
#{shape}(*args)
|
638
|
-
#{operation}
|
639
|
-
end
|
636
|
+
def #{operation}_#{shape}(*args) # def fill_polygon(*args)
|
637
|
+
#{shape}(*args) # polygon(*args)
|
638
|
+
#{operation} # fill
|
639
|
+
end # end
|
640
640
|
METHOD
|
641
641
|
end
|
642
642
|
|
data/lib/prawn/graphics/color.rb
CHANGED
@@ -154,27 +154,29 @@ module Prawn
|
|
154
154
|
raise ArgumentError, "unknown color space: '#{color_space}'"
|
155
155
|
end
|
156
156
|
|
157
|
-
operator =
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
157
|
+
operator =
|
158
|
+
case type
|
159
|
+
when :fill
|
160
|
+
'cs'
|
161
|
+
when :stroke
|
162
|
+
'CS'
|
163
|
+
else
|
164
|
+
raise ArgumentError, "unknown type '#{type}'"
|
165
|
+
end
|
165
166
|
|
166
167
|
renderer.add_content "/#{color_space} #{operator}"
|
167
168
|
end
|
168
169
|
|
169
170
|
def set_color(type, color, options = {})
|
170
|
-
operator =
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
171
|
+
operator =
|
172
|
+
case type
|
173
|
+
when :fill
|
174
|
+
'scn'
|
175
|
+
when :stroke
|
176
|
+
'SCN'
|
177
|
+
else
|
178
|
+
raise ArgumentError, "unknown type '#{type}'"
|
179
|
+
end
|
178
180
|
|
179
181
|
if options[:pattern]
|
180
182
|
set_color_space type, :Pattern
|
@@ -28,7 +28,7 @@ module Prawn
|
|
28
28
|
unless JOIN_STYLES.key?(current_join_style)
|
29
29
|
raise Prawn::Errors::InvalidJoinStyle,
|
30
30
|
"#{style} is not a recognized join style. Valid styles are " +
|
31
|
-
|
31
|
+
JOIN_STYLES.keys.join(', ')
|
32
32
|
end
|
33
33
|
|
34
34
|
write_stroke_join_style
|
@@ -95,14 +95,15 @@ module Prawn
|
|
95
95
|
patterns["SP#{registry_key}"] = shading
|
96
96
|
end
|
97
97
|
|
98
|
-
operator =
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
98
|
+
operator =
|
99
|
+
case type
|
100
|
+
when :fill
|
101
|
+
'scn'
|
102
|
+
when :stroke
|
103
|
+
'SCN'
|
104
|
+
else
|
105
|
+
raise ArgumentError, "unknown type '#{type}'"
|
106
|
+
end
|
106
107
|
|
107
108
|
set_color_space type, :Pattern
|
108
109
|
renderer.add_content "/SP#{registry_key} #{operator}"
|
@@ -113,6 +114,7 @@ module Prawn
|
|
113
114
|
*arguments, from: nil, to: nil, r1: nil, r2: nil, stops: nil,
|
114
115
|
apply_transformations: nil
|
115
116
|
)
|
117
|
+
|
116
118
|
case arguments.length
|
117
119
|
when 0
|
118
120
|
apply_transformations = true if apply_transformations.nil?
|
@@ -128,22 +130,23 @@ module Prawn
|
|
128
130
|
raise ArgumentError, 'At least two stops must be specified'
|
129
131
|
end
|
130
132
|
|
131
|
-
stops =
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
133
|
+
stops =
|
134
|
+
stops.map.with_index do |stop, index|
|
135
|
+
case stop
|
136
|
+
when Array, Hash
|
137
|
+
position, color = stop
|
138
|
+
else
|
139
|
+
position = index / (stops.length.to_f - 1)
|
140
|
+
color = stop
|
141
|
+
end
|
142
|
+
|
143
|
+
unless (0..1).cover?(position)
|
144
|
+
raise ArgumentError, 'position must be between 0 and 1'
|
145
|
+
end
|
146
|
+
|
147
|
+
GradientStop.new(position, normalize_color(color))
|
138
148
|
end
|
139
149
|
|
140
|
-
unless (0..1).cover?(position)
|
141
|
-
raise ArgumentError, 'position must be between 0 and 1'
|
142
|
-
end
|
143
|
-
|
144
|
-
GradientStop.new(position, normalize_color(color))
|
145
|
-
end
|
146
|
-
|
147
150
|
if stops.first.position != 0
|
148
151
|
raise ArgumentError, 'The first stop must have a position of 0'
|
149
152
|
end
|
@@ -159,8 +162,10 @@ module Prawn
|
|
159
162
|
r1 ? :radial : :axial,
|
160
163
|
apply_transformations,
|
161
164
|
stops,
|
162
|
-
from,
|
163
|
-
|
165
|
+
from,
|
166
|
+
to,
|
167
|
+
r1,
|
168
|
+
r2
|
164
169
|
)
|
165
170
|
end
|
166
171
|
# rubocop: enable Metrics/ParameterLists
|
@@ -195,37 +200,40 @@ module Prawn
|
|
195
200
|
'for more information.'
|
196
201
|
end
|
197
202
|
|
198
|
-
shader_stops =
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
203
|
+
shader_stops =
|
204
|
+
gradient.stops.each_cons(2).map do |first, second|
|
205
|
+
ref!(
|
206
|
+
FunctionType: 2,
|
207
|
+
Domain: [0.0, 1.0],
|
208
|
+
C0: first.color,
|
209
|
+
C1: second.color,
|
210
|
+
N: 1.0
|
211
|
+
)
|
212
|
+
end
|
207
213
|
|
208
214
|
# If there's only two stops, we can use the single shader.
|
209
215
|
# Otherwise we stitch the multiple shaders together.
|
210
|
-
shader =
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
216
|
+
shader =
|
217
|
+
if shader_stops.length == 1
|
218
|
+
shader_stops.first
|
219
|
+
else
|
220
|
+
ref!(
|
221
|
+
FunctionType: 3, # stitching function
|
222
|
+
Domain: [0.0, 1.0],
|
223
|
+
Functions: shader_stops,
|
224
|
+
Bounds: gradient.stops[1..-2].map(&:position),
|
225
|
+
Encode: [0.0, 1.0] * shader_stops.length
|
226
|
+
)
|
227
|
+
end
|
221
228
|
|
222
229
|
x1, y1, x2, y2, transformation = gradient_coordinates(gradient)
|
223
230
|
|
224
|
-
coords =
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
231
|
+
coords =
|
232
|
+
if gradient.type == :axial
|
233
|
+
[0, 0, x2 - x1, y2 - y1]
|
234
|
+
else
|
235
|
+
[0, 0, gradient.r1, x2 - x1, y2 - y1, gradient.r2]
|
236
|
+
end
|
229
237
|
|
230
238
|
shading = ref!(
|
231
239
|
ShadingType: gradient.type == :axial ? 2 : 3,
|
@@ -48,7 +48,7 @@ module Prawn
|
|
48
48
|
if options[:origin].nil?
|
49
49
|
transformation_matrix(cos, sin, -sin, cos, 0, 0, &block)
|
50
50
|
else
|
51
|
-
raise Prawn::Errors::BlockRequired unless
|
51
|
+
raise Prawn::Errors::BlockRequired unless block
|
52
52
|
|
53
53
|
x = options[:origin][0] + bounds.absolute_left
|
54
54
|
y = options[:origin][1] + bounds.absolute_bottom
|
@@ -118,7 +118,7 @@ module Prawn
|
|
118
118
|
if options[:origin].nil?
|
119
119
|
transformation_matrix(factor, 0, 0, factor, 0, 0, &block)
|
120
120
|
else
|
121
|
-
raise Prawn::Errors::BlockRequired unless
|
121
|
+
raise Prawn::Errors::BlockRequired unless block
|
122
122
|
|
123
123
|
x = options[:origin][0] + bounds.absolute_left
|
124
124
|
y = options[:origin][1] + bounds.absolute_bottom
|
@@ -149,11 +149,11 @@ module Prawn
|
|
149
149
|
raise ArgumentError,
|
150
150
|
'Transformation matrix must have exacty 6 elements'
|
151
151
|
end
|
152
|
-
values = matrix.map { |x| x.to_f.round(5) }.join(' ')
|
153
152
|
save_graphics_state if block_given?
|
154
153
|
|
155
154
|
add_to_transformation_stack(*matrix)
|
156
155
|
|
156
|
+
values = PDF::Core.real_params(matrix)
|
157
157
|
renderer.add_content "#{values} cm"
|
158
158
|
if block_given?
|
159
159
|
yield
|
data/lib/prawn/grid.rb
CHANGED
@@ -56,6 +56,7 @@ module Prawn
|
|
56
56
|
# @group Experimental API
|
57
57
|
class Grid
|
58
58
|
attr_reader :pdf, :columns, :rows, :gutter, :row_gutter, :column_gutter
|
59
|
+
|
59
60
|
def initialize(pdf, options = {}) # :nodoc:
|
60
61
|
valid_options = %i[columns rows gutter row_gutter column_gutter]
|
61
62
|
Prawn.verify_options valid_options, options
|
@@ -213,12 +214,14 @@ module Prawn
|
|
213
214
|
# A MultiBox is specified by 2 Boxes and spans the areas between.
|
214
215
|
#
|
215
216
|
# @group Experimental API
|
216
|
-
class MultiBox
|
217
|
+
class MultiBox
|
217
218
|
def initialize(pdf, box1, box2)
|
218
219
|
@pdf = pdf
|
219
220
|
@boxes = [box1, box2]
|
220
221
|
end
|
221
222
|
|
223
|
+
attr_reader :pdf
|
224
|
+
|
222
225
|
def name
|
223
226
|
@boxes.map(&:name).join(':')
|
224
227
|
end
|
@@ -255,6 +258,38 @@ module Prawn
|
|
255
258
|
bottom_box.bottom
|
256
259
|
end
|
257
260
|
|
261
|
+
def top_left
|
262
|
+
[left, top]
|
263
|
+
end
|
264
|
+
|
265
|
+
def top_right
|
266
|
+
[right, top]
|
267
|
+
end
|
268
|
+
|
269
|
+
def bottom_left
|
270
|
+
[left, bottom]
|
271
|
+
end
|
272
|
+
|
273
|
+
def bottom_right
|
274
|
+
[right, bottom]
|
275
|
+
end
|
276
|
+
|
277
|
+
def bounding_box(&blk)
|
278
|
+
pdf.bounding_box(top_left, width: width, height: height, &blk)
|
279
|
+
end
|
280
|
+
|
281
|
+
def show(grid_color = 'CCCCCC')
|
282
|
+
bounding_box do
|
283
|
+
original_stroke_color = pdf.stroke_color
|
284
|
+
|
285
|
+
pdf.stroke_color = grid_color
|
286
|
+
pdf.text name
|
287
|
+
pdf.stroke_bounds
|
288
|
+
|
289
|
+
pdf.stroke_color = original_stroke_color
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
258
293
|
private
|
259
294
|
|
260
295
|
def left_box
|
data/lib/prawn/images.rb
CHANGED
@@ -66,10 +66,10 @@ module Prawn
|
|
66
66
|
# (See also: Prawn::Images::PNG , Prawn::Images::JPG)
|
67
67
|
#
|
68
68
|
def image(file, options = {})
|
69
|
-
Prawn.verify_options
|
70
|
-
at position vposition height
|
71
|
-
|
72
|
-
|
69
|
+
Prawn.verify_options(
|
70
|
+
%i[at position vposition height width scale fit],
|
71
|
+
options
|
72
|
+
)
|
73
73
|
|
74
74
|
pdf_obj, info = build_image_object(file)
|
75
75
|
embed_image(pdf_obj, info, options)
|
@@ -156,29 +156,31 @@ module Prawn
|
|
156
156
|
def image_position(width, height, options)
|
157
157
|
options[:position] ||= :left
|
158
158
|
|
159
|
-
y =
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
159
|
+
y =
|
160
|
+
case options[:vposition]
|
161
|
+
when :top
|
162
|
+
bounds.absolute_top
|
163
|
+
when :center
|
164
|
+
bounds.absolute_top - (bounds.height - height) / 2.0
|
165
|
+
when :bottom
|
166
|
+
bounds.absolute_bottom + height
|
167
|
+
when Numeric
|
168
|
+
bounds.absolute_top - options[:vposition]
|
169
|
+
else
|
170
|
+
determine_y_with_page_flow(height)
|
171
|
+
end
|
172
|
+
|
173
|
+
x =
|
174
|
+
case options[:position]
|
175
|
+
when :left
|
176
|
+
bounds.left_side
|
177
|
+
when :center
|
178
|
+
bounds.left_side + (bounds.width - width) / 2.0
|
179
|
+
when :right
|
180
|
+
bounds.right_side - width
|
181
|
+
when Numeric
|
182
|
+
options[:position] + bounds.left_side
|
183
|
+
end
|
182
184
|
|
183
185
|
[x, y]
|
184
186
|
end
|
data/lib/prawn/images/jpg.rb
CHANGED
@@ -16,6 +16,8 @@ module Prawn
|
|
16
16
|
# of a JPG image that we need to embed them in a PDF
|
17
17
|
#
|
18
18
|
class JPG < Image
|
19
|
+
class FormatError < StandardError; end
|
20
|
+
|
19
21
|
# @group Extension API
|
20
22
|
|
21
23
|
attr_reader :width, :height, :bits, :channels
|
@@ -35,6 +37,7 @@ module Prawn
|
|
35
37
|
# <tt>:data</tt>:: A binary string of JPEG data
|
36
38
|
#
|
37
39
|
def initialize(data)
|
40
|
+
super()
|
38
41
|
@data = data
|
39
42
|
d = StringIO.new(@data)
|
40
43
|
d.binmode
|
@@ -43,7 +46,7 @@ module Prawn
|
|
43
46
|
d.seek(2) # Skip the first two bytes of JPEG identifier.
|
44
47
|
loop do
|
45
48
|
marker, code, length = d.read(4).unpack('CCn')
|
46
|
-
raise 'JPEG marker not found!' if marker != c_marker
|
49
|
+
raise FormatError, 'JPEG marker not found!' if marker != c_marker
|
47
50
|
|
48
51
|
if JPEG_SOF_BLOCKS.include?(code)
|
49
52
|
@bits, @height, @width, @channels = d.read(6).unpack('CnnC')
|
data/lib/prawn/images/png.rb
CHANGED
@@ -34,6 +34,7 @@ module Prawn
|
|
34
34
|
# <tt>data</tt>:: A binary string of PNG data
|
35
35
|
#
|
36
36
|
def initialize(data)
|
37
|
+
super()
|
37
38
|
data = StringIO.new(data.dup)
|
38
39
|
|
39
40
|
data.read(8) # Skip the default header
|
@@ -212,7 +213,7 @@ module Prawn
|
|
212
213
|
# - An array with N elements, where N is two times the number of color
|
213
214
|
# components.
|
214
215
|
rgb = transparency[:rgb]
|
215
|
-
obj.data[:Mask] = rgb.
|
216
|
+
obj.data[:Mask] = rgb.map { |x| [x, x] }.flatten
|
216
217
|
end
|
217
218
|
|
218
219
|
# For PNG color types 4 and 6, the transparency data is stored as
|