prawn 2.4.0 → 2.5.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/lib/prawn/document/bounding_box.rb +213 -141
- data/lib/prawn/document/column_box.rb +61 -26
- data/lib/prawn/document/internals.rb +25 -16
- data/lib/prawn/document/span.rb +20 -18
- data/lib/prawn/document.rb +257 -171
- data/lib/prawn/encoding.rb +2 -5
- data/lib/prawn/errors.rb +23 -34
- data/lib/prawn/font.rb +248 -135
- data/lib/prawn/font_metric_cache.rb +11 -10
- data/lib/prawn/fonts/afm.rb +85 -45
- data/lib/prawn/fonts/dfont.rb +7 -1
- data/lib/prawn/fonts/otf.rb +4 -1
- data/lib/prawn/fonts/to_unicode_cmap.rb +151 -0
- data/lib/prawn/fonts/ttc.rb +7 -2
- data/lib/prawn/fonts/ttf.rb +305 -93
- data/lib/prawn/fonts.rb +14 -0
- data/lib/prawn/graphics/blend_mode.rb +25 -28
- data/lib/prawn/graphics/cap_style.rb +9 -12
- data/lib/prawn/graphics/color.rb +57 -34
- data/lib/prawn/graphics/dash.rb +45 -42
- data/lib/prawn/graphics/join_style.rb +17 -11
- data/lib/prawn/graphics/patterns.rb +190 -69
- data/lib/prawn/graphics/transformation.rb +48 -41
- data/lib/prawn/graphics/transparency.rb +16 -40
- data/lib/prawn/graphics.rb +363 -253
- data/lib/prawn/grid.rb +184 -57
- data/lib/prawn/image_handler.rb +27 -10
- data/lib/prawn/images/image.rb +8 -10
- data/lib/prawn/images/jpg.rb +42 -19
- data/lib/prawn/images/png.rb +92 -41
- data/lib/prawn/images.rb +44 -57
- data/lib/prawn/measurement_extensions.rb +39 -8
- data/lib/prawn/measurements.rb +60 -5
- data/lib/prawn/outline.rb +114 -108
- data/lib/prawn/repeater.rb +51 -35
- data/lib/prawn/security/arcfour.rb +4 -4
- data/lib/prawn/security.rb +75 -70
- data/lib/prawn/soft_mask.rb +42 -30
- data/lib/prawn/stamp.rb +38 -42
- data/lib/prawn/text/box.rb +146 -96
- data/lib/prawn/text/formatted/arranger.rb +87 -26
- data/lib/prawn/text/formatted/box.rb +221 -150
- data/lib/prawn/text/formatted/fragment.rb +130 -14
- data/lib/prawn/text/formatted/line_wrap.rb +33 -24
- data/lib/prawn/text/formatted/parser.rb +112 -72
- data/lib/prawn/text/formatted/wrap.rb +12 -17
- data/lib/prawn/text/formatted.rb +75 -0
- data/lib/prawn/text.rb +441 -196
- data/lib/prawn/transformation_stack.rb +29 -10
- data/lib/prawn/utilities.rb +13 -13
- data/lib/prawn/version.rb +2 -1
- data/lib/prawn/view.rb +68 -53
- data/lib/prawn.rb +23 -18
- data.tar.gz.sig +0 -0
- metadata +54 -177
- metadata.gz.sig +0 -0
- data/.yardopts +0 -10
- data/Gemfile +0 -5
- data/Rakefile +0 -25
- data/manual/absolute_position.pdf +0 -0
- data/manual/basic_concepts/adding_pages.rb +0 -26
- data/manual/basic_concepts/basic_concepts.rb +0 -43
- data/manual/basic_concepts/creation.rb +0 -38
- data/manual/basic_concepts/cursor.rb +0 -32
- data/manual/basic_concepts/measurement.rb +0 -24
- data/manual/basic_concepts/origin.rb +0 -37
- data/manual/basic_concepts/other_cursor_helpers.rb +0 -39
- data/manual/basic_concepts/view.rb +0 -48
- data/manual/bounding_box/bounding_box.rb +0 -41
- data/manual/bounding_box/bounds.rb +0 -48
- data/manual/bounding_box/canvas.rb +0 -23
- data/manual/bounding_box/creation.rb +0 -22
- data/manual/bounding_box/indentation.rb +0 -45
- data/manual/bounding_box/nesting.rb +0 -52
- data/manual/bounding_box/russian_boxes.rb +0 -40
- data/manual/bounding_box/stretchy.rb +0 -29
- data/manual/contents.rb +0 -35
- data/manual/cover.rb +0 -43
- data/manual/document_and_page_options/background.rb +0 -29
- data/manual/document_and_page_options/document_and_page_options.rb +0 -34
- data/manual/document_and_page_options/metadata.rb +0 -25
- data/manual/document_and_page_options/page_margins.rb +0 -36
- data/manual/document_and_page_options/page_size.rb +0 -34
- data/manual/document_and_page_options/print_scaling.rb +0 -23
- data/manual/example_helper.rb +0 -8
- data/manual/graphics/blend_mode.rb +0 -52
- data/manual/graphics/circle_and_ellipse.rb +0 -21
- data/manual/graphics/color.rb +0 -22
- data/manual/graphics/common_lines.rb +0 -29
- data/manual/graphics/fill_and_stroke.rb +0 -41
- data/manual/graphics/fill_rules.rb +0 -38
- data/manual/graphics/gradients.rb +0 -43
- data/manual/graphics/graphics.rb +0 -64
- data/manual/graphics/helper.rb +0 -34
- data/manual/graphics/line_width.rb +0 -36
- data/manual/graphics/lines_and_curves.rb +0 -40
- data/manual/graphics/polygon.rb +0 -27
- data/manual/graphics/rectangle.rb +0 -20
- data/manual/graphics/rotate.rb +0 -25
- data/manual/graphics/scale.rb +0 -42
- data/manual/graphics/soft_masks.rb +0 -44
- data/manual/graphics/stroke_cap.rb +0 -30
- data/manual/graphics/stroke_dash.rb +0 -47
- data/manual/graphics/stroke_join.rb +0 -29
- data/manual/graphics/translate.rb +0 -29
- data/manual/graphics/transparency.rb +0 -33
- data/manual/how_to_read_this_manual.rb +0 -39
- data/manual/images/absolute_position.rb +0 -22
- data/manual/images/fit.rb +0 -20
- data/manual/images/horizontal.rb +0 -24
- data/manual/images/images.rb +0 -41
- data/manual/images/plain_image.rb +0 -17
- data/manual/images/scale.rb +0 -21
- data/manual/images/vertical.rb +0 -30
- data/manual/images/width_and_height.rb +0 -24
- data/manual/layout/boxes.rb +0 -26
- data/manual/layout/content.rb +0 -24
- data/manual/layout/layout.rb +0 -27
- data/manual/layout/simple_grid.rb +0 -22
- data/manual/outline/add_subsection_to.rb +0 -60
- data/manual/outline/insert_section_after.rb +0 -46
- data/manual/outline/outline.rb +0 -33
- data/manual/outline/sections_and_pages.rb +0 -66
- data/manual/repeatable_content/alternate_page_numbering.rb +0 -36
- data/manual/repeatable_content/page_numbering.rb +0 -55
- data/manual/repeatable_content/repeatable_content.rb +0 -35
- data/manual/repeatable_content/repeater.rb +0 -54
- data/manual/repeatable_content/stamp.rb +0 -40
- data/manual/security/encryption.rb +0 -28
- data/manual/security/permissions.rb +0 -43
- data/manual/security/security.rb +0 -28
- data/manual/table.rb +0 -16
- data/manual/text/alignment.rb +0 -43
- data/manual/text/color.rb +0 -24
- data/manual/text/column_box.rb +0 -30
- data/manual/text/fallback_fonts.rb +0 -41
- data/manual/text/font.rb +0 -40
- data/manual/text/font_size.rb +0 -44
- data/manual/text/font_style.rb +0 -25
- data/manual/text/formatted_callbacks.rb +0 -70
- data/manual/text/formatted_text.rb +0 -61
- data/manual/text/free_flowing_text.rb +0 -50
- data/manual/text/inline.rb +0 -40
- data/manual/text/kerning_and_character_spacing.rb +0 -38
- data/manual/text/leading.rb +0 -24
- data/manual/text/line_wrapping.rb +0 -60
- data/manual/text/paragraph_indentation.rb +0 -31
- data/manual/text/positioned_text.rb +0 -37
- data/manual/text/registering_families.rb +0 -51
- data/manual/text/rendering_and_color.rb +0 -36
- data/manual/text/right_to_left_text.rb +0 -54
- data/manual/text/rotation.rb +0 -52
- data/manual/text/single_usage.rb +0 -36
- data/manual/text/text.rb +0 -75
- data/manual/text/text_box_excess.rb +0 -35
- data/manual/text/text_box_extensions.rb +0 -48
- data/manual/text/text_box_overflow.rb +0 -51
- data/manual/text/utf8.rb +0 -27
- data/manual/text/win_ansi_charset.rb +0 -62
- data/prawn.gemspec +0 -51
- data/spec/data/curves.pdf +0 -66
- data/spec/extensions/encoding_helpers.rb +0 -11
- data/spec/prawn/document/bounding_box_spec.rb +0 -550
- data/spec/prawn/document/column_box_spec.rb +0 -75
- data/spec/prawn/document/security_spec.rb +0 -176
- data/spec/prawn/document_annotations_spec.rb +0 -76
- data/spec/prawn/document_destinations_spec.rb +0 -15
- data/spec/prawn/document_grid_spec.rb +0 -99
- data/spec/prawn/document_reference_spec.rb +0 -27
- data/spec/prawn/document_span_spec.rb +0 -44
- data/spec/prawn/document_spec.rb +0 -805
- data/spec/prawn/font_metric_cache_spec.rb +0 -54
- data/spec/prawn/font_spec.rb +0 -544
- data/spec/prawn/graphics/blend_mode_spec.rb +0 -63
- data/spec/prawn/graphics/transparency_spec.rb +0 -81
- data/spec/prawn/graphics_spec.rb +0 -872
- data/spec/prawn/graphics_stroke_styles_spec.rb +0 -229
- data/spec/prawn/image_handler_spec.rb +0 -53
- data/spec/prawn/images/jpg_spec.rb +0 -20
- data/spec/prawn/images/png_spec.rb +0 -283
- data/spec/prawn/images_spec.rb +0 -229
- data/spec/prawn/measurements_extensions_spec.rb +0 -24
- data/spec/prawn/outline_spec.rb +0 -512
- data/spec/prawn/repeater_spec.rb +0 -166
- data/spec/prawn/soft_mask_spec.rb +0 -74
- data/spec/prawn/stamp_spec.rb +0 -173
- data/spec/prawn/text/box_spec.rb +0 -1110
- data/spec/prawn/text/formatted/arranger_spec.rb +0 -466
- data/spec/prawn/text/formatted/box_spec.rb +0 -849
- data/spec/prawn/text/formatted/fragment_spec.rb +0 -343
- data/spec/prawn/text/formatted/line_wrap_spec.rb +0 -495
- data/spec/prawn/text/formatted/parser_spec.rb +0 -697
- data/spec/prawn/text_draw_text_spec.rb +0 -150
- data/spec/prawn/text_rendering_mode_spec.rb +0 -48
- data/spec/prawn/text_spacing_spec.rb +0 -95
- data/spec/prawn/text_spec.rb +0 -603
- data/spec/prawn/text_with_inline_formatting_spec.rb +0 -35
- data/spec/prawn/transformation_stack_spec.rb +0 -66
- data/spec/prawn/view_spec.rb +0 -63
- data/spec/prawn_manual_spec.rb +0 -35
- data/spec/spec_helper.rb +0 -48
data/lib/prawn/grid.rb
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# grid.rb: Provides a basic grid layout system for Prawn
|
4
|
-
#
|
5
|
-
# Contributed by Andrew O'Brien in March 2009
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
|
9
3
|
module Prawn
|
10
|
-
class Document
|
4
|
+
class Document # rubocop: disable Style/Documentation
|
11
5
|
# @group Experimental API
|
12
6
|
|
13
|
-
# Defines the grid system for a particular document.
|
7
|
+
# Defines the grid system for a particular document. Takes the number of
|
14
8
|
# rows and columns and the width to use for the gutter as the
|
15
9
|
# keys :rows, :columns, :gutter, :row_gutter, :column_gutter
|
16
10
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
|
11
|
+
# @note A completely new grid object is built each time `define_grid`
|
12
|
+
# is called. This means that all subsequent calls to grid() will use
|
13
|
+
# the newly defined Grid object -- grids are not nestable like
|
14
|
+
# bounding boxes are.
|
15
|
+
#
|
16
|
+
# @param options [Hash{Symbol => any}]
|
17
|
+
# @option options :columns [Integer] Number of columns in the grid.
|
18
|
+
# @option options :rows [Integer] Number of rows in the grid.
|
19
|
+
# @option options :gutter [Number] Gutter size. `:row_gutter` and
|
20
|
+
# `:column_gutter` are ignored if specified.
|
21
|
+
# @option options :row_gutter [Number] Row gutter size.
|
22
|
+
# @option options :column_gutter [Number] Column gutter size.
|
23
|
+
# @return [Grid]
|
22
24
|
def define_grid(options = {})
|
23
25
|
@boxes = nil
|
24
26
|
@grid = Grid.new(self, options)
|
@@ -27,25 +29,37 @@ module Prawn
|
|
27
29
|
# A method that can either be used to access a particular grid on the page
|
28
30
|
# or work with the grid system directly.
|
29
31
|
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
32
|
+
# @overload grid
|
33
|
+
# Get current grid.
|
34
|
+
#
|
35
|
+
# @return [Grid]
|
36
|
+
#
|
37
|
+
# @overload grid(row, column)
|
38
|
+
# Get a grid box.
|
39
|
+
#
|
40
|
+
# @param row [Integer]
|
41
|
+
# @param column [Integer]
|
42
|
+
# @return [GridBox]
|
33
43
|
#
|
44
|
+
# @overload grid(box1, box2)
|
45
|
+
# Get a grid multi-box.
|
46
|
+
#
|
47
|
+
# @param box1 [Array(Integer, Integer)] Start box coordinates.
|
48
|
+
# @param box2 [Array(Integer, Integer)] End box coordinates.
|
49
|
+
# @return [MultiBox]
|
34
50
|
def grid(*args)
|
35
51
|
@boxes ||= {}
|
36
52
|
@boxes[args] ||=
|
37
|
-
|
38
|
-
|
39
|
-
|
53
|
+
if args.empty?
|
54
|
+
@grid
|
55
|
+
else
|
56
|
+
g1, g2 = args
|
57
|
+
|
58
|
+
if g1.is_a?(Array) && g2.is_a?(Array) &&
|
59
|
+
g1.length == 2 && g2.length == 2
|
60
|
+
multi_box(single_box(*g1), single_box(*g2))
|
40
61
|
else
|
41
|
-
g1, g2
|
42
|
-
|
43
|
-
if g1.is_a?(Array) && g2.is_a?(Array) &&
|
44
|
-
g1.length == 2 && g2.length == 2
|
45
|
-
multi_box(single_box(*g1), single_box(*g2))
|
46
|
-
else
|
47
|
-
single_box(g1, g2)
|
48
|
-
end
|
62
|
+
single_box(g1, g2)
|
49
63
|
end
|
50
64
|
end
|
51
65
|
end
|
@@ -55,11 +69,41 @@ module Prawn
|
|
55
69
|
#
|
56
70
|
# @group Experimental API
|
57
71
|
class Grid
|
58
|
-
|
72
|
+
# @private
|
73
|
+
# @return [Prawn::Document]
|
74
|
+
attr_reader :pdf
|
59
75
|
|
60
|
-
|
76
|
+
# Number of columns in the grid.
|
77
|
+
# @return [Integer]
|
78
|
+
attr_reader :columns
|
79
|
+
|
80
|
+
# Number of rows in the grid.
|
81
|
+
# @return [Integer]
|
82
|
+
attr_reader :rows
|
83
|
+
|
84
|
+
# Gutter size.
|
85
|
+
# @return [Number]
|
86
|
+
attr_reader :gutter
|
87
|
+
|
88
|
+
# Row gutter size.
|
89
|
+
# @return [Number]
|
90
|
+
attr_reader :row_gutter
|
91
|
+
|
92
|
+
# Column gutter size.
|
93
|
+
# @return [Number]
|
94
|
+
attr_reader :column_gutter
|
95
|
+
|
96
|
+
# @param pdf [Prawn::Document]
|
97
|
+
# @param options [Hash{Symbol => any}]
|
98
|
+
# @option options :columns [Integer] Number of columns in the grid.
|
99
|
+
# @option options :rows [Integer] Number of rows in the grid.
|
100
|
+
# @option options :gutter [Number] Gutter size. `:row_gutter` and
|
101
|
+
# `:column_gutter` are ignored if specified.
|
102
|
+
# @option options :row_gutter [Number] Row gutter size.
|
103
|
+
# @option options :column_gutter [Number] Column gutter size.
|
104
|
+
def initialize(pdf, options = {})
|
61
105
|
valid_options = %i[columns rows gutter row_gutter column_gutter]
|
62
|
-
Prawn.verify_options
|
106
|
+
Prawn.verify_options(valid_options, options)
|
63
107
|
|
64
108
|
@pdf = pdf
|
65
109
|
@columns = options[:columns]
|
@@ -68,16 +112,23 @@ module Prawn
|
|
68
112
|
end
|
69
113
|
|
70
114
|
# Calculates the base width of boxes.
|
115
|
+
#
|
116
|
+
# @return [Float]
|
71
117
|
def column_width
|
72
118
|
@column_width ||= subdivide(pdf.bounds.width, columns, column_gutter)
|
73
119
|
end
|
74
120
|
|
75
121
|
# Calculates the base height of boxes.
|
122
|
+
#
|
123
|
+
# @return [Float]
|
76
124
|
def row_height
|
77
125
|
@row_height ||= subdivide(pdf.bounds.height, rows, row_gutter)
|
78
126
|
end
|
79
127
|
|
80
|
-
# Diagnostic tool to show all of the
|
128
|
+
# Diagnostic tool to show all of the grid boxes.
|
129
|
+
#
|
130
|
+
# @param color [Color]
|
131
|
+
# @return [void]
|
81
132
|
def show_all(color = 'CCCCCC')
|
82
133
|
rows.times do |row|
|
83
134
|
columns.times do |column|
|
@@ -89,17 +140,17 @@ module Prawn
|
|
89
140
|
private
|
90
141
|
|
91
142
|
def subdivide(total, num, gutter)
|
92
|
-
(total
|
143
|
+
(Float(total) - (gutter * Float((num - 1)))) / Float(num)
|
93
144
|
end
|
94
145
|
|
95
146
|
def apply_gutter(options)
|
96
147
|
if options.key?(:gutter)
|
97
|
-
@gutter = options[:gutter]
|
148
|
+
@gutter = Float(options[:gutter])
|
98
149
|
@row_gutter = @gutter
|
99
150
|
@column_gutter = @gutter
|
100
151
|
else
|
101
|
-
@row_gutter = options[:row_gutter]
|
102
|
-
@column_gutter = options[:column_gutter]
|
152
|
+
@row_gutter = Float(options[:row_gutter])
|
153
|
+
@column_gutter = Float(options[:column_gutter])
|
103
154
|
@gutter = 0
|
104
155
|
end
|
105
156
|
end
|
@@ -107,10 +158,11 @@ module Prawn
|
|
107
158
|
|
108
159
|
# A Box is a class that represents a bounded area of a page.
|
109
160
|
# A Grid object has methods that allow easy access to the coordinates of
|
110
|
-
# its corners, which can be plugged into most existing
|
161
|
+
# its corners, which can be plugged into most existing Prawn methods.
|
111
162
|
#
|
112
163
|
# @group Experimental API
|
113
164
|
class GridBox
|
165
|
+
# @private
|
114
166
|
attr_reader :pdf
|
115
167
|
|
116
168
|
def initialize(pdf, rows, columns)
|
@@ -122,82 +174,111 @@ module Prawn
|
|
122
174
|
# Mostly diagnostic method that outputs the name of a box as
|
123
175
|
# col_num, row_num
|
124
176
|
#
|
177
|
+
# @return [String]
|
125
178
|
def name
|
126
179
|
"#{@rows},#{@columns}"
|
127
180
|
end
|
128
181
|
|
129
|
-
#
|
182
|
+
# @private
|
130
183
|
def total_height
|
131
|
-
pdf.bounds.height
|
184
|
+
Float(pdf.bounds.height)
|
132
185
|
end
|
133
186
|
|
134
|
-
# Width of a box
|
187
|
+
# Width of a box.
|
188
|
+
#
|
189
|
+
# @return [Float]
|
135
190
|
def width
|
136
|
-
grid.column_width
|
191
|
+
Float(grid.column_width)
|
137
192
|
end
|
138
193
|
|
139
|
-
# Height of a box
|
194
|
+
# Height of a box.
|
195
|
+
#
|
196
|
+
# @return [Float]
|
140
197
|
def height
|
141
|
-
grid.row_height
|
198
|
+
Float(grid.row_height)
|
142
199
|
end
|
143
200
|
|
144
|
-
# Width of the gutter
|
201
|
+
# Width of the gutter.
|
202
|
+
#
|
203
|
+
# @return [Float]
|
145
204
|
def gutter
|
146
|
-
grid.gutter
|
205
|
+
Float(grid.gutter)
|
147
206
|
end
|
148
207
|
|
149
|
-
# x-coordinate of left side
|
208
|
+
# x-coordinate of left side.
|
209
|
+
#
|
210
|
+
# @return [Float]
|
150
211
|
def left
|
151
|
-
@left ||= (width + grid.column_gutter) * @columns
|
212
|
+
@left ||= (width + grid.column_gutter) * Float(@columns)
|
152
213
|
end
|
153
214
|
|
154
|
-
# x-coordinate of right side
|
215
|
+
# x-coordinate of right side.
|
216
|
+
#
|
217
|
+
# @return [Float]
|
155
218
|
def right
|
156
219
|
@right ||= left + width
|
157
220
|
end
|
158
221
|
|
159
|
-
# y-coordinate of the top
|
222
|
+
# y-coordinate of the top.
|
223
|
+
#
|
224
|
+
# @return [Float]
|
160
225
|
def top
|
161
|
-
@top ||= total_height - ((height + grid.row_gutter) * @rows
|
226
|
+
@top ||= total_height - ((height + grid.row_gutter) * Float(@rows))
|
162
227
|
end
|
163
228
|
|
164
|
-
# y-coordinate of the bottom
|
229
|
+
# y-coordinate of the bottom.
|
230
|
+
#
|
231
|
+
# @return [Float]
|
165
232
|
def bottom
|
166
233
|
@bottom ||= top - height
|
167
234
|
end
|
168
235
|
|
169
|
-
# x,y coordinates of top left corner
|
236
|
+
# x,y coordinates of top left corner.
|
237
|
+
#
|
238
|
+
# @return [Array(Float, Float)]
|
170
239
|
def top_left
|
171
240
|
[left, top]
|
172
241
|
end
|
173
242
|
|
174
|
-
# x,y coordinates of top right corner
|
243
|
+
# x,y coordinates of top right corner.
|
244
|
+
#
|
245
|
+
# @return [Array(Float, Float)]
|
175
246
|
def top_right
|
176
247
|
[right, top]
|
177
248
|
end
|
178
249
|
|
179
|
-
# x,y coordinates of bottom left corner
|
250
|
+
# x,y coordinates of bottom left corner.
|
251
|
+
#
|
252
|
+
# @return [Array(Float, Float)]
|
180
253
|
def bottom_left
|
181
254
|
[left, bottom]
|
182
255
|
end
|
183
256
|
|
184
|
-
# x,y coordinates of bottom right corner
|
257
|
+
# x,y coordinates of bottom right corner.
|
258
|
+
#
|
259
|
+
# @return [Array(Float, Float)]
|
185
260
|
def bottom_right
|
186
261
|
[right, bottom]
|
187
262
|
end
|
188
263
|
|
189
264
|
# Creates a standard bounding box based on the grid box.
|
265
|
+
#
|
266
|
+
# @yield
|
267
|
+
# @return [void]
|
190
268
|
def bounding_box(&blk)
|
191
269
|
pdf.bounding_box(top_left, width: width, height: height, &blk)
|
192
270
|
end
|
193
271
|
|
194
|
-
# Diagnostic method
|
272
|
+
# Drawn the box. Diagnostic method.
|
273
|
+
#
|
274
|
+
# @param grid_color [Color]
|
275
|
+
# @return [void]
|
195
276
|
def show(grid_color = 'CCCCCC')
|
196
277
|
bounding_box do
|
197
278
|
original_stroke_color = pdf.stroke_color
|
198
279
|
|
199
280
|
pdf.stroke_color = grid_color
|
200
|
-
pdf.text
|
281
|
+
pdf.text(name)
|
201
282
|
pdf.stroke_bounds
|
202
283
|
|
203
284
|
pdf.stroke_color = original_stroke_color
|
@@ -220,70 +301,116 @@ module Prawn
|
|
220
301
|
@boxes = [box1, box2]
|
221
302
|
end
|
222
303
|
|
304
|
+
# @private
|
223
305
|
attr_reader :pdf
|
224
306
|
|
307
|
+
# Mostly diagnostic method that outputs the name of a box.
|
308
|
+
#
|
309
|
+
# @return [String]
|
225
310
|
def name
|
226
311
|
@boxes.map(&:name).join(':')
|
227
312
|
end
|
228
313
|
|
314
|
+
# @private
|
229
315
|
def total_height
|
230
316
|
@boxes[0].total_height
|
231
317
|
end
|
232
318
|
|
319
|
+
# Width of a box.
|
320
|
+
#
|
321
|
+
# @return [Float]
|
233
322
|
def width
|
234
323
|
right_box.right - left_box.left
|
235
324
|
end
|
236
325
|
|
326
|
+
# Height of a box.
|
327
|
+
#
|
328
|
+
# @return [Float]
|
237
329
|
def height
|
238
330
|
top_box.top - bottom_box.bottom
|
239
331
|
end
|
240
332
|
|
333
|
+
# Width of the gutter.
|
334
|
+
#
|
335
|
+
# @return [Float]
|
241
336
|
def gutter
|
242
337
|
@boxes[0].gutter
|
243
338
|
end
|
244
339
|
|
340
|
+
# x-coordinate of left side.
|
341
|
+
#
|
342
|
+
# @return [Float]
|
245
343
|
def left
|
246
344
|
left_box.left
|
247
345
|
end
|
248
346
|
|
347
|
+
# x-coordinate of right side.
|
348
|
+
#
|
349
|
+
# @return [Float]
|
249
350
|
def right
|
250
351
|
right_box.right
|
251
352
|
end
|
252
353
|
|
354
|
+
# y-coordinate of the top.
|
355
|
+
#
|
356
|
+
# @return [Float]
|
253
357
|
def top
|
254
358
|
top_box.top
|
255
359
|
end
|
256
360
|
|
361
|
+
# y-coordinate of the bottom.
|
362
|
+
#
|
363
|
+
# @return [Float]
|
257
364
|
def bottom
|
258
365
|
bottom_box.bottom
|
259
366
|
end
|
260
367
|
|
368
|
+
# x,y coordinates of top left corner.
|
369
|
+
#
|
370
|
+
# @return [Array(Float, Float)]
|
261
371
|
def top_left
|
262
372
|
[left, top]
|
263
373
|
end
|
264
374
|
|
375
|
+
# x,y coordinates of top right corner.
|
376
|
+
#
|
377
|
+
# @return [Array(Float, Float)]
|
265
378
|
def top_right
|
266
379
|
[right, top]
|
267
380
|
end
|
268
381
|
|
382
|
+
# x,y coordinates of bottom left corner.
|
383
|
+
#
|
384
|
+
# @return [Array(Float, Float)]
|
269
385
|
def bottom_left
|
270
386
|
[left, bottom]
|
271
387
|
end
|
272
388
|
|
389
|
+
# x,y coordinates of bottom right corner.
|
390
|
+
#
|
391
|
+
# @return [Array(Float, Float)]
|
273
392
|
def bottom_right
|
274
393
|
[right, bottom]
|
275
394
|
end
|
276
395
|
|
396
|
+
# Creates a standard bounding box based on the grid box.
|
397
|
+
#
|
398
|
+
# @yield
|
399
|
+
# @return [void]
|
277
400
|
def bounding_box(&blk)
|
278
401
|
pdf.bounding_box(top_left, width: width, height: height, &blk)
|
279
402
|
end
|
280
403
|
|
404
|
+
# Drawn the box. Diagnostic method.
|
405
|
+
#
|
406
|
+
# @param grid_color [Color]
|
407
|
+
# @return [void]
|
281
408
|
def show(grid_color = 'CCCCCC')
|
282
409
|
bounding_box do
|
283
410
|
original_stroke_color = pdf.stroke_color
|
284
411
|
|
285
412
|
pdf.stroke_color = grid_color
|
286
|
-
pdf.text
|
413
|
+
pdf.text(name)
|
287
414
|
pdf.stroke_bounds
|
288
415
|
|
289
416
|
pdf.stroke_color = original_stroke_color
|
data/lib/prawn/image_handler.rb
CHANGED
@@ -1,39 +1,56 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
#
|
5
|
-
# Contributed by Evan Sharp in November 2013.
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
|
9
|
-
module Prawn
|
3
|
+
module Prawn # rubocop: disable Style/Documentation
|
10
4
|
# @group Extension API
|
11
5
|
|
6
|
+
# Image handler.
|
7
|
+
#
|
8
|
+
# @return [ImageHandler]
|
12
9
|
def self.image_handler
|
13
10
|
@image_handler ||= ImageHandler.new
|
14
11
|
end
|
15
12
|
|
13
|
+
# ImageHandler provides a way to register image processors with Prawn.
|
16
14
|
class ImageHandler
|
15
|
+
# @private
|
17
16
|
def initialize
|
18
17
|
@handlers = []
|
19
18
|
end
|
20
19
|
|
20
|
+
# Register an image handler.
|
21
|
+
#
|
22
|
+
# @param handler [Object]
|
23
|
+
# @return [void]
|
21
24
|
def register(handler)
|
22
25
|
@handlers.delete(handler)
|
23
|
-
@handlers.push
|
26
|
+
@handlers.push(handler)
|
24
27
|
end
|
25
28
|
|
29
|
+
# Register an image handler with the highest priority.
|
30
|
+
#
|
31
|
+
# @param handler [Object]
|
32
|
+
# @return [void]
|
26
33
|
def register!(handler)
|
27
34
|
@handlers.delete(handler)
|
28
|
-
@handlers.unshift
|
35
|
+
@handlers.unshift(handler)
|
29
36
|
end
|
30
37
|
|
38
|
+
# Unregister an image handler.
|
39
|
+
#
|
40
|
+
# @param handler [Object]
|
41
|
+
# @return [void]
|
31
42
|
def unregister(handler)
|
32
43
|
@handlers.reject! { |h| h == handler }
|
33
44
|
end
|
34
45
|
|
46
|
+
# Find an image handler for an image.
|
47
|
+
#
|
48
|
+
# @param image_blob [String]
|
49
|
+
# @return [Object]
|
50
|
+
# @raise [Prawn::Errors::UnsupportedImageType] If no image handler were
|
51
|
+
# found for the image.
|
35
52
|
def find(image_blob)
|
36
|
-
handler = @handlers.find { |h| h.can_render?
|
53
|
+
handler = @handlers.find { |h| h.can_render?(image_blob) }
|
37
54
|
|
38
55
|
return handler if handler
|
39
56
|
|
data/lib/prawn/images/image.rb
CHANGED
@@ -1,28 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# image.rb : Base class for image info objects
|
4
|
-
#
|
5
|
-
# Copyright September 2011, Brad Ediger. All rights reserved.
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
|
9
3
|
require 'digest/sha1'
|
10
4
|
|
11
5
|
module Prawn
|
12
6
|
module Images
|
7
|
+
# Base class for image info objects
|
8
|
+
# @abstract
|
13
9
|
class Image
|
14
10
|
# @group Extension API
|
15
11
|
|
12
|
+
# Calculate the final image dimensions from provided options.
|
13
|
+
# @private
|
16
14
|
def calc_image_dimensions(options)
|
17
15
|
w = options[:width] || width
|
18
16
|
h = options[:height] || height
|
19
17
|
|
20
18
|
if options[:width] && !options[:height]
|
21
|
-
wp = w / width
|
19
|
+
wp = w / Float(width)
|
22
20
|
w = width * wp
|
23
21
|
h = height * wp
|
24
22
|
elsif options[:height] && !options[:width]
|
25
|
-
hp = h / height
|
23
|
+
hp = h / Float(height)
|
26
24
|
w = width * hp
|
27
25
|
h = height * hp
|
28
26
|
elsif options[:scale]
|
@@ -30,8 +28,8 @@ module Prawn
|
|
30
28
|
h = height * options[:scale]
|
31
29
|
elsif options[:fit]
|
32
30
|
bw, bh = options[:fit]
|
33
|
-
bp = bw / bh
|
34
|
-
ip = width / height
|
31
|
+
bp = bw / Float(bh)
|
32
|
+
ip = width / Float(height)
|
35
33
|
if ip > bp
|
36
34
|
w = bw
|
37
35
|
h = bw / ip
|
data/lib/prawn/images/jpg.rb
CHANGED
@@ -1,41 +1,60 @@
|
|
1
1
|
# encoding: ASCII-8BIT
|
2
|
-
|
3
2
|
# frozen_string_literal: true
|
4
3
|
|
5
|
-
# jpg.rb : Extracts the data from a JPG that is needed for embedding
|
6
|
-
#
|
7
|
-
# Copyright April 2008, James Healy. All Rights Reserved.
|
8
|
-
#
|
9
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
10
|
-
|
11
4
|
require 'stringio'
|
12
5
|
|
13
6
|
module Prawn
|
14
|
-
module Images
|
15
|
-
# A convenience class that wraps the logic for extracting the parts
|
16
|
-
#
|
17
|
-
#
|
7
|
+
module Images # rubocop: disable Style/Documentation
|
8
|
+
# A convenience class that wraps the logic for extracting the parts of a JPG
|
9
|
+
# image that we need to embed them in a PDF.
|
18
10
|
class JPG < Image
|
11
|
+
# Signals an issue with the image format. The image is probably corrupted
|
12
|
+
# if you're getting this.
|
19
13
|
class FormatError < StandardError; end
|
20
14
|
|
21
15
|
# @group Extension API
|
22
16
|
|
23
|
-
|
24
|
-
|
17
|
+
# Image width in pixels.
|
18
|
+
# @return [Integer]
|
19
|
+
attr_reader :width
|
20
|
+
|
21
|
+
# Image height in pixels.
|
22
|
+
# @return [Integer]
|
23
|
+
attr_reader :height
|
24
|
+
|
25
|
+
# Sample Precision in bits.
|
26
|
+
# @return [Integer]
|
27
|
+
attr_reader :bits
|
28
|
+
|
29
|
+
# Number of image components (channels).
|
30
|
+
# @return [Integer]
|
31
|
+
attr_reader :channels
|
25
32
|
|
33
|
+
# Scaled width of the image in PDF points.
|
34
|
+
# @return [Number]
|
35
|
+
attr_accessor :scaled_width
|
36
|
+
|
37
|
+
# Scaled height of the image in PDF points.
|
38
|
+
# @return [Number]
|
39
|
+
attr_accessor :scaled_height
|
40
|
+
|
41
|
+
# @private
|
26
42
|
JPEG_SOF_BLOCKS = [
|
27
43
|
0xC0, 0xC1, 0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE,
|
28
|
-
0xCF
|
44
|
+
0xCF,
|
29
45
|
].freeze
|
30
46
|
|
47
|
+
# Can this image handler process this image?
|
48
|
+
#
|
49
|
+
# @param image_blob [String]
|
50
|
+
# @return [Boolean]
|
31
51
|
def self.can_render?(image_blob)
|
32
52
|
image_blob[0, 3].unpack('C*') == [255, 216, 255]
|
33
53
|
end
|
34
54
|
|
35
|
-
# Process a new JPG image
|
36
|
-
#
|
37
|
-
# <tt>:data</tt>:: A binary string of JPEG data
|
55
|
+
# Process a new JPG image.
|
38
56
|
#
|
57
|
+
# @param data [String] A binary string of JPEG data.
|
39
58
|
def initialize(data)
|
40
59
|
super()
|
41
60
|
@data = data
|
@@ -57,9 +76,11 @@ module Prawn
|
|
57
76
|
end
|
58
77
|
end
|
59
78
|
|
60
|
-
# Build a PDF object representing this image in
|
79
|
+
# Build a PDF object representing this image in `document`, and return
|
61
80
|
# a Reference to it.
|
62
81
|
#
|
82
|
+
# @param document [Prawn::Document]
|
83
|
+
# @return [PDF::Core::Reference]
|
63
84
|
def build_pdf_object(document)
|
64
85
|
color_space =
|
65
86
|
case channels
|
@@ -79,7 +100,7 @@ module Prawn
|
|
79
100
|
ColorSpace: color_space,
|
80
101
|
BitsPerComponent: bits,
|
81
102
|
Width: width,
|
82
|
-
Height: height
|
103
|
+
Height: height,
|
83
104
|
)
|
84
105
|
|
85
106
|
# add extra decode params for CMYK images. By swapping the
|
@@ -94,5 +115,7 @@ module Prawn
|
|
94
115
|
obj
|
95
116
|
end
|
96
117
|
end
|
118
|
+
|
119
|
+
Prawn.image_handler.register(Prawn::Images::JPG)
|
97
120
|
end
|
98
121
|
end
|