prawn 2.3.0 → 2.4.0
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 +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
|