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
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Prawn::SoftMask do
6
+ let(:pdf) { create_pdf }
7
+
8
+ def make_soft_mask
9
+ pdf.save_graphics_state do
10
+ pdf.soft_mask do
11
+ if block_given?
12
+ yield
13
+ else
14
+ pdf.fill_color '808080'
15
+ pdf.fill_rectangle [100, 100], 200, 200
16
+ end
17
+ end
18
+
19
+ pdf.fill_color '000000'
20
+ pdf.fill_rectangle [0, 0], 200, 200
21
+ end
22
+ end
23
+
24
+ it 'has PDF version at least 1.4' do
25
+ make_soft_mask
26
+ str = pdf.render
27
+ expect(str[0, 8]).to eq('%PDF-1.4')
28
+ end
29
+
30
+ it 'creates a new extended graphics state for each unique soft mask' do
31
+ make_soft_mask do
32
+ pdf.fill_color '808080'
33
+ pdf.fill_rectangle [100, 100], 200, 200
34
+ end
35
+
36
+ make_soft_mask do
37
+ pdf.fill_color '808080'
38
+ pdf.fill_rectangle [10, 10], 200, 200
39
+ end
40
+
41
+ extgstates = PDF::Inspector::ExtGState.analyze(pdf.render).extgstates
42
+ expect(extgstates.length).to eq(2)
43
+ end
44
+
45
+ it 'a new extended graphics state contains soft mask with drawing '\
46
+ 'instructions' do
47
+ make_soft_mask do
48
+ pdf.fill_color '808080'
49
+ pdf.fill_rectangle [100, 100], 200, 200
50
+ end
51
+
52
+ extgstate = PDF::Inspector::ExtGState.analyze(pdf.render).extgstates.first
53
+ expect(extgstate[:soft_mask][:G].data).to eq(
54
+ "q\n/DeviceRGB cs\n0.0 0.0 0.0 scn\n/DeviceRGB CS\n0.0 0.0 0.0 SCN\n"\
55
+ "1 w\n0 J\n0 j\n[] 0 d\n/DeviceRGB cs\n0.50196 0.50196 0.50196 scn\n"\
56
+ "100.0 -100.0 200.0 200.0 re\nf\nQ\n"
57
+ )
58
+ end
59
+
60
+ it 'does not create duplicate extended graphics states' do
61
+ make_soft_mask do
62
+ pdf.fill_color '808080'
63
+ pdf.fill_rectangle [100, 100], 200, 200
64
+ end
65
+
66
+ make_soft_mask do
67
+ pdf.fill_color '808080'
68
+ pdf.fill_rectangle [100, 100], 200, 200
69
+ end
70
+
71
+ extgstates = PDF::Inspector::ExtGState.analyze(pdf.render).extgstates
72
+ expect(extgstates.length).to eq(1)
73
+ end
74
+ end
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Prawn::Stamp do
6
+ describe 'create_stamp before any page is added' do
7
+ let(:pdf) { Prawn::Document.new(skip_page_creation: true) }
8
+
9
+ it 'works with the font class' do
10
+ # If anything goes wrong, Prawn::Errors::NotOnPage will be raised
11
+ pdf.create_stamp('my_stamp') do
12
+ pdf.font.height
13
+ end
14
+ end
15
+
16
+ it 'works with setting color' do
17
+ # If anything goes wrong, Prawn::Errors::NotOnPage will be raised
18
+ pdf.create_stamp('my_stamp') do
19
+ pdf.fill_color = 'ff0000'
20
+ end
21
+ end
22
+ end
23
+
24
+ describe '#stamp_at' do
25
+ let(:pdf) { create_pdf }
26
+
27
+ it 'works' do
28
+ pdf.create_stamp('MyStamp')
29
+ pdf.stamp_at('MyStamp', [100, 200])
30
+ # I had modified PDF::Inspector::XObject to receive the
31
+ # invoke_xobject message and count the number of times it was
32
+ # called, but it was only called once, so I reverted checking the
33
+ # output with a regular expression
34
+ expect(pdf.render).to match(%r{/Stamp1 Do.*?}m)
35
+ end
36
+ end
37
+
38
+ describe 'Document with a stamp' do
39
+ let(:pdf) { create_pdf }
40
+
41
+ it 'raises NameTaken error when attempt to create stamp with '\
42
+ 'same name as an existing stamp' do
43
+ pdf.create_stamp('MyStamp')
44
+ expect do
45
+ pdf.create_stamp('MyStamp')
46
+ end.to raise_error(Prawn::Errors::NameTaken)
47
+ end
48
+
49
+ it 'raises InvalidName error when attempt to create stamp with '\
50
+ 'a blank name' do
51
+ expect do
52
+ pdf.create_stamp('')
53
+ end.to raise_error(Prawn::Errors::InvalidName)
54
+ end
55
+
56
+ it 'a new XObject should be defined for each stamp created' do
57
+ pdf.create_stamp('MyStamp')
58
+ pdf.create_stamp('AnotherStamp')
59
+ pdf.stamp('MyStamp')
60
+ pdf.stamp('AnotherStamp')
61
+
62
+ inspector = PDF::Inspector::XObject.analyze(pdf.render)
63
+ xobjects = inspector.page_xobjects.last
64
+ expect(xobjects.length).to eq(2)
65
+ end
66
+
67
+ it 'calling stamp with a name that does not match an existing stamp ' \
68
+ 'should raise_error UndefinedObjectName' do
69
+ pdf.create_stamp('MyStamp')
70
+ expect do
71
+ pdf.stamp('OtherStamp')
72
+ end.to raise_error(Prawn::Errors::UndefinedObjectName)
73
+ end
74
+
75
+ it 'stamp should be drawn into the document each time stamp is called' do
76
+ pdf.create_stamp('MyStamp')
77
+ pdf.stamp('MyStamp')
78
+ pdf.stamp('MyStamp')
79
+ pdf.stamp('MyStamp')
80
+ # I had modified PDF::Inspector::XObject to receive the
81
+ # invoke_xobject message and count the number of times it was
82
+ # called, but it was only called once, so I reverted checking the
83
+ # output with a regular expression
84
+ expect(pdf.render).to match(%r{(/Stamp1 Do.*?){3}}m)
85
+ end
86
+
87
+ it 'stamp should render clickable links' do
88
+ pdf.create_stamp 'bar' do
89
+ pdf.text '<b>Prawn</b> <link href="http://github.com">GitHub</link>',
90
+ inline_format: true
91
+ end
92
+ pdf.stamp 'bar'
93
+
94
+ output = pdf.render
95
+ objects = output.split('endobj')
96
+
97
+ objects.each do |obj|
98
+ next unless %r{/Type /Page$}.match?(obj)
99
+
100
+ # The page object must contain the annotation reference
101
+ # to render a clickable link
102
+ expect(obj).to match(%r{^/Annots \[\d \d .\]$})
103
+ end
104
+ end
105
+
106
+ it 'resources added during stamp creation should be added to the ' \
107
+ 'stamp XObject, not the page' do
108
+ pdf.create_stamp('MyStamp') do
109
+ pdf.transparent(0.5) { pdf.circle([100, 100], 10) }
110
+ end
111
+ pdf.stamp('MyStamp')
112
+
113
+ # Inspector::XObject does not give information about resources, so
114
+ # resorting to string matching
115
+
116
+ output = pdf.render
117
+ objects = output.split('endobj')
118
+ objects.each do |object|
119
+ case object
120
+ when %r{/Type /Page$}
121
+ expect(object).to_not match(%r{/ExtGState})
122
+ when %r{/Type /XObject$}
123
+ expect(object).to match(%r{/ExtGState})
124
+ end
125
+ end
126
+ end
127
+
128
+ it 'stamp stream should be wrapped in a graphic state' do
129
+ pdf.create_stamp('MyStamp') do
130
+ pdf.text "This should have a 'q' before it and a 'Q' after it"
131
+ end
132
+ pdf.stamp('MyStamp')
133
+ stamps = PDF::Inspector::XObject.analyze(pdf.render)
134
+ expect(stamps.xobject_streams[:Stamp1].data.chomp).to match(/q(.|\s)*Q\Z/)
135
+ end
136
+
137
+ it 'does not add to the page graphic state stack' do
138
+ expect(pdf.state.page.stack.stack.size).to eq(1)
139
+
140
+ pdf.create_stamp('MyStamp') do
141
+ pdf.save_graphics_state
142
+ pdf.save_graphics_state
143
+ pdf.save_graphics_state
144
+ pdf.text "This should have a 'q' before it and a 'Q' after it"
145
+ pdf.restore_graphics_state
146
+ end
147
+ expect(pdf.state.page.stack.stack.size).to eq(1)
148
+ end
149
+
150
+ it 'is able to change fill and stroke colors within the stamp stream' do
151
+ pdf.create_stamp('MyStamp') do
152
+ pdf.fill_color(100, 100, 20, 0)
153
+ pdf.stroke_color(100, 100, 20, 0)
154
+ end
155
+ pdf.stamp('MyStamp')
156
+ stamps = PDF::Inspector::XObject.analyze(pdf.render)
157
+ stamp_stream = stamps.xobject_streams[:Stamp1].data
158
+ expect(stamp_stream).to include("/DeviceCMYK cs\n1.0 1.0 0.2 0.0 scn")
159
+ expect(stamp_stream).to include("/DeviceCMYK CS\n1.0 1.0 0.2 0.0 SCN")
160
+ end
161
+
162
+ it 'saves the color space even when same as current page color space' do
163
+ pdf.stroke_color(100, 100, 20, 0)
164
+ pdf.create_stamp('MyStamp') do
165
+ pdf.stroke_color(100, 100, 20, 0)
166
+ end
167
+ pdf.stamp('MyStamp')
168
+ stamps = PDF::Inspector::XObject.analyze(pdf.render)
169
+ stamp_stream = stamps.xobject_streams[:Stamp1].data
170
+ expect(stamp_stream).to include("/DeviceCMYK CS\n1.0 1.0 0.2 0.0 SCN")
171
+ end
172
+ end
173
+ end