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.
Files changed (309) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +1 -0
  4. data/GPLv2 +20 -21
  5. data/Gemfile +3 -9
  6. data/Rakefile +9 -40
  7. data/lib/prawn/document/bounding_box.rb +54 -40
  8. data/lib/prawn/document/column_box.rb +8 -10
  9. data/lib/prawn/document/internals.rb +39 -146
  10. data/lib/prawn/document/span.rb +23 -17
  11. data/lib/prawn/document.rb +217 -182
  12. data/lib/prawn/encoding.rb +69 -101
  13. data/lib/prawn/errors.rb +47 -43
  14. data/lib/prawn/font.rb +124 -104
  15. data/lib/prawn/font_metric_cache.rb +23 -21
  16. data/lib/prawn/fonts/afm.rb +292 -0
  17. data/lib/prawn/{font → fonts}/dfont.rb +5 -12
  18. data/lib/prawn/fonts/otf.rb +11 -0
  19. data/lib/prawn/fonts/ttc.rb +36 -0
  20. data/lib/prawn/{font → fonts}/ttf.rb +140 -88
  21. data/lib/prawn/graphics/blend_mode.rb +65 -0
  22. data/lib/prawn/graphics/cap_style.rb +5 -5
  23. data/lib/prawn/graphics/color.rb +46 -44
  24. data/lib/prawn/graphics/dash.rb +27 -11
  25. data/lib/prawn/graphics/join_style.rb +11 -6
  26. data/lib/prawn/graphics/patterns.rb +220 -78
  27. data/lib/prawn/graphics/transformation.rb +20 -12
  28. data/lib/prawn/graphics/transparency.rb +20 -18
  29. data/lib/prawn/graphics.rb +153 -115
  30. data/lib/prawn/grid.rb +93 -50
  31. data/lib/prawn/image_handler.rb +4 -4
  32. data/lib/prawn/images/image.rb +3 -2
  33. data/lib/prawn/images/jpg.rb +31 -24
  34. data/lib/prawn/images/png.rb +101 -68
  35. data/lib/prawn/images.rb +64 -56
  36. data/lib/prawn/measurement_extensions.rb +10 -9
  37. data/lib/prawn/measurements.rb +20 -23
  38. data/lib/prawn/outline.rb +96 -75
  39. data/lib/prawn/repeater.rb +16 -16
  40. data/lib/prawn/security/arcfour.rb +2 -2
  41. data/lib/prawn/security.rb +100 -85
  42. data/lib/prawn/soft_mask.rb +37 -38
  43. data/lib/prawn/stamp.rb +28 -13
  44. data/lib/prawn/text/box.rb +24 -29
  45. data/lib/prawn/text/formatted/arranger.rb +108 -63
  46. data/lib/prawn/text/formatted/box.rb +187 -124
  47. data/lib/prawn/text/formatted/fragment.rb +24 -20
  48. data/lib/prawn/text/formatted/line_wrap.rb +133 -73
  49. data/lib/prawn/text/formatted/parser.rb +147 -127
  50. data/lib/prawn/text/formatted/wrap.rb +48 -35
  51. data/lib/prawn/text/formatted.rb +5 -5
  52. data/lib/prawn/text.rb +103 -68
  53. data/lib/prawn/transformation_stack.rb +44 -0
  54. data/lib/prawn/utilities.rb +10 -22
  55. data/lib/prawn/version.rb +5 -0
  56. data/lib/prawn/view.rb +101 -0
  57. data/lib/prawn.rb +39 -54
  58. data/manual/basic_concepts/adding_pages.rb +6 -7
  59. data/manual/basic_concepts/basic_concepts.rb +34 -25
  60. data/manual/basic_concepts/creation.rb +10 -11
  61. data/manual/basic_concepts/cursor.rb +4 -5
  62. data/manual/basic_concepts/measurement.rb +8 -9
  63. data/manual/basic_concepts/origin.rb +5 -6
  64. data/manual/basic_concepts/other_cursor_helpers.rb +11 -12
  65. data/manual/basic_concepts/view.rb +48 -0
  66. data/manual/bounding_box/bounding_box.rb +30 -28
  67. data/manual/bounding_box/bounds.rb +12 -13
  68. data/manual/bounding_box/canvas.rb +7 -8
  69. data/manual/bounding_box/creation.rb +6 -7
  70. data/manual/bounding_box/indentation.rb +14 -15
  71. data/manual/bounding_box/nesting.rb +25 -18
  72. data/manual/bounding_box/russian_boxes.rb +18 -18
  73. data/manual/bounding_box/stretchy.rb +12 -14
  74. data/manual/contents.rb +28 -22
  75. data/manual/cover.rb +33 -32
  76. data/manual/document_and_page_options/background.rb +15 -13
  77. data/manual/document_and_page_options/document_and_page_options.rb +24 -22
  78. data/manual/document_and_page_options/metadata.rb +20 -18
  79. data/manual/document_and_page_options/page_margins.rb +18 -20
  80. data/manual/document_and_page_options/page_size.rb +13 -13
  81. data/manual/document_and_page_options/print_scaling.rb +18 -15
  82. data/manual/example_helper.rb +5 -4
  83. data/manual/graphics/blend_mode.rb +52 -0
  84. data/manual/graphics/circle_and_ellipse.rb +4 -5
  85. data/manual/graphics/color.rb +7 -9
  86. data/manual/graphics/common_lines.rb +7 -8
  87. data/manual/graphics/fill_and_stroke.rb +5 -6
  88. data/manual/graphics/fill_rules.rb +12 -11
  89. data/manual/graphics/gradients.rb +27 -21
  90. data/manual/graphics/graphics.rb +46 -40
  91. data/manual/graphics/helper.rb +19 -9
  92. data/manual/graphics/line_width.rb +8 -7
  93. data/manual/graphics/lines_and_curves.rb +8 -9
  94. data/manual/graphics/polygon.rb +6 -8
  95. data/manual/graphics/rectangle.rb +4 -5
  96. data/manual/graphics/rotate.rb +6 -9
  97. data/manual/graphics/scale.rb +14 -13
  98. data/manual/graphics/soft_masks.rb +4 -6
  99. data/manual/graphics/stroke_cap.rb +7 -8
  100. data/manual/graphics/stroke_dash.rb +15 -16
  101. data/manual/graphics/stroke_join.rb +6 -7
  102. data/manual/graphics/translate.rb +10 -10
  103. data/manual/graphics/transparency.rb +7 -9
  104. data/manual/how_to_read_this_manual.rb +8 -9
  105. data/manual/images/absolute_position.rb +6 -7
  106. data/manual/images/fit.rb +7 -8
  107. data/manual/images/horizontal.rb +10 -11
  108. data/manual/images/images.rb +28 -27
  109. data/manual/images/plain_image.rb +5 -6
  110. data/manual/images/scale.rb +9 -10
  111. data/manual/images/vertical.rb +16 -14
  112. data/manual/images/width_and_height.rb +10 -11
  113. data/manual/layout/boxes.rb +10 -11
  114. data/manual/layout/content.rb +9 -10
  115. data/manual/layout/layout.rb +17 -18
  116. data/manual/layout/simple_grid.rb +6 -7
  117. data/manual/outline/add_subsection_to.rb +20 -21
  118. data/manual/outline/insert_section_after.rb +15 -16
  119. data/manual/outline/outline.rb +22 -21
  120. data/manual/outline/sections_and_pages.rb +17 -18
  121. data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
  122. data/manual/repeatable_content/page_numbering.rb +17 -16
  123. data/manual/repeatable_content/repeatable_content.rb +27 -23
  124. data/manual/repeatable_content/repeater.rb +15 -16
  125. data/manual/repeatable_content/stamp.rb +14 -15
  126. data/manual/security/encryption.rb +8 -11
  127. data/manual/security/permissions.rb +20 -15
  128. data/manual/security/security.rb +18 -18
  129. data/manual/table.rb +16 -0
  130. data/manual/text/alignment.rb +16 -17
  131. data/manual/text/color.rb +12 -12
  132. data/manual/text/column_box.rb +9 -11
  133. data/manual/text/fallback_fonts.rb +25 -21
  134. data/manual/text/font.rb +11 -12
  135. data/manual/text/font_size.rb +13 -14
  136. data/manual/text/font_style.rb +10 -8
  137. data/manual/text/formatted_callbacks.rb +33 -23
  138. data/manual/text/formatted_text.rb +36 -25
  139. data/manual/text/free_flowing_text.rb +22 -23
  140. data/manual/text/inline.rb +18 -19
  141. data/manual/text/kerning_and_character_spacing.rb +14 -15
  142. data/manual/text/leading.rb +7 -8
  143. data/manual/text/line_wrapping.rb +37 -18
  144. data/manual/text/paragraph_indentation.rb +15 -10
  145. data/manual/text/positioned_text.rb +16 -17
  146. data/manual/text/registering_families.rb +27 -24
  147. data/manual/text/rendering_and_color.rb +9 -10
  148. data/manual/text/right_to_left_text.rb +30 -19
  149. data/manual/text/rotation.rb +33 -24
  150. data/manual/text/single_usage.rb +8 -9
  151. data/manual/text/text.rb +56 -54
  152. data/manual/text/text_box_excess.rb +20 -17
  153. data/manual/text/text_box_extensions.rb +18 -15
  154. data/manual/text/text_box_overflow.rb +24 -17
  155. data/manual/text/utf8.rb +12 -13
  156. data/manual/text/win_ansi_charset.rb +28 -25
  157. data/prawn.gemspec +45 -50
  158. data/spec/extensions/encoding_helpers.rb +3 -3
  159. data/spec/prawn/document/bounding_box_spec.rb +550 -0
  160. data/spec/prawn/document/column_box_spec.rb +75 -0
  161. data/spec/prawn/document/security_spec.rb +176 -0
  162. data/spec/prawn/document_annotations_spec.rb +76 -0
  163. data/spec/prawn/document_destinations_spec.rb +15 -0
  164. data/spec/prawn/document_grid_spec.rb +99 -0
  165. data/spec/prawn/document_reference_spec.rb +27 -0
  166. data/spec/prawn/document_span_spec.rb +44 -0
  167. data/spec/prawn/document_spec.rb +805 -0
  168. data/spec/prawn/font_metric_cache_spec.rb +54 -0
  169. data/spec/prawn/font_spec.rb +544 -0
  170. data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
  171. data/spec/prawn/graphics/transparency_spec.rb +81 -0
  172. data/spec/prawn/graphics_spec.rb +872 -0
  173. data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
  174. data/spec/prawn/image_handler_spec.rb +53 -0
  175. data/spec/prawn/images/jpg_spec.rb +20 -0
  176. data/spec/prawn/images/png_spec.rb +283 -0
  177. data/spec/prawn/images_spec.rb +229 -0
  178. data/spec/prawn/measurements_extensions_spec.rb +24 -0
  179. data/spec/prawn/outline_spec.rb +512 -0
  180. data/spec/prawn/repeater_spec.rb +166 -0
  181. data/spec/prawn/soft_mask_spec.rb +74 -0
  182. data/spec/prawn/stamp_spec.rb +173 -0
  183. data/spec/prawn/text/box_spec.rb +1110 -0
  184. data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
  185. data/spec/prawn/text/formatted/box_spec.rb +849 -0
  186. data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
  187. data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
  188. data/spec/prawn/text/formatted/parser_spec.rb +697 -0
  189. data/spec/prawn/text_draw_text_spec.rb +150 -0
  190. data/spec/prawn/text_rendering_mode_spec.rb +48 -0
  191. data/spec/prawn/text_spacing_spec.rb +95 -0
  192. data/spec/prawn/text_spec.rb +603 -0
  193. data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
  194. data/spec/prawn/transformation_stack_spec.rb +66 -0
  195. data/spec/prawn/view_spec.rb +63 -0
  196. data/spec/prawn_manual_spec.rb +35 -0
  197. data/spec/spec_helper.rb +19 -25
  198. data.tar.gz.sig +0 -0
  199. metadata +113 -276
  200. metadata.gz.sig +0 -0
  201. data/data/encodings/win_ansi.txt +0 -29
  202. data/data/images/16bit.alpha +0 -0
  203. data/data/images/16bit.color +0 -0
  204. data/data/images/16bit.png +0 -0
  205. data/data/images/arrow.png +0 -0
  206. data/data/images/arrow2.png +0 -0
  207. data/data/images/dice.alpha +0 -0
  208. data/data/images/dice.color +0 -0
  209. data/data/images/dice.png +0 -0
  210. data/data/images/dice_interlaced.png +0 -0
  211. data/data/images/fractal.jpg +0 -0
  212. data/data/images/indexed_color.dat +0 -0
  213. data/data/images/indexed_color.png +0 -0
  214. data/data/images/letterhead.jpg +0 -0
  215. data/data/images/license.md +0 -8
  216. data/data/images/page_white_text.alpha +0 -0
  217. data/data/images/page_white_text.color +0 -0
  218. data/data/images/page_white_text.png +0 -0
  219. data/data/images/pigs.jpg +0 -0
  220. data/data/images/prawn.png +0 -0
  221. data/data/images/ruport.png +0 -0
  222. data/data/images/ruport_data.dat +0 -0
  223. data/data/images/ruport_transparent.png +0 -0
  224. data/data/images/ruport_type0.png +0 -0
  225. data/data/images/stef.jpg +0 -0
  226. data/data/images/tru256.bmp +0 -0
  227. data/data/images/web-links.dat +0 -1
  228. data/data/images/web-links.png +0 -0
  229. data/data/pdfs/complex_template.pdf +0 -0
  230. data/data/pdfs/contains_ttf_font.pdf +0 -0
  231. data/data/pdfs/encrypted.pdf +0 -0
  232. data/data/pdfs/form.pdf +1 -819
  233. data/data/pdfs/hexagon.pdf +0 -61
  234. data/data/pdfs/indirect_reference.pdf +0 -86
  235. data/data/pdfs/multipage_template.pdf +0 -127
  236. data/data/pdfs/nested_pages.pdf +0 -118
  237. data/data/pdfs/page_without_mediabox.pdf +0 -193
  238. data/data/pdfs/resources_as_indirect_object.pdf +0 -83
  239. data/data/pdfs/two_hexagons.pdf +0 -90
  240. data/data/pdfs/version_1_6.pdf +0 -61
  241. data/data/shift_jis_text.txt +0 -1
  242. data/lib/prawn/document/graphics_state.rb +0 -73
  243. data/lib/prawn/font/afm.rb +0 -247
  244. data/lib/prawn/table/cell/image.rb +0 -69
  245. data/lib/prawn/table/cell/in_table.rb +0 -33
  246. data/lib/prawn/table/cell/span_dummy.rb +0 -93
  247. data/lib/prawn/table/cell/subtable.rb +0 -66
  248. data/lib/prawn/table/cell/text.rb +0 -154
  249. data/lib/prawn/table/cell.rb +0 -772
  250. data/lib/prawn/table/cells.rb +0 -255
  251. data/lib/prawn/table/column_width_calculator.rb +0 -182
  252. data/lib/prawn/table.rb +0 -644
  253. data/manual/table/basic_block.rb +0 -53
  254. data/manual/table/before_rendering_page.rb +0 -26
  255. data/manual/table/cell_border_lines.rb +0 -24
  256. data/manual/table/cell_borders_and_bg.rb +0 -31
  257. data/manual/table/cell_dimensions.rb +0 -30
  258. data/manual/table/cell_text.rb +0 -38
  259. data/manual/table/column_widths.rb +0 -30
  260. data/manual/table/content_and_subtables.rb +0 -39
  261. data/manual/table/creation.rb +0 -27
  262. data/manual/table/filtering.rb +0 -36
  263. data/manual/table/flow_and_header.rb +0 -17
  264. data/manual/table/image_cells.rb +0 -33
  265. data/manual/table/position.rb +0 -29
  266. data/manual/table/row_colors.rb +0 -20
  267. data/manual/table/span.rb +0 -30
  268. data/manual/table/style.rb +0 -22
  269. data/manual/table/table.rb +0 -52
  270. data/manual/table/width.rb +0 -27
  271. data/spec/acceptance/png.rb +0 -25
  272. data/spec/annotations_spec.rb +0 -74
  273. data/spec/bounding_box_spec.rb +0 -510
  274. data/spec/cell_spec.rb +0 -629
  275. data/spec/column_box_spec.rb +0 -65
  276. data/spec/destinations_spec.rb +0 -15
  277. data/spec/document_spec.rb +0 -730
  278. data/spec/extensions/mocha.rb +0 -46
  279. data/spec/font_metric_cache_spec.rb +0 -52
  280. data/spec/font_spec.rb +0 -449
  281. data/spec/formatted_text_arranger_spec.rb +0 -421
  282. data/spec/formatted_text_box_spec.rb +0 -639
  283. data/spec/formatted_text_fragment_spec.rb +0 -298
  284. data/spec/graphics_spec.rb +0 -669
  285. data/spec/grid_spec.rb +0 -96
  286. data/spec/image_handler_spec.rb +0 -54
  287. data/spec/images_spec.rb +0 -153
  288. data/spec/inline_formatted_text_parser_spec.rb +0 -564
  289. data/spec/jpg_spec.rb +0 -25
  290. data/spec/line_wrap_spec.rb +0 -344
  291. data/spec/measurement_units_spec.rb +0 -25
  292. data/spec/outline_spec.rb +0 -430
  293. data/spec/png_spec.rb +0 -237
  294. data/spec/reference_spec.rb +0 -25
  295. data/spec/repeater_spec.rb +0 -160
  296. data/spec/security_spec.rb +0 -158
  297. data/spec/soft_mask_spec.rb +0 -79
  298. data/spec/span_spec.rb +0 -44
  299. data/spec/stamp_spec.rb +0 -160
  300. data/spec/stroke_styles_spec.rb +0 -211
  301. data/spec/table/span_dummy_spec.rb +0 -17
  302. data/spec/table_spec.rb +0 -1527
  303. data/spec/text_at_spec.rb +0 -115
  304. data/spec/text_box_spec.rb +0 -1034
  305. data/spec/text_rendering_mode_spec.rb +0 -45
  306. data/spec/text_spacing_spec.rb +0 -93
  307. data/spec/text_spec.rb +0 -437
  308. data/spec/text_with_inline_formatting_spec.rb +0 -35
  309. data/spec/transparency_spec.rb +0 -91
@@ -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("C*") == [137, 80, 78, 71, 13, 10, 26, 10]
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) # Skip the default header
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 = data.read(4).unpack("N")[0]
47
- section = data.read(4)
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("NNCCCCC")
53
+ values = data.read(chunk_size).unpack('NNCCCCC')
53
54
 
54
- @width = values[0]
55
- @height = values[1]
56
- @bits = values[2]
57
- @color_type = values[3]
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 = values[5]
60
- @interlace_method = values[6]
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
- # Indexed colour, RGB. Each byte in this chunk is an alpha for
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).unpack("n").first
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("nnn")
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) # Skip the CRC
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 self.color_type
99
+ case color_type
105
100
  when 0, 3, 4
106
- return 1
101
+ 1
107
102
  when 2, 6
108
- return 3
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
- split_image_data if alpha_channel?
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
- @color_type == 4 || @color_type == 6
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
- :Type => :XObject,
159
- :Subtype => :Image,
160
- :Height => height,
161
- :Width => width,
162
- :BitsPerComponent => bits
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
- :FlateDecode => {
170
- :Predictor => 15,
171
- :Colors => colors,
172
- :BitsPerComponent => bits,
173
- :Columns => width
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] = [:Indexed,
187
- :DeviceRGB,
188
- (palette.size / 3) -1,
189
- palette_obj]
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.collect { |x| [x,x] }.flatten
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 a alpha
219
- # channel mixed in with the main image data. The PNG class seperates
220
- # it out for us and makes it available via the alpha_channel attribute
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
- :Type => :XObject,
224
- :Subtype => :Image,
225
- :Height => height,
226
- :Width => width,
227
- :BitsPerComponent => bits,
228
- :ColorSpace => :DeviceGray,
229
- :Decode => [0, 1]
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
- :FlateDecode => {
235
- :Predictor => 15,
236
- :Colors => 1,
237
- :BitsPerComponent => bits,
238
- :Columns => width
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 = (color_bytes + alpha_bytes) * self.width + 1
268
+ scanline_length = (color_bytes + alpha_bytes) * width + 1
267
269
  scanlines = @img_data.bytesize / scanline_length
268
- pixels = self.width * self.height
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
- self.width.times do
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 #rewind
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 the image.
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, :center) or an y-offset
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 inside [width,height]
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://prawn.majesticseacreature.com/media/prawn_logo.png")
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 [:at, :position, :vposition, :height,
65
- :width, :scale, :fit], options
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
- io = verify_and_open_image(file)
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
- min_version(info.min_pdf_version) if info.respond_to?(:min_pdf_version)
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] = {:obj => image_obj, :info => info}
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.merge!(label => pdf_obj)
129
+ state.page.xobjects[label] = pdf_obj
123
130
 
124
- # add the image to the current page
125
- instruct = "\nq\n%.3f 0 0 %.3f %.3f %.3f cm\n/%s Do\nQ"
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 verify_and_open_image(io_or_path)
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
- io = io_or_path.open('rb')
147
- io
152
+
153
+ io_or_path.binread
148
154
  end
149
155
 
150
- def image_position(w,h,options)
156
+ def image_position(width, height, options)
151
157
  options[:position] ||= :left
152
158
 
153
- y = case options[:vposition]
154
- when :top
155
- bounds.absolute_top
156
- when :center
157
- bounds.absolute_top - (bounds.height - h) / 2.0
158
- when :bottom
159
- bounds.absolute_bottom + h
160
- when Numeric
161
- bounds.absolute_top - options[:vposition]
162
- else
163
- determine_y_with_page_flow(h)
164
- end
165
-
166
- x = case options[:position]
167
- when :left
168
- bounds.left_side
169
- when :center
170
- bounds.left_side + (bounds.width - w) / 2.0
171
- when :right
172
- bounds.right_side - w
173
- when Numeric
174
- options[:position] + bounds.left_side
175
- end
176
-
177
- return [x,y]
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(h)
181
- if overruns_page?(h)
188
+ def determine_y_with_page_flow(height)
189
+ if overruns_page?(height)
182
190
  bounds.move_past_bottom
183
191
  end
184
- self.y
192
+ y
185
193
  end
186
194
 
187
- def overruns_page?(h)
188
- (self.y - h) < reference_bounds.absolute_bottom
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
- # encoding: utf-8
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
- return mm2pt(self)
21
+ mm2pt(self)
21
22
  end
22
23
 
23
24
  def cm
24
- return cm2pt(self)
25
+ cm2pt(self)
25
26
  end
26
27
 
27
28
  def dm
28
- return dm2pt(self)
29
+ dm2pt(self)
29
30
  end
30
31
 
31
32
  def m
32
- return m2pt(self)
33
+ m2pt(self)
33
34
  end
34
35
 
35
36
  def in
36
- return in2pt(self)
37
+ in2pt(self)
37
38
  end
38
39
 
39
40
  def yd
40
- return yd2pt(self)
41
+ yd2pt(self)
41
42
  end
42
43
 
43
44
  def ft
44
- return ft2pt(self)
45
+ ft2pt(self)
45
46
  end
46
47
 
47
48
  def pt
48
- return pt2pt(self)
49
+ pt2pt(self)
49
50
  end
50
51
  end
@@ -1,77 +1,74 @@
1
- # encoding: utf-8
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
- return cm*10
15
+ cm * 10
15
16
  end
16
17
 
17
18
  def dm2mm(dm)
18
- return dm*100
19
+ dm * 100
19
20
  end
20
21
 
21
22
  def m2mm(m)
22
- return m*1000
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
- return ft * 12
29
+ ft * 12
31
30
  end
32
31
 
33
32
  def yd2in(yd)
34
- return yd*36
33
+ yd * 36
35
34
  end
36
35
 
37
-
38
- # ============================================================================
39
36
  # PostscriptPoint-converisons
40
-
41
37
  def pt2pt(pt)
42
- return pt
38
+ pt
43
39
  end
44
40
 
45
41
  def in2pt(inch)
46
- return inch * 72
42
+ inch * 72
47
43
  end
48
44
 
49
45
  def ft2pt(ft)
50
- return in2pt(ft2in(ft))
46
+ in2pt(ft2in(ft))
51
47
  end
52
48
 
53
49
  def yd2pt(yd)
54
- return in2pt(yd2in(yd))
50
+ in2pt(yd2in(yd))
55
51
  end
56
52
 
57
53
  def mm2pt(mm)
58
- return mm*(72 / 25.4)
54
+ mm * (72 / 25.4)
59
55
  end
60
56
 
61
57
  def cm2pt(cm)
62
- return mm2pt(cm2mm(cm))
58
+ mm2pt(cm2mm(cm))
63
59
  end
64
60
 
65
61
  def dm2pt(dm)
66
- return mm2pt(dm2mm(dm))
62
+ mm2pt(dm2mm(dm))
67
63
  end
68
64
 
69
65
  def m2pt(m)
70
- return mm2pt(m2mm(m))
66
+ mm2pt(m2mm(m))
71
67
  end
72
68
 
73
69
  def pt2mm(pt)
74
- return pt * 1 / mm2pt(1)# (25.4 / 72)
70
+ pt * 1 / mm2pt(1) # (25.4 / 72)
75
71
  end
76
72
  end
77
73
  end
74
+ # rubocop: enable Naming/MethodParameterName