prawn 2.1.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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/GPLv2 +20 -21
- data/Gemfile +3 -9
- data/Rakefile +9 -41
- data/lib/prawn.rb +37 -49
- data/lib/prawn/document.rb +193 -141
- data/lib/prawn/document/bounding_box.rb +50 -30
- data/lib/prawn/document/column_box.rb +7 -7
- data/lib/prawn/document/internals.rb +8 -6
- data/lib/prawn/document/span.rb +22 -16
- data/lib/prawn/encoding.rb +69 -68
- data/lib/prawn/errors.rb +12 -7
- data/lib/prawn/font.rb +104 -69
- data/lib/prawn/font_metric_cache.rb +20 -13
- data/lib/prawn/{font → fonts}/afm.rb +108 -72
- data/lib/prawn/{font → fonts}/dfont.rb +5 -11
- data/lib/prawn/fonts/otf.rb +11 -0
- data/lib/prawn/fonts/ttc.rb +36 -0
- data/lib/prawn/{font → fonts}/ttf.rb +126 -81
- data/lib/prawn/graphics.rb +119 -81
- data/lib/prawn/graphics/blend_mode.rb +9 -8
- data/lib/prawn/graphics/cap_style.rb +3 -3
- data/lib/prawn/graphics/color.rb +43 -39
- data/lib/prawn/graphics/dash.rb +23 -11
- data/lib/prawn/graphics/join_style.rb +9 -3
- data/lib/prawn/graphics/patterns.rb +204 -102
- data/lib/prawn/graphics/transformation.rb +15 -9
- data/lib/prawn/graphics/transparency.rb +17 -13
- data/lib/prawn/grid.rb +84 -48
- data/lib/prawn/image_handler.rb +5 -5
- data/lib/prawn/images.rb +60 -49
- data/lib/prawn/images/image.rb +2 -1
- data/lib/prawn/images/jpg.rb +31 -22
- data/lib/prawn/images/png.rb +67 -63
- data/lib/prawn/measurement_extensions.rb +10 -9
- data/lib/prawn/measurements.rb +19 -15
- data/lib/prawn/outline.rb +98 -77
- data/lib/prawn/repeater.rb +15 -11
- data/lib/prawn/security.rb +93 -70
- data/lib/prawn/security/arcfour.rb +2 -2
- data/lib/prawn/soft_mask.rb +26 -26
- data/lib/prawn/stamp.rb +20 -13
- data/lib/prawn/text.rb +76 -60
- data/lib/prawn/text/box.rb +18 -14
- data/lib/prawn/text/formatted.rb +5 -5
- data/lib/prawn/text/formatted/arranger.rb +80 -40
- data/lib/prawn/text/formatted/box.rb +140 -101
- data/lib/prawn/text/formatted/fragment.rb +11 -14
- data/lib/prawn/text/formatted/line_wrap.rb +128 -67
- data/lib/prawn/text/formatted/parser.rb +147 -123
- data/lib/prawn/text/formatted/wrap.rb +48 -32
- data/lib/prawn/transformation_stack.rb +7 -5
- data/lib/prawn/utilities.rb +7 -22
- data/lib/prawn/version.rb +2 -2
- data/lib/prawn/view.rb +17 -7
- data/manual/basic_concepts/adding_pages.rb +6 -7
- data/manual/basic_concepts/basic_concepts.rb +31 -22
- data/manual/basic_concepts/creation.rb +10 -11
- data/manual/basic_concepts/cursor.rb +4 -5
- data/manual/basic_concepts/measurement.rb +7 -8
- data/manual/basic_concepts/origin.rb +5 -6
- data/manual/basic_concepts/other_cursor_helpers.rb +11 -12
- data/manual/basic_concepts/view.rb +22 -16
- data/manual/bounding_box/bounding_box.rb +29 -24
- data/manual/bounding_box/bounds.rb +11 -12
- data/manual/bounding_box/canvas.rb +7 -8
- data/manual/bounding_box/creation.rb +6 -7
- data/manual/bounding_box/indentation.rb +14 -15
- data/manual/bounding_box/nesting.rb +25 -18
- data/manual/bounding_box/russian_boxes.rb +14 -13
- data/manual/bounding_box/stretchy.rb +12 -13
- data/manual/contents.rb +28 -22
- data/manual/cover.rb +33 -28
- data/manual/document_and_page_options/background.rb +15 -13
- data/manual/document_and_page_options/document_and_page_options.rb +25 -20
- data/manual/document_and_page_options/metadata.rb +18 -16
- data/manual/document_and_page_options/page_margins.rb +18 -20
- data/manual/document_and_page_options/page_size.rb +13 -12
- data/manual/document_and_page_options/print_scaling.rb +18 -15
- data/manual/example_helper.rb +5 -4
- data/manual/graphics/blend_mode.rb +12 -9
- data/manual/graphics/circle_and_ellipse.rb +4 -5
- data/manual/graphics/color.rb +7 -9
- data/manual/graphics/common_lines.rb +7 -8
- data/manual/graphics/fill_and_stroke.rb +5 -6
- data/manual/graphics/fill_rules.rb +10 -10
- data/manual/graphics/gradients.rb +27 -21
- data/manual/graphics/graphics.rb +48 -40
- data/manual/graphics/helper.rb +19 -9
- data/manual/graphics/line_width.rb +8 -7
- data/manual/graphics/lines_and_curves.rb +7 -8
- data/manual/graphics/polygon.rb +6 -8
- data/manual/graphics/rectangle.rb +4 -5
- data/manual/graphics/rotate.rb +6 -7
- data/manual/graphics/scale.rb +14 -15
- data/manual/graphics/soft_masks.rb +3 -4
- data/manual/graphics/stroke_cap.rb +6 -7
- data/manual/graphics/stroke_dash.rb +15 -16
- data/manual/graphics/stroke_join.rb +5 -6
- data/manual/graphics/translate.rb +10 -10
- data/manual/graphics/transparency.rb +7 -8
- data/manual/how_to_read_this_manual.rb +6 -6
- data/manual/images/absolute_position.rb +6 -7
- data/manual/images/fit.rb +7 -8
- data/manual/images/horizontal.rb +10 -11
- data/manual/images/images.rb +28 -24
- data/manual/images/plain_image.rb +5 -6
- data/manual/images/scale.rb +9 -10
- data/manual/images/vertical.rb +16 -14
- data/manual/images/width_and_height.rb +10 -11
- data/manual/layout/boxes.rb +5 -6
- data/manual/layout/content.rb +7 -8
- data/manual/layout/layout.rb +18 -16
- data/manual/layout/simple_grid.rb +6 -7
- data/manual/outline/add_subsection_to.rb +20 -21
- data/manual/outline/insert_section_after.rb +15 -16
- data/manual/outline/outline.rb +21 -17
- data/manual/outline/sections_and_pages.rb +17 -18
- data/manual/repeatable_content/alternate_page_numbering.rb +21 -17
- data/manual/repeatable_content/page_numbering.rb +17 -16
- data/manual/repeatable_content/repeatable_content.rb +25 -19
- data/manual/repeatable_content/repeater.rb +14 -15
- data/manual/repeatable_content/stamp.rb +14 -15
- data/manual/security/encryption.rb +9 -10
- data/manual/security/permissions.rb +21 -14
- data/manual/security/security.rb +19 -16
- data/manual/table.rb +3 -3
- data/manual/text/alignment.rb +16 -17
- data/manual/text/color.rb +12 -11
- data/manual/text/column_box.rb +9 -10
- data/manual/text/fallback_fonts.rb +25 -21
- data/manual/text/font.rb +11 -12
- data/manual/text/font_size.rb +13 -14
- data/manual/text/font_style.rb +10 -8
- data/manual/text/formatted_callbacks.rb +33 -24
- data/manual/text/formatted_text.rb +36 -25
- data/manual/text/free_flowing_text.rb +22 -23
- data/manual/text/inline.rb +18 -19
- data/manual/text/kerning_and_character_spacing.rb +14 -15
- data/manual/text/leading.rb +7 -8
- data/manual/text/line_wrapping.rb +37 -18
- data/manual/text/paragraph_indentation.rb +12 -14
- data/manual/text/positioned_text.rb +15 -16
- data/manual/text/registering_families.rb +20 -21
- data/manual/text/rendering_and_color.rb +9 -10
- data/manual/text/right_to_left_text.rb +26 -19
- data/manual/text/rotation.rb +33 -23
- data/manual/text/single_usage.rb +8 -9
- data/manual/text/text.rb +57 -52
- data/manual/text/text_box_excess.rb +20 -17
- data/manual/text/text_box_extensions.rb +18 -15
- data/manual/text/text_box_overflow.rb +20 -19
- data/manual/text/utf8.rb +11 -12
- data/manual/text/win_ansi_charset.rb +27 -25
- data/prawn.gemspec +41 -34
- data/spec/extensions/encoding_helpers.rb +3 -3
- data/spec/prawn/document/bounding_box_spec.rb +550 -0
- data/spec/prawn/document/column_box_spec.rb +75 -0
- data/spec/prawn/document/security_spec.rb +176 -0
- data/spec/prawn/document_annotations_spec.rb +76 -0
- data/spec/prawn/document_destinations_spec.rb +15 -0
- data/spec/prawn/document_grid_spec.rb +99 -0
- data/spec/prawn/document_reference_spec.rb +27 -0
- data/spec/prawn/document_span_spec.rb +44 -0
- data/spec/prawn/document_spec.rb +805 -0
- data/spec/prawn/font_metric_cache_spec.rb +54 -0
- data/spec/prawn/font_spec.rb +544 -0
- data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
- data/spec/prawn/graphics/transparency_spec.rb +81 -0
- data/spec/prawn/graphics_spec.rb +872 -0
- data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
- data/spec/{image_handler_spec.rb → prawn/image_handler_spec.rb} +14 -14
- data/spec/prawn/images/jpg_spec.rb +20 -0
- data/spec/prawn/images/png_spec.rb +283 -0
- data/spec/prawn/images_spec.rb +229 -0
- data/spec/prawn/measurements_extensions_spec.rb +24 -0
- data/spec/prawn/outline_spec.rb +512 -0
- data/spec/prawn/repeater_spec.rb +166 -0
- data/spec/prawn/soft_mask_spec.rb +74 -0
- data/spec/prawn/stamp_spec.rb +173 -0
- data/spec/prawn/text/box_spec.rb +1110 -0
- data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
- data/spec/prawn/text/formatted/box_spec.rb +849 -0
- data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
- data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
- data/spec/prawn/text/formatted/parser_spec.rb +697 -0
- data/spec/prawn/text_draw_text_spec.rb +150 -0
- data/spec/prawn/text_rendering_mode_spec.rb +48 -0
- data/spec/prawn/text_spacing_spec.rb +95 -0
- data/spec/prawn/text_spec.rb +603 -0
- data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
- data/spec/{transformation_stack_spec.rb → prawn/transformation_stack_spec.rb} +22 -19
- data/spec/prawn/view_spec.rb +63 -0
- data/spec/prawn_manual_spec.rb +35 -0
- data/spec/spec_helper.rb +18 -19
- metadata +102 -222
- metadata.gz.sig +0 -0
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.color +0 -0
- data/data/images/16bit.png +0 -0
- data/data/images/arrow.png +0 -0
- data/data/images/arrow2.png +0 -0
- data/data/images/blend_modes_bottom_layer.jpg +0 -0
- data/data/images/blend_modes_top_layer.jpg +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.color +0 -0
- data/data/images/dice.png +0 -0
- data/data/images/dice_interlaced.png +0 -0
- data/data/images/fractal.jpg +0 -0
- data/data/images/indexed_color.dat +0 -0
- data/data/images/indexed_color.png +0 -0
- data/data/images/indexed_transparency.png +0 -0
- data/data/images/indexed_transparency_alpha.dat +0 -0
- data/data/images/indexed_transparency_color.dat +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/license.md +0 -8
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.color +0 -0
- data/data/images/page_white_text.png +0 -0
- data/data/images/pigs.jpg +0 -0
- data/data/images/prawn.png +0 -0
- data/data/images/ruport.png +0 -0
- data/data/images/ruport_data.dat +0 -0
- data/data/images/ruport_transparent.png +0 -0
- data/data/images/ruport_type0.png +0 -0
- data/data/images/stef.jpg +0 -0
- data/data/images/tru256.bmp +0 -0
- data/data/images/web-links.dat +0 -1
- data/data/images/web-links.png +0 -0
- data/data/pdfs/complex_template.pdf +0 -0
- data/data/pdfs/contains_ttf_font.pdf +0 -0
- data/data/pdfs/encrypted.pdf +0 -0
- data/data/pdfs/form.pdf +1 -819
- data/data/pdfs/hexagon.pdf +0 -61
- data/data/pdfs/indirect_reference.pdf +0 -86
- data/data/pdfs/multipage_template.pdf +0 -127
- data/data/pdfs/nested_pages.pdf +0 -118
- data/data/pdfs/page_without_mediabox.pdf +0 -193
- data/data/pdfs/resources_as_indirect_object.pdf +0 -83
- data/data/pdfs/two_hexagons.pdf +0 -90
- data/data/pdfs/version_1_6.pdf +0 -61
- data/data/shift_jis_text.txt +0 -1
- data/spec/acceptance/png_spec.rb +0 -35
- data/spec/annotations_spec.rb +0 -67
- data/spec/blend_mode_spec.rb +0 -71
- data/spec/bounding_box_spec.rb +0 -501
- data/spec/column_box_spec.rb +0 -59
- data/spec/destinations_spec.rb +0 -13
- data/spec/document_spec.rb +0 -738
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -475
- data/spec/formatted_text_arranger_spec.rb +0 -452
- data/spec/formatted_text_box_spec.rb +0 -716
- data/spec/formatted_text_fragment_spec.rb +0 -299
- data/spec/graphics_spec.rb +0 -705
- data/spec/grid_spec.rb +0 -95
- data/spec/images_spec.rb +0 -167
- data/spec/inline_formatted_text_parser_spec.rb +0 -568
- data/spec/jpg_spec.rb +0 -23
- data/spec/line_wrap_spec.rb +0 -366
- data/spec/measurement_units_spec.rb +0 -22
- data/spec/outline_spec.rb +0 -409
- data/spec/png_spec.rb +0 -257
- data/spec/reference_spec.rb +0 -25
- data/spec/repeater_spec.rb +0 -154
- data/spec/security_spec.rb +0 -151
- data/spec/soft_mask_spec.rb +0 -78
- data/spec/span_spec.rb +0 -43
- data/spec/stamp_spec.rb +0 -179
- data/spec/stroke_styles_spec.rb +0 -208
- data/spec/text_at_spec.rb +0 -142
- data/spec/text_box_spec.rb +0 -1042
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -543
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -91
- data/spec/view_spec.rb +0 -42
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
# transformation.rb: Implements rotate, translate, skew, scale and a generic
|
4
4
|
# transformation_matrix
|
5
5
|
#
|
@@ -48,7 +48,8 @@ module Prawn
|
|
48
48
|
if options[:origin].nil?
|
49
49
|
transformation_matrix(cos, sin, -sin, cos, 0, 0, &block)
|
50
50
|
else
|
51
|
-
|
51
|
+
raise Prawn::Errors::BlockRequired unless block
|
52
|
+
|
52
53
|
x = options[:origin][0] + bounds.absolute_left
|
53
54
|
y = options[:origin][1] + bounds.absolute_bottom
|
54
55
|
x_prime = x * cos - y * sin
|
@@ -59,8 +60,8 @@ module Prawn
|
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
62
|
-
# Translate the user space. If a block is not provided, then you must
|
63
|
-
# and restore the graphics state yourself.
|
63
|
+
# Translate the user space. If a block is not provided, then you must
|
64
|
+
# save and restore the graphics state yourself.
|
64
65
|
#
|
65
66
|
# Example without a block: move the text up and over 10
|
66
67
|
#
|
@@ -117,7 +118,8 @@ module Prawn
|
|
117
118
|
if options[:origin].nil?
|
118
119
|
transformation_matrix(factor, 0, 0, factor, 0, 0, &block)
|
119
120
|
else
|
120
|
-
|
121
|
+
raise Prawn::Errors::BlockRequired unless block
|
122
|
+
|
121
123
|
x = options[:origin][0] + bounds.absolute_left
|
122
124
|
y = options[:origin][1] + bounds.absolute_bottom
|
123
125
|
x_prime = factor * x
|
@@ -142,12 +144,16 @@ module Prawn
|
|
142
144
|
# Transform the user space (see notes for rotate regarding graphics state)
|
143
145
|
# Generally, one would use the rotate, scale, translate, and skew
|
144
146
|
# convenience methods instead of calling transformation_matrix directly
|
145
|
-
def transformation_matrix(
|
146
|
-
|
147
|
+
def transformation_matrix(*matrix)
|
148
|
+
if matrix.length != 6
|
149
|
+
raise ArgumentError,
|
150
|
+
'Transformation matrix must have exacty 6 elements'
|
151
|
+
end
|
147
152
|
save_graphics_state if block_given?
|
148
153
|
|
149
|
-
add_to_transformation_stack(
|
154
|
+
add_to_transformation_stack(*matrix)
|
150
155
|
|
156
|
+
values = PDF::Core.real_params(matrix)
|
151
157
|
renderer.add_content "#{values} cm"
|
152
158
|
if block_given?
|
153
159
|
yield
|
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
# transparency.rb : Implements transparency
|
4
4
|
#
|
5
5
|
# Copyright October 2009, Daniel Nelson. All Rights Reserved.
|
@@ -51,14 +51,16 @@ module Prawn
|
|
51
51
|
# pdf.fill_and_stroke_circle([x, y], 25)
|
52
52
|
# end
|
53
53
|
#
|
54
|
-
def transparent(opacity, stroke_opacity = opacity
|
54
|
+
def transparent(opacity, stroke_opacity = opacity)
|
55
55
|
renderer.min_version(1.4)
|
56
56
|
|
57
|
-
opacity
|
57
|
+
opacity = [[opacity, 0.0].max, 1.0].min
|
58
58
|
stroke_opacity = [[stroke_opacity, 0.0].max, 1.0].min
|
59
59
|
|
60
60
|
save_graphics_state
|
61
|
-
renderer.add_content
|
61
|
+
renderer.add_content(
|
62
|
+
"/#{opacity_dictionary_name(opacity, stroke_opacity)} gs"
|
63
|
+
)
|
62
64
|
yield
|
63
65
|
restore_graphics_state
|
64
66
|
end
|
@@ -77,21 +79,23 @@ module Prawn
|
|
77
79
|
key = "#{opacity}_#{stroke_opacity}"
|
78
80
|
|
79
81
|
if opacity_dictionary_registry[key]
|
80
|
-
dictionary =
|
81
|
-
dictionary_name =
|
82
|
+
dictionary = opacity_dictionary_registry[key][:obj]
|
83
|
+
dictionary_name = opacity_dictionary_registry[key][:name]
|
82
84
|
else
|
83
85
|
dictionary = ref!(
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
86
|
+
Type: :ExtGState,
|
87
|
+
CA: stroke_opacity,
|
88
|
+
ca: opacity
|
87
89
|
)
|
88
90
|
|
89
91
|
dictionary_name = "Tr#{next_opacity_dictionary_id}"
|
90
|
-
opacity_dictionary_registry[key] = {
|
91
|
-
|
92
|
+
opacity_dictionary_registry[key] = {
|
93
|
+
name: dictionary_name,
|
94
|
+
obj: dictionary
|
95
|
+
}
|
92
96
|
end
|
93
97
|
|
94
|
-
page.ext_gstates
|
98
|
+
page.ext_gstates[dictionary_name] = dictionary
|
95
99
|
dictionary_name
|
96
100
|
end
|
97
101
|
end
|
data/lib/prawn/grid.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# grid.rb: Provides a basic grid layout system for Prawn
|
4
4
|
#
|
@@ -33,21 +33,21 @@ module Prawn
|
|
33
33
|
#
|
34
34
|
def grid(*args)
|
35
35
|
@boxes ||= {}
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
36
|
+
@boxes[args] ||=
|
37
|
+
begin
|
38
|
+
if args.empty?
|
39
|
+
@grid
|
40
|
+
else
|
41
|
+
g1, g2 = args
|
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
|
49
|
+
end
|
47
50
|
end
|
48
|
-
end
|
49
|
-
|
50
|
-
@boxes[args]
|
51
51
|
end
|
52
52
|
|
53
53
|
# A Grid represents the entire grid system of a Page and calculates
|
@@ -56,14 +56,15 @@ 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
|
-
valid_options = [
|
61
|
+
valid_options = %i[columns rows gutter row_gutter column_gutter]
|
61
62
|
Prawn.verify_options valid_options, options
|
62
63
|
|
63
64
|
@pdf = pdf
|
64
65
|
@columns = options[:columns]
|
65
66
|
@rows = options[:rows]
|
66
|
-
|
67
|
+
apply_gutter(options)
|
67
68
|
end
|
68
69
|
|
69
70
|
# Calculates the base width of boxes.
|
@@ -77,10 +78,10 @@ module Prawn
|
|
77
78
|
end
|
78
79
|
|
79
80
|
# Diagnostic tool to show all of the grids. Defaults to gray.
|
80
|
-
def show_all(color =
|
81
|
-
|
82
|
-
|
83
|
-
pdf.grid(
|
81
|
+
def show_all(color = 'CCCCCC')
|
82
|
+
rows.times do |row|
|
83
|
+
columns.times do |column|
|
84
|
+
pdf.grid(row, column).show(color)
|
84
85
|
end
|
85
86
|
end
|
86
87
|
end
|
@@ -91,12 +92,13 @@ module Prawn
|
|
91
92
|
(total.to_f - (gutter * (num - 1).to_f)) / num.to_f
|
92
93
|
end
|
93
94
|
|
94
|
-
def
|
95
|
+
def apply_gutter(options)
|
95
96
|
if options.key?(:gutter)
|
96
97
|
@gutter = options[:gutter].to_f
|
97
|
-
@row_gutter
|
98
|
+
@row_gutter = @gutter
|
99
|
+
@column_gutter = @gutter
|
98
100
|
else
|
99
|
-
@row_gutter
|
101
|
+
@row_gutter = options[:row_gutter].to_f
|
100
102
|
@column_gutter = options[:column_gutter].to_f
|
101
103
|
@gutter = 0
|
102
104
|
end
|
@@ -111,17 +113,17 @@ module Prawn
|
|
111
113
|
class GridBox
|
112
114
|
attr_reader :pdf
|
113
115
|
|
114
|
-
def initialize(pdf,
|
116
|
+
def initialize(pdf, rows, columns)
|
115
117
|
@pdf = pdf
|
116
|
-
@
|
117
|
-
@
|
118
|
+
@rows = rows
|
119
|
+
@columns = columns
|
118
120
|
end
|
119
121
|
|
120
122
|
# Mostly diagnostic method that outputs the name of a box as
|
121
123
|
# col_num, row_num
|
122
124
|
#
|
123
125
|
def name
|
124
|
-
"#{@
|
126
|
+
"#{@rows},#{@columns}"
|
125
127
|
end
|
126
128
|
|
127
129
|
# :nodoc
|
@@ -146,7 +148,7 @@ module Prawn
|
|
146
148
|
|
147
149
|
# x-coordinate of left side
|
148
150
|
def left
|
149
|
-
@left ||= (width + grid.column_gutter) * @
|
151
|
+
@left ||= (width + grid.column_gutter) * @columns.to_f
|
150
152
|
end
|
151
153
|
|
152
154
|
# x-coordinate of right side
|
@@ -156,7 +158,7 @@ module Prawn
|
|
156
158
|
|
157
159
|
# y-coordinate of the top
|
158
160
|
def top
|
159
|
-
@top ||= total_height - ((height + grid.row_gutter) * @
|
161
|
+
@top ||= total_height - ((height + grid.row_gutter) * @rows.to_f)
|
160
162
|
end
|
161
163
|
|
162
164
|
# y-coordinate of the bottom
|
@@ -186,16 +188,16 @@ module Prawn
|
|
186
188
|
|
187
189
|
# Creates a standard bounding box based on the grid box.
|
188
190
|
def bounding_box(&blk)
|
189
|
-
pdf.bounding_box(top_left, :
|
191
|
+
pdf.bounding_box(top_left, width: width, height: height, &blk)
|
190
192
|
end
|
191
193
|
|
192
194
|
# Diagnostic method
|
193
|
-
def show(grid_color =
|
194
|
-
|
195
|
+
def show(grid_color = 'CCCCCC')
|
196
|
+
bounding_box do
|
195
197
|
original_stroke_color = pdf.stroke_color
|
196
198
|
|
197
199
|
pdf.stroke_color = grid_color
|
198
|
-
pdf.text
|
200
|
+
pdf.text name
|
199
201
|
pdf.stroke_bounds
|
200
202
|
|
201
203
|
pdf.stroke_color = original_stroke_color
|
@@ -212,18 +214,20 @@ module Prawn
|
|
212
214
|
# A MultiBox is specified by 2 Boxes and spans the areas between.
|
213
215
|
#
|
214
216
|
# @group Experimental API
|
215
|
-
class MultiBox
|
216
|
-
def initialize(pdf,
|
217
|
+
class MultiBox
|
218
|
+
def initialize(pdf, box1, box2)
|
217
219
|
@pdf = pdf
|
218
|
-
@
|
220
|
+
@boxes = [box1, box2]
|
219
221
|
end
|
220
222
|
|
223
|
+
attr_reader :pdf
|
224
|
+
|
221
225
|
def name
|
222
|
-
@
|
226
|
+
@boxes.map(&:name).join(':')
|
223
227
|
end
|
224
228
|
|
225
229
|
def total_height
|
226
|
-
@
|
230
|
+
@boxes[0].total_height
|
227
231
|
end
|
228
232
|
|
229
233
|
def width
|
@@ -235,7 +239,7 @@ module Prawn
|
|
235
239
|
end
|
236
240
|
|
237
241
|
def gutter
|
238
|
-
@
|
242
|
+
@boxes[0].gutter
|
239
243
|
end
|
240
244
|
|
241
245
|
def left
|
@@ -254,33 +258,65 @@ module Prawn
|
|
254
258
|
bottom_box.bottom
|
255
259
|
end
|
256
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
|
+
|
257
293
|
private
|
258
294
|
|
259
295
|
def left_box
|
260
|
-
@left_box ||= @
|
296
|
+
@left_box ||= @boxes.min_by(&:left)
|
261
297
|
end
|
262
298
|
|
263
299
|
def right_box
|
264
|
-
@right_box ||= @
|
300
|
+
@right_box ||= @boxes.max_by(&:right)
|
265
301
|
end
|
266
302
|
|
267
303
|
def top_box
|
268
|
-
@top_box ||= @
|
304
|
+
@top_box ||= @boxes.max_by(&:top)
|
269
305
|
end
|
270
306
|
|
271
307
|
def bottom_box
|
272
|
-
@bottom_box ||= @
|
308
|
+
@bottom_box ||= @boxes.min_by(&:bottom)
|
273
309
|
end
|
274
310
|
end
|
275
311
|
|
276
312
|
private
|
277
313
|
|
278
|
-
def single_box(
|
279
|
-
GridBox.new(self,
|
314
|
+
def single_box(rows, columns)
|
315
|
+
GridBox.new(self, rows, columns)
|
280
316
|
end
|
281
317
|
|
282
|
-
def multi_box(
|
283
|
-
MultiBox.new(self,
|
318
|
+
def multi_box(box1, box2)
|
319
|
+
MultiBox.new(self, box1, box2)
|
284
320
|
end
|
285
321
|
end
|
286
322
|
end
|
data/lib/prawn/image_handler.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# ImageHandler provides a way to register image processors with Prawn
|
4
4
|
#
|
@@ -29,16 +29,16 @@ module Prawn
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def unregister(handler)
|
32
|
-
@handlers.reject!{ |h| h == handler }
|
32
|
+
@handlers.reject! { |h| h == handler }
|
33
33
|
end
|
34
34
|
|
35
35
|
def find(image_blob)
|
36
|
-
handler = @handlers.find{ |h| h.can_render? image_blob }
|
36
|
+
handler = @handlers.find { |h| h.can_render? image_blob }
|
37
37
|
|
38
38
|
return handler if handler
|
39
39
|
|
40
|
-
|
41
|
-
|
40
|
+
raise Prawn::Errors::UnsupportedImageType,
|
41
|
+
'image file is an unrecognised format'
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
data/lib/prawn/images.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
2
5
|
# images.rb : Implements PDF image embedding
|
3
6
|
#
|
4
7
|
# Copyright April 2008, James Healy, Gregory Brown. All Rights Reserved.
|
@@ -17,16 +20,19 @@ module Prawn
|
|
17
20
|
# images with alpha channels can be processor and memory intensive.)
|
18
21
|
#
|
19
22
|
# Arguments:
|
20
|
-
# <tt>file</tt>:: path to file or an object that responds to #read and
|
23
|
+
# <tt>file</tt>:: path to file or an object that responds to #read and
|
24
|
+
# #rewind
|
21
25
|
#
|
22
26
|
# Options:
|
23
|
-
# <tt>:at</tt>:: an array [x,y] with the location of the top left corner of
|
27
|
+
# <tt>:at</tt>:: an array [x,y] with the location of the top left corner of
|
28
|
+
# the image.
|
24
29
|
# <tt>:position</tt>:: One of (:left, :center, :right) or an x-offset
|
25
|
-
# <tt>:vposition</tt>:: One of (:top, :center, :
|
30
|
+
# <tt>:vposition</tt>:: One of (:top, :center, :bottom) or an y-offset
|
26
31
|
# <tt>:height</tt>:: the height of the image [actual height of the image]
|
27
32
|
# <tt>:width</tt>:: the width of the image [actual width of the image]
|
28
33
|
# <tt>:scale</tt>:: scale the dimensions of the image proportionally
|
29
|
-
# <tt>:fit</tt>:: scale the dimensions of the image proportionally to fit
|
34
|
+
# <tt>:fit</tt>:: scale the dimensions of the image proportionally to fit
|
35
|
+
# inside [width,height]
|
30
36
|
#
|
31
37
|
# Prawn::Document.generate("image2.pdf", :page_layout => :landscape) do
|
32
38
|
# pigs = "#{Prawn::DATADIR}/images/pigs.jpg"
|
@@ -52,7 +58,7 @@ module Prawn
|
|
52
58
|
# require "open-uri"
|
53
59
|
#
|
54
60
|
# Prawn::Document.generate("remote_images.pdf") do
|
55
|
-
# image open("http://
|
61
|
+
# image open("http://prawnpdf.org/media/prawn_logo.png")
|
56
62
|
# end
|
57
63
|
#
|
58
64
|
# This method returns an image info object which can be used to check the
|
@@ -60,8 +66,10 @@ module Prawn
|
|
60
66
|
# (See also: Prawn::Images::PNG , Prawn::Images::JPG)
|
61
67
|
#
|
62
68
|
def image(file, options = {})
|
63
|
-
Prawn.verify_options
|
64
|
-
|
69
|
+
Prawn.verify_options(
|
70
|
+
%i[at position vposition height width scale fit],
|
71
|
+
options
|
72
|
+
)
|
65
73
|
|
66
74
|
pdf_obj, info = build_image_object(file)
|
67
75
|
embed_image(pdf_obj, info, options)
|
@@ -74,8 +82,7 @@ module Prawn
|
|
74
82
|
#
|
75
83
|
# @private
|
76
84
|
def build_image_object(file)
|
77
|
-
|
78
|
-
image_content = io.read
|
85
|
+
image_content = verify_and_read_image(file)
|
79
86
|
image_sha1 = Digest::SHA1.hexdigest(image_content)
|
80
87
|
|
81
88
|
# if this image has already been embedded, just reuse it
|
@@ -87,11 +94,13 @@ module Prawn
|
|
87
94
|
info = Prawn.image_handler.find(image_content).new(image_content)
|
88
95
|
|
89
96
|
# Bump PDF version if the image requires it
|
90
|
-
|
97
|
+
if info.respond_to?(:min_pdf_version)
|
98
|
+
renderer.min_version(info.min_pdf_version)
|
99
|
+
end
|
91
100
|
|
92
101
|
# Add the image to the PDF and register it in case we see it again.
|
93
102
|
image_obj = info.build_pdf_object(self)
|
94
|
-
image_registry[image_sha1] = { :
|
103
|
+
image_registry[image_sha1] = { obj: image_obj, info: info }
|
95
104
|
end
|
96
105
|
|
97
106
|
[image_obj, info]
|
@@ -117,15 +126,15 @@ module Prawn
|
|
117
126
|
# add a reference to the image object to the current page
|
118
127
|
# resource list and give it a label
|
119
128
|
label = "I#{next_image_id}"
|
120
|
-
state.page.xobjects
|
129
|
+
state.page.xobjects[label] = pdf_obj
|
121
130
|
|
122
|
-
cm_params = PDF::Core.real_params([
|
131
|
+
cm_params = PDF::Core.real_params([w, 0, 0, h, x, y - h])
|
123
132
|
renderer.add_content("\nq\n#{cm_params} cm\n/#{label} Do\nQ")
|
124
133
|
end
|
125
134
|
|
126
135
|
private
|
127
136
|
|
128
|
-
def
|
137
|
+
def verify_and_read_image(io_or_path)
|
129
138
|
# File or IO
|
130
139
|
if io_or_path.respond_to?(:rewind)
|
131
140
|
io = io_or_path
|
@@ -135,54 +144,56 @@ module Prawn
|
|
135
144
|
# read the file as binary so the size is calculated correctly
|
136
145
|
# guard binmode because some objects acting io-like don't implement it
|
137
146
|
io.binmode if io.respond_to?(:binmode)
|
138
|
-
return io
|
147
|
+
return io.read
|
139
148
|
end
|
140
149
|
# String or Pathname
|
141
150
|
io_or_path = Pathname.new(io_or_path)
|
142
|
-
|
143
|
-
|
144
|
-
|
151
|
+
raise ArgumentError, "#{io_or_path} not found" unless io_or_path.file?
|
152
|
+
|
153
|
+
io_or_path.binread
|
145
154
|
end
|
146
155
|
|
147
|
-
def image_position(
|
156
|
+
def image_position(width, height, options)
|
148
157
|
options[:position] ||= :left
|
149
158
|
|
150
|
-
y =
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
184
|
+
|
185
|
+
[x, y]
|
175
186
|
end
|
176
187
|
|
177
|
-
def determine_y_with_page_flow(
|
178
|
-
if overruns_page?(
|
188
|
+
def determine_y_with_page_flow(height)
|
189
|
+
if overruns_page?(height)
|
179
190
|
bounds.move_past_bottom
|
180
191
|
end
|
181
|
-
|
192
|
+
y
|
182
193
|
end
|
183
194
|
|
184
|
-
def overruns_page?(
|
185
|
-
(
|
195
|
+
def overruns_page?(height)
|
196
|
+
(y - height) < reference_bounds.absolute_bottom
|
186
197
|
end
|
187
198
|
|
188
199
|
def image_registry
|