prawn 0.13.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 (348) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +10 -0
  4. data/GPLv2 +20 -21
  5. data/Gemfile +3 -16
  6. data/Rakefile +17 -39
  7. data/lib/prawn/document/bounding_box.rb +85 -42
  8. data/lib/prawn/document/column_box.rb +21 -11
  9. data/lib/prawn/document/internals.rb +40 -147
  10. data/lib/prawn/document/span.rb +25 -17
  11. data/lib/prawn/document.rb +286 -245
  12. data/lib/prawn/encoding.rb +68 -101
  13. data/lib/prawn/errors.rb +47 -43
  14. data/lib/prawn/font.rb +204 -155
  15. data/lib/prawn/font_metric_cache.rb +25 -21
  16. data/lib/prawn/fonts/afm.rb +292 -0
  17. data/lib/prawn/{font → fonts}/dfont.rb +7 -13
  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 +142 -80
  21. data/lib/prawn/graphics/blend_mode.rb +65 -0
  22. data/lib/prawn/graphics/cap_style.rb +6 -5
  23. data/lib/prawn/graphics/color.rb +47 -44
  24. data/lib/prawn/graphics/dash.rb +30 -13
  25. data/lib/prawn/graphics/join_style.rb +13 -6
  26. data/lib/prawn/graphics/patterns.rb +221 -90
  27. data/lib/prawn/graphics/transformation.rb +21 -12
  28. data/lib/prawn/graphics/transparency.rb +21 -17
  29. data/lib/prawn/graphics.rb +155 -128
  30. data/lib/prawn/{layout/grid.rb → grid.rb} +110 -47
  31. data/lib/prawn/image_handler.rb +16 -2
  32. data/lib/prawn/images/image.rb +4 -2
  33. data/lib/prawn/images/jpg.rb +39 -30
  34. data/lib/prawn/images/png.rb +132 -169
  35. data/lib/prawn/images.rb +70 -62
  36. data/lib/prawn/measurement_extensions.rb +15 -10
  37. data/lib/prawn/measurements.rb +22 -23
  38. data/lib/prawn/outline.rb +301 -13
  39. data/lib/prawn/repeater.rb +19 -17
  40. data/lib/prawn/security/arcfour.rb +54 -0
  41. data/lib/prawn/security.rb +108 -86
  42. data/lib/prawn/soft_mask.rb +40 -41
  43. data/lib/prawn/stamp.rb +29 -12
  44. data/lib/prawn/text/box.rb +27 -29
  45. data/lib/prawn/text/formatted/arranger.rb +110 -67
  46. data/lib/prawn/text/formatted/box.rb +233 -165
  47. data/lib/prawn/text/formatted/fragment.rb +27 -27
  48. data/lib/prawn/text/formatted/line_wrap.rb +137 -97
  49. data/lib/prawn/text/formatted/parser.rb +149 -127
  50. data/lib/prawn/text/formatted/wrap.rb +57 -37
  51. data/lib/prawn/text/formatted.rb +6 -4
  52. data/lib/prawn/text.rb +105 -73
  53. data/lib/prawn/transformation_stack.rb +44 -0
  54. data/lib/prawn/utilities.rb +11 -21
  55. data/lib/prawn/version.rb +5 -0
  56. data/lib/prawn/view.rb +101 -0
  57. data/lib/prawn.rb +42 -68
  58. data/{data/images/fractal.jpg → manual/absolute_position.pdf} +0 -0
  59. data/manual/basic_concepts/adding_pages.rb +9 -10
  60. data/manual/basic_concepts/basic_concepts.rb +33 -24
  61. data/manual/basic_concepts/creation.rb +10 -11
  62. data/manual/basic_concepts/cursor.rb +9 -10
  63. data/manual/basic_concepts/measurement.rb +10 -11
  64. data/manual/basic_concepts/origin.rb +8 -9
  65. data/manual/basic_concepts/other_cursor_helpers.rb +17 -18
  66. data/manual/basic_concepts/view.rb +48 -0
  67. data/manual/bounding_box/bounding_box.rb +31 -29
  68. data/manual/bounding_box/bounds.rb +17 -18
  69. data/manual/bounding_box/canvas.rb +8 -9
  70. data/manual/bounding_box/creation.rb +8 -9
  71. data/manual/bounding_box/indentation.rb +22 -23
  72. data/manual/bounding_box/nesting.rb +32 -25
  73. data/manual/bounding_box/russian_boxes.rb +19 -19
  74. data/manual/bounding_box/stretchy.rb +18 -20
  75. data/manual/contents.rb +35 -0
  76. data/manual/cover.rb +43 -0
  77. data/manual/document_and_page_options/background.rb +16 -14
  78. data/manual/document_and_page_options/document_and_page_options.rb +26 -23
  79. data/manual/document_and_page_options/metadata.rb +21 -19
  80. data/manual/document_and_page_options/page_margins.rb +20 -22
  81. data/manual/document_and_page_options/page_size.rb +15 -15
  82. data/manual/document_and_page_options/print_scaling.rb +23 -0
  83. data/manual/example_helper.rb +5 -408
  84. data/manual/graphics/blend_mode.rb +52 -0
  85. data/manual/graphics/circle_and_ellipse.rb +8 -9
  86. data/manual/graphics/color.rb +11 -13
  87. data/manual/graphics/common_lines.rb +13 -12
  88. data/manual/graphics/fill_and_stroke.rb +10 -11
  89. data/manual/graphics/fill_rules.rb +13 -12
  90. data/manual/graphics/gradients.rb +28 -22
  91. data/manual/graphics/graphics.rb +52 -46
  92. data/manual/graphics/helper.rb +20 -10
  93. data/manual/graphics/line_width.rb +13 -12
  94. data/manual/graphics/lines_and_curves.rb +13 -14
  95. data/manual/graphics/polygon.rb +10 -12
  96. data/manual/graphics/rectangle.rb +7 -8
  97. data/manual/graphics/rotate.rb +9 -12
  98. data/manual/graphics/scale.rb +19 -18
  99. data/manual/graphics/soft_masks.rb +5 -7
  100. data/manual/graphics/stroke_cap.rb +10 -11
  101. data/manual/graphics/stroke_dash.rb +16 -17
  102. data/manual/graphics/stroke_join.rb +10 -11
  103. data/manual/graphics/translate.rb +13 -13
  104. data/manual/graphics/transparency.rb +11 -13
  105. data/manual/{manual/how_to_read_this_manual.rb → how_to_read_this_manual.rb} +23 -25
  106. data/manual/images/absolute_position.rb +9 -10
  107. data/manual/images/fit.rb +9 -10
  108. data/manual/images/horizontal.rb +13 -14
  109. data/manual/images/images.rb +31 -30
  110. data/manual/images/plain_image.rb +6 -7
  111. data/manual/images/scale.rb +12 -13
  112. data/manual/images/vertical.rb +19 -17
  113. data/manual/images/width_and_height.rb +13 -14
  114. data/manual/layout/boxes.rb +14 -15
  115. data/manual/layout/content.rb +12 -13
  116. data/manual/layout/layout.rb +19 -20
  117. data/manual/layout/simple_grid.rb +8 -9
  118. data/manual/outline/add_subsection_to.rb +26 -27
  119. data/manual/outline/insert_section_after.rb +19 -20
  120. data/manual/outline/outline.rb +23 -22
  121. data/manual/outline/sections_and_pages.rb +24 -25
  122. data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
  123. data/manual/repeatable_content/page_numbering.rb +20 -19
  124. data/manual/repeatable_content/repeatable_content.rb +26 -22
  125. data/manual/repeatable_content/repeater.rb +18 -19
  126. data/manual/repeatable_content/stamp.rb +18 -19
  127. data/manual/security/encryption.rb +8 -11
  128. data/manual/security/permissions.rb +20 -15
  129. data/manual/security/security.rb +20 -20
  130. data/manual/table.rb +16 -0
  131. data/manual/text/alignment.rb +17 -18
  132. data/manual/text/color.rb +13 -13
  133. data/manual/text/column_box.rb +10 -12
  134. data/manual/text/fallback_fonts.rb +29 -25
  135. data/manual/text/font.rb +17 -18
  136. data/manual/text/font_size.rb +21 -22
  137. data/manual/text/font_style.rb +12 -10
  138. data/manual/text/formatted_callbacks.rb +36 -26
  139. data/manual/text/formatted_text.rb +41 -34
  140. data/manual/text/free_flowing_text.rb +28 -29
  141. data/manual/text/inline.rb +23 -26
  142. data/manual/text/kerning_and_character_spacing.rb +20 -21
  143. data/manual/text/leading.rb +10 -11
  144. data/manual/text/line_wrapping.rb +40 -21
  145. data/manual/text/paragraph_indentation.rb +17 -12
  146. data/manual/text/positioned_text.rb +19 -20
  147. data/manual/text/registering_families.rb +33 -30
  148. data/manual/text/rendering_and_color.rb +11 -12
  149. data/manual/text/right_to_left_text.rb +31 -20
  150. data/manual/text/rotation.rb +36 -27
  151. data/manual/text/single_usage.rb +13 -14
  152. data/manual/text/text.rb +62 -62
  153. data/manual/text/text_box_excess.rb +22 -19
  154. data/manual/text/text_box_extensions.rb +21 -18
  155. data/manual/text/text_box_overflow.rb +28 -21
  156. data/manual/text/utf8.rb +16 -17
  157. data/manual/text/win_ansi_charset.rb +29 -26
  158. data/prawn.gemspec +45 -43
  159. data/spec/extensions/encoding_helpers.rb +4 -3
  160. data/spec/prawn/document/bounding_box_spec.rb +550 -0
  161. data/spec/prawn/document/column_box_spec.rb +75 -0
  162. data/spec/prawn/document/security_spec.rb +176 -0
  163. data/spec/prawn/document_annotations_spec.rb +76 -0
  164. data/spec/prawn/document_destinations_spec.rb +15 -0
  165. data/spec/prawn/document_grid_spec.rb +99 -0
  166. data/spec/prawn/document_reference_spec.rb +27 -0
  167. data/spec/prawn/document_span_spec.rb +44 -0
  168. data/spec/prawn/document_spec.rb +805 -0
  169. data/spec/prawn/font_metric_cache_spec.rb +54 -0
  170. data/spec/prawn/font_spec.rb +544 -0
  171. data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
  172. data/spec/prawn/graphics/transparency_spec.rb +81 -0
  173. data/spec/prawn/graphics_spec.rb +872 -0
  174. data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
  175. data/spec/prawn/image_handler_spec.rb +53 -0
  176. data/spec/prawn/images/jpg_spec.rb +20 -0
  177. data/spec/prawn/images/png_spec.rb +283 -0
  178. data/spec/prawn/images_spec.rb +229 -0
  179. data/spec/prawn/measurements_extensions_spec.rb +24 -0
  180. data/spec/prawn/outline_spec.rb +512 -0
  181. data/spec/prawn/repeater_spec.rb +166 -0
  182. data/spec/prawn/soft_mask_spec.rb +74 -0
  183. data/spec/prawn/stamp_spec.rb +173 -0
  184. data/spec/prawn/text/box_spec.rb +1110 -0
  185. data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
  186. data/spec/prawn/text/formatted/box_spec.rb +849 -0
  187. data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
  188. data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
  189. data/spec/prawn/text/formatted/parser_spec.rb +697 -0
  190. data/spec/prawn/text_draw_text_spec.rb +150 -0
  191. data/spec/prawn/text_rendering_mode_spec.rb +48 -0
  192. data/spec/prawn/text_spacing_spec.rb +95 -0
  193. data/spec/prawn/text_spec.rb +603 -0
  194. data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
  195. data/spec/prawn/transformation_stack_spec.rb +66 -0
  196. data/spec/prawn/view_spec.rb +63 -0
  197. data/spec/prawn_manual_spec.rb +35 -0
  198. data/spec/spec_helper.rb +22 -21
  199. data.tar.gz.sig +0 -0
  200. metadata +168 -307
  201. metadata.gz.sig +0 -0
  202. data/README.md +0 -109
  203. data/data/encodings/win_ansi.txt +0 -29
  204. data/data/images/16bit.alpha +0 -0
  205. data/data/images/16bit.dat +0 -0
  206. data/data/images/16bit.png +0 -0
  207. data/data/images/arrow.png +0 -0
  208. data/data/images/arrow2.png +0 -0
  209. data/data/images/barcode_issue.png +0 -0
  210. data/data/images/dice.alpha +0 -0
  211. data/data/images/dice.dat +0 -0
  212. data/data/images/dice.png +0 -0
  213. data/data/images/dice_interlaced.png +0 -0
  214. data/data/images/indexed_color.dat +0 -0
  215. data/data/images/indexed_color.png +0 -0
  216. data/data/images/letterhead.jpg +0 -0
  217. data/data/images/page_white_text.alpha +0 -0
  218. data/data/images/page_white_text.dat +0 -0
  219. data/data/images/page_white_text.png +0 -0
  220. data/data/images/pigs.jpg +0 -0
  221. data/data/images/prawn.png +0 -0
  222. data/data/images/ruport.png +0 -0
  223. data/data/images/ruport_data.dat +0 -0
  224. data/data/images/ruport_transparent.png +0 -0
  225. data/data/images/ruport_type0.png +0 -0
  226. data/data/images/stef.jpg +0 -0
  227. data/data/images/tru256.bmp +0 -0
  228. data/data/images/web-links.dat +0 -1
  229. data/data/images/web-links.png +0 -0
  230. data/data/pdfs/complex_template.pdf +0 -0
  231. data/data/pdfs/contains_ttf_font.pdf +0 -0
  232. data/data/pdfs/encrypted.pdf +0 -0
  233. data/data/pdfs/form.pdf +1 -819
  234. data/data/pdfs/hexagon.pdf +0 -61
  235. data/data/pdfs/indirect_reference.pdf +0 -86
  236. data/data/pdfs/multipage_template.pdf +0 -127
  237. data/data/pdfs/nested_pages.pdf +0 -118
  238. data/data/pdfs/page_without_mediabox.pdf +0 -193
  239. data/data/pdfs/resources_as_indirect_object.pdf +0 -83
  240. data/data/pdfs/two_hexagons.pdf +0 -90
  241. data/data/pdfs/version_1_6.pdf +0 -61
  242. data/data/shift_jis_text.txt +0 -1
  243. data/lib/pdf/core/annotations.rb +0 -60
  244. data/lib/pdf/core/byte_string.rb +0 -9
  245. data/lib/pdf/core/destinations.rb +0 -90
  246. data/lib/pdf/core/document_state.rb +0 -78
  247. data/lib/pdf/core/filter_list.rb +0 -51
  248. data/lib/pdf/core/filters.rb +0 -36
  249. data/lib/pdf/core/graphics_state.rb +0 -68
  250. data/lib/pdf/core/literal_string.rb +0 -16
  251. data/lib/pdf/core/name_tree.rb +0 -177
  252. data/lib/pdf/core/object_store.rb +0 -320
  253. data/lib/pdf/core/outline.rb +0 -315
  254. data/lib/pdf/core/page.rb +0 -212
  255. data/lib/pdf/core/page_geometry.rb +0 -126
  256. data/lib/pdf/core/pdf_object.rb +0 -124
  257. data/lib/pdf/core/reference.rb +0 -103
  258. data/lib/pdf/core/stream.rb +0 -98
  259. data/lib/pdf/core/text.rb +0 -275
  260. data/lib/pdf/core.rb +0 -35
  261. data/lib/prawn/compatibility.rb +0 -91
  262. data/lib/prawn/document/graphics_state.rb +0 -73
  263. data/lib/prawn/document/snapshot.rb +0 -89
  264. data/lib/prawn/font/afm.rb +0 -203
  265. data/lib/prawn/layout.rb +0 -20
  266. data/lib/prawn/table/cell/image.rb +0 -70
  267. data/lib/prawn/table/cell/in_table.rb +0 -27
  268. data/lib/prawn/table/cell/span_dummy.rb +0 -92
  269. data/lib/prawn/table/cell/subtable.rb +0 -65
  270. data/lib/prawn/table/cell/text.rb +0 -153
  271. data/lib/prawn/table/cell.rb +0 -770
  272. data/lib/prawn/table/cells.rb +0 -295
  273. data/lib/prawn/table.rb +0 -643
  274. data/manual/example_file.rb +0 -116
  275. data/manual/example_package.rb +0 -53
  276. data/manual/example_section.rb +0 -46
  277. data/manual/manual/cover.rb +0 -35
  278. data/manual/manual/foreword.rb +0 -85
  279. data/manual/manual/manual.rb +0 -35
  280. data/manual/syntax_highlight.rb +0 -52
  281. data/manual/table/basic_block.rb +0 -53
  282. data/manual/table/before_rendering_page.rb +0 -26
  283. data/manual/table/cell_border_lines.rb +0 -24
  284. data/manual/table/cell_borders_and_bg.rb +0 -31
  285. data/manual/table/cell_dimensions.rb +0 -30
  286. data/manual/table/cell_text.rb +0 -38
  287. data/manual/table/column_widths.rb +0 -30
  288. data/manual/table/content_and_subtables.rb +0 -39
  289. data/manual/table/creation.rb +0 -27
  290. data/manual/table/filtering.rb +0 -36
  291. data/manual/table/flow_and_header.rb +0 -17
  292. data/manual/table/image_cells.rb +0 -33
  293. data/manual/table/position.rb +0 -29
  294. data/manual/table/row_colors.rb +0 -20
  295. data/manual/table/span.rb +0 -30
  296. data/manual/table/style.rb +0 -22
  297. data/manual/table/table.rb +0 -52
  298. data/manual/table/width.rb +0 -27
  299. data/manual/templates/full_template.rb +0 -25
  300. data/manual/templates/page_template.rb +0 -48
  301. data/manual/templates/templates.rb +0 -27
  302. data/manual/text/group.rb +0 -29
  303. data/spec/acceptance/png.rb +0 -23
  304. data/spec/annotations_spec.rb +0 -74
  305. data/spec/bounding_box_spec.rb +0 -493
  306. data/spec/cell_spec.rb +0 -628
  307. data/spec/column_box_spec.rb +0 -33
  308. data/spec/destinations_spec.rb +0 -15
  309. data/spec/document_spec.rb +0 -761
  310. data/spec/extensions/mocha.rb +0 -44
  311. data/spec/filters_spec.rb +0 -34
  312. data/spec/font_metric_cache_spec.rb +0 -52
  313. data/spec/font_spec.rb +0 -464
  314. data/spec/formatted_text_arranger_spec.rb +0 -421
  315. data/spec/formatted_text_box_spec.rb +0 -650
  316. data/spec/formatted_text_fragment_spec.rb +0 -298
  317. data/spec/graphics_spec.rb +0 -651
  318. data/spec/grid_spec.rb +0 -85
  319. data/spec/image_handler_spec.rb +0 -42
  320. data/spec/images_spec.rb +0 -157
  321. data/spec/inline_formatted_text_parser_spec.rb +0 -564
  322. data/spec/jpg_spec.rb +0 -25
  323. data/spec/line_wrap_spec.rb +0 -333
  324. data/spec/measurement_units_spec.rb +0 -23
  325. data/spec/name_tree_spec.rb +0 -112
  326. data/spec/object_store_spec.rb +0 -170
  327. data/spec/outline_spec.rb +0 -448
  328. data/spec/pdf_object_spec.rb +0 -172
  329. data/spec/png_spec.rb +0 -240
  330. data/spec/reference_spec.rb +0 -82
  331. data/spec/repeater_spec.rb +0 -158
  332. data/spec/security_spec.rb +0 -158
  333. data/spec/snapshot_spec.rb +0 -186
  334. data/spec/soft_mask_spec.rb +0 -117
  335. data/spec/span_spec.rb +0 -44
  336. data/spec/stamp_spec.rb +0 -158
  337. data/spec/stream_spec.rb +0 -58
  338. data/spec/stroke_styles_spec.rb +0 -211
  339. data/spec/table/span_dummy_spec.rb +0 -17
  340. data/spec/table_spec.rb +0 -1355
  341. data/spec/template_spec.rb +0 -351
  342. data/spec/text_at_spec.rb +0 -130
  343. data/spec/text_box_spec.rb +0 -1030
  344. data/spec/text_rendering_mode_spec.rb +0 -45
  345. data/spec/text_spacing_spec.rb +0 -93
  346. data/spec/text_spec.rb +0 -425
  347. data/spec/text_with_inline_formatting_spec.rb +0 -35
  348. data/spec/transparency_spec.rb +0 -89
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  # dash.rb : Implements stroke dashing
4
4
  #
@@ -9,6 +9,7 @@
9
9
  module Prawn
10
10
  module Graphics
11
11
  module Dash
12
+ # @group Stable API
12
13
 
13
14
  # Sets the dash pattern for stroked lines and curves or return the
14
15
  # current dash pattern setting if +length+ is nil.
@@ -27,8 +28,9 @@ module Prawn
27
28
  # 3 on, 2 off, 3 on, 2 off, ...
28
29
  #
29
30
  # * If the parameter +length+ is an array, it specifies the
30
- # lengths of alternating dashes and gaps. The :space option is
31
- # ignored in this case.
31
+ # lengths of alternating dashes and gaps. The numbers must be
32
+ # non-negative and not all zero. The :space option is ignored
33
+ # in this case.
32
34
  #
33
35
  # Examples:
34
36
  #
@@ -36,6 +38,8 @@ module Prawn
36
38
  # 2 on, 1 off, 2 on, 1 off, ...
37
39
  # length = [3, 1, 2, 3]
38
40
  # 3 on, 1 off, 2 on, 3 off, 3 on, 1 off, ...
41
+ # length = [3, 0, 1]
42
+ # 3 on, 0 off, 1 on, 3 off, 0 on, 1 off, ...
39
43
  #
40
44
  # Options may contain the keys :space and :phase
41
45
  #
@@ -51,17 +55,31 @@ module Prawn
51
55
  # Integers or Floats may be used for length and the option values.
52
56
  # Dash units are in PDF points (1/72 inch).
53
57
  #
54
- def dash(length=nil, options={})
58
+ def dash(length = nil, options = {})
55
59
  return current_dash_state if length.nil?
56
60
 
57
- self.current_dash_state = { :dash => length,
58
- :space => length.kind_of?(Array) ? nil : options[:space] || length,
59
- :phase => options[:phase] || 0 }
61
+ length = Array(length)
62
+
63
+ if length.all?(&:zero?)
64
+ raise ArgumentError,
65
+ 'Zero length dashes are invalid. Call #undash to disable dashes.'
66
+ elsif length.any?(&:negative?)
67
+ raise ArgumentError,
68
+ 'Negative numbers are not allowed for dash lengths.'
69
+ end
70
+
71
+ length = length.first if length.length == 1
72
+
73
+ self.current_dash_state = {
74
+ dash: length,
75
+ space: length.is_a?(Array) ? nil : options[:space] || length,
76
+ phase: options[:phase] || 0
77
+ }
60
78
 
61
79
  write_stroke_dash
62
80
  end
63
81
 
64
- alias_method :dash=, :dash
82
+ alias dash= dash
65
83
 
66
84
  # Stops dashing, restoring solid stroked lines and curves
67
85
  #
@@ -76,14 +94,14 @@ module Prawn
76
94
  current_dash_state != undashed_setting
77
95
  end
78
96
 
97
+ private
98
+
79
99
  def write_stroke_dash
80
- add_content dash_setting
100
+ renderer.add_content dash_setting
81
101
  end
82
102
 
83
- private
84
-
85
103
  def undashed_setting
86
- { :dash => nil, :space => nil, :phase => 0 }
104
+ { dash: nil, space: nil, phase: 0 }
87
105
  end
88
106
 
89
107
  def current_dash_state=(dash_options)
@@ -97,7 +115,6 @@ module Prawn
97
115
  def dash_setting
98
116
  graphic_state.dash_setting
99
117
  end
100
-
101
118
  end
102
119
  end
103
120
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  # join_style.rb : Implements stroke join styling
4
4
  #
@@ -9,7 +9,9 @@
9
9
  module Prawn
10
10
  module Graphics
11
11
  module JoinStyle
12
- JOIN_STYLES = { :miter => 0, :round => 1, :bevel => 2 }
12
+ JOIN_STYLES = { miter: 0, round: 1, bevel: 2 }.freeze
13
+
14
+ # @group Stable API
13
15
 
14
16
  # Sets the join style for stroked lines and curves
15
17
  #
@@ -18,15 +20,21 @@ module Prawn
18
20
  # NOTE: if this method is never called, :miter will be used for join style
19
21
  # throughout the document
20
22
  #
21
- def join_style(style=nil)
23
+ def join_style(style = nil)
22
24
  return current_join_style || :miter if style.nil?
23
25
 
24
26
  self.current_join_style = style
25
27
 
28
+ unless JOIN_STYLES.key?(current_join_style)
29
+ raise Prawn::Errors::InvalidJoinStyle,
30
+ "#{style} is not a recognized join style. Valid styles are " +
31
+ JOIN_STYLES.keys.join(', ')
32
+ end
33
+
26
34
  write_stroke_join_style
27
35
  end
28
36
 
29
- alias_method :join_style=, :join_style
37
+ alias join_style= join_style
30
38
 
31
39
  private
32
40
 
@@ -38,9 +46,8 @@ module Prawn
38
46
  graphic_state.join_style = style
39
47
  end
40
48
 
41
-
42
49
  def write_stroke_join_style
43
- add_content "#{JOIN_STYLES[current_join_style]} j"
50
+ renderer.add_content "#{JOIN_STYLES[current_join_style]} j"
44
51
  end
45
52
  end
46
53
  end
@@ -1,4 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest/sha1'
2
4
 
3
5
  # patterns.rb : Implements axial & radial gradients
4
6
  #
@@ -10,127 +12,256 @@
10
12
  module Prawn
11
13
  module Graphics
12
14
  module Patterns
15
+ GradientStop = Struct.new(:position, :color)
16
+ Gradient = Struct.new(
17
+ :type, :apply_transformations, :stops, :from, :to, :r1, :r2
18
+ )
13
19
 
14
- # Sets the fill gradient from color1 to color2.
15
- # old arguments: point, width, height, color1, color2, options = {}
16
- # new arguments: from, to, color1, color1
17
- # or from, r1, to, r2, color1, color2
18
- def fill_gradient(*args)
19
- if args[1].is_a?(Array) || args[2].is_a?(Array)
20
- set_gradient(:fill, *args)
21
- else
22
- warn "[DEPRECATION] 'fill_gradient(point, width, height,...)' is deprecated in favor of 'fill_gradient(from, to,...)'. " +
23
- "Old arguments will be removed in release 1.1"
24
- set_gradient :fill, args[0], [args[0].first, args[0].last - args[2]], args[3], args[4]
25
- end
20
+ # @group Stable API
21
+
22
+ # Sets the fill gradient.
23
+ # old arguments:
24
+ # from, to, color1, color2
25
+ # or
26
+ # from, r1, to, r2, color1, color2
27
+ # new arguments:
28
+ # from: [x, y]
29
+ # to: [x, y]
30
+ # r1: radius
31
+ # r2: radius
32
+ # stops: [color, color, ...] or
33
+ # { position => color, position => color, ... }
34
+ # apply_transformations: true
35
+ #
36
+ # Examples:
37
+ #
38
+ # # draws a horizontal axial gradient that starts at red on the left
39
+ # # and ends at blue on the right
40
+ # fill_gradient from: [0, 0], to: [100, 0], stops: ['red', 'blue']
41
+ #
42
+ # # draws a horizontal radial gradient that starts at red, is green
43
+ # # 80% of the way through, and finishes blue
44
+ # fill_gradient from: [0, 0], r1: 0, to: [100, 0], r2: 180,
45
+ # stops: { 0 => 'red', 0.8 => 'green', 1 => 'blue' }
46
+ #
47
+ # <tt>from</tt> and <tt>to</tt> specify the axis of where the gradient
48
+ # should be painted.
49
+ #
50
+ # <tt>r1</tt> and <tt>r2</tt>, if specified, make a radial gradient with
51
+ # the starting circle of radius <tt>r1</tt> centered at <tt>from</tt>
52
+ # and ending at a circle of radius <tt>r2</tt> centered at <tt>to</tt>.
53
+ # If <tt>r1</tt> is not specified, a axial gradient will be drawn.
54
+ #
55
+ # <tt>stops</tt> is an array or hash of stops. Each stop is either just a
56
+ # string indicating the color, in which case the stops will be evenly
57
+ # distributed across the gradient, or a hash where the key is
58
+ # a position between 0 and 1 indicating what distance through the
59
+ # gradient the color should change, and the value is a color string.
60
+ #
61
+ # Option <tt>apply_transformations</tt>, if set true, will transform the
62
+ # gradient's co-ordinate space so it matches the current co-ordinate
63
+ # space of the document. This option will be the default from Prawn v3,
64
+ # and is default true if you use the new arguments format.
65
+ # The default for the old arguments format, false, will mean if you
66
+ # (for example) scale your document by 2 and put a gradient inside, you
67
+ # will have to manually multiply your co-ordinates by 2 so the gradient
68
+ # is correctly positioned.
69
+ def fill_gradient(*args, **kwargs)
70
+ set_gradient(:fill, *args, **kwargs)
26
71
  end
27
72
 
28
- # Sets the stroke gradient from color1 to color2.
29
- # old arguments: point, width, height, color1, color2, options = {}
30
- # new arguments: from, to, color1, color2
31
- # or from, r1, to, r2, color1, color2
32
- def stroke_gradient(*args)
33
- if args[1].is_a?(Array) || args[2].is_a?(Array)
34
- set_gradient(:stroke, *args)
35
- else
36
- warn "[DEPRECATION] 'stroke_gradient(point, width, height,...)' is deprecated in favor of 'stroke_gradient(from, to,...)'. " +
37
- "Old arguments will be removed in release 1.1"
38
- set_gradient :stroke, args[0], [args[0].first, args[0].last - args[2]], args[3], args[4]
39
- end
73
+ # Sets the stroke gradient.
74
+ # See fill_gradient for a description of the arguments to this method.
75
+ def stroke_gradient(*args, **kwargs)
76
+ set_gradient(:stroke, *args, **kwargs)
40
77
  end
41
78
 
42
79
  private
43
80
 
44
- def set_gradient(type, *grad)
81
+ def set_gradient(type, *grad, **kwargs)
82
+ gradient = parse_gradient_arguments(*grad, **kwargs)
83
+
45
84
  patterns = page.resources[:Pattern] ||= {}
46
85
 
47
- registry_key = gradient_registry_key grad
86
+ registry_key = gradient_registry_key gradient
48
87
 
49
- if patterns["SP#{registry_key}"]
50
- shading = patterns["SP#{registry_key}"]
51
- else
52
- unless shading = gradient_registry[registry_key]
53
- shading = gradient(*grad)
88
+ unless patterns.key? "SP#{registry_key}"
89
+ shading = gradient_registry[registry_key]
90
+ unless shading
91
+ shading = create_gradient_pattern(gradient)
54
92
  gradient_registry[registry_key] = shading
55
93
  end
56
94
 
57
95
  patterns["SP#{registry_key}"] = shading
58
96
  end
59
97
 
60
- operator = case type
61
- when :fill
62
- 'scn'
63
- when :stroke
64
- 'SCN'
98
+ operator =
99
+ case type
100
+ when :fill
101
+ 'scn'
102
+ when :stroke
103
+ 'SCN'
104
+ else
105
+ raise ArgumentError, "unknown type '#{type}'"
106
+ end
107
+
108
+ set_color_space type, :Pattern
109
+ renderer.add_content "/SP#{registry_key} #{operator}"
110
+ end
111
+
112
+ # rubocop: disable Metrics/ParameterLists
113
+ def parse_gradient_arguments(
114
+ *arguments, from: nil, to: nil, r1: nil, r2: nil, stops: nil,
115
+ apply_transformations: nil
116
+ )
117
+
118
+ case arguments.length
119
+ when 0
120
+ apply_transformations = true if apply_transformations.nil?
121
+ when 4
122
+ from, to, *stops = arguments
123
+ when 6
124
+ from, r1, to, r2, *stops = arguments
65
125
  else
66
- raise ArgumentError, "unknown type '#{type}'"
126
+ raise ArgumentError, "Unknown type of gradient: #{arguments.inspect}"
67
127
  end
68
128
 
69
- set_color_space type, :Pattern
70
- add_content "/SP#{registry_key} #{operator}"
129
+ if stops.length < 2
130
+ raise ArgumentError, 'At least two stops must be specified'
131
+ end
132
+
133
+ stops =
134
+ stops.map.with_index do |stop, index|
135
+ case stop
136
+ when Array, Hash
137
+ position, color = stop
138
+ else
139
+ position = index / (stops.length.to_f - 1)
140
+ color = stop
141
+ end
142
+
143
+ unless (0..1).cover?(position)
144
+ raise ArgumentError, 'position must be between 0 and 1'
145
+ end
146
+
147
+ GradientStop.new(position, normalize_color(color))
148
+ end
149
+
150
+ if stops.first.position != 0
151
+ raise ArgumentError, 'The first stop must have a position of 0'
152
+ end
153
+ if stops.last.position != 1
154
+ raise ArgumentError, 'The last stop must have a position of 1'
155
+ end
156
+
157
+ if stops.map { |stop| color_type(stop.color) }.uniq.length > 1
158
+ raise ArgumentError, 'All colors must be of the same color space'
159
+ end
160
+
161
+ Gradient.new(
162
+ r1 ? :radial : :axial,
163
+ apply_transformations,
164
+ stops,
165
+ from,
166
+ to,
167
+ r1,
168
+ r2
169
+ )
71
170
  end
171
+ # rubocop: enable Metrics/ParameterLists
72
172
 
73
173
  def gradient_registry_key(gradient)
74
- if gradient[1].is_a?(Array) # axial
75
- [
76
- map_to_absolute(gradient[0]),
77
- map_to_absolute(gradient[1]),
78
- gradient[2], gradient[3]
79
- ]
80
- else # radial
81
- [
82
- map_to_absolute(gradient[0]),
83
- gradient[1],
84
- map_to_absolute(gradient[2]),
85
- gradient[3],
86
- gradient[4], gradient[5]
87
- ]
88
- end.hash
174
+ _x1, _y1, x2, y2, transformation = gradient_coordinates(gradient)
175
+
176
+ key = [
177
+ gradient.type.to_s,
178
+ transformation,
179
+ x2, y2,
180
+ gradient.r1 || -1, gradient.r2 || -1,
181
+ gradient.stops.length,
182
+ gradient.stops.map { |s| [s.position, s.color] }
183
+ ].flatten
184
+ Digest::SHA1.hexdigest(key.join(','))
89
185
  end
90
186
 
91
187
  def gradient_registry
92
188
  @gradient_registry ||= {}
93
189
  end
94
190
 
95
- def gradient(*args)
96
- if args.length != 4 && args.length != 6
97
- raise ArgumentError, "Unknown type of gradient: #{args.inspect}"
191
+ def create_gradient_pattern(gradient)
192
+ if gradient.apply_transformations.nil? &&
193
+ current_transformation_matrix_with_translation(0, 0) !=
194
+ [1, 0, 0, 1, 0, 0]
195
+ warn 'Gradients in Prawn 2.x and lower are not correctly positioned '\
196
+ 'when a transformation has been made to the document. ' \
197
+ "Pass 'apply_transformations: true' to correctly transform the " \
198
+ 'gradient, or see ' \
199
+ 'https://github.com/prawnpdf/prawn/wiki/Gradient-Transformations ' \
200
+ 'for more information.'
98
201
  end
99
202
 
100
- color1 = normalize_color(args[-2]).dup.freeze
101
- color2 = normalize_color(args[-1]).dup.freeze
203
+ shader_stops =
204
+ gradient.stops.each_cons(2).map do |first, second|
205
+ ref!(
206
+ FunctionType: 2,
207
+ Domain: [0.0, 1.0],
208
+ C0: first.color,
209
+ C1: second.color,
210
+ N: 1.0
211
+ )
212
+ end
102
213
 
103
- if color_type(color1) != color_type(color2)
104
- raise ArgumentError, "Both colors must be of the same color space: #{color1.inspect} and #{color2.inspect}"
105
- end
214
+ # If there's only two stops, we can use the single shader.
215
+ # Otherwise we stitch the multiple shaders together.
216
+ shader =
217
+ if shader_stops.length == 1
218
+ shader_stops.first
219
+ else
220
+ ref!(
221
+ FunctionType: 3, # stitching function
222
+ Domain: [0.0, 1.0],
223
+ Functions: shader_stops,
224
+ Bounds: gradient.stops[1..-2].map(&:position),
225
+ Encode: [0.0, 1.0] * shader_stops.length
226
+ )
227
+ end
228
+
229
+ x1, y1, x2, y2, transformation = gradient_coordinates(gradient)
230
+
231
+ coords =
232
+ if gradient.type == :axial
233
+ [0, 0, x2 - x1, y2 - y1]
234
+ else
235
+ [0, 0, gradient.r1, x2 - x1, y2 - y1, gradient.r2]
236
+ end
237
+
238
+ shading = ref!(
239
+ ShadingType: gradient.type == :axial ? 2 : 3,
240
+ ColorSpace: color_space(gradient.stops.first.color),
241
+ Coords: coords,
242
+ Function: shader,
243
+ Extend: [true, true]
244
+ )
245
+
246
+ ref!(
247
+ PatternType: 2, # shading pattern
248
+ Shading: shading,
249
+ Matrix: transformation
250
+ )
251
+ end
252
+
253
+ def gradient_coordinates(gradient)
254
+ x1, y1 = map_to_absolute(gradient.from)
255
+ x2, y2 = map_to_absolute(gradient.to)
256
+
257
+ transformation =
258
+ if gradient.apply_transformations
259
+ current_transformation_matrix_with_translation(x1, y1)
260
+ else
261
+ [1, 0, 0, 1, x1, y1]
262
+ end
106
263
 
107
- process_color color1
108
- process_color color2
109
-
110
- shader = ref!({
111
- :FunctionType => 2,
112
- :Domain => [0.0, 1.0],
113
- :C0 => color1,
114
- :C1 => color2,
115
- :N => 1.0,
116
- })
117
-
118
- shading = ref!({
119
- :ShadingType => args.length == 4 ? 2 : 3, # axial : radial shading
120
- :ColorSpace => color_space(color1),
121
- :Coords => args.length == 4 ?
122
- [0, 0, args[1].first - args[0].first, args[1].last - args[0].last] :
123
- [0, 0, args[1], args[2].first - args[0].first, args[2].last - args[0].last, args[3]],
124
- :Function => shader,
125
- :Extend => [true, true],
126
- })
127
-
128
- ref!({
129
- :PatternType => 2, # shading pattern
130
- :Shading => shading,
131
- :Matrix => [1, 0,
132
- 0, 1] + map_to_absolute(args[0]),
133
- })
264
+ [x1, y1, x2, y2, transformation]
134
265
  end
135
266
  end
136
267
  end
@@ -1,5 +1,5 @@
1
- # encoding: utf-8
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
  #
@@ -10,6 +10,7 @@
10
10
  module Prawn
11
11
  module Graphics
12
12
  module Transformation
13
+ # @group Stable API
13
14
 
14
15
  # Rotate the user space. If a block is not provided, then you must save
15
16
  # and restore the graphics state yourself.
@@ -39,7 +40,7 @@ module Prawn
39
40
  # pdf.stroke_rectangle([x, y], width, height)
40
41
  # end
41
42
  #
42
- def rotate(angle, options={}, &block)
43
+ def rotate(angle, options = {}, &block)
43
44
  Prawn.verify_options(:origin, options)
44
45
  rad = degree_to_rad(angle)
45
46
  cos = Math.cos(rad)
@@ -47,7 +48,8 @@ module Prawn
47
48
  if options[:origin].nil?
48
49
  transformation_matrix(cos, sin, -sin, cos, 0, 0, &block)
49
50
  else
50
- raise Prawn::Errors::BlockRequired unless block_given?
51
+ raise Prawn::Errors::BlockRequired unless block
52
+
51
53
  x = options[:origin][0] + bounds.absolute_left
52
54
  y = options[:origin][1] + bounds.absolute_bottom
53
55
  x_prime = x * cos - y * sin
@@ -58,8 +60,8 @@ module Prawn
58
60
  end
59
61
  end
60
62
 
61
- # Translate the user space. If a block is not provided, then you must save
62
- # 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.
63
65
  #
64
66
  # Example without a block: move the text up and over 10
65
67
  #
@@ -111,12 +113,13 @@ module Prawn
111
113
  # pdf.stroke_rectangle([x, y], width, height)
112
114
  # end
113
115
  #
114
- def scale(factor, options={}, &block)
116
+ def scale(factor, options = {}, &block)
115
117
  Prawn.verify_options(:origin, options)
116
118
  if options[:origin].nil?
117
119
  transformation_matrix(factor, 0, 0, factor, 0, 0, &block)
118
120
  else
119
- raise Prawn::Errors::BlockRequired unless block_given?
121
+ raise Prawn::Errors::BlockRequired unless block
122
+
120
123
  x = options[:origin][0] + bounds.absolute_left
121
124
  y = options[:origin][1] + bounds.absolute_bottom
122
125
  x_prime = factor * x
@@ -141,16 +144,22 @@ module Prawn
141
144
  # Transform the user space (see notes for rotate regarding graphics state)
142
145
  # Generally, one would use the rotate, scale, translate, and skew
143
146
  # convenience methods instead of calling transformation_matrix directly
144
- def transformation_matrix(a, b, c, d, e, f)
145
- values = [a, b, c, d, e, f].map { |x| "%.5f" % x }.join(" ")
147
+ def transformation_matrix(*matrix)
148
+ if matrix.length != 6
149
+ raise ArgumentError,
150
+ 'Transformation matrix must have exacty 6 elements'
151
+ end
146
152
  save_graphics_state if block_given?
147
- add_content "#{values} cm"
153
+
154
+ add_to_transformation_stack(*matrix)
155
+
156
+ values = PDF::Core.real_params(matrix)
157
+ renderer.add_content "#{values} cm"
148
158
  if block_given?
149
159
  yield
150
160
  restore_graphics_state
151
161
  end
152
162
  end
153
-
154
163
  end
155
164
  end
156
165
  end
@@ -1,5 +1,5 @@
1
- # encoding: utf-8
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.
@@ -9,7 +9,6 @@
9
9
 
10
10
  module Prawn
11
11
  module Graphics
12
-
13
12
  # The Prawn::Transparency module is used to place transparent
14
13
  # content on the page. It has the capacity for separate
15
14
  # transparency values for stroked content and all other content.
@@ -29,6 +28,7 @@ module Prawn
29
28
  # end
30
29
  #
31
30
  module Transparency
31
+ # @group Stable API
32
32
 
33
33
  # Sets the <tt>opacity</tt> and <tt>stroke_opacity</tt> for all
34
34
  # the content within the <tt>block</tt>
@@ -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, &block)
55
- min_version(1.4)
54
+ def transparent(opacity, stroke_opacity = opacity)
55
+ renderer.min_version(1.4)
56
56
 
57
- opacity = [[opacity, 0.0].max, 1.0].min
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
- add_content "/#{opacity_dictionary_name(opacity, stroke_opacity)} gs"
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,23 +79,25 @@ module Prawn
77
79
  key = "#{opacity}_#{stroke_opacity}"
78
80
 
79
81
  if opacity_dictionary_registry[key]
80
- dictionary = opacity_dictionary_registry[key][:obj]
81
- dictionary_name = opacity_dictionary_registry[key][:name]
82
+ dictionary = opacity_dictionary_registry[key][:obj]
83
+ dictionary_name = opacity_dictionary_registry[key][:name]
82
84
  else
83
- dictionary = ref!(:Type => :ExtGState,
84
- :CA => stroke_opacity,
85
- :ca => opacity
86
- )
85
+ dictionary = ref!(
86
+ Type: :ExtGState,
87
+ CA: stroke_opacity,
88
+ ca: opacity
89
+ )
87
90
 
88
91
  dictionary_name = "Tr#{next_opacity_dictionary_id}"
89
- opacity_dictionary_registry[key] = { :name => dictionary_name,
90
- :obj => dictionary }
92
+ opacity_dictionary_registry[key] = {
93
+ name: dictionary_name,
94
+ obj: dictionary
95
+ }
91
96
  end
92
97
 
93
- page.ext_gstates.merge!(dictionary_name => dictionary)
98
+ page.ext_gstates[dictionary_name] = dictionary
94
99
  dictionary_name
95
100
  end
96
-
97
101
  end
98
102
  end
99
103
  end