prawn 1.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/.yardopts +1 -0
- data/GPLv2 +20 -21
- data/Gemfile +3 -9
- data/Rakefile +9 -40
- data/lib/prawn/document/bounding_box.rb +54 -40
- data/lib/prawn/document/column_box.rb +8 -10
- data/lib/prawn/document/internals.rb +39 -146
- data/lib/prawn/document/span.rb +23 -17
- data/lib/prawn/document.rb +217 -182
- data/lib/prawn/encoding.rb +69 -101
- data/lib/prawn/errors.rb +47 -43
- data/lib/prawn/font.rb +124 -104
- data/lib/prawn/font_metric_cache.rb +23 -21
- data/lib/prawn/fonts/afm.rb +292 -0
- data/lib/prawn/{font → fonts}/dfont.rb +5 -12
- data/lib/prawn/fonts/otf.rb +11 -0
- data/lib/prawn/fonts/ttc.rb +36 -0
- data/lib/prawn/{font → fonts}/ttf.rb +140 -88
- data/lib/prawn/graphics/blend_mode.rb +65 -0
- data/lib/prawn/graphics/cap_style.rb +5 -5
- data/lib/prawn/graphics/color.rb +46 -44
- data/lib/prawn/graphics/dash.rb +27 -11
- data/lib/prawn/graphics/join_style.rb +11 -6
- data/lib/prawn/graphics/patterns.rb +220 -78
- data/lib/prawn/graphics/transformation.rb +20 -12
- data/lib/prawn/graphics/transparency.rb +20 -18
- data/lib/prawn/graphics.rb +153 -115
- data/lib/prawn/grid.rb +93 -50
- data/lib/prawn/image_handler.rb +4 -4
- data/lib/prawn/images/image.rb +3 -2
- data/lib/prawn/images/jpg.rb +31 -24
- data/lib/prawn/images/png.rb +101 -68
- data/lib/prawn/images.rb +64 -56
- data/lib/prawn/measurement_extensions.rb +10 -9
- data/lib/prawn/measurements.rb +20 -23
- data/lib/prawn/outline.rb +96 -75
- data/lib/prawn/repeater.rb +16 -16
- data/lib/prawn/security/arcfour.rb +2 -2
- data/lib/prawn/security.rb +100 -85
- data/lib/prawn/soft_mask.rb +37 -38
- data/lib/prawn/stamp.rb +28 -13
- data/lib/prawn/text/box.rb +24 -29
- data/lib/prawn/text/formatted/arranger.rb +108 -63
- data/lib/prawn/text/formatted/box.rb +187 -124
- data/lib/prawn/text/formatted/fragment.rb +24 -20
- data/lib/prawn/text/formatted/line_wrap.rb +133 -73
- data/lib/prawn/text/formatted/parser.rb +147 -127
- data/lib/prawn/text/formatted/wrap.rb +48 -35
- data/lib/prawn/text/formatted.rb +5 -5
- data/lib/prawn/text.rb +103 -68
- data/lib/prawn/transformation_stack.rb +44 -0
- data/lib/prawn/utilities.rb +10 -22
- data/lib/prawn/version.rb +5 -0
- data/lib/prawn/view.rb +101 -0
- data/lib/prawn.rb +39 -54
- data/manual/basic_concepts/adding_pages.rb +6 -7
- data/manual/basic_concepts/basic_concepts.rb +34 -25
- data/manual/basic_concepts/creation.rb +10 -11
- data/manual/basic_concepts/cursor.rb +4 -5
- data/manual/basic_concepts/measurement.rb +8 -9
- data/manual/basic_concepts/origin.rb +5 -6
- data/manual/basic_concepts/other_cursor_helpers.rb +11 -12
- data/manual/basic_concepts/view.rb +48 -0
- data/manual/bounding_box/bounding_box.rb +30 -28
- data/manual/bounding_box/bounds.rb +12 -13
- 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 +18 -18
- data/manual/bounding_box/stretchy.rb +12 -14
- data/manual/contents.rb +28 -22
- data/manual/cover.rb +33 -32
- data/manual/document_and_page_options/background.rb +15 -13
- data/manual/document_and_page_options/document_and_page_options.rb +24 -22
- data/manual/document_and_page_options/metadata.rb +20 -18
- data/manual/document_and_page_options/page_margins.rb +18 -20
- data/manual/document_and_page_options/page_size.rb +13 -13
- data/manual/document_and_page_options/print_scaling.rb +18 -15
- data/manual/example_helper.rb +5 -4
- data/manual/graphics/blend_mode.rb +52 -0
- 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 +12 -11
- data/manual/graphics/gradients.rb +27 -21
- data/manual/graphics/graphics.rb +46 -40
- data/manual/graphics/helper.rb +19 -9
- data/manual/graphics/line_width.rb +8 -7
- data/manual/graphics/lines_and_curves.rb +8 -9
- data/manual/graphics/polygon.rb +6 -8
- data/manual/graphics/rectangle.rb +4 -5
- data/manual/graphics/rotate.rb +6 -9
- data/manual/graphics/scale.rb +14 -13
- data/manual/graphics/soft_masks.rb +4 -6
- data/manual/graphics/stroke_cap.rb +7 -8
- data/manual/graphics/stroke_dash.rb +15 -16
- data/manual/graphics/stroke_join.rb +6 -7
- data/manual/graphics/translate.rb +10 -10
- data/manual/graphics/transparency.rb +7 -9
- data/manual/how_to_read_this_manual.rb +8 -9
- 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 -27
- 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 +10 -11
- data/manual/layout/content.rb +9 -10
- data/manual/layout/layout.rb +17 -18
- 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 +22 -21
- data/manual/outline/sections_and_pages.rb +17 -18
- data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
- data/manual/repeatable_content/page_numbering.rb +17 -16
- data/manual/repeatable_content/repeatable_content.rb +27 -23
- data/manual/repeatable_content/repeater.rb +15 -16
- data/manual/repeatable_content/stamp.rb +14 -15
- data/manual/security/encryption.rb +8 -11
- data/manual/security/permissions.rb +20 -15
- data/manual/security/security.rb +18 -18
- data/manual/table.rb +16 -0
- data/manual/text/alignment.rb +16 -17
- data/manual/text/color.rb +12 -12
- data/manual/text/column_box.rb +9 -11
- 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 -23
- 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 +15 -10
- data/manual/text/positioned_text.rb +16 -17
- data/manual/text/registering_families.rb +27 -24
- data/manual/text/rendering_and_color.rb +9 -10
- data/manual/text/right_to_left_text.rb +30 -19
- data/manual/text/rotation.rb +33 -24
- data/manual/text/single_usage.rb +8 -9
- data/manual/text/text.rb +56 -54
- 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 +24 -17
- data/manual/text/utf8.rb +12 -13
- data/manual/text/win_ansi_charset.rb +28 -25
- data/prawn.gemspec +45 -50
- 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/prawn/image_handler_spec.rb +53 -0
- 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/prawn/transformation_stack_spec.rb +66 -0
- data/spec/prawn/view_spec.rb +63 -0
- data/spec/prawn_manual_spec.rb +35 -0
- data/spec/spec_helper.rb +19 -25
- data.tar.gz.sig +0 -0
- metadata +113 -276
- metadata.gz.sig +0 -0
- data/data/encodings/win_ansi.txt +0 -29
- 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/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/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/lib/prawn/document/graphics_state.rb +0 -73
- data/lib/prawn/font/afm.rb +0 -247
- data/lib/prawn/table/cell/image.rb +0 -69
- data/lib/prawn/table/cell/in_table.rb +0 -33
- data/lib/prawn/table/cell/span_dummy.rb +0 -93
- data/lib/prawn/table/cell/subtable.rb +0 -66
- data/lib/prawn/table/cell/text.rb +0 -154
- data/lib/prawn/table/cell.rb +0 -772
- data/lib/prawn/table/cells.rb +0 -255
- data/lib/prawn/table/column_width_calculator.rb +0 -182
- data/lib/prawn/table.rb +0 -644
- data/manual/table/basic_block.rb +0 -53
- data/manual/table/before_rendering_page.rb +0 -26
- data/manual/table/cell_border_lines.rb +0 -24
- data/manual/table/cell_borders_and_bg.rb +0 -31
- data/manual/table/cell_dimensions.rb +0 -30
- data/manual/table/cell_text.rb +0 -38
- data/manual/table/column_widths.rb +0 -30
- data/manual/table/content_and_subtables.rb +0 -39
- data/manual/table/creation.rb +0 -27
- data/manual/table/filtering.rb +0 -36
- data/manual/table/flow_and_header.rb +0 -17
- data/manual/table/image_cells.rb +0 -33
- data/manual/table/position.rb +0 -29
- data/manual/table/row_colors.rb +0 -20
- data/manual/table/span.rb +0 -30
- data/manual/table/style.rb +0 -22
- data/manual/table/table.rb +0 -52
- data/manual/table/width.rb +0 -27
- data/spec/acceptance/png.rb +0 -25
- data/spec/annotations_spec.rb +0 -74
- data/spec/bounding_box_spec.rb +0 -510
- data/spec/cell_spec.rb +0 -629
- data/spec/column_box_spec.rb +0 -65
- data/spec/destinations_spec.rb +0 -15
- data/spec/document_spec.rb +0 -730
- data/spec/extensions/mocha.rb +0 -46
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -449
- data/spec/formatted_text_arranger_spec.rb +0 -421
- data/spec/formatted_text_box_spec.rb +0 -639
- data/spec/formatted_text_fragment_spec.rb +0 -298
- data/spec/graphics_spec.rb +0 -669
- data/spec/grid_spec.rb +0 -96
- data/spec/image_handler_spec.rb +0 -54
- data/spec/images_spec.rb +0 -153
- data/spec/inline_formatted_text_parser_spec.rb +0 -564
- data/spec/jpg_spec.rb +0 -25
- data/spec/line_wrap_spec.rb +0 -344
- data/spec/measurement_units_spec.rb +0 -25
- data/spec/outline_spec.rb +0 -430
- data/spec/png_spec.rb +0 -237
- data/spec/reference_spec.rb +0 -25
- data/spec/repeater_spec.rb +0 -160
- data/spec/security_spec.rb +0 -158
- data/spec/soft_mask_spec.rb +0 -79
- data/spec/span_spec.rb +0 -44
- data/spec/stamp_spec.rb +0 -160
- data/spec/stroke_styles_spec.rb +0 -211
- data/spec/table/span_dummy_spec.rb +0 -17
- data/spec/table_spec.rb +0 -1527
- data/spec/text_at_spec.rb +0 -115
- data/spec/text_box_spec.rb +0 -1034
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -437
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -91
data/lib/prawn/images/png.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# encoding: ASCII-8BIT
|
2
2
|
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
3
5
|
# png.rb : Extracts the data from a PNG that is needed for embedding
|
4
6
|
#
|
5
7
|
# Based on some similar code in PDF::Writer by Austin Ziegler
|
@@ -9,8 +11,6 @@
|
|
9
11
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
10
12
|
|
11
13
|
require 'stringio'
|
12
|
-
require 'enumerator'
|
13
|
-
|
14
14
|
module Prawn
|
15
15
|
module Images
|
16
16
|
# A convenience class that wraps the logic for extracting the parts
|
@@ -26,7 +26,7 @@ module Prawn
|
|
26
26
|
attr_accessor :scaled_width, :scaled_height
|
27
27
|
|
28
28
|
def self.can_render?(image_blob)
|
29
|
-
image_blob[0, 8].unpack(
|
29
|
+
image_blob[0, 8].unpack('C*') == [137, 80, 78, 71, 13, 10, 26, 10]
|
30
30
|
end
|
31
31
|
|
32
32
|
# Process a new PNG image
|
@@ -34,30 +34,31 @@ 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
|
-
data.read(8)
|
40
|
+
data.read(8) # Skip the default header
|
40
41
|
|
41
|
-
@palette
|
42
|
-
@img_data =
|
42
|
+
@palette = +''
|
43
|
+
@img_data = +''
|
43
44
|
@transparency = {}
|
44
45
|
|
45
46
|
loop do
|
46
|
-
chunk_size
|
47
|
-
section
|
47
|
+
chunk_size = data.read(4).unpack1('N')
|
48
|
+
section = data.read(4)
|
48
49
|
case section
|
49
50
|
when 'IHDR'
|
50
51
|
# we can grab other interesting values from here (like width,
|
51
52
|
# height, etc)
|
52
|
-
values = data.read(chunk_size).unpack(
|
53
|
+
values = data.read(chunk_size).unpack('NNCCCCC')
|
53
54
|
|
54
|
-
@width
|
55
|
-
@height
|
56
|
-
@bits
|
57
|
-
@color_type
|
55
|
+
@width = values[0]
|
56
|
+
@height = values[1]
|
57
|
+
@bits = values[2]
|
58
|
+
@color_type = values[3]
|
58
59
|
@compression_method = values[4]
|
59
|
-
@filter_method
|
60
|
-
@interlace_method
|
60
|
+
@filter_method = values[5]
|
61
|
+
@interlace_method = values[6]
|
61
62
|
when 'PLTE'
|
62
63
|
@palette << data.read(chunk_size)
|
63
64
|
when 'IDAT'
|
@@ -68,21 +69,15 @@ module Prawn
|
|
68
69
|
@transparency = {}
|
69
70
|
case @color_type
|
70
71
|
when 3
|
71
|
-
|
72
|
-
# the palette index in the PLTE ("palette") chunk up until the
|
73
|
-
# last non-opaque entry. Set up an array, stretching over all
|
74
|
-
# palette entries which will be 0 (opaque) or 1 (transparent).
|
75
|
-
@transparency[:indexed] = data.read(chunk_size).unpack("C*")
|
76
|
-
short = 255 - @transparency[:indexed].size
|
77
|
-
@transparency[:indexed] += ([255] * short) if short > 0
|
72
|
+
@transparency[:palette] = data.read(chunk_size).unpack('C*')
|
78
73
|
when 0
|
79
74
|
# Greyscale. Corresponding to entries in the PLTE chunk.
|
80
75
|
# Grey is two bytes, range 0 .. (2 ^ bit-depth) - 1
|
81
|
-
grayval = data.read(chunk_size).
|
76
|
+
grayval = data.read(chunk_size).unpack1('n')
|
82
77
|
@transparency[:grayscale] = grayval
|
83
78
|
when 2
|
84
79
|
# True colour with proper alpha channel.
|
85
|
-
@transparency[:rgb] = data.read(chunk_size).unpack(
|
80
|
+
@transparency[:rgb] = data.read(chunk_size).unpack('nnn')
|
86
81
|
end
|
87
82
|
when 'IEND'
|
88
83
|
# we've got everything we need, exit the loop
|
@@ -92,7 +87,7 @@ module Prawn
|
|
92
87
|
data.seek(data.pos + chunk_size)
|
93
88
|
end
|
94
89
|
|
95
|
-
data.read(4)
|
90
|
+
data.read(4) # Skip the CRC
|
96
91
|
end
|
97
92
|
|
98
93
|
@img_data = Zlib::Inflate.inflate(@img_data)
|
@@ -101,11 +96,11 @@ module Prawn
|
|
101
96
|
# number of color components to each pixel
|
102
97
|
#
|
103
98
|
def colors
|
104
|
-
case
|
99
|
+
case color_type
|
105
100
|
when 0, 3, 4
|
106
|
-
|
101
|
+
1
|
107
102
|
when 2, 6
|
108
|
-
|
103
|
+
3
|
109
104
|
end
|
110
105
|
end
|
111
106
|
|
@@ -113,11 +108,20 @@ module Prawn
|
|
113
108
|
# where it's required.
|
114
109
|
#
|
115
110
|
def split_alpha_channel!
|
116
|
-
|
111
|
+
if alpha_channel?
|
112
|
+
if color_type == 3
|
113
|
+
generate_alpha_channel
|
114
|
+
else
|
115
|
+
split_image_data
|
116
|
+
end
|
117
|
+
end
|
117
118
|
end
|
118
119
|
|
119
120
|
def alpha_channel?
|
120
|
-
|
121
|
+
return true if color_type == 4 || color_type == 6
|
122
|
+
return @transparency.any? if color_type == 3
|
123
|
+
|
124
|
+
false
|
121
125
|
end
|
122
126
|
|
123
127
|
# Build a PDF object representing this image in +document+, and return
|
@@ -155,22 +159,22 @@ module Prawn
|
|
155
159
|
|
156
160
|
# build the image dict
|
157
161
|
obj = document.ref!(
|
158
|
-
:
|
159
|
-
:
|
160
|
-
:
|
161
|
-
:
|
162
|
-
:
|
162
|
+
Type: :XObject,
|
163
|
+
Subtype: :Image,
|
164
|
+
Height: height,
|
165
|
+
Width: width,
|
166
|
+
BitsPerComponent: bits
|
163
167
|
)
|
164
168
|
|
165
169
|
# append the actual image data to the object as a stream
|
166
170
|
obj << img_data
|
167
171
|
|
168
172
|
obj.stream.filters << {
|
169
|
-
:
|
170
|
-
:
|
171
|
-
:
|
172
|
-
:
|
173
|
-
:
|
173
|
+
FlateDecode: {
|
174
|
+
Predictor: 15,
|
175
|
+
Colors: colors,
|
176
|
+
BitsPerComponent: bits,
|
177
|
+
Columns: width
|
174
178
|
}
|
175
179
|
}
|
176
180
|
|
@@ -183,10 +187,12 @@ module Prawn
|
|
183
187
|
palette_obj << palette
|
184
188
|
|
185
189
|
# build the color space array for the image
|
186
|
-
obj.data[:ColorSpace] = [
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
+
obj.data[:ColorSpace] = [
|
191
|
+
:Indexed,
|
192
|
+
:DeviceRGB,
|
193
|
+
(palette.size / 3) - 1,
|
194
|
+
palette_obj
|
195
|
+
]
|
190
196
|
end
|
191
197
|
|
192
198
|
# *************************************
|
@@ -207,35 +213,31 @@ module Prawn
|
|
207
213
|
# - An array with N elements, where N is two times the number of color
|
208
214
|
# components.
|
209
215
|
rgb = transparency[:rgb]
|
210
|
-
obj.data[:Mask] = rgb.
|
211
|
-
elsif transparency[:indexed]
|
212
|
-
# TODO: broken. I was attempting to us Color Key Masking, but I think
|
213
|
-
# we need to construct an SMask i think. Maybe do it inside
|
214
|
-
# the PNG class, and store it in alpha_channel
|
215
|
-
#obj.data[:Mask] = transparency[:indexed]
|
216
|
+
obj.data[:Mask] = rgb.map { |x| [x, x] }.flatten
|
216
217
|
end
|
217
218
|
|
218
|
-
# For PNG color types 4 and 6, the transparency data is stored as
|
219
|
-
# channel mixed in with the main image data. The PNG class
|
220
|
-
# it out for us and makes it available via the alpha_channel
|
219
|
+
# For PNG color types 4 and 6, the transparency data is stored as
|
220
|
+
# a alpha channel mixed in with the main image data. The PNG class
|
221
|
+
# seperates it out for us and makes it available via the alpha_channel
|
222
|
+
# attribute
|
221
223
|
if alpha_channel?
|
222
224
|
smask_obj = document.ref!(
|
223
|
-
:
|
224
|
-
:
|
225
|
-
:
|
226
|
-
:
|
227
|
-
:
|
228
|
-
:
|
229
|
-
:
|
225
|
+
Type: :XObject,
|
226
|
+
Subtype: :Image,
|
227
|
+
Height: height,
|
228
|
+
Width: width,
|
229
|
+
BitsPerComponent: bits,
|
230
|
+
ColorSpace: :DeviceGray,
|
231
|
+
Decode: [0, 1]
|
230
232
|
)
|
231
233
|
smask_obj.stream << alpha_channel
|
232
234
|
|
233
235
|
smask_obj.stream.filters << {
|
234
|
-
:
|
235
|
-
:
|
236
|
-
:
|
237
|
-
:
|
238
|
-
:
|
236
|
+
FlateDecode: {
|
237
|
+
Predictor: 15,
|
238
|
+
Colors: 1,
|
239
|
+
BitsPerComponent: bits,
|
240
|
+
Columns: width
|
239
241
|
}
|
240
242
|
}
|
241
243
|
obj.data[:SMask] = smask_obj
|
@@ -263,9 +265,9 @@ module Prawn
|
|
263
265
|
alpha_bytes = bits / 8
|
264
266
|
color_bytes = colors * bits / 8
|
265
267
|
|
266
|
-
scanline_length
|
268
|
+
scanline_length = (color_bytes + alpha_bytes) * width + 1
|
267
269
|
scanlines = @img_data.bytesize / scanline_length
|
268
|
-
pixels =
|
270
|
+
pixels = width * height
|
269
271
|
|
270
272
|
data = StringIO.new(@img_data)
|
271
273
|
data.binmode
|
@@ -286,7 +288,7 @@ module Prawn
|
|
286
288
|
color.putc filter
|
287
289
|
alpha.putc filter
|
288
290
|
|
289
|
-
|
291
|
+
width.times do
|
290
292
|
color.write data.read(color_bytes)
|
291
293
|
alpha.write data.read(alpha_bytes)
|
292
294
|
end
|
@@ -294,6 +296,37 @@ module Prawn
|
|
294
296
|
|
295
297
|
@img_data = color_data
|
296
298
|
end
|
299
|
+
|
300
|
+
def generate_alpha_channel
|
301
|
+
alpha_palette = Hash.new(0xff)
|
302
|
+
0.upto(palette.bytesize / 3) do |n|
|
303
|
+
alpha_palette[n] = @transparency[:palette][n] || 0xff
|
304
|
+
end
|
305
|
+
|
306
|
+
scanline_length = width + 1
|
307
|
+
scanlines = @img_data.bytesize / scanline_length
|
308
|
+
pixels = width * height
|
309
|
+
|
310
|
+
data = StringIO.new(@img_data)
|
311
|
+
data.binmode
|
312
|
+
|
313
|
+
@alpha_channel = [0x00].pack('C') * (pixels + scanlines)
|
314
|
+
alpha = StringIO.new(@alpha_channel)
|
315
|
+
alpha.binmode
|
316
|
+
|
317
|
+
scanlines.times do |line|
|
318
|
+
data.seek(line * scanline_length)
|
319
|
+
|
320
|
+
filter = data.getbyte
|
321
|
+
|
322
|
+
alpha.putc filter
|
323
|
+
|
324
|
+
width.times do
|
325
|
+
color = data.read(1).unpack1('C')
|
326
|
+
alpha.putc alpha_palette[color]
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
297
330
|
end
|
298
331
|
end
|
299
332
|
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.
|
@@ -9,7 +12,6 @@ require 'digest/sha1'
|
|
9
12
|
require 'pathname'
|
10
13
|
|
11
14
|
module Prawn
|
12
|
-
|
13
15
|
module Images
|
14
16
|
# @group Stable API
|
15
17
|
|
@@ -18,16 +20,19 @@ module Prawn
|
|
18
20
|
# images with alpha channels can be processor and memory intensive.)
|
19
21
|
#
|
20
22
|
# Arguments:
|
21
|
-
# <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
|
22
25
|
#
|
23
26
|
# Options:
|
24
|
-
# <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.
|
25
29
|
# <tt>:position</tt>:: One of (:left, :center, :right) or an x-offset
|
26
|
-
# <tt>:vposition</tt>:: One of (:top, :center, :
|
30
|
+
# <tt>:vposition</tt>:: One of (:top, :center, :bottom) or an y-offset
|
27
31
|
# <tt>:height</tt>:: the height of the image [actual height of the image]
|
28
32
|
# <tt>:width</tt>:: the width of the image [actual width of the image]
|
29
33
|
# <tt>:scale</tt>:: scale the dimensions of the image proportionally
|
30
|
-
# <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]
|
31
36
|
#
|
32
37
|
# Prawn::Document.generate("image2.pdf", :page_layout => :landscape) do
|
33
38
|
# pigs = "#{Prawn::DATADIR}/images/pigs.jpg"
|
@@ -53,16 +58,18 @@ module Prawn
|
|
53
58
|
# require "open-uri"
|
54
59
|
#
|
55
60
|
# Prawn::Document.generate("remote_images.pdf") do
|
56
|
-
# image open("http://
|
61
|
+
# image open("http://prawnpdf.org/media/prawn_logo.png")
|
57
62
|
# end
|
58
63
|
#
|
59
64
|
# This method returns an image info object which can be used to check the
|
60
65
|
# dimensions of an image object if needed.
|
61
66
|
# (See also: Prawn::Images::PNG , Prawn::Images::JPG)
|
62
67
|
#
|
63
|
-
def image(file, options={})
|
64
|
-
Prawn.verify_options
|
65
|
-
|
68
|
+
def image(file, options = {})
|
69
|
+
Prawn.verify_options(
|
70
|
+
%i[at position vposition height width scale fit],
|
71
|
+
options
|
72
|
+
)
|
66
73
|
|
67
74
|
pdf_obj, info = build_image_object(file)
|
68
75
|
embed_image(pdf_obj, info, options)
|
@@ -70,14 +77,12 @@ module Prawn
|
|
70
77
|
info
|
71
78
|
end
|
72
79
|
|
73
|
-
|
74
80
|
# Builds an info object (Prawn::Images::*) and a PDF reference representing
|
75
81
|
# the given image. Return a pair: [pdf_obj, info].
|
76
82
|
#
|
77
83
|
# @private
|
78
84
|
def build_image_object(file)
|
79
|
-
|
80
|
-
image_content = io.read
|
85
|
+
image_content = verify_and_read_image(file)
|
81
86
|
image_sha1 = Digest::SHA1.hexdigest(image_content)
|
82
87
|
|
83
88
|
# if this image has already been embedded, just reuse it
|
@@ -89,11 +94,13 @@ module Prawn
|
|
89
94
|
info = Prawn.image_handler.find(image_content).new(image_content)
|
90
95
|
|
91
96
|
# Bump PDF version if the image requires it
|
92
|
-
|
97
|
+
if info.respond_to?(:min_pdf_version)
|
98
|
+
renderer.min_version(info.min_pdf_version)
|
99
|
+
end
|
93
100
|
|
94
101
|
# Add the image to the PDF and register it in case we see it again.
|
95
102
|
image_obj = info.build_pdf_object(self)
|
96
|
-
image_registry[image_sha1] = {:
|
103
|
+
image_registry[image_sha1] = { obj: image_obj, info: info }
|
97
104
|
end
|
98
105
|
|
99
106
|
[image_obj, info]
|
@@ -107,28 +114,27 @@ module Prawn
|
|
107
114
|
# @private
|
108
115
|
def embed_image(pdf_obj, info, options)
|
109
116
|
# find where the image will be placed and how big it will be
|
110
|
-
w,h = info.calc_image_dimensions(options)
|
117
|
+
w, h = info.calc_image_dimensions(options)
|
111
118
|
|
112
119
|
if options[:at]
|
113
|
-
x,y = map_to_absolute(options[:at])
|
120
|
+
x, y = map_to_absolute(options[:at])
|
114
121
|
else
|
115
|
-
x,y = image_position(w,h,options)
|
122
|
+
x, y = image_position(w, h, options)
|
116
123
|
move_text_position h
|
117
124
|
end
|
118
125
|
|
119
126
|
# add a reference to the image object to the current page
|
120
127
|
# resource list and give it a label
|
121
128
|
label = "I#{next_image_id}"
|
122
|
-
state.page.xobjects
|
129
|
+
state.page.xobjects[label] = pdf_obj
|
123
130
|
|
124
|
-
|
125
|
-
|
126
|
-
add_content instruct % [ w, h, x, y - h, label ]
|
131
|
+
cm_params = PDF::Core.real_params([w, 0, 0, h, x, y - h])
|
132
|
+
renderer.add_content("\nq\n#{cm_params} cm\n/#{label} Do\nQ")
|
127
133
|
end
|
128
134
|
|
129
135
|
private
|
130
136
|
|
131
|
-
def
|
137
|
+
def verify_and_read_image(io_or_path)
|
132
138
|
# File or IO
|
133
139
|
if io_or_path.respond_to?(:rewind)
|
134
140
|
io = io_or_path
|
@@ -138,54 +144,56 @@ module Prawn
|
|
138
144
|
# read the file as binary so the size is calculated correctly
|
139
145
|
# guard binmode because some objects acting io-like don't implement it
|
140
146
|
io.binmode if io.respond_to?(:binmode)
|
141
|
-
return io
|
147
|
+
return io.read
|
142
148
|
end
|
143
149
|
# String or Pathname
|
144
150
|
io_or_path = Pathname.new(io_or_path)
|
145
151
|
raise ArgumentError, "#{io_or_path} not found" unless io_or_path.file?
|
146
|
-
|
147
|
-
|
152
|
+
|
153
|
+
io_or_path.binread
|
148
154
|
end
|
149
155
|
|
150
|
-
def image_position(
|
156
|
+
def image_position(width, height, options)
|
151
157
|
options[:position] ||= :left
|
152
158
|
|
153
|
-
y =
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
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]
|
178
186
|
end
|
179
187
|
|
180
|
-
def determine_y_with_page_flow(
|
181
|
-
if overruns_page?(
|
188
|
+
def determine_y_with_page_flow(height)
|
189
|
+
if overruns_page?(height)
|
182
190
|
bounds.move_past_bottom
|
183
191
|
end
|
184
|
-
|
192
|
+
y
|
185
193
|
end
|
186
194
|
|
187
|
-
def overruns_page?(
|
188
|
-
(
|
195
|
+
def overruns_page?(height)
|
196
|
+
(y - height) < reference_bounds.absolute_bottom
|
189
197
|
end
|
190
198
|
|
191
199
|
def image_registry
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# measurement_extensions.rb: Core extensions for Prawn::Measurements
|
3
4
|
#
|
4
5
|
# Copyright December 2008, Florian Witteler. All Rights Reserved.
|
@@ -17,34 +18,34 @@ class Numeric
|
|
17
18
|
# @group Experimental API
|
18
19
|
|
19
20
|
def mm
|
20
|
-
|
21
|
+
mm2pt(self)
|
21
22
|
end
|
22
23
|
|
23
24
|
def cm
|
24
|
-
|
25
|
+
cm2pt(self)
|
25
26
|
end
|
26
27
|
|
27
28
|
def dm
|
28
|
-
|
29
|
+
dm2pt(self)
|
29
30
|
end
|
30
31
|
|
31
32
|
def m
|
32
|
-
|
33
|
+
m2pt(self)
|
33
34
|
end
|
34
35
|
|
35
36
|
def in
|
36
|
-
|
37
|
+
in2pt(self)
|
37
38
|
end
|
38
39
|
|
39
40
|
def yd
|
40
|
-
|
41
|
+
yd2pt(self)
|
41
42
|
end
|
42
43
|
|
43
44
|
def ft
|
44
|
-
|
45
|
+
ft2pt(self)
|
45
46
|
end
|
46
47
|
|
47
48
|
def pt
|
48
|
-
|
49
|
+
pt2pt(self)
|
49
50
|
end
|
50
51
|
end
|
data/lib/prawn/measurements.rb
CHANGED
@@ -1,77 +1,74 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# measurements.rb: Conversions from other measurements to PDF points
|
3
4
|
#
|
4
5
|
# Copyright December 2008, Florian Witteler. All Rights Reserved.
|
5
6
|
#
|
7
|
+
|
8
|
+
# rubocop: disable Naming/MethodParameterName
|
6
9
|
module Prawn
|
7
10
|
# @group Stable API
|
8
11
|
|
9
12
|
module Measurements
|
10
|
-
|
11
|
-
# ============================================================================
|
12
|
-
#metric conversions
|
13
|
+
# metric conversions
|
13
14
|
def cm2mm(cm)
|
14
|
-
|
15
|
+
cm * 10
|
15
16
|
end
|
16
17
|
|
17
18
|
def dm2mm(dm)
|
18
|
-
|
19
|
+
dm * 100
|
19
20
|
end
|
20
21
|
|
21
22
|
def m2mm(m)
|
22
|
-
|
23
|
+
m * 1000
|
23
24
|
end
|
24
25
|
|
25
|
-
# ============================================================================
|
26
26
|
# imperial conversions
|
27
27
|
# from http://en.wikipedia.org/wiki/Imperial_units
|
28
|
-
|
29
28
|
def ft2in(ft)
|
30
|
-
|
29
|
+
ft * 12
|
31
30
|
end
|
32
31
|
|
33
32
|
def yd2in(yd)
|
34
|
-
|
33
|
+
yd * 36
|
35
34
|
end
|
36
35
|
|
37
|
-
|
38
|
-
# ============================================================================
|
39
36
|
# PostscriptPoint-converisons
|
40
|
-
|
41
37
|
def pt2pt(pt)
|
42
|
-
|
38
|
+
pt
|
43
39
|
end
|
44
40
|
|
45
41
|
def in2pt(inch)
|
46
|
-
|
42
|
+
inch * 72
|
47
43
|
end
|
48
44
|
|
49
45
|
def ft2pt(ft)
|
50
|
-
|
46
|
+
in2pt(ft2in(ft))
|
51
47
|
end
|
52
48
|
|
53
49
|
def yd2pt(yd)
|
54
|
-
|
50
|
+
in2pt(yd2in(yd))
|
55
51
|
end
|
56
52
|
|
57
53
|
def mm2pt(mm)
|
58
|
-
|
54
|
+
mm * (72 / 25.4)
|
59
55
|
end
|
60
56
|
|
61
57
|
def cm2pt(cm)
|
62
|
-
|
58
|
+
mm2pt(cm2mm(cm))
|
63
59
|
end
|
64
60
|
|
65
61
|
def dm2pt(dm)
|
66
|
-
|
62
|
+
mm2pt(dm2mm(dm))
|
67
63
|
end
|
68
64
|
|
69
65
|
def m2pt(m)
|
70
|
-
|
66
|
+
mm2pt(m2mm(m))
|
71
67
|
end
|
72
68
|
|
73
69
|
def pt2mm(pt)
|
74
|
-
|
70
|
+
pt * 1 / mm2pt(1) # (25.4 / 72)
|
75
71
|
end
|
76
72
|
end
|
77
73
|
end
|
74
|
+
# rubocop: enable Naming/MethodParameterName
|