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
data/prawn.gemspec CHANGED
@@ -1,49 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ basedir = __dir__
4
+
5
+ require "#{basedir}/lib/prawn/version"
6
+
1
7
  Gem::Specification.new do |spec|
2
- spec.name = "prawn"
3
- spec.version = File.read(File.expand_path('VERSION', File.dirname(__FILE__))).strip
8
+ spec.name = 'prawn'
9
+ spec.version = Prawn::VERSION
4
10
  spec.platform = Gem::Platform::RUBY
5
- spec.summary = "A fast and nimble PDF generator for Ruby"
6
- spec.files = Dir.glob("{examples,lib,spec,manual}/**/**/*") +
7
- Dir.glob("data/{encodings,images,pdfs}/*") +
8
- Dir.glob("data/fonts/{MustRead.html,*.afm}") +
9
- ["data/shift_jis_text.txt"] +
10
- ["Rakefile", "prawn.gemspec", "Gemfile",
11
- "COPYING", "LICENSE", "GPLv2", "GPLv3"]
12
- spec.require_path = "lib"
13
- spec.required_ruby_version = '>= 1.9.3'
14
- spec.required_rubygems_version = ">= 1.3.6"
15
-
16
- spec.test_files = Dir[ "spec/*_spec.rb" ]
17
- spec.extra_rdoc_files = %w{README.md LICENSE COPYING GPLv2 GPLv3}
18
- spec.rdoc_options << '--title' << 'Prawn Documentation' <<
19
- '--main' << 'README.md' << '-q'
20
- spec.authors = ["Gregory Brown","Brad Ediger","Daniel Nelson","Jonathan Greenberg","James Healy"]
21
- spec.email = ["gregory.t.brown@gmail.com","brad@bradediger.com","dnelson@bluejade.com","greenberg@entryway.net","jimmy@deefa.com"]
22
- spec.rubyforge_project = "prawn"
23
- spec.add_dependency('pdf-reader', '~>1.2')
24
- spec.add_dependency('ttfunk', '~>1.0.3')
25
- spec.add_dependency('ruby-rc4')
26
- spec.add_dependency('afm')
27
- spec.add_development_dependency('pdf-inspector', '~> 1.1.0')
28
- spec.add_development_dependency('coderay', '~> 1.0.7')
29
- spec.add_development_dependency('rdoc')
30
- spec.homepage = "http://prawn.majesticseacreature.com"
11
+ spec.summary = 'A fast and nimble PDF generator for Ruby'
12
+
13
+ spec.cert_chain = ['certs/pointlessone.pem']
14
+ if $PROGRAM_NAME.end_with? 'gem'
15
+ spec.signing_key = File.expand_path('~/.gem/gem-private_key.pem')
16
+ end
17
+
18
+ spec.files = Dir.glob('{examples,lib,spec,manual}/**/**/*') +
19
+ Dir.glob('data/fonts/{MustRead.html,*.afm}') +
20
+ [
21
+ 'Rakefile', 'prawn.gemspec', 'Gemfile',
22
+ 'COPYING', 'LICENSE', 'GPLv2', 'GPLv3',
23
+ '.yardopts'
24
+ ]
25
+ spec.require_path = 'lib'
26
+ spec.required_ruby_version = '>= 2.5'
27
+ spec.required_rubygems_version = '>= 1.3.6'
28
+
29
+ spec.authors = [
30
+ 'Gregory Brown', 'Brad Ediger', 'Daniel Nelson', 'Jonathan Greenberg',
31
+ 'James Healy'
32
+ ]
33
+ spec.email = [
34
+ 'gregory.t.brown@gmail.com', 'brad@bradediger.com', 'dnelson@bluejade.com',
35
+ 'greenberg@entryway.net', 'jimmy@deefa.com'
36
+ ]
37
+ spec.licenses = %w[PRAWN GPL-2.0 GPL-3.0]
38
+
39
+ spec.add_dependency('pdf-core', '~> 0.9.0')
40
+ spec.add_dependency('ttfunk', '~> 1.7')
41
+
42
+ spec.add_development_dependency('pdf-inspector', '>= 1.2.1', '< 2.0.a')
43
+ spec.add_development_dependency('pdf-reader', ['~> 1.4', '>= 1.4.1'])
44
+ spec.add_development_dependency('prawn-dev', '~> 0.1.0')
45
+ spec.add_development_dependency('prawn-manual_builder', '>= 0.3.0')
46
+
47
+ spec.homepage = 'http://prawnpdf.org'
31
48
  spec.description = <<END_DESC
32
49
  Prawn is a fast, tiny, and nimble PDF generator for Ruby
33
- END_DESC
34
- spec.post_install_message = <<END_DESC
35
-
36
- ********************************************
37
-
38
-
39
- A lot has changed recently in Prawn.
40
-
41
- Please read the changelog for details:
42
-
43
- https://github.com/prawnpdf/prawn/wiki/CHANGELOG
44
-
45
-
46
- ********************************************
47
-
48
50
  END_DESC
49
51
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EncodingHelpers
2
4
  def win1252_string(str)
3
- ruby_19 { str.force_encoding("Windows-1252") }
4
- str
5
+ str.dup.force_encoding(Encoding::Windows_1252)
5
6
  end
6
7
 
7
8
  def bin_string(str)
8
- ruby_19 { str.force_encoding("ASCII-8BIT") } || ruby_18 { str }
9
+ str.dup.force_encoding(Encoding::ASCII_8BIT)
9
10
  end
10
11
  end
@@ -0,0 +1,550 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Prawn::Document::BoundingBox do
6
+ let(:pdf) { create_pdf }
7
+
8
+ describe 'attributes' do
9
+ let(:box) do
10
+ described_class.new(
11
+ nil,
12
+ nil,
13
+ [100, 125],
14
+ width: 50,
15
+ height: 75
16
+ )
17
+ end
18
+
19
+ it 'has an anchor at (x, y - height)' do
20
+ expect(box.anchor).to eq([100, 50])
21
+ end
22
+
23
+ it 'has a left boundary of 0' do
24
+ expect(box.left).to eq(0)
25
+ end
26
+
27
+ it 'has a right boundary equal to the width' do
28
+ expect(box.right).to eq(50)
29
+ end
30
+
31
+ it 'has a top boundary of height' do
32
+ expect(box.top).to eq(75)
33
+ end
34
+
35
+ it 'has a bottom boundary of 0' do
36
+ expect(box.bottom).to eq(0)
37
+ end
38
+
39
+ it 'has a top-left of [0, height]' do
40
+ expect(box.top_left).to eq([0, 75])
41
+ end
42
+
43
+ it 'has a top-right of [width, height]' do
44
+ expect(box.top_right).to eq([50, 75])
45
+ end
46
+
47
+ it 'has a bottom-left of [0, 0]' do
48
+ expect(box.bottom_left).to eq([0, 0])
49
+ end
50
+
51
+ it 'has a bottom-right of [width ,0]' do
52
+ expect(box.bottom_right).to eq([50, 0])
53
+ end
54
+
55
+ it 'has an absolute left boundary of x' do
56
+ expect(box.absolute_left).to eq(100)
57
+ end
58
+
59
+ it 'has an absolute right boundary of x + width' do
60
+ expect(box.absolute_right).to eq(150)
61
+ end
62
+
63
+ it 'has an absolute top boundary of y' do
64
+ expect(box.absolute_top).to eq(125)
65
+ end
66
+
67
+ it 'has an absolute bottom boundary of y - height' do
68
+ expect(box.absolute_bottom).to eq(50)
69
+ end
70
+
71
+ it 'has an absolute bottom-left of [x, y - height]' do
72
+ expect(box.absolute_bottom_left).to eq([100, 50])
73
+ end
74
+
75
+ it 'has an absolute bottom-right of [x + width, y - height]' do
76
+ expect(box.absolute_bottom_right).to eq([150, 50])
77
+ end
78
+
79
+ it 'has an absolute top-left of [x, y]' do
80
+ expect(box.absolute_top_left).to eq([100, 125])
81
+ end
82
+
83
+ it 'has an absolute top-right of [x + width, y]' do
84
+ expect(box.absolute_top_right).to eq([150, 125])
85
+ end
86
+ end
87
+
88
+ describe 'validations' do
89
+ it 'requires width to be set' do
90
+ expect do
91
+ described_class.new(nil, nil, [100, 100])
92
+ end.to raise_error(ArgumentError)
93
+ end
94
+
95
+ it 'raise_errors an ArgumentError if a block is not passed' do
96
+ pdf = Prawn::Document.new
97
+ expect do
98
+ pdf.bounding_box([0, 0], width: 200)
99
+ end.to raise_error(ArgumentError)
100
+ end
101
+ end
102
+
103
+ describe 'drawing' do
104
+ it 'does not stomp on the arguments to bounding_box' do
105
+ pdf = Prawn::Document.new
106
+ x = [100, 500]
107
+ pdf.bounding_box x, width: 100 do
108
+ pdf.text 'bork-bork-bork'
109
+ end
110
+ expect(x).to eq([100, 500])
111
+ end
112
+
113
+ it 'restores Document#bounds to the correct margin box on exit' do
114
+ pdf = Prawn::Document.new(margin: 200)
115
+
116
+ # add a multi-page bounding box
117
+ pdf.bounding_box([100, pdf.bounds.top], width: 400) do
118
+ pdf.text "The rain in spain falls mainly in the plains.\n" * 30
119
+ end
120
+
121
+ pdf.start_new_page(margin: 0)
122
+
123
+ x_min, y_min, x_max, y_max = pdf.page.dimensions
124
+
125
+ expect(pdf.bounds.absolute_top_left).to eq([x_min, y_max])
126
+ expect(pdf.bounds.absolute_bottom_right).to eq([x_max, y_min])
127
+ end
128
+
129
+ it 'restores the parent bounding box when calls are nested' do
130
+ pdf.bounding_box [100, 500], width: 300, height: 300 do
131
+ expect(pdf.bounds.absolute_top)
132
+ .to eq(500 + pdf.margin_box.absolute_bottom)
133
+ expect(pdf.bounds.absolute_left)
134
+ .to eq(100 + pdf.margin_box.absolute_left)
135
+
136
+ parent_box = pdf.bounds
137
+
138
+ pdf.bounding_box [50, 200], width: 100, height: 100 do
139
+ expect(pdf.bounds.absolute_top)
140
+ .to eq(200 + parent_box.absolute_bottom)
141
+ expect(pdf.bounds.absolute_left).to eq(50 + parent_box.absolute_left)
142
+ end
143
+
144
+ expect(pdf.bounds.absolute_top)
145
+ .to eq(500 + pdf.margin_box.absolute_bottom)
146
+ expect(pdf.bounds.absolute_left)
147
+ .to eq(100 + pdf.margin_box.absolute_left)
148
+ end
149
+ end
150
+
151
+ it 'calculates a height if none is specified' do
152
+ pdf.bounding_box([100, 500], width: 100) do
153
+ pdf.text 'The rain in Spain falls mainly on the plains.'
154
+ end
155
+
156
+ expect(pdf.y).to be_within(0.001).of(458.384)
157
+ end
158
+
159
+ it 'keeps track of the max height the box was stretched to' do
160
+ box =
161
+ pdf.bounding_box(pdf.bounds.top_left, width: 100) do
162
+ pdf.move_down 100
163
+ pdf.move_up 15
164
+ end
165
+
166
+ expect(box.height).to eq(100)
167
+ end
168
+
169
+ it 'advances the y-position by bbox.height by default' do
170
+ orig_y = pdf.y
171
+ pdf.bounding_box [0, pdf.cursor], width: pdf.bounds.width, height: 30 do
172
+ pdf.text 'hello'
173
+ end
174
+ expect(pdf.y).to be_within(0.001).of(orig_y - 30)
175
+ end
176
+
177
+ it 'does not advance y-position if passed :hold_position => true' do
178
+ orig_y = pdf.y
179
+ pdf.bounding_box(
180
+ [0, pdf.cursor],
181
+ width: pdf.bounds.width,
182
+ hold_position: true
183
+ ) do
184
+ pdf.text 'hello'
185
+ end
186
+ # y only advances by height of one line ("hello")
187
+ expect(pdf.y).to be_within(0.001).of(orig_y - pdf.height_of('hello'))
188
+ end
189
+
190
+ it 'does not advance y-position of a stretchy bbox if it would stretch '\
191
+ 'the bbox further' do
192
+ bottom = pdf.y = pdf.margin_box.absolute_bottom
193
+ pdf.bounding_box [0, pdf.margin_box.top], width: pdf.bounds.width do
194
+ pdf.y = bottom
195
+ pdf.text 'hello' # starts a new page
196
+ end
197
+ expect(pdf.page_count).to eq(2)
198
+
199
+ # Restoring the position (to the absolute bottom) would stretch the bbox
200
+ # to the bottom of the page, which we don't want. This should be
201
+ # equivalent to a bbox with :hold_position => true, where we only advance
202
+ # by the amount that was actually drawn.
203
+ expect(pdf.y).to be_within(0.001).of(
204
+ pdf.margin_box.absolute_top - pdf.height_of('hello')
205
+ )
206
+ end
207
+ end
208
+
209
+ describe 'Indentation' do
210
+ it 'temporarilies shift the x coordinate and width' do
211
+ pdf.bounding_box([100, 100], width: 200) do
212
+ pdf.indent(20) do
213
+ expect(pdf.bounds.absolute_left).to eq(120)
214
+ expect(pdf.bounds.width).to eq(180)
215
+ end
216
+ end
217
+ end
218
+
219
+ it 'restores the x coordinate and width after block exits' do
220
+ pdf.bounding_box([100, 100], width: 200) do
221
+ pdf.indent(20) do
222
+ # no-op
223
+ end
224
+ expect(pdf.bounds.absolute_left).to eq(100)
225
+ expect(pdf.bounds.width).to eq(200)
226
+ end
227
+ end
228
+
229
+ it 'restores the x coordinate and width on error' do
230
+ pdf.bounding_box([100, 100], width: 200) do
231
+ pdf.indent(20) { raise }
232
+ rescue StandardError
233
+ expect(pdf.bounds.absolute_left).to eq(100)
234
+ expect(pdf.bounds.width).to eq(200)
235
+ end
236
+ end
237
+
238
+ it 'maintains left indentation across a page break' do
239
+ original_left = pdf.bounds.absolute_left
240
+
241
+ pdf.indent(20) do
242
+ expect(pdf.bounds.absolute_left).to eq(original_left + 20)
243
+ pdf.start_new_page
244
+ expect(pdf.bounds.absolute_left).to eq(original_left + 20)
245
+ end
246
+
247
+ expect(pdf.bounds.absolute_left).to eq(original_left)
248
+ end
249
+
250
+ it 'maintains right indentation across a page break' do
251
+ original_width = pdf.bounds.width
252
+
253
+ pdf.indent(0, 20) do
254
+ expect(pdf.bounds.width).to eq(original_width - 20)
255
+ pdf.start_new_page
256
+ expect(pdf.bounds.width).to eq(original_width - 20)
257
+ end
258
+
259
+ expect(pdf.bounds.width).to eq(original_width)
260
+ end
261
+
262
+ it 'optionally allows adjustment of the right bound as well' do
263
+ pdf.bounding_box([100, 100], width: 200) do
264
+ pdf.indent(20, 30) do
265
+ expect(pdf.bounds.absolute_left).to eq(120)
266
+ expect(pdf.bounds.width).to eq(150)
267
+ end
268
+ expect(pdf.bounds.absolute_left).to eq(100)
269
+ expect(pdf.bounds.width).to eq(200)
270
+ end
271
+ end
272
+
273
+ describe 'in a ColumnBox' do
274
+ it 'subtracts the given indentation from the available width' do
275
+ pdf.column_box(
276
+ [0, pdf.cursor],
277
+ width: pdf.bounds.width,
278
+ height: 200,
279
+ columns: 2,
280
+ spacer: 20
281
+ ) do
282
+ width = pdf.bounds.width
283
+ pdf.indent(20) do
284
+ expect(pdf.bounds.width).to be_within(0.01).of(width - 20)
285
+ end
286
+ end
287
+ end
288
+
289
+ it 'subtracts right padding from the available width' do
290
+ pdf.column_box(
291
+ [0, pdf.cursor],
292
+ width: pdf.bounds.width,
293
+ height: 200,
294
+ columns: 2,
295
+ spacer: 20
296
+ ) do
297
+ width = pdf.bounds.width
298
+ pdf.indent(20, 30) do
299
+ expect(pdf.bounds.width).to be_within(0.01).of(width - 50)
300
+ end
301
+ end
302
+ end
303
+
304
+ it 'maintains the same left indentation across column breaks' do
305
+ pdf.column_box(
306
+ [0, pdf.cursor],
307
+ width: pdf.bounds.width,
308
+ columns: 3,
309
+ spacer: 15
310
+ ) do
311
+ 3.times do |_column|
312
+ x = pdf.bounds.left_side
313
+ pdf.indent(20) do
314
+ expect(pdf.bounds.left_side).to eq(x + 20)
315
+ end
316
+ pdf.bounds.move_past_bottom
317
+ end
318
+ end
319
+ end
320
+
321
+ it 'does not change the right margin if only left indentation is '\
322
+ 'requested' do
323
+ pdf.column_box(
324
+ [0, pdf.cursor],
325
+ width: pdf.bounds.width,
326
+ columns: 3,
327
+ spacer: 15
328
+ ) do
329
+ 3.times do |_column|
330
+ x = pdf.bounds.right_side
331
+ pdf.indent(20) do
332
+ expect(pdf.bounds.right_side).to eq(x)
333
+ end
334
+ pdf.bounds.move_past_bottom
335
+ end
336
+ end
337
+ end
338
+
339
+ it 'maintains the same right indentation across columns' do
340
+ pdf.column_box(
341
+ [0, pdf.cursor],
342
+ width: pdf.bounds.width,
343
+ columns: 3,
344
+ spacer: 15
345
+ ) do
346
+ 3.times do |_column|
347
+ x = pdf.bounds.right_side
348
+ pdf.indent(20, 10) do
349
+ expect(pdf.bounds.right_side).to eq(x - 10)
350
+ end
351
+ pdf.bounds.move_past_bottom
352
+ end
353
+ end
354
+ end
355
+
356
+ it 'keeps the right indentation after nesting indents' do
357
+ pdf.column_box(
358
+ [0, pdf.cursor],
359
+ width: pdf.bounds.width,
360
+ columns: 3,
361
+ spacer: 15
362
+ ) do
363
+ 3.times do |_column|
364
+ # I am giving a right indent of 10...
365
+ pdf.indent(20, 10) do
366
+ x = pdf.bounds.right_side
367
+ # ...and no right indent here...
368
+ pdf.indent(20) do
369
+ # right indent is inherited from the parent!
370
+ expect(pdf.bounds.right_side).to eq(x)
371
+ end
372
+ end
373
+ pdf.bounds.move_past_bottom
374
+ end
375
+ end
376
+ end
377
+
378
+ it 'reverts the right indentation if negative indent is given in '\
379
+ 'nested indent' do
380
+ pdf.column_box(
381
+ [0, pdf.cursor],
382
+ width: pdf.bounds.width,
383
+ columns: 3,
384
+ spacer: 15
385
+ ) do
386
+ 3.times do |_column|
387
+ x = pdf.bounds.right_side
388
+ pdf.indent(20, 10) do
389
+ # requesting a negative right-indent of equivalent size...
390
+ pdf.indent(20, -10) do
391
+ # ...resets the right margin to that of the column!
392
+ expect(pdf.bounds.right_side).to eq(x)
393
+ end
394
+ end
395
+ pdf.bounds.move_past_bottom
396
+ end
397
+ end
398
+ end
399
+
400
+ it 'reduces the available column width by the sum of ' \
401
+ 'all nested indents' do
402
+ pdf.column_box(
403
+ [0, pdf.cursor],
404
+ width: pdf.bounds.width,
405
+ columns: 3,
406
+ spacer: 15
407
+ ) do
408
+ 3.times do |_column|
409
+ w = pdf.bounds.width
410
+ pdf.indent(20, 10) do
411
+ pdf.indent(20, 10) do
412
+ expect(pdf.bounds.width).to eq(w - 60)
413
+ end
414
+ end
415
+ pdf.bounds.move_past_bottom
416
+ end
417
+ end
418
+ end
419
+ end
420
+ end
421
+
422
+ describe 'A canvas' do
423
+ it 'uses whatever the last set y position is' do
424
+ pdf.canvas do
425
+ pdf.bounding_box([100, 500], width: 200) { pdf.move_down 50 }
426
+ end
427
+ expect(pdf.y).to eq(450)
428
+ end
429
+
430
+ it 'restores the original ypos after execution', issue: 523 do
431
+ doc = Prawn::Document.new(skip_page_creation: true)
432
+ doc.start_new_page
433
+
434
+ original_ypos = doc.y
435
+
436
+ doc.canvas do
437
+ # draw
438
+ end
439
+
440
+ expect(doc.y).to eq(original_ypos)
441
+ end
442
+ end
443
+
444
+ describe 'Deep-copying' do
445
+ it 'creates a new object that does not copy @document' do
446
+ Prawn::Document.new do |pdf|
447
+ orig = pdf.bounds
448
+ copy = orig.deep_copy
449
+
450
+ expect(copy).to_not eq(pdf.bounds)
451
+ expect(copy.document).to be_nil
452
+ end
453
+ end
454
+
455
+ it 'deep-copies parent bounds' do
456
+ Prawn::Document.new do |pdf|
457
+ outside = pdf.bounds
458
+ pdf.bounding_box [100, 100], width: 100 do
459
+ copy = pdf.bounds.deep_copy
460
+
461
+ # the parent bounds should have the same parameters
462
+ expect(copy.parent.width).to eq(outside.width)
463
+ expect(copy.parent.height).to eq(outside.height)
464
+
465
+ # but should not be the same object
466
+ expect(copy.parent).to_not eq(outside)
467
+ end
468
+ end
469
+ end
470
+ end
471
+
472
+ describe 'Prawn::Document#reference_bounds' do
473
+ it 'returns self for non-stretchy bounds' do
474
+ pdf.bounding_box([0, pdf.cursor], width: 100, height: 100) do
475
+ expect(pdf.reference_bounds).to eq(pdf.bounds)
476
+ end
477
+ end
478
+
479
+ it 'returns the parent bounds if in a stretchy box' do
480
+ pdf.bounding_box([0, pdf.cursor], width: 100, height: 100) do
481
+ correct_bounds = pdf.bounds
482
+ pdf.bounding_box([0, pdf.cursor], width: 100) do
483
+ expect(pdf.reference_bounds).to eq(correct_bounds)
484
+ end
485
+ end
486
+ end
487
+
488
+ it 'finds the non-stretchy box through 2 levels' do
489
+ pdf.bounding_box([0, pdf.cursor], width: 100, height: 100) do
490
+ correct_bounds = pdf.bounds
491
+ pdf.bounding_box([0, pdf.cursor], width: 100) do
492
+ pdf.bounding_box([0, pdf.cursor], width: 100) do
493
+ expect(pdf.reference_bounds).to eq(correct_bounds)
494
+ end
495
+ end
496
+ end
497
+ end
498
+
499
+ it "returns the margin box if there's no explicit bbox" do
500
+ expect(pdf.reference_bounds).to eq(pdf.margin_box)
501
+
502
+ pdf.bounding_box([0, pdf.cursor], width: 100) do
503
+ expect(pdf.reference_bounds).to eq(pdf.margin_box)
504
+ end
505
+ end
506
+
507
+ it "returns the canvas box if we're in a canvas" do
508
+ pdf.canvas do
509
+ canvas_box = pdf.bounds
510
+
511
+ expect(pdf.reference_bounds).to eq(canvas_box)
512
+
513
+ pdf.bounding_box([0, pdf.cursor], width: 100) do
514
+ expect(pdf.reference_bounds).to eq(canvas_box)
515
+ end
516
+ end
517
+ end
518
+ end
519
+
520
+ describe '#move_past_bottom' do
521
+ it 'ordinarilies start a new page' do
522
+ pdf.bounds.move_past_bottom
523
+ pdf.text 'Foo'
524
+
525
+ pages = PDF::Inspector::Page.analyze(pdf.render).pages
526
+ expect(pages.size).to eq(2)
527
+ expect(pages[0][:strings]).to eq([])
528
+ expect(pages[1][:strings]).to eq(['Foo'])
529
+ end
530
+
531
+ it 'moves to the top of the next page if it exists already' do
532
+ # save away the y-position at the top of a page
533
+ top_y = pdf.y
534
+
535
+ # create a blank page but go to the page before it
536
+ pdf.start_new_page
537
+ pdf.go_to_page 1
538
+ pdf.text 'Foo'
539
+
540
+ pdf.bounds.move_past_bottom
541
+ expect(pdf.y).to be_within(0.001).of(top_y)
542
+ pdf.text 'Bar'
543
+
544
+ pages = PDF::Inspector::Page.analyze(pdf.render).pages
545
+ expect(pages.size).to eq(2)
546
+ expect(pages[0][:strings]).to eq(['Foo'])
547
+ expect(pages[1][:strings]).to eq(['Bar'])
548
+ end
549
+ end
550
+ end