prawn 2.1.0 → 2.2.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 (278) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +0 -0
  4. data/Gemfile +1 -9
  5. data/Rakefile +12 -22
  6. data/lib/prawn.rb +29 -48
  7. data/lib/prawn/document.rb +148 -123
  8. data/lib/prawn/document/bounding_box.rb +33 -26
  9. data/lib/prawn/document/column_box.rb +5 -7
  10. data/lib/prawn/document/internals.rb +6 -6
  11. data/lib/prawn/document/span.rb +20 -17
  12. data/lib/prawn/encoding.rb +65 -67
  13. data/lib/prawn/errors.rb +10 -7
  14. data/lib/prawn/font.rb +78 -62
  15. data/lib/prawn/font/afm.rb +93 -66
  16. data/lib/prawn/font/dfont.rb +2 -10
  17. data/lib/prawn/font/ttc.rb +34 -0
  18. data/lib/prawn/font/ttf.rb +73 -65
  19. data/lib/prawn/font_metric_cache.rb +9 -8
  20. data/lib/prawn/graphics.rb +110 -70
  21. data/lib/prawn/graphics/blend_mode.rb +7 -8
  22. data/lib/prawn/graphics/cap_style.rb +2 -4
  23. data/lib/prawn/graphics/color.rb +23 -26
  24. data/lib/prawn/graphics/dash.rb +22 -12
  25. data/lib/prawn/graphics/join_style.rb +8 -4
  26. data/lib/prawn/graphics/patterns.rb +185 -96
  27. data/lib/prawn/graphics/transformation.rb +11 -9
  28. data/lib/prawn/graphics/transparency.rb +15 -13
  29. data/lib/prawn/grid.rb +20 -20
  30. data/lib/prawn/image_handler.rb +4 -6
  31. data/lib/prawn/images.rb +22 -15
  32. data/lib/prawn/images/image.rb +0 -1
  33. data/lib/prawn/images/jpg.rb +26 -22
  34. data/lib/prawn/images/png.rb +60 -57
  35. data/lib/prawn/measurement_extensions.rb +8 -9
  36. data/lib/prawn/measurements.rb +14 -15
  37. data/lib/prawn/outline.rb +96 -78
  38. data/lib/prawn/repeater.rb +12 -10
  39. data/lib/prawn/security.rb +66 -48
  40. data/lib/prawn/security/arcfour.rb +1 -3
  41. data/lib/prawn/soft_mask.rb +23 -25
  42. data/lib/prawn/stamp.rb +16 -12
  43. data/lib/prawn/text.rb +59 -45
  44. data/lib/prawn/text/box.rb +9 -8
  45. data/lib/prawn/text/formatted.rb +4 -6
  46. data/lib/prawn/text/formatted/arranger.rb +51 -30
  47. data/lib/prawn/text/formatted/box.rb +112 -88
  48. data/lib/prawn/text/formatted/fragment.rb +10 -15
  49. data/lib/prawn/text/formatted/line_wrap.rb +118 -61
  50. data/lib/prawn/text/formatted/parser.rb +134 -110
  51. data/lib/prawn/text/formatted/wrap.rb +42 -32
  52. data/lib/prawn/transformation_stack.rb +3 -4
  53. data/lib/prawn/utilities.rb +6 -21
  54. data/lib/prawn/version.rb +1 -3
  55. data/lib/prawn/view.rb +4 -2
  56. data/manual/basic_concepts/adding_pages.rb +4 -7
  57. data/manual/basic_concepts/basic_concepts.rb +29 -22
  58. data/manual/basic_concepts/creation.rb +8 -11
  59. data/manual/basic_concepts/cursor.rb +2 -5
  60. data/manual/basic_concepts/measurement.rb +3 -6
  61. data/manual/basic_concepts/origin.rb +3 -6
  62. data/manual/basic_concepts/other_cursor_helpers.rb +9 -12
  63. data/manual/basic_concepts/view.rb +20 -16
  64. data/manual/bounding_box/bounding_box.rb +27 -24
  65. data/manual/bounding_box/bounds.rb +9 -12
  66. data/manual/bounding_box/canvas.rb +2 -5
  67. data/manual/bounding_box/creation.rb +4 -7
  68. data/manual/bounding_box/indentation.rb +12 -15
  69. data/manual/bounding_box/nesting.rb +22 -17
  70. data/manual/bounding_box/russian_boxes.rb +8 -9
  71. data/manual/bounding_box/stretchy.rb +10 -13
  72. data/manual/contents.rb +26 -22
  73. data/manual/cover.rb +22 -20
  74. data/manual/document_and_page_options/background.rb +9 -13
  75. data/manual/document_and_page_options/document_and_page_options.rb +23 -20
  76. data/manual/document_and_page_options/metadata.rb +16 -16
  77. data/manual/document_and_page_options/page_margins.rb +16 -20
  78. data/manual/document_and_page_options/page_size.rb +11 -12
  79. data/manual/document_and_page_options/print_scaling.rb +15 -15
  80. data/manual/example_helper.rb +2 -4
  81. data/manual/graphics/blend_mode.rb +10 -9
  82. data/manual/graphics/circle_and_ellipse.rb +2 -5
  83. data/manual/graphics/color.rb +5 -9
  84. data/manual/graphics/common_lines.rb +5 -8
  85. data/manual/graphics/fill_and_stroke.rb +2 -5
  86. data/manual/graphics/fill_rules.rb +7 -10
  87. data/manual/graphics/gradients.rb +25 -21
  88. data/manual/graphics/graphics.rb +49 -43
  89. data/manual/graphics/helper.rb +10 -9
  90. data/manual/graphics/line_width.rb +5 -7
  91. data/manual/graphics/lines_and_curves.rb +5 -8
  92. data/manual/graphics/polygon.rb +4 -8
  93. data/manual/graphics/rectangle.rb +2 -5
  94. data/manual/graphics/rotate.rb +4 -7
  95. data/manual/graphics/scale.rb +12 -15
  96. data/manual/graphics/soft_masks.rb +1 -4
  97. data/manual/graphics/stroke_cap.rb +3 -6
  98. data/manual/graphics/stroke_dash.rb +9 -12
  99. data/manual/graphics/stroke_join.rb +2 -5
  100. data/manual/graphics/translate.rb +7 -10
  101. data/manual/graphics/transparency.rb +5 -8
  102. data/manual/how_to_read_this_manual.rb +4 -6
  103. data/manual/images/absolute_position.rb +4 -7
  104. data/manual/images/fit.rb +5 -8
  105. data/manual/images/horizontal.rb +6 -9
  106. data/manual/images/images.rb +25 -23
  107. data/manual/images/plain_image.rb +3 -6
  108. data/manual/images/scale.rb +7 -10
  109. data/manual/images/vertical.rb +10 -13
  110. data/manual/images/width_and_height.rb +8 -11
  111. data/manual/layout/boxes.rb +3 -6
  112. data/manual/layout/content.rb +5 -8
  113. data/manual/layout/layout.rb +16 -16
  114. data/manual/layout/simple_grid.rb +4 -7
  115. data/manual/outline/add_subsection_to.rb +18 -21
  116. data/manual/outline/insert_section_after.rb +13 -16
  117. data/manual/outline/outline.rb +19 -17
  118. data/manual/outline/sections_and_pages.rb +15 -18
  119. data/manual/repeatable_content/alternate_page_numbering.rb +19 -17
  120. data/manual/repeatable_content/page_numbering.rb +15 -16
  121. data/manual/repeatable_content/repeatable_content.rb +23 -19
  122. data/manual/repeatable_content/repeater.rb +12 -15
  123. data/manual/repeatable_content/stamp.rb +12 -15
  124. data/manual/security/encryption.rb +7 -10
  125. data/manual/security/permissions.rb +17 -14
  126. data/manual/security/security.rb +17 -16
  127. data/manual/table.rb +2 -4
  128. data/manual/text/alignment.rb +14 -17
  129. data/manual/text/color.rb +10 -11
  130. data/manual/text/column_box.rb +5 -8
  131. data/manual/text/fallback_fonts.rb +23 -21
  132. data/manual/text/font.rb +9 -12
  133. data/manual/text/font_size.rb +11 -14
  134. data/manual/text/font_style.rb +4 -7
  135. data/manual/text/formatted_callbacks.rb +23 -21
  136. data/manual/text/formatted_text.rb +31 -25
  137. data/manual/text/free_flowing_text.rb +18 -21
  138. data/manual/text/inline.rb +16 -19
  139. data/manual/text/kerning_and_character_spacing.rb +12 -15
  140. data/manual/text/leading.rb +5 -8
  141. data/manual/text/line_wrapping.rb +33 -17
  142. data/manual/text/paragraph_indentation.rb +11 -14
  143. data/manual/text/positioned_text.rb +13 -16
  144. data/manual/text/registering_families.rb +16 -19
  145. data/manual/text/rendering_and_color.rb +7 -10
  146. data/manual/text/right_to_left_text.rb +24 -19
  147. data/manual/text/rotation.rb +26 -23
  148. data/manual/text/single_usage.rb +6 -9
  149. data/manual/text/text.rb +56 -52
  150. data/manual/text/text_box_excess.rb +18 -17
  151. data/manual/text/text_box_extensions.rb +16 -15
  152. data/manual/text/text_box_overflow.rb +15 -18
  153. data/manual/text/utf8.rb +9 -12
  154. data/manual/text/win_ansi_charset.rb +18 -19
  155. data/prawn.gemspec +37 -27
  156. data/spec/extensions/encoding_helpers.rb +0 -2
  157. data/spec/manual_spec.rb +33 -0
  158. data/spec/prawn/document/bounding_box_spec.rb +546 -0
  159. data/spec/prawn/document/column_box_spec.rb +73 -0
  160. data/spec/prawn/document/security_spec.rb +173 -0
  161. data/spec/prawn/document_annotations_spec.rb +74 -0
  162. data/spec/prawn/document_destinations_spec.rb +13 -0
  163. data/spec/prawn/document_grid_spec.rb +96 -0
  164. data/spec/prawn/document_reference_spec.rb +25 -0
  165. data/spec/prawn/document_span_spec.rb +34 -0
  166. data/spec/prawn/document_spec.rb +751 -0
  167. data/spec/prawn/font_metric_cache_spec.rb +52 -0
  168. data/spec/prawn/font_spec.rb +513 -0
  169. data/spec/prawn/graphics/blend_mode_spec.rb +61 -0
  170. data/spec/prawn/graphics/transparency_spec.rb +79 -0
  171. data/spec/prawn/graphics_spec.rb +817 -0
  172. data/spec/prawn/graphics_stroke_styles_spec.rb +227 -0
  173. data/spec/{image_handler_spec.rb → prawn/image_handler_spec.rb} +13 -15
  174. data/spec/prawn/images/jpg_spec.rb +18 -0
  175. data/spec/prawn/images/png_spec.rb +281 -0
  176. data/spec/prawn/images_spec.rb +170 -0
  177. data/spec/prawn/measurements_extensions_spec.rb +22 -0
  178. data/spec/prawn/outline_spec.rb +408 -0
  179. data/spec/prawn/repeater_spec.rb +163 -0
  180. data/spec/prawn/soft_mask_spec.rb +72 -0
  181. data/spec/prawn/stamp_spec.rb +168 -0
  182. data/spec/prawn/text/box_spec.rb +1113 -0
  183. data/spec/prawn/text/formatted/arranger_spec.rb +464 -0
  184. data/spec/prawn/text/formatted/box_spec.rb +825 -0
  185. data/spec/prawn/text/formatted/fragment_spec.rb +341 -0
  186. data/spec/prawn/text/formatted/line_wrap_spec.rb +491 -0
  187. data/spec/prawn/text/formatted/parser_spec.rb +667 -0
  188. data/spec/prawn/text_draw_text_spec.rb +147 -0
  189. data/spec/prawn/text_rendering_mode_spec.rb +42 -0
  190. data/spec/prawn/text_spacing_spec.rb +93 -0
  191. data/spec/prawn/text_spec.rb +601 -0
  192. data/spec/prawn/text_with_inline_formatting_spec.rb +33 -0
  193. data/spec/{transformation_stack_spec.rb → prawn/transformation_stack_spec.rb} +21 -20
  194. data/spec/prawn/view_spec.rb +45 -0
  195. data/spec/spec_helper.rb +16 -16
  196. metadata +96 -151
  197. metadata.gz.sig +1 -0
  198. data/data/images/16bit.alpha +0 -0
  199. data/data/images/16bit.color +0 -0
  200. data/data/images/16bit.png +0 -0
  201. data/data/images/arrow.png +0 -0
  202. data/data/images/arrow2.png +0 -0
  203. data/data/images/blend_modes_bottom_layer.jpg +0 -0
  204. data/data/images/blend_modes_top_layer.jpg +0 -0
  205. data/data/images/dice.alpha +0 -0
  206. data/data/images/dice.color +0 -0
  207. data/data/images/dice.png +0 -0
  208. data/data/images/dice_interlaced.png +0 -0
  209. data/data/images/fractal.jpg +0 -0
  210. data/data/images/indexed_color.dat +0 -0
  211. data/data/images/indexed_color.png +0 -0
  212. data/data/images/indexed_transparency.png +0 -0
  213. data/data/images/indexed_transparency_alpha.dat +0 -0
  214. data/data/images/indexed_transparency_color.dat +0 -0
  215. data/data/images/letterhead.jpg +0 -0
  216. data/data/images/license.md +0 -8
  217. data/data/images/page_white_text.alpha +0 -0
  218. data/data/images/page_white_text.color +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/spec/acceptance/png_spec.rb +0 -35
  244. data/spec/annotations_spec.rb +0 -67
  245. data/spec/blend_mode_spec.rb +0 -71
  246. data/spec/bounding_box_spec.rb +0 -501
  247. data/spec/column_box_spec.rb +0 -59
  248. data/spec/destinations_spec.rb +0 -13
  249. data/spec/document_spec.rb +0 -738
  250. data/spec/font_metric_cache_spec.rb +0 -52
  251. data/spec/font_spec.rb +0 -475
  252. data/spec/formatted_text_arranger_spec.rb +0 -452
  253. data/spec/formatted_text_box_spec.rb +0 -716
  254. data/spec/formatted_text_fragment_spec.rb +0 -299
  255. data/spec/graphics_spec.rb +0 -705
  256. data/spec/grid_spec.rb +0 -95
  257. data/spec/images_spec.rb +0 -167
  258. data/spec/inline_formatted_text_parser_spec.rb +0 -568
  259. data/spec/jpg_spec.rb +0 -23
  260. data/spec/line_wrap_spec.rb +0 -366
  261. data/spec/measurement_units_spec.rb +0 -22
  262. data/spec/outline_spec.rb +0 -409
  263. data/spec/png_spec.rb +0 -257
  264. data/spec/reference_spec.rb +0 -25
  265. data/spec/repeater_spec.rb +0 -154
  266. data/spec/security_spec.rb +0 -151
  267. data/spec/soft_mask_spec.rb +0 -78
  268. data/spec/span_spec.rb +0 -43
  269. data/spec/stamp_spec.rb +0 -179
  270. data/spec/stroke_styles_spec.rb +0 -208
  271. data/spec/text_at_spec.rb +0 -142
  272. data/spec/text_box_spec.rb +0 -1042
  273. data/spec/text_rendering_mode_spec.rb +0 -45
  274. data/spec/text_spacing_spec.rb +0 -93
  275. data/spec/text_spec.rb +0 -543
  276. data/spec/text_with_inline_formatting_spec.rb +0 -35
  277. data/spec/transparency_spec.rb +0 -91
  278. data/spec/view_spec.rb +0 -42
@@ -0,0 +1,227 @@
1
+ require 'spec_helper'
2
+
3
+ describe Prawn::Graphics do
4
+ let(:pdf) { create_pdf }
5
+
6
+ describe 'When stroking with default settings' do
7
+ it 'cap_style should be :butt' do
8
+ expect(pdf.cap_style).to eq(:butt)
9
+ end
10
+
11
+ it 'join_style should be :miter' do
12
+ expect(pdf.join_style).to eq(:miter)
13
+ end
14
+
15
+ it 'dashed? should be_false' do
16
+ expect(pdf).to_not be_dashed
17
+ end
18
+ end
19
+
20
+ describe 'Cap styles' do
21
+ it 'is able to use assignment operator' do
22
+ pdf.cap_style = :round
23
+ expect(pdf.cap_style).to eq(:round)
24
+ end
25
+
26
+ describe '#cap_style(:butt)' do
27
+ it 'rendered PDF should include butt style cap' do
28
+ pdf.cap_style(:butt)
29
+ cap_style = PDF::Inspector::Graphics::CapStyle.analyze(pdf.render)
30
+ .cap_style
31
+ expect(cap_style).to eq(0)
32
+ end
33
+ end
34
+
35
+ describe '#cap_style(:round)' do
36
+ it 'rendered PDF should include round style cap' do
37
+ pdf.cap_style(:round)
38
+ cap_style = PDF::Inspector::Graphics::CapStyle.analyze(pdf.render)
39
+ .cap_style
40
+ expect(cap_style).to eq(1)
41
+ end
42
+ end
43
+
44
+ describe '#cap_style(:projecting_square)' do
45
+ it 'rendered PDF should include projecting_square style cap' do
46
+ pdf.cap_style(:projecting_square)
47
+ cap_style = PDF::Inspector::Graphics::CapStyle.analyze(pdf.render)
48
+ .cap_style
49
+ expect(cap_style).to eq(2)
50
+ end
51
+ end
52
+
53
+ it 'carries the current cap style settings over to new pages' do
54
+ pdf.cap_style(:round)
55
+ pdf.start_new_page
56
+ cap_styles = PDF::Inspector::Graphics::CapStyle.analyze(pdf.render)
57
+ expect(cap_styles.cap_style_count).to eq(2)
58
+ expect(cap_styles.cap_style).to eq(1)
59
+ end
60
+ end
61
+
62
+ describe 'Join styles' do
63
+ it 'is able to use assignment operator' do
64
+ pdf.join_style = :round
65
+ expect(pdf.join_style).to eq(:round)
66
+ end
67
+
68
+ describe '#join_style(:miter)' do
69
+ it 'rendered PDF should include miter style join' do
70
+ pdf.join_style(:miter)
71
+ join_style = PDF::Inspector::Graphics::JoinStyle.analyze(pdf.render)
72
+ .join_style
73
+ expect(join_style).to eq(0)
74
+ end
75
+ end
76
+
77
+ describe '#join_style(:round)' do
78
+ it 'rendered PDF should include round style join' do
79
+ pdf.join_style(:round)
80
+ join_style = PDF::Inspector::Graphics::JoinStyle.analyze(pdf.render)
81
+ .join_style
82
+ expect(join_style).to eq(1)
83
+ end
84
+ end
85
+
86
+ describe '#join_style(:bevel)' do
87
+ it 'rendered PDF should include bevel style join' do
88
+ pdf.join_style(:bevel)
89
+ join_style = PDF::Inspector::Graphics::JoinStyle.analyze(pdf.render)
90
+ .join_style
91
+ expect(join_style).to eq(2)
92
+ end
93
+ end
94
+
95
+ it 'carries the current join style settings over to new pages' do
96
+ pdf.join_style(:round)
97
+ pdf.start_new_page
98
+ join_styles = PDF::Inspector::Graphics::JoinStyle.analyze(pdf.render)
99
+ expect(join_styles.join_style_count).to eq(2)
100
+ expect(join_styles.join_style).to eq(1)
101
+ end
102
+
103
+ context 'with invalid arguments' do
104
+ it 'raises an exception' do
105
+ expect { pdf.join_style(:mitre) }
106
+ .to raise_error(Prawn::Errors::InvalidJoinStyle)
107
+ end
108
+ end
109
+ end
110
+
111
+ describe 'Dashes' do
112
+ it 'is able to use assignment operator' do
113
+ pdf.dash = 2
114
+ expect(pdf).to be_dashed
115
+ end
116
+
117
+ describe 'setting a dash' do
118
+ it 'dashed? should be_true' do
119
+ pdf.dash(2)
120
+ expect(pdf).to be_dashed
121
+ end
122
+
123
+ it 'rendered PDF should include a stroked dash' do
124
+ pdf.dash(2)
125
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
126
+ expect(dashes.stroke_dash).to eq([[2, 2], 0])
127
+ end
128
+ end
129
+
130
+ describe 'setting a dash by passing a single argument' do
131
+ it 'space between dashes should be the same length as the dash in the '\
132
+ 'rendered PDF' do
133
+ pdf.dash(2)
134
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
135
+ expect(dashes.stroke_dash).to eq([[2, 2], 0])
136
+ end
137
+ end
138
+
139
+ describe 'with a space option that differs from the first argument' do
140
+ it 'space between dashes in the rendered PDF should be different length '\
141
+ 'than the length of the dash' do
142
+ pdf.dash(2, space: 3)
143
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
144
+ expect(dashes.stroke_dash).to eq([[2, 3], 0])
145
+ end
146
+ end
147
+
148
+ describe 'with a non-zero phase option' do
149
+ it 'rendered PDF should include a non-zero phase' do
150
+ pdf.dash(2, phase: 1)
151
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
152
+ expect(dashes.stroke_dash).to eq([[2, 2], 1])
153
+ end
154
+ end
155
+
156
+ describe 'setting a dash by using an array' do
157
+ it 'dash and spaces should be set from the array' do
158
+ pdf.dash([1, 2, 3, 4])
159
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
160
+ expect(dashes.stroke_dash).to eq([[1, 2, 3, 4], 0])
161
+ end
162
+
163
+ it 'at least one number in the array must not be zero' do
164
+ pdf.dash([1, 0])
165
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
166
+ expect(dashes.stroke_dash).to eq([[1, 0], 0])
167
+ end
168
+
169
+ it 'space options has to be ignored' do
170
+ pdf.dash([1, 2, 3, 4], space: 3)
171
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
172
+ expect(dashes.stroke_dash).to eq([[1, 2, 3, 4], 0])
173
+ end
174
+
175
+ it 'phase options should be correctly used' do
176
+ pdf.dash([1, 2, 3, 4], phase: 3)
177
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
178
+ expect(dashes.stroke_dash).to eq([[1, 2, 3, 4], 3])
179
+ end
180
+ end
181
+
182
+ describe 'clearing stroke dash' do
183
+ it 'restores solid line' do
184
+ pdf.dash(2)
185
+ pdf.undash
186
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
187
+ expect(dashes.stroke_dash).to eq([[], 0])
188
+ end
189
+ end
190
+
191
+ it 'carries the current dash settings over to new pages' do
192
+ pdf.dash(2)
193
+ pdf.start_new_page
194
+ dashes = PDF::Inspector::Graphics::Dash.analyze(pdf.render)
195
+ expect(dashes.stroke_dash_count).to eq(2)
196
+ expect(dashes.stroke_dash).to eq([[2, 2], 0])
197
+ end
198
+
199
+ describe '#dashed?' do
200
+ it 'an initial document should not be dashed' do
201
+ expect(pdf.dashed?).to eq(false)
202
+ end
203
+
204
+ it 'returns true if any of the currently active settings are dashed' do
205
+ pdf.dash(2)
206
+ pdf.save_graphics_state
207
+ expect(pdf.dashed?).to eq(true)
208
+ end
209
+
210
+ it 'returns false if the document was most recently undashed' do
211
+ pdf.dash(2)
212
+ pdf.save_graphics_state
213
+ pdf.undash
214
+ pdf.save_graphics_state
215
+ expect(pdf.dashed?).to eq(false)
216
+ end
217
+
218
+ it 'returns true when restoring to a state that was dashed' do
219
+ pdf.dash(2)
220
+ pdf.save_graphics_state
221
+ pdf.undash
222
+ pdf.restore_graphics_state
223
+ expect(pdf.dashed?).to eq(true)
224
+ end
225
+ end
226
+ end
227
+ end
@@ -1,34 +1,32 @@
1
- # encoding: utf-8
1
+ require 'spec_helper'
2
2
 
3
- require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
3
+ describe Prawn::ImageHandler do
4
+ let(:image_handler) { described_class.new }
4
5
 
5
- describe "ImageHandler" do
6
- let(:image_handler) { Prawn::ImageHandler.new }
6
+ let(:handler_a) { instance_double('Handler A') }
7
+ let(:handler_b) { instance_double('Handler B') }
7
8
 
8
- let(:handler_a) { double("Handler A") }
9
- let(:handler_b) { double("Handler B") }
10
-
11
- it "finds the image handler for an image" do
9
+ it 'finds the image handler for an image' do
12
10
  allow(handler_a).to receive(:can_render?).and_return(true)
13
11
 
14
12
  image_handler.register(handler_a)
15
13
  image_handler.register(handler_b)
16
14
 
17
- handler = image_handler.find("arbitrary blob")
15
+ handler = image_handler.find('arbitrary blob')
18
16
  expect(handler).to eq(handler_a)
19
17
  end
20
18
 
21
- it "can prepend handlers" do
19
+ it 'can prepend handlers' do
22
20
  allow(handler_b).to receive(:can_render?).and_return(true)
23
21
 
24
22
  image_handler.register(handler_a)
25
23
  image_handler.register!(handler_b)
26
24
 
27
- handler = image_handler.find("arbitrary blob")
25
+ handler = image_handler.find('arbitrary blob')
28
26
  expect(handler).to eq(handler_b)
29
27
  end
30
28
 
31
- it "can unregister a handler" do
29
+ it 'can unregister a handler' do
32
30
  allow(handler_b).to receive(:can_render?).and_return(true)
33
31
 
34
32
  image_handler.register(handler_a)
@@ -40,14 +38,14 @@ describe "ImageHandler" do
40
38
  expect(handler).to eq(handler_b)
41
39
  end
42
40
 
43
- it "raises an error when no matching handler is found" do
41
+ it 'raises an error when no matching handler is found' do
44
42
  allow(handler_a).to receive(:can_render?).and_return(false)
45
43
  allow(handler_b).to receive(:can_render?).and_return(false)
46
44
 
47
45
  image_handler.register(handler_a)
48
46
  image_handler.register(handler_b)
49
47
 
50
- expect { image_handler.find("arbitrary blob") }.
51
- to(raise_error(Prawn::Errors::UnsupportedImageType))
48
+ expect { image_handler.find('arbitrary blob') }
49
+ .to(raise_error(Prawn::Errors::UnsupportedImageType))
52
50
  end
53
51
  end
@@ -0,0 +1,18 @@
1
+ # Spec'ing the PNG class. Not complete yet - still needs to check the
2
+ # contents of palette and transparency to ensure they're correct.
3
+ # Need to find files that have these sections first.
4
+
5
+ require 'spec_helper'
6
+
7
+ describe Prawn::Images::JPG do
8
+ let(:img_data) { File.binread("#{Prawn::DATADIR}/images/pigs.jpg") }
9
+
10
+ it 'reads the basic attributes correctly' do
11
+ jpg = described_class.new(img_data)
12
+
13
+ expect(jpg.width).to eq(604)
14
+ expect(jpg.height).to eq(453)
15
+ expect(jpg.bits).to eq(8)
16
+ expect(jpg.channels).to eq(3)
17
+ end
18
+ end
@@ -0,0 +1,281 @@
1
+ # Spec'ing the PNG class. Not complete yet - still needs to check the
2
+ # contents of palette and transparency to ensure they're correct.
3
+ # Need to find files that have these sections first.
4
+ #
5
+ # see http://www.w3.org/TR/PNG/ for a detailed description of the PNG spec,
6
+ # particuarly Table 11.1 for the different color types
7
+
8
+ require 'spec_helper'
9
+
10
+ describe Prawn::Images::PNG do
11
+ describe 'When making a pdf file with png images' do
12
+ image_dir = "#{Prawn::BASEDIR}/data/images"
13
+ images = [
14
+ ['Type 0', "#{image_dir}/web-links.png"],
15
+ ['Type 0 with transparency', "#{image_dir}/ruport_type0.png"],
16
+ ['Type 2', "#{image_dir}/ruport.png"],
17
+ ['Type 2 with transparency', "#{image_dir}/arrow2.png"],
18
+ ['Type 3', "#{image_dir}/indexed_color.png"],
19
+ ['Type 3 with transparency', "#{image_dir}/indexed_transparency.png"],
20
+ ['Type 4', "#{image_dir}/page_white_text.png"],
21
+ ['Type 6', "#{image_dir}/dice.png"],
22
+ ['Type 6 in 16bit', "#{image_dir}/16bit.png"]
23
+ ]
24
+
25
+ images.each do |header, file|
26
+ describe "and the image is #{header}" do
27
+ it 'does not error' do
28
+ expect do
29
+ Prawn::Document.generate("#{header}.pdf", page_size: 'A5') do
30
+ fill_color '00FF00'
31
+
32
+ fill_rectangle bounds.top_left, bounds.width, bounds.height
33
+ text header
34
+
35
+ image file, at: [50, 450]
36
+ end
37
+ end.to_not raise_error
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ describe 'When reading a greyscale PNG file (color type 0)' do
44
+ let(:data_filename) { "#{Prawn::DATADIR}/images/web-links.dat" }
45
+ let(:img_data) { File.binread("#{Prawn::DATADIR}/images/web-links.png") }
46
+
47
+ it 'reads the attributes from the header chunk correctly' do
48
+ png = described_class.new(img_data)
49
+
50
+ expect(png.width).to eq(21)
51
+ expect(png.height).to eq(14)
52
+ expect(png.bits).to eq(8)
53
+ expect(png.color_type).to eq(0)
54
+ expect(png.compression_method).to eq(0)
55
+ expect(png.filter_method).to eq(0)
56
+ expect(png.interlace_method).to eq(0)
57
+ end
58
+
59
+ it 'reads the image data chunk correctly' do
60
+ png = described_class.new(img_data)
61
+ data = Zlib::Inflate.inflate(File.binread(data_filename))
62
+ expect(png.img_data).to eq(data)
63
+ end
64
+ end
65
+
66
+ describe 'When reading a greyscale PNG with transparency (color type 0)' do
67
+ let(:img_data) { File.binread("#{Prawn::DATADIR}/images/ruport_type0.png") }
68
+
69
+ # In a greyscale type 0 PNG image, the tRNS chunk should contain a single
70
+ # value that indicates the color that should be interpreted as transparent.
71
+ #
72
+ # http://www.w3.org/TR/PNG/#11tRNS
73
+ it 'reads the tRNS chunk correctly' do
74
+ png = described_class.new(img_data)
75
+ expect(png.transparency[:grayscale]).to eq(255)
76
+ end
77
+ end
78
+
79
+ describe 'When reading an RGB PNG file (color type 2)' do
80
+ let(:data_filename) { "#{Prawn::DATADIR}/images/ruport_data.dat" }
81
+ let(:img_data) { File.binread("#{Prawn::DATADIR}/images/ruport.png") }
82
+
83
+ it 'reads the attributes from the header chunk correctly' do
84
+ png = described_class.new(img_data)
85
+
86
+ expect(png.width).to eq(258)
87
+ expect(png.height).to eq(105)
88
+ expect(png.bits).to eq(8)
89
+ expect(png.color_type).to eq(2)
90
+ expect(png.compression_method).to eq(0)
91
+ expect(png.filter_method).to eq(0)
92
+ expect(png.interlace_method).to eq(0)
93
+ end
94
+
95
+ it 'reads the image data chunk correctly' do
96
+ png = described_class.new(img_data)
97
+ data = Zlib::Inflate.inflate(File.binread(data_filename))
98
+ expect(png.img_data).to eq(data)
99
+ end
100
+ end
101
+
102
+ describe 'When reading an RGB PNG file with transparency (color type 2)' do
103
+ let(:img_data) { File.binread("#{Prawn::DATADIR}/images/arrow2.png") }
104
+
105
+ # In a RGB type 2 PNG image, the tRNS chunk should contain a single RGB
106
+ # value that indicates the color that should be interpreted as transparent.
107
+ # In this case it's green.
108
+ #
109
+ # http://www.w3.org/TR/PNG/#11tRNS
110
+ it 'reads the tRNS chunk correctly' do
111
+ png = described_class.new(img_data)
112
+ expect(png.transparency[:rgb]).to eq([0, 255, 0])
113
+ end
114
+ end
115
+
116
+ describe 'When reading an indexed color PNG file with transparency '\
117
+ '(color type 3)' do
118
+ let(:filename) { "#{Prawn::DATADIR}/images/indexed_transparency.png" }
119
+ let(:color_filename) do
120
+ "#{Prawn::DATADIR}/images/indexed_transparency_color.dat"
121
+ end
122
+ let(:transparency_filename) do
123
+ "#{Prawn::DATADIR}/images/indexed_transparency_alpha.dat"
124
+ end
125
+ let(:img_data) { File.binread(filename) }
126
+ let(:png) { described_class.new(img_data) }
127
+
128
+ it 'reads the attributes from the header chunk correctly' do
129
+ expect(png.width).to eq(200)
130
+ expect(png.height).to eq(200)
131
+ expect(png.bits).to eq(8)
132
+ expect(png.color_type).to eq(3)
133
+ expect(png.compression_method).to eq(0)
134
+ expect(png.filter_method).to eq(0)
135
+ expect(png.interlace_method).to eq(0)
136
+ end
137
+
138
+ it 'reads the image data correctly' do
139
+ data = Zlib::Inflate.inflate(File.binread(color_filename))
140
+ expect(png.img_data).to eq(data)
141
+ end
142
+
143
+ it 'reads the image transparency correctly' do
144
+ png.split_alpha_channel!
145
+
146
+ data = Zlib::Inflate.inflate(File.binread(transparency_filename))
147
+ expect(png.alpha_channel).to eq(data)
148
+ end
149
+ end
150
+
151
+ describe 'When reading an indexed color PNG file (color type 3)' do
152
+ let(:data_filename) { "#{Prawn::DATADIR}/images/indexed_color.dat" }
153
+ let(:img_data) do
154
+ File.binread("#{Prawn::DATADIR}/images/indexed_color.png")
155
+ end
156
+
157
+ it 'reads the attributes from the header chunk correctly' do
158
+ png = described_class.new(img_data)
159
+
160
+ expect(png.width).to eq(150)
161
+ expect(png.height).to eq(200)
162
+ expect(png.bits).to eq(8)
163
+ expect(png.color_type).to eq(3)
164
+ expect(png.compression_method).to eq(0)
165
+ expect(png.filter_method).to eq(0)
166
+ expect(png.interlace_method).to eq(0)
167
+ end
168
+
169
+ it 'reads the image data chunk correctly' do
170
+ png = described_class.new(img_data)
171
+ data = Zlib::Inflate.inflate(File.binread(data_filename))
172
+ expect(png.img_data).to eq(data)
173
+ end
174
+ end
175
+
176
+ describe 'When reading a greyscale+alpha PNG file (color type 4)' do
177
+ let(:color_data_filename) do
178
+ "#{Prawn::DATADIR}/images/page_white_text.color"
179
+ end
180
+ let(:alpha_data_filename) do
181
+ "#{Prawn::DATADIR}/images/page_white_text.alpha"
182
+ end
183
+ let(:img_data) do
184
+ File.binread("#{Prawn::DATADIR}/images/page_white_text.png")
185
+ end
186
+
187
+ it 'reads the attributes from the header chunk correctly' do
188
+ png = described_class.new(img_data)
189
+
190
+ expect(png.width).to eq(16)
191
+ expect(png.height).to eq(16)
192
+ expect(png.bits).to eq(8)
193
+ expect(png.color_type).to eq(4)
194
+ expect(png.compression_method).to eq(0)
195
+ expect(png.filter_method).to eq(0)
196
+ expect(png.interlace_method).to eq(0)
197
+ end
198
+
199
+ it 'correctly returns the raw image data (with no alpha channel) from '\
200
+ 'the image data chunk' do
201
+ png = described_class.new(img_data)
202
+ png.split_alpha_channel!
203
+ data = File.binread(color_data_filename)
204
+ expect(png.img_data).to eq(data)
205
+ end
206
+
207
+ it 'correctly extracts the alpha channel data from the image data chunk' do
208
+ png = described_class.new(img_data)
209
+ png.split_alpha_channel!
210
+ data = File.binread(alpha_data_filename)
211
+ expect(png.alpha_channel).to eq(data)
212
+ end
213
+ end
214
+
215
+ describe 'When reading an RGB+alpha PNG file (color type 6)' do
216
+ let(:color_data_filename) { "#{Prawn::DATADIR}/images/dice.color" }
217
+ let(:alpha_data_filename) { "#{Prawn::DATADIR}/images/dice.alpha" }
218
+ let(:img_data) { File.binread("#{Prawn::DATADIR}/images/dice.png") }
219
+
220
+ it 'reads the attributes from the header chunk correctly' do
221
+ png = described_class.new(img_data)
222
+
223
+ expect(png.width).to eq(320)
224
+ expect(png.height).to eq(240)
225
+ expect(png.bits).to eq(8)
226
+ expect(png.color_type).to eq(6)
227
+ expect(png.compression_method).to eq(0)
228
+ expect(png.filter_method).to eq(0)
229
+ expect(png.interlace_method).to eq(0)
230
+ end
231
+
232
+ it 'correctly returns the raw image data (with no alpha channel) from '\
233
+ 'the image data chunk' do
234
+ png = described_class.new(img_data)
235
+ png.split_alpha_channel!
236
+ data = File.binread(color_data_filename)
237
+ expect(png.img_data).to eq(data)
238
+ end
239
+
240
+ it 'correctly extracts the alpha channel data from the image data chunk' do
241
+ png = described_class.new(img_data)
242
+ png.split_alpha_channel!
243
+ data = File.binread(alpha_data_filename)
244
+ expect(png.alpha_channel).to eq(data)
245
+ end
246
+ end
247
+
248
+ describe 'When reading a 16bit RGB+alpha PNG file (color type 6)' do
249
+ let(:color_data_filename) { "#{Prawn::DATADIR}/images/16bit.color" }
250
+ # alpha channel truncated to 8-bit
251
+ let(:alpha_data_filename) { "#{Prawn::DATADIR}/images/16bit.alpha" }
252
+ let(:img_data) { File.binread("#{Prawn::DATADIR}/images/16bit.png") }
253
+
254
+ it 'reads the attributes from the header chunk correctly' do
255
+ png = described_class.new(img_data)
256
+
257
+ expect(png.width).to eq(32)
258
+ expect(png.height).to eq(32)
259
+ expect(png.bits).to eq(16)
260
+ expect(png.color_type).to eq(6)
261
+ expect(png.compression_method).to eq(0)
262
+ expect(png.filter_method).to eq(0)
263
+ expect(png.interlace_method).to eq(0)
264
+ end
265
+
266
+ it 'correctly returns the raw image data (with no alpha channel) from '\
267
+ 'the image data chunk' do
268
+ png = described_class.new(img_data)
269
+ png.split_alpha_channel!
270
+ data = File.binread(color_data_filename)
271
+ expect(png.img_data).to eq(data)
272
+ end
273
+
274
+ it 'correctly extracts the alpha channel data from the image data chunk' do
275
+ png = described_class.new(img_data)
276
+ png.split_alpha_channel!
277
+ data = File.binread(alpha_data_filename)
278
+ expect(png.alpha_channel).to eq(data)
279
+ end
280
+ end
281
+ end