prawn 2.1.0 → 2.3.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 (280) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/GPLv2 +20 -21
  5. data/Gemfile +3 -9
  6. data/Rakefile +20 -23
  7. data/lib/prawn.rb +36 -49
  8. data/lib/prawn/document.rb +180 -133
  9. data/lib/prawn/document/bounding_box.rb +41 -29
  10. data/lib/prawn/document/column_box.rb +7 -7
  11. data/lib/prawn/document/internals.rb +8 -6
  12. data/lib/prawn/document/span.rb +21 -16
  13. data/lib/prawn/encoding.rb +69 -68
  14. data/lib/prawn/errors.rb +12 -7
  15. data/lib/prawn/font.rb +102 -69
  16. data/lib/prawn/font_metric_cache.rb +14 -8
  17. data/lib/prawn/{font → fonts}/afm.rb +102 -68
  18. data/lib/prawn/{font → fonts}/dfont.rb +5 -11
  19. data/lib/prawn/fonts/otf.rb +11 -0
  20. data/lib/prawn/fonts/ttc.rb +36 -0
  21. data/lib/prawn/{font → fonts}/ttf.rb +87 -68
  22. data/lib/prawn/graphics.rb +119 -81
  23. data/lib/prawn/graphics/blend_mode.rb +9 -8
  24. data/lib/prawn/graphics/cap_style.rb +3 -3
  25. data/lib/prawn/graphics/color.rb +27 -25
  26. data/lib/prawn/graphics/dash.rb +23 -11
  27. data/lib/prawn/graphics/join_style.rb +9 -3
  28. data/lib/prawn/graphics/patterns.rb +190 -96
  29. data/lib/prawn/graphics/transformation.rb +15 -9
  30. data/lib/prawn/graphics/transparency.rb +17 -13
  31. data/lib/prawn/grid.rb +48 -47
  32. data/lib/prawn/image_handler.rb +5 -5
  33. data/lib/prawn/images.rb +39 -30
  34. data/lib/prawn/images/image.rb +2 -1
  35. data/lib/prawn/images/jpg.rb +28 -22
  36. data/lib/prawn/images/png.rb +65 -62
  37. data/lib/prawn/measurement_extensions.rb +10 -9
  38. data/lib/prawn/measurements.rb +19 -15
  39. data/lib/prawn/outline.rb +97 -77
  40. data/lib/prawn/repeater.rb +14 -10
  41. data/lib/prawn/security.rb +81 -61
  42. data/lib/prawn/security/arcfour.rb +2 -2
  43. data/lib/prawn/soft_mask.rb +26 -26
  44. data/lib/prawn/stamp.rb +20 -13
  45. data/lib/prawn/text.rb +68 -52
  46. data/lib/prawn/text/box.rb +11 -8
  47. data/lib/prawn/text/formatted.rb +5 -5
  48. data/lib/prawn/text/formatted/arranger.rb +53 -32
  49. data/lib/prawn/text/formatted/box.rb +134 -100
  50. data/lib/prawn/text/formatted/fragment.rb +11 -14
  51. data/lib/prawn/text/formatted/line_wrap.rb +122 -63
  52. data/lib/prawn/text/formatted/parser.rb +139 -117
  53. data/lib/prawn/text/formatted/wrap.rb +43 -31
  54. data/lib/prawn/transformation_stack.rb +7 -5
  55. data/lib/prawn/utilities.rb +7 -22
  56. data/lib/prawn/version.rb +2 -2
  57. data/lib/prawn/view.rb +17 -7
  58. data/manual/basic_concepts/adding_pages.rb +6 -7
  59. data/manual/basic_concepts/basic_concepts.rb +31 -22
  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 +6 -7
  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 +22 -16
  66. data/manual/bounding_box/bounding_box.rb +29 -24
  67. data/manual/bounding_box/bounds.rb +11 -12
  68. data/manual/bounding_box/canvas.rb +4 -5
  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 +24 -17
  72. data/manual/bounding_box/russian_boxes.rb +14 -13
  73. data/manual/bounding_box/stretchy.rb +12 -13
  74. data/manual/contents.rb +28 -22
  75. data/manual/cover.rb +33 -28
  76. data/manual/document_and_page_options/background.rb +11 -13
  77. data/manual/document_and_page_options/document_and_page_options.rb +25 -20
  78. data/manual/document_and_page_options/metadata.rb +18 -16
  79. data/manual/document_and_page_options/page_margins.rb +18 -20
  80. data/manual/document_and_page_options/page_size.rb +13 -12
  81. data/manual/document_and_page_options/print_scaling.rb +17 -15
  82. data/manual/example_helper.rb +5 -4
  83. data/manual/graphics/blend_mode.rb +12 -9
  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 +4 -5
  88. data/manual/graphics/fill_rules.rb +9 -10
  89. data/manual/graphics/gradients.rb +27 -21
  90. data/manual/graphics/graphics.rb +48 -40
  91. data/manual/graphics/helper.rb +12 -9
  92. data/manual/graphics/line_width.rb +8 -7
  93. data/manual/graphics/lines_and_curves.rb +7 -8
  94. data/manual/graphics/polygon.rb +6 -8
  95. data/manual/graphics/rectangle.rb +4 -5
  96. data/manual/graphics/rotate.rb +6 -7
  97. data/manual/graphics/scale.rb +14 -15
  98. data/manual/graphics/soft_masks.rb +3 -4
  99. data/manual/graphics/stroke_cap.rb +6 -7
  100. data/manual/graphics/stroke_dash.rb +11 -12
  101. data/manual/graphics/stroke_join.rb +5 -6
  102. data/manual/graphics/translate.rb +9 -10
  103. data/manual/graphics/transparency.rb +7 -8
  104. data/manual/how_to_read_this_manual.rb +6 -6
  105. data/manual/images/absolute_position.rb +6 -7
  106. data/manual/images/fit.rb +7 -8
  107. data/manual/images/horizontal.rb +9 -10
  108. data/manual/images/images.rb +28 -24
  109. data/manual/images/plain_image.rb +5 -6
  110. data/manual/images/scale.rb +9 -10
  111. data/manual/images/vertical.rb +13 -14
  112. data/manual/images/width_and_height.rb +10 -11
  113. data/manual/layout/boxes.rb +5 -6
  114. data/manual/layout/content.rb +7 -8
  115. data/manual/layout/layout.rb +18 -16
  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 +21 -17
  120. data/manual/outline/sections_and_pages.rb +17 -18
  121. data/manual/repeatable_content/alternate_page_numbering.rb +21 -17
  122. data/manual/repeatable_content/page_numbering.rb +17 -16
  123. data/manual/repeatable_content/repeatable_content.rb +25 -19
  124. data/manual/repeatable_content/repeater.rb +14 -15
  125. data/manual/repeatable_content/stamp.rb +14 -15
  126. data/manual/security/encryption.rb +9 -10
  127. data/manual/security/permissions.rb +19 -14
  128. data/manual/security/security.rb +19 -16
  129. data/manual/table.rb +3 -3
  130. data/manual/text/alignment.rb +16 -17
  131. data/manual/text/color.rb +12 -11
  132. data/manual/text/column_box.rb +9 -10
  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 +7 -8
  137. data/manual/text/formatted_callbacks.rb +25 -21
  138. data/manual/text/formatted_text.rb +33 -25
  139. data/manual/text/free_flowing_text.rb +20 -21
  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 +13 -14
  145. data/manual/text/positioned_text.rb +15 -16
  146. data/manual/text/registering_families.rb +20 -21
  147. data/manual/text/rendering_and_color.rb +9 -10
  148. data/manual/text/right_to_left_text.rb +26 -19
  149. data/manual/text/rotation.rb +28 -23
  150. data/manual/text/single_usage.rb +8 -9
  151. data/manual/text/text.rb +57 -52
  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 +18 -19
  155. data/manual/text/utf8.rb +11 -12
  156. data/manual/text/win_ansi_charset.rb +21 -19
  157. data/prawn.gemspec +44 -31
  158. data/spec/extensions/encoding_helpers.rb +3 -3
  159. data/spec/prawn/document/bounding_box_spec.rb +546 -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 +36 -0
  167. data/spec/prawn/document_spec.rb +802 -0
  168. data/spec/prawn/font_metric_cache_spec.rb +54 -0
  169. data/spec/prawn/font_spec.rb +542 -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 +837 -0
  173. data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
  174. data/spec/{image_handler_spec.rb → prawn/image_handler_spec.rb} +14 -14
  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 +224 -0
  178. data/spec/prawn/measurements_extensions_spec.rb +24 -0
  179. data/spec/prawn/outline_spec.rb +412 -0
  180. data/spec/prawn/repeater_spec.rb +165 -0
  181. data/spec/prawn/soft_mask_spec.rb +74 -0
  182. data/spec/prawn/stamp_spec.rb +172 -0
  183. data/spec/prawn/text/box_spec.rb +1112 -0
  184. data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
  185. data/spec/prawn/text/formatted/box_spec.rb +846 -0
  186. data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
  187. data/spec/prawn/text/formatted/line_wrap_spec.rb +494 -0
  188. data/spec/prawn/text/formatted/parser_spec.rb +697 -0
  189. data/spec/prawn/text_draw_text_spec.rb +149 -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/{transformation_stack_spec.rb → prawn/transformation_stack_spec.rb} +22 -19
  195. data/spec/prawn/view_spec.rb +63 -0
  196. data/spec/prawn_manual_spec.rb +35 -0
  197. data/spec/spec_helper.rb +18 -19
  198. metadata +144 -180
  199. metadata.gz.sig +4 -0
  200. data/data/images/16bit.alpha +0 -0
  201. data/data/images/16bit.color +0 -0
  202. data/data/images/16bit.png +0 -0
  203. data/data/images/arrow.png +0 -0
  204. data/data/images/arrow2.png +0 -0
  205. data/data/images/blend_modes_bottom_layer.jpg +0 -0
  206. data/data/images/blend_modes_top_layer.jpg +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/indexed_transparency.png +0 -0
  215. data/data/images/indexed_transparency_alpha.dat +0 -0
  216. data/data/images/indexed_transparency_color.dat +0 -0
  217. data/data/images/letterhead.jpg +0 -0
  218. data/data/images/license.md +0 -8
  219. data/data/images/page_white_text.alpha +0 -0
  220. data/data/images/page_white_text.color +0 -0
  221. data/data/images/page_white_text.png +0 -0
  222. data/data/images/pigs.jpg +0 -0
  223. data/data/images/prawn.png +0 -0
  224. data/data/images/ruport.png +0 -0
  225. data/data/images/ruport_data.dat +0 -0
  226. data/data/images/ruport_transparent.png +0 -0
  227. data/data/images/ruport_type0.png +0 -0
  228. data/data/images/stef.jpg +0 -0
  229. data/data/images/tru256.bmp +0 -0
  230. data/data/images/web-links.dat +0 -1
  231. data/data/images/web-links.png +0 -0
  232. data/data/pdfs/complex_template.pdf +0 -0
  233. data/data/pdfs/contains_ttf_font.pdf +0 -0
  234. data/data/pdfs/encrypted.pdf +0 -0
  235. data/data/pdfs/form.pdf +1 -819
  236. data/data/pdfs/hexagon.pdf +0 -61
  237. data/data/pdfs/indirect_reference.pdf +0 -86
  238. data/data/pdfs/multipage_template.pdf +0 -127
  239. data/data/pdfs/nested_pages.pdf +0 -118
  240. data/data/pdfs/page_without_mediabox.pdf +0 -193
  241. data/data/pdfs/resources_as_indirect_object.pdf +0 -83
  242. data/data/pdfs/two_hexagons.pdf +0 -90
  243. data/data/pdfs/version_1_6.pdf +0 -61
  244. data/data/shift_jis_text.txt +0 -1
  245. data/spec/acceptance/png_spec.rb +0 -35
  246. data/spec/annotations_spec.rb +0 -67
  247. data/spec/blend_mode_spec.rb +0 -71
  248. data/spec/bounding_box_spec.rb +0 -501
  249. data/spec/column_box_spec.rb +0 -59
  250. data/spec/destinations_spec.rb +0 -13
  251. data/spec/document_spec.rb +0 -738
  252. data/spec/font_metric_cache_spec.rb +0 -52
  253. data/spec/font_spec.rb +0 -475
  254. data/spec/formatted_text_arranger_spec.rb +0 -452
  255. data/spec/formatted_text_box_spec.rb +0 -716
  256. data/spec/formatted_text_fragment_spec.rb +0 -299
  257. data/spec/graphics_spec.rb +0 -705
  258. data/spec/grid_spec.rb +0 -95
  259. data/spec/images_spec.rb +0 -167
  260. data/spec/inline_formatted_text_parser_spec.rb +0 -568
  261. data/spec/jpg_spec.rb +0 -23
  262. data/spec/line_wrap_spec.rb +0 -366
  263. data/spec/measurement_units_spec.rb +0 -22
  264. data/spec/outline_spec.rb +0 -409
  265. data/spec/png_spec.rb +0 -257
  266. data/spec/reference_spec.rb +0 -25
  267. data/spec/repeater_spec.rb +0 -154
  268. data/spec/security_spec.rb +0 -151
  269. data/spec/soft_mask_spec.rb +0 -78
  270. data/spec/span_spec.rb +0 -43
  271. data/spec/stamp_spec.rb +0 -179
  272. data/spec/stroke_styles_spec.rb +0 -208
  273. data/spec/text_at_spec.rb +0 -142
  274. data/spec/text_box_spec.rb +0 -1042
  275. data/spec/text_rendering_mode_spec.rb +0 -45
  276. data/spec/text_spacing_spec.rb +0 -93
  277. data/spec/text_spec.rb +0 -543
  278. data/spec/text_with_inline_formatting_spec.rb +0 -35
  279. data/spec/transparency_spec.rb +0 -91
  280. data/spec/view_spec.rb +0 -42
@@ -1,452 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
-
5
- describe Prawn::Text::Formatted::Arranger do
6
- let(:document) { create_pdf }
7
- subject { Prawn::Text::Formatted::Arranger.new document }
8
-
9
- describe '#format_array' do
10
- it 'populates the unconsumed array' do
11
- array = [
12
- { text: 'hello ' },
13
- { text: 'world how ', styles: [:bold] },
14
- { text: 'are', styles: [:bold, :italic] },
15
- { text: ' you?' }
16
- ]
17
-
18
- subject.format_array = array
19
-
20
- expect(subject.unconsumed[0]).to eq(text: 'hello ')
21
- expect(subject.unconsumed[1]).to eq(text: 'world how ', styles: [:bold])
22
- expect(subject.unconsumed[2]).to eq(text: 'are', styles: [:bold, :italic])
23
- expect(subject.unconsumed[3]).to eq(text: ' you?')
24
- end
25
-
26
- it 'splits newlins into their own elements' do
27
- array = [
28
- { text: "\nhello\nworld" }
29
- ]
30
-
31
- subject.format_array = array
32
-
33
- expect(subject.unconsumed[0]).to eq(text: "\n")
34
- expect(subject.unconsumed[1]).to eq(text: "hello")
35
- expect(subject.unconsumed[2]).to eq(text: "\n")
36
- expect(subject.unconsumed[3]).to eq(text: "world")
37
- end
38
- end
39
-
40
- describe '#preview_next_string' do
41
- context 'with a formatted array' do
42
- let(:array) { [{ text: 'hello' }] }
43
-
44
- before do
45
- subject.format_array = array
46
- end
47
-
48
- it 'does not populate the consumed array' do
49
- subject.preview_next_string
50
- expect(subject.consumed).to eq([])
51
- end
52
-
53
- it 'returns the text of the next unconsumed hash' do
54
- expect(subject.preview_next_string).to eq("hello")
55
- end
56
-
57
- it 'returns nil if there is no more unconsumed text' do
58
- subject.next_string
59
- expect(subject.preview_next_string).to be_nil
60
- end
61
- end
62
- end
63
-
64
- describe '#next_string' do
65
- let(:array) {
66
- [
67
- { text: 'hello ' },
68
- { text: 'world how ', styles: [:bold] },
69
- { text: 'are', styles: [:bold, :italic] },
70
- { text: ' you?' }
71
- ]
72
- }
73
-
74
- before do
75
- subject.format_array = array
76
- end
77
-
78
- it 'raises RuntimeError if called after a line was finalized' do
79
- subject.finalize_line
80
- expect { subject.next_string }.to raise_error(RuntimeError)
81
- end
82
-
83
- it 'populates the conumed array' do
84
- while string = subject.next_string
85
- end
86
-
87
- expect(subject.consumed[0]).to eq(text: 'hello ')
88
- expect(subject.consumed[1]).to eq(text: 'world how ', styles: [:bold])
89
- expect(subject.consumed[2]).to eq(text: 'are', styles: [:bold, :italic])
90
- expect(subject.consumed[3]).to eq(text: ' you?')
91
- end
92
-
93
- it 'populates the current_format_state array' do
94
- string = subject.next_string
95
- expect(subject.current_format_state).to eq({})
96
-
97
- string = subject.next_string
98
- expect(subject.current_format_state).to eq(:styles => [:bold])
99
-
100
- string = subject.next_string
101
- expect(subject.current_format_state).to eq(:styles => [:bold, :italic])
102
-
103
- string = subject.next_string
104
- expect(subject.current_format_state).to eq({})
105
- end
106
-
107
- it 'returns the text of the newly consumed hash' do
108
- expect(subject.next_string).to eq('hello ')
109
- end
110
-
111
- it 'returns nil when there are no more unconsumed hashes' do
112
- 4.times do
113
- subject.next_string
114
- end
115
-
116
- expect(subject.next_string).to be_nil
117
- end
118
- end
119
-
120
- describe '#retrieve_fragment' do
121
- context 'with a formatted array whos text is an empty string' do
122
- let(:array) {
123
- [
124
- { text: "hello\nworld\n\n\nhow are you?" },
125
- { text: "\n" },
126
- { text: "\n" },
127
- { text: "\n" },
128
- { text: "" },
129
- { text: "fine, thanks." },
130
- { text: "" },
131
- { text: "\n" },
132
- { text: "" }
133
- ]
134
- }
135
-
136
- before do
137
- subject.format_array = array
138
-
139
- while string = subject.next_string
140
- end
141
-
142
- subject.finalize_line
143
- end
144
-
145
- it 'never returns a fragment whose text is an empty string' do
146
- while fragment = subject.retrieve_fragment
147
- expect(fragment.text).not_to be_empty
148
- end
149
- end
150
- end
151
-
152
- context 'with formatted array' do
153
- let(:array) {
154
- [
155
- { text: 'hello ' },
156
- { text: 'world how ', styles: [:bold] },
157
- { text: 'are', styles: [:bold, :italic] },
158
- { text: ' you?' }
159
- ]
160
- }
161
-
162
- before do
163
- subject.format_array = array
164
- end
165
-
166
- context 'after all strings have been consumed' do
167
- before do
168
- while string = subject.next_string
169
- end
170
- end
171
-
172
- it 'should raise RuntimeError an error if not finalized' do
173
- expect { subject.retrieve_fragment }.to raise_error(RuntimeError)
174
- end
175
-
176
- context 'and finalized' do
177
- before do
178
- subject.finalize_line
179
- end
180
-
181
- it 'returns the consumed fragments in order of consumption' do
182
- expect(subject.retrieve_fragment.text).to eq("hello ")
183
- expect(subject.retrieve_fragment.text).to eq("world how ")
184
- expect(subject.retrieve_fragment.text).to eq("are")
185
- expect(subject.retrieve_fragment.text).to eq(" you?")
186
- end
187
-
188
- it 'does not alter the current font style' do
189
- subject.retrieve_fragment
190
- expect(subject.current_format_state[:styles]).to be_nil
191
- end
192
- end
193
- end
194
- end
195
- end
196
- end
197
-
198
- describe "Core::Text::Formatted::Arranger#update_last_string" do
199
- it "should update the last retrieved string with what actually fit on" \
200
- "the line and the list of unconsumed with what did not" do
201
- create_pdf
202
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
203
- array = [{ :text => "hello " },
204
- { :text => "world how ", :styles => [:bold] },
205
- { :text => "are", :styles => [:bold, :italic] },
206
- { :text => " you now?", :styles => [:bold, :italic] }]
207
- arranger.format_array = array
208
- while string = arranger.next_string
209
- end
210
- arranger.update_last_string(" you", " now?", nil)
211
- expect(arranger.consumed[3]).to eq(:text => " you",
212
- :styles => [:bold, :italic])
213
- expect(arranger.unconsumed).to eq([{ :text => " now?",
214
- :styles => [:bold, :italic] }])
215
- end
216
- it "should set the format state to the previously processed fragment" do
217
- create_pdf
218
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
219
- array = [{ :text => "hello " },
220
- { :text => "world how ", :styles => [:bold] },
221
- { :text => "are", :styles => [:bold, :italic] },
222
- { :text => " you now?" }]
223
- arranger.format_array = array
224
- 3.times { arranger.next_string }
225
- expect(arranger.current_format_state).to eq(:styles => [:bold, :italic])
226
- arranger.update_last_string("", "are", "-")
227
- expect(arranger.current_format_state).to eq(:styles => [:bold])
228
- end
229
-
230
- context "when the entire string was used" do
231
- it "should not push empty string onto unconsumed" do
232
- create_pdf
233
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
234
- array = [
235
- { :text => "hello " },
236
- { :text => "world how ", :styles => [:bold] },
237
- { :text => "are", :styles => [:bold, :italic] },
238
- { :text => " you now?" }
239
- ]
240
- arranger.format_array = array
241
- while string = arranger.next_string
242
- end
243
- arranger.update_last_string(" you now?", "", nil)
244
- expect(arranger.unconsumed).to eq([])
245
- end
246
- end
247
- end
248
- describe "Core::Text::Formatted::Arranger#space_count" do
249
- before(:each) do
250
- create_pdf
251
- @arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
252
- array = [{ :text => "hello " },
253
- { :text => "world how ", :styles => [:bold] },
254
- { :text => "are", :styles => [:bold, :italic] },
255
- { :text => " you?" }]
256
- @arranger.format_array = array
257
- while string = @arranger.next_string
258
- end
259
- end
260
- it "should raise_error an error if called before finalize_line was called" do
261
- expect do
262
- @arranger.space_count
263
- end.to raise_error(RuntimeError)
264
- end
265
- it "should return the total number of spaces in all fragments" do
266
- @arranger.finalize_line
267
- expect(@arranger.space_count).to eq(4)
268
- end
269
- end
270
- describe "Core::Text::Formatted::Arranger#finalize_line" do
271
- it "should make it so that all trailing white space fragments " \
272
- "exclude trailing white space" do
273
- create_pdf
274
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
275
- array = [{ :text => "hello " },
276
- { :text => "world how ", :styles => [:bold] },
277
- { :text => " ", :styles => [:bold, :italic] }]
278
- arranger.format_array = array
279
- while string = arranger.next_string
280
- end
281
- arranger.finalize_line
282
- expect(arranger.fragments.length).to eq(3)
283
-
284
- fragment = arranger.retrieve_fragment
285
- expect(fragment.text).to eq("hello ")
286
-
287
- fragment = arranger.retrieve_fragment
288
- expect(fragment.text).to eq("world how")
289
-
290
- fragment = arranger.retrieve_fragment
291
- expect(fragment.text).to eq("")
292
- end
293
- end
294
-
295
- describe "Core::Text::Formatted::Arranger#line_width" do
296
- before(:each) do
297
- create_pdf
298
- @arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
299
- array = [{ :text => "hello " },
300
- { :text => "world", :styles => [:bold] }]
301
- @arranger.format_array = array
302
- while string = @arranger.next_string
303
- end
304
- end
305
- it "should raise_error an error if called before finalize_line was called" do
306
- expect do
307
- @arranger.line_width
308
- end.to raise_error(RuntimeError)
309
- end
310
- it "should return the width of the complete line" do
311
- @arranger.finalize_line
312
- expect(@arranger.line_width).to be > 0
313
- end
314
- end
315
-
316
- describe "Core::Text::Formatted::Arranger#line_width with character_spacing > 0" do
317
- it "should return a width greater than a line without a character_spacing" do
318
- create_pdf
319
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
320
-
321
- array = [{ :text => "hello " },
322
- { :text => "world", :styles => [:bold] }]
323
- arranger.format_array = array
324
- while string = arranger.next_string
325
- end
326
- arranger.finalize_line
327
-
328
- base_line_width = arranger.line_width
329
-
330
- array = [{ :text => "hello " },
331
- { :text => "world", :styles => [:bold],
332
- :character_spacing => 7 }]
333
- arranger.format_array = array
334
- while string = arranger.next_string
335
- end
336
- arranger.finalize_line
337
- expect(arranger.line_width).to be > base_line_width
338
- end
339
- end
340
-
341
- describe "Core::Text::Formatted::Arranger#line" do
342
- before(:each) do
343
- create_pdf
344
- @arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
345
- array = [{ :text => "hello " },
346
- { :text => "world", :styles => [:bold] }]
347
- @arranger.format_array = array
348
- while string = @arranger.next_string
349
- end
350
- end
351
- it "should raise_error an error if called before finalize_line was called" do
352
- expect do
353
- @arranger.line
354
- end.to raise_error(RuntimeError)
355
- end
356
- it "should return the complete line" do
357
- @arranger.finalize_line
358
- expect(@arranger.line).to eq("hello world")
359
- end
360
- end
361
-
362
- describe "Core::Text::Formatted::Arranger#unconsumed" do
363
- it "should return the original array if nothing was consumed" do
364
- create_pdf
365
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
366
- array = [{ :text => "hello " },
367
- { :text => "world how ", :styles => [:bold] },
368
- { :text => "are", :styles => [:bold, :italic] },
369
- { :text => " you now?" }]
370
- arranger.format_array = array
371
- expect(arranger.unconsumed).to eq(array)
372
- end
373
- it "should return an empty array if everything was consumed" do
374
- create_pdf
375
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
376
- array = [{ :text => "hello " },
377
- { :text => "world how ", :styles => [:bold] },
378
- { :text => "are", :styles => [:bold, :italic] },
379
- { :text => " you now?" }]
380
- arranger.format_array = array
381
- while string = arranger.next_string
382
- end
383
- expect(arranger.unconsumed).to eq([])
384
- end
385
- end
386
-
387
- describe "Core::Text::Formatted::Arranger#finished" do
388
- it "should be_false if anything was not printed" do
389
- create_pdf
390
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
391
- array = [{ :text => "hello " },
392
- { :text => "world how ", :styles => [:bold] },
393
- { :text => "are", :styles => [:bold, :italic] },
394
- { :text => " you now?" }]
395
- arranger.format_array = array
396
- while string = arranger.next_string
397
- end
398
- arranger.update_last_string(" you", "now?", nil)
399
- expect(arranger).not_to be_finished
400
- end
401
- it "should be_false if everything was printed" do
402
- create_pdf
403
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
404
- array = [{ :text => "hello " },
405
- { :text => "world how ", :styles => [:bold] },
406
- { :text => "are", :styles => [:bold, :italic] },
407
- { :text => " you now?" }]
408
- arranger.format_array = array
409
- while string = arranger.next_string
410
- end
411
- expect(arranger).to be_finished
412
- end
413
- end
414
-
415
- describe "Core::Text::Formatted::Arranger.max_line_height" do
416
- it "should be the height of the maximum consumed fragment" do
417
- create_pdf
418
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
419
- array = [{ :text => "hello " },
420
- { :text => "world how ", :styles => [:bold] },
421
- { :text => "are", :styles => [:bold, :italic],
422
- :size => 28 },
423
- { :text => " you now?" }]
424
- arranger.format_array = array
425
- while string = arranger.next_string
426
- end
427
- arranger.finalize_line
428
- expect(arranger.max_line_height).to be_within(0.0001).of(33.32)
429
- end
430
- end
431
-
432
- describe "Core::Text::Formatted::Arranger#repack_unretrieved" do
433
- it "should restore part of the original string" do
434
- create_pdf
435
- arranger = Prawn::Text::Formatted::Arranger.new(@pdf)
436
- array = [{ :text => "hello " },
437
- { :text => "world how ", :styles => [:bold] },
438
- { :text => "are", :styles => [:bold, :italic] },
439
- { :text => " you now?" }]
440
- arranger.format_array = array
441
- while string = arranger.next_string
442
- end
443
- arranger.finalize_line
444
- arranger.retrieve_fragment
445
- arranger.retrieve_fragment
446
- arranger.repack_unretrieved
447
- expect(arranger.unconsumed).to eq([
448
- { :text => "are", :styles => [:bold, :italic] },
449
- { :text => " you now?" }
450
- ])
451
- end
452
- end
@@ -1,716 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
-
5
- describe "Text::Formatted::Box wrapping" do
6
- before(:each) do
7
- create_pdf
8
- end
9
-
10
- it "should not wrap between two fragments" do
11
- texts = [
12
- { :text => "Hello " },
13
- { :text => "World" },
14
- { :text => "2", :styles => [:superscript] }
15
- ]
16
- text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
17
- text_box.render
18
- expect(text_box.text).to eq("Hello\nWorld2")
19
- end
20
-
21
- it "should not raise an Encoding::CompatibilityError when keeping a TTF and an AFM font together" do
22
- file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
23
-
24
- @pdf.font_families["Kai"] = {
25
- :normal => { :file => file, :font => "Kai" }
26
- }
27
-
28
- texts = [
29
- { :text => "Hello " },
30
- { :text => "再见", :font => "Kai" },
31
- { :text => "World" }
32
- ]
33
- text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
34
-
35
- text_box.render
36
- end
37
-
38
- it "should wrap between two fragments when the preceding fragment ends with white space" do
39
- texts = [
40
- { :text => "Hello " },
41
- { :text => "World " },
42
- { :text => "2", :styles => [:superscript] }
43
- ]
44
- text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
45
- text_box.render
46
- expect(text_box.text).to eq("Hello World\n2")
47
-
48
- texts = [
49
- { :text => "Hello " },
50
- { :text => "World\n" },
51
- { :text => "2", :styles => [:superscript] }
52
- ]
53
- text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
54
- text_box.render
55
- expect(text_box.text).to eq("Hello World\n2")
56
- end
57
-
58
- it "should wrap between two fragments when the final fragment begins with white space" do
59
- texts = [
60
- { :text => "Hello " },
61
- { :text => "World" },
62
- { :text => " 2", :styles => [:superscript] }
63
- ]
64
- text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
65
- text_box.render
66
- expect(text_box.text).to eq("Hello World\n2")
67
-
68
- texts = [
69
- { :text => "Hello " },
70
- { :text => "World" },
71
- { :text => "\n2", :styles => [:superscript] }
72
- ]
73
- text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
74
- text_box.render
75
- expect(text_box.text).to eq("Hello World\n2")
76
- end
77
-
78
- it "should properly handle empty slices using default encoding" do
79
- texts = [{ :text => "Noua Delineatio Geographica generalis | Apostolicarum peregrinationum | S FRANCISCI XAUERII | Indiarum & Iaponiæ Apostoli", :font => 'Courier', :size => 10 }]
80
- text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Noua Delineatio Geographica gen"))
81
- expect {
82
- text_box.render
83
- }.not_to raise_error
84
- expect(text_box.text).to eq("Noua Delineatio Geographica\ngeneralis | Apostolicarum\nperegrinationum | S FRANCISCI\nXAUERII | Indiarum & Iaponi\346\nApostoli")
85
- end
86
- end
87
-
88
- describe "Text::Formatted::Box with :fallback_fonts option that includes" \
89
- "a Chinese font and set of Chinese glyphs not in the current font" do
90
- it "should change the font to the Chinese font for the Chinese glyphs" do
91
- create_pdf
92
- file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
93
- @pdf.font_families["Kai"] = {
94
- :normal => { :file => file, :font => "Kai" }
95
- }
96
- formatted_text = [{ :text => "hello你好" },
97
- { :text => "再见goodbye" }]
98
- @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Kai"])
99
-
100
- text = PDF::Inspector::Text.analyze(@pdf.render)
101
-
102
- fonts_used = text.font_settings.map { |e| e[:name] }
103
- expect(fonts_used.length).to eq(4)
104
- expect(fonts_used[0]).to eq(:Helvetica)
105
- expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
106
- expect(fonts_used[2].to_s).to match(/GBZenKai-Medium/)
107
- expect(fonts_used[3]).to eq(:Helvetica)
108
-
109
- expect(text.strings[0]).to eq("hello")
110
- expect(text.strings[1]).to eq("你好")
111
- expect(text.strings[2]).to eq("再见")
112
- expect(text.strings[3]).to eq("goodbye")
113
- end
114
- end
115
-
116
- describe "Text::Formatted::Box with :fallback_fonts option that includes" \
117
- "an AFM font and Win-Ansi glyph not in the current Chinese font" do
118
- it "should change the font to the AFM font for the Win-Ansi glyph" do
119
- create_pdf
120
- file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
121
- @pdf.font_families["Kai"] = {
122
- :normal => { :file => file, :font => "Kai" }
123
- }
124
- @pdf.font("Kai")
125
- formatted_text = [{ :text => "hello你好" },
126
- { :text => "再见€" }]
127
- @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Helvetica"])
128
-
129
- text = PDF::Inspector::Text.analyze(@pdf.render)
130
-
131
- fonts_used = text.font_settings.map { |e| e[:name] }
132
- expect(fonts_used.length).to eq(4)
133
- expect(fonts_used[0].to_s).to match(/GBZenKai-Medium/)
134
- expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
135
- expect(fonts_used[2].to_s).to match(/GBZenKai-Medium/)
136
- expect(fonts_used[3]).to eq(:Helvetica)
137
-
138
- expect(text.strings[0]).to eq("hello")
139
- expect(text.strings[1]).to eq("你好")
140
- expect(text.strings[2]).to eq("再见")
141
- expect(text.strings[3]).to eq("€")
142
- end
143
- end
144
-
145
- describe "Text::Formatted::Box with :fallback_fonts option and fragment " \
146
- "level font" do
147
- it "should use the fragment level font except for glyphs not in that font" do
148
- create_pdf
149
- file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
150
- @pdf.font_families["Kai"] = {
151
- :normal => { :file => file, :font => "Kai" }
152
- }
153
-
154
- file = "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
155
- @pdf.font_families["DejaVu Sans"] = {
156
- :normal => { :file => file }
157
- }
158
-
159
- formatted_text = [{ :text => "hello你好" },
160
- { :text => "再见goodbye", :font => "Times-Roman" }]
161
- @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Kai"])
162
-
163
- text = PDF::Inspector::Text.analyze(@pdf.render)
164
-
165
- fonts_used = text.font_settings.map { |e| e[:name] }
166
- expect(fonts_used.length).to eq(4)
167
- expect(fonts_used[0]).to eq(:Helvetica)
168
- expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
169
- expect(fonts_used[2].to_s).to match(/GBZenKai-Medium/)
170
- expect(fonts_used[3]).to eq(:"Times-Roman")
171
-
172
- expect(text.strings[0]).to eq("hello")
173
- expect(text.strings[1]).to eq("你好")
174
- expect(text.strings[2]).to eq("再见")
175
- expect(text.strings[3]).to eq("goodbye")
176
- end
177
- end
178
-
179
- describe "Text::Formatted::Box" do
180
- before(:each) do
181
- create_pdf
182
- file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
183
- @pdf.font_families["Kai"] = {
184
- :normal => { :file => file, :font => "Kai" }
185
- }
186
-
187
- file = "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
188
- @pdf.font_families["DejaVu Sans"] = {
189
- :normal => { :file => file }
190
- }
191
-
192
- @formatted_text = [{ :text => "hello你好" }]
193
- @pdf.fallback_fonts(["Kai"])
194
- @pdf.fallback_fonts = ["Kai"]
195
- end
196
- it "#fallback_fonts should return the document-wide fallback fonts" do
197
- expect(@pdf.fallback_fonts).to eq(["Kai"])
198
- end
199
- it "should be able to set text fallback_fonts document-wide" do
200
- @pdf.formatted_text_box(@formatted_text)
201
-
202
- text = PDF::Inspector::Text.analyze(@pdf.render)
203
-
204
- fonts_used = text.font_settings.map { |e| e[:name] }
205
- expect(fonts_used.length).to eq(2)
206
- expect(fonts_used[0]).to eq(:Helvetica)
207
- expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
208
- end
209
- it "should be able to override document-wide fallback_fonts" do
210
- @pdf.fallback_fonts = ["DejaVu Sans"]
211
- @pdf.formatted_text_box(@formatted_text, :fallback_fonts => ["Kai"])
212
-
213
- text = PDF::Inspector::Text.analyze(@pdf.render)
214
-
215
- fonts_used = text.font_settings.map { |e| e[:name] }
216
- expect(fonts_used.length).to eq(2)
217
- expect(fonts_used[0]).to eq(:Helvetica)
218
- expect(fonts_used[1]).to match(/Kai/)
219
- end
220
- it "should omit the fallback fonts overhead when passing an empty array " \
221
- "as the :fallback_fonts" do
222
- @pdf.font("Kai")
223
-
224
- box = Prawn::Text::Formatted::Box.new(@formatted_text,
225
- :document => @pdf,
226
- :fallback_fonts => [])
227
-
228
- expect(box).to_not receive(:process_fallback_fonts)
229
- box.render
230
- end
231
-
232
- it "should be able to clear document-wide fallback_fonts" do
233
- @pdf.fallback_fonts([])
234
- box = Prawn::Text::Formatted::Box.new(@formatted_text,
235
- :document => @pdf)
236
-
237
- @pdf.font("Kai")
238
-
239
- expect(box).to_not receive(:process_fallback_fonts)
240
- box.render
241
- end
242
- end
243
-
244
- describe "Text::Formatted::Box with :fallback_fonts option " \
245
- "with glyphs not in the primary or the fallback fonts" do
246
- it "should raise an exception" do
247
- file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
248
- create_pdf
249
- formatted_text = [{ :text => "hello world. 世界你好。" }]
250
-
251
- expect {
252
- @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Courier"])
253
- }.to raise_error(Prawn::Errors::IncompatibleStringEncoding)
254
- end
255
- end
256
-
257
- describe "Text::Formatted::Box#extensions" do
258
- it "should be able to override default line wrapping" do
259
- create_pdf
260
- Prawn::Text::Formatted::Box.extensions << TestFormattedWrapOverride
261
- @pdf.formatted_text_box([{ :text => "hello world" }], {})
262
- Prawn::Text::Formatted::Box.extensions.delete(TestFormattedWrapOverride)
263
- text = PDF::Inspector::Text.analyze(@pdf.render)
264
- expect(text.strings[0]).to eq("all your base are belong to us")
265
- end
266
- it "overriding Text::Formatted::Box line wrapping should not affect " \
267
- "Text::Box wrapping" do
268
- create_pdf
269
- Prawn::Text::Formatted::Box.extensions << TestFormattedWrapOverride
270
- @pdf.text_box("hello world", {})
271
- Prawn::Text::Formatted::Box.extensions.delete(TestFormattedWrapOverride)
272
- text = PDF::Inspector::Text.analyze(@pdf.render)
273
- expect(text.strings[0]).to eq("hello world")
274
- end
275
- it "overriding Text::Box line wrapping should override Text::Box wrapping" do
276
- create_pdf
277
- Prawn::Text::Box.extensions << TestFormattedWrapOverride
278
- @pdf.text_box("hello world", {})
279
- Prawn::Text::Box.extensions.delete(TestFormattedWrapOverride)
280
- text = PDF::Inspector::Text.analyze(@pdf.render)
281
- expect(text.strings[0]).to eq("all your base are belong to us")
282
- end
283
- end
284
-
285
- describe "Text::Formatted::Box#render" do
286
- it "should handle newlines" do
287
- create_pdf
288
- array = [{ :text => "hello\nworld" }]
289
- options = { :document => @pdf }
290
- text_box = Prawn::Text::Formatted::Box.new(array, options)
291
- text_box.render
292
- expect(text_box.text).to eq("hello\nworld")
293
- end
294
- it "should omit spaces from the beginning of the line" do
295
- create_pdf
296
- array = [{ :text => " hello\n world" }]
297
- options = { :document => @pdf }
298
- text_box = Prawn::Text::Formatted::Box.new(array, options)
299
- text_box.render
300
- expect(text_box.text).to eq("hello\nworld")
301
- end
302
- it "should be okay printing a line of whitespace" do
303
- create_pdf
304
- array = [{ :text => "hello\n \nworld" }]
305
- options = { :document => @pdf }
306
- text_box = Prawn::Text::Formatted::Box.new(array, options)
307
- text_box.render
308
- expect(text_box.text).to eq("hello\n\nworld")
309
-
310
- array = [{ :text => "hello" + " " * 500 },
311
- { :text => " " * 500 },
312
- { :text => " " * 500 + "\n" },
313
- { :text => "world" }]
314
- options = { :document => @pdf }
315
- text_box = Prawn::Text::Formatted::Box.new(array, options)
316
- text_box.render
317
- expect(text_box.text).to eq("hello\n\nworld")
318
- end
319
- it "should enable fragment level direction setting" do
320
- create_pdf
321
- number_of_hellos = 18
322
- array = [
323
- { :text => "hello " * number_of_hellos },
324
- { :text => "world", :direction => :ltr },
325
- { :text => ", how are you?" }
326
- ]
327
- options = { :document => @pdf, :direction => :rtl }
328
- text_box = Prawn::Text::Formatted::Box.new(array, options)
329
- text_box.render
330
- text = PDF::Inspector::Text.analyze(@pdf.render)
331
- expect(text.strings[0]).to eq("era woh ,")
332
- expect(text.strings[1]).to eq("world")
333
- expect(text.strings[2]).to eq(" olleh" * number_of_hellos)
334
- expect(text.strings[3]).to eq("?uoy")
335
- end
336
- end
337
-
338
- describe "Text::Formatted::Box#render" do
339
- it "should be able to perform fragment callbacks" do
340
- create_pdf
341
- callback_object = TestFragmentCallback.new("something", 7, :document => @pdf)
342
- expect(callback_object).to receive(:render_behind).with(
343
- kind_of(Prawn::Text::Formatted::Fragment)
344
- )
345
- expect(callback_object).to receive(:render_in_front).with(
346
- kind_of(Prawn::Text::Formatted::Fragment)
347
- )
348
- array = [{ :text => "hello world " },
349
- { :text => "callback now",
350
- :callback => callback_object }]
351
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
352
- text_box.render
353
- end
354
- it "should be able to perform fragment callbacks on multiple objects" do
355
- create_pdf
356
-
357
- callback_object = TestFragmentCallback.new("something", 7, :document => @pdf)
358
- expect(callback_object).to receive(:render_behind).with(
359
- kind_of(Prawn::Text::Formatted::Fragment)
360
- )
361
- expect(callback_object).to receive(:render_in_front).with(
362
- kind_of(Prawn::Text::Formatted::Fragment)
363
- )
364
-
365
- callback_object2 = TestFragmentCallback.new("something else", 14, :document => @pdf)
366
- expect(callback_object2).to receive(:render_behind).with(
367
- kind_of(Prawn::Text::Formatted::Fragment)
368
- )
369
- expect(callback_object2).to receive(:render_in_front).with(
370
- kind_of(Prawn::Text::Formatted::Fragment)
371
- )
372
-
373
- array = [{ :text => "hello world " },
374
- { :text => "callback now",
375
- :callback => [callback_object, callback_object2] }]
376
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
377
- text_box.render
378
- end
379
- it "fragment callbacks should be able to define only the callback they need" do
380
- create_pdf
381
- behind = TestFragmentCallbackBehind.new("something", 7,
382
- :document => @pdf)
383
- in_front = TestFragmentCallbackInFront.new("something", 7,
384
- :document => @pdf)
385
- array = [{ :text => "hello world " },
386
- { :text => "callback now",
387
- :callback => [behind, in_front] }]
388
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
389
-
390
- text_box.render # trigger callbacks
391
- end
392
- it "should be able to set the font" do
393
- create_pdf
394
- array = [{ :text => "this contains " },
395
- { :text => "Times-Bold",
396
- :styles => [:bold],
397
- :font => "Times-Roman" },
398
- { :text => " text" }]
399
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
400
- text_box.render
401
- contents = PDF::Inspector::Text.analyze(@pdf.render)
402
- fonts = contents.font_settings.map { |e| e[:name] }
403
- expect(fonts).to eq([:Helvetica, :"Times-Bold", :Helvetica])
404
- expect(contents.strings[0]).to eq("this contains ")
405
- expect(contents.strings[1]).to eq("Times-Bold")
406
- expect(contents.strings[2]).to eq(" text")
407
- end
408
- it "should be able to set bold" do
409
- create_pdf
410
- array = [{ :text => "this contains " },
411
- { :text => "bold", :styles => [:bold] },
412
- { :text => " text" }]
413
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
414
- text_box.render
415
- contents = PDF::Inspector::Text.analyze(@pdf.render)
416
- fonts = contents.font_settings.map { |e| e[:name] }
417
- expect(fonts).to eq([:Helvetica, :"Helvetica-Bold", :Helvetica])
418
- expect(contents.strings[0]).to eq("this contains ")
419
- expect(contents.strings[1]).to eq("bold")
420
- expect(contents.strings[2]).to eq(" text")
421
- end
422
- it "should be able to set italics" do
423
- create_pdf
424
- array = [{ :text => "this contains " },
425
- { :text => "italic", :styles => [:italic] },
426
- { :text => " text" }]
427
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
428
- text_box.render
429
- contents = PDF::Inspector::Text.analyze(@pdf.render)
430
- fonts = contents.font_settings.map { |e| e[:name] }
431
- expect(fonts).to eq([:Helvetica, :"Helvetica-Oblique", :Helvetica])
432
- end
433
- it "should be able to set subscript" do
434
- create_pdf
435
- array = [{ :text => "this contains " },
436
- { :text => "subscript", :size => 18, :styles => [:subscript] },
437
- { :text => " text" }]
438
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
439
- text_box.render
440
- contents = PDF::Inspector::Text.analyze(@pdf.render)
441
- expect(contents.font_settings[0][:size]).to eq(12)
442
- expect(contents.font_settings[1][:size]).to be_within(0.0001).of(18 * 0.583)
443
- end
444
- it "should be able to set superscript" do
445
- create_pdf
446
- array = [{ :text => "this contains " },
447
- { :text => "superscript", :size => 18, :styles => [:superscript] },
448
- { :text => " text" }]
449
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
450
- text_box.render
451
- contents = PDF::Inspector::Text.analyze(@pdf.render)
452
- expect(contents.font_settings[0][:size]).to eq(12)
453
- expect(contents.font_settings[1][:size]).to be_within(0.0001).of(18 * 0.583)
454
- end
455
- it "should be able to set compound bold and italic text" do
456
- create_pdf
457
- array = [{ :text => "this contains " },
458
- { :text => "bold italic", :styles => [:bold, :italic] },
459
- { :text => " text" }]
460
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
461
- text_box.render
462
- contents = PDF::Inspector::Text.analyze(@pdf.render)
463
- fonts = contents.font_settings.map { |e| e[:name] }
464
- expect(fonts).to eq([:Helvetica, :"Helvetica-BoldOblique", :Helvetica])
465
- end
466
- it "should be able to underline" do
467
- create_pdf
468
- array = [{ :text => "this contains " },
469
- { :text => "underlined", :styles => [:underline] },
470
- { :text => " text" }]
471
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
472
- text_box.render
473
- line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
474
- expect(line_drawing.points.length).to eq(2)
475
- end
476
- it "should be able to strikethrough" do
477
- create_pdf
478
- array = [{ :text => "this contains " },
479
- { :text => "struckthrough", :styles => [:strikethrough] },
480
- { :text => " text" }]
481
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
482
- text_box.render
483
- line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
484
- expect(line_drawing.points.length).to eq(2)
485
- end
486
- it "should be able to add URL links" do
487
- create_pdf
488
- expect(@pdf).to receive(:link_annotation).with(kind_of(Array), :Border => [0, 0, 0],
489
- :A => {
490
- :Type => :Action,
491
- :S => :URI,
492
- :URI => "http://example.com"
493
- })
494
- array = [{ :text => "click " },
495
- { :text => "here", :link => "http://example.com" },
496
- { :text => " to visit" }]
497
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
498
- text_box.render
499
- end
500
- it "should be able to add destination links" do
501
- create_pdf
502
- expect(@pdf).to receive(:link_annotation).with(kind_of(Array), :Border => [0, 0, 0],
503
- :Dest => "ToC")
504
- array = [{ :text => "Go to the " },
505
- { :text => "Table of Contents", :anchor => "ToC" }]
506
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
507
- text_box.render
508
- end
509
- it "should be able to add local actions" do
510
- create_pdf
511
- expect(@pdf).to receive(:link_annotation).with(kind_of(Array), :Border => [0, 0, 0],
512
- :A => {
513
- :Type => :Action,
514
- :S => :Launch,
515
- :F => "../example.pdf",
516
- :NewWindow => true
517
- })
518
- array = [{ :text => "click " },
519
- { :text => "here", :local => "../example.pdf" },
520
- { :text => " to open a local file" }]
521
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
522
- text_box.render
523
- end
524
- it "should be able to set font size" do
525
- create_pdf
526
- array = [{ :text => "this contains " },
527
- { :text => "sized", :size => 24 },
528
- { :text => " text" }]
529
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
530
- text_box.render
531
- contents = PDF::Inspector::Text.analyze(@pdf.render)
532
- expect(contents.font_settings[0][:size]).to eq(12)
533
- expect(contents.font_settings[1][:size]).to eq(24)
534
- end
535
- it "should set the baseline based on the tallest fragment on a given line" do
536
- create_pdf
537
- array = [{ :text => "this contains " },
538
- { :text => "sized", :size => 24 },
539
- { :text => " text" }]
540
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
541
- text_box.render
542
- @pdf.font_size(24) do
543
- expect(text_box.height).to be_within(0.001).of(@pdf.font.ascender + @pdf.font.descender)
544
- end
545
- end
546
- it "should be able to set color via an rgb hex string" do
547
- create_pdf
548
- array = [{ :text => "rgb",
549
- :color => "ff0000" }]
550
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
551
- text_box.render
552
- colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
553
- expect(colors.fill_color_count).to eq(2)
554
- expect(colors.stroke_color_count).to eq(2)
555
- end
556
- it "should be able to set color using a cmyk array" do
557
- create_pdf
558
- array = [{ :text => "cmyk",
559
- :color => [100, 0, 0, 0] }]
560
- text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
561
- text_box.render
562
- colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
563
- expect(colors.fill_color_count).to eq(2)
564
- expect(colors.stroke_color_count).to eq(2)
565
- end
566
- end
567
-
568
- describe "Text::Formatted::Box#render(:dry_run => true)" do
569
- it "should not change the graphics state of the document" do
570
- create_pdf
571
-
572
- state_before = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
573
- fill_color_count = state_before.fill_color_count
574
- stroke_color_count = state_before.stroke_color_count
575
- stroke_color_space_count = state_before.stroke_color_space_count
576
-
577
- array = [{ :text => 'Foo',
578
- :color => [0, 0, 0, 100] }]
579
- options = { :document => @pdf }
580
- text_box = Prawn::Text::Formatted::Box.new(array, options)
581
- text_box.render(:dry_run => true)
582
-
583
- state_after = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
584
- expect(state_after.fill_color_count).to eq(fill_color_count)
585
- expect(state_after.stroke_color_count).to eq(stroke_color_count)
586
- expect(state_after.stroke_color_space_count).to eq(stroke_color_space_count)
587
- end
588
- end
589
-
590
- describe "Text::Formatted::Box#render with fragment level :character_spacing option" do
591
- it "should draw the character spacing to the document" do
592
- create_pdf
593
- array = [{ :text => "hello world",
594
- :character_spacing => 7 }]
595
- options = { :document => @pdf }
596
- text_box = Prawn::Text::Formatted::Box.new(array, options)
597
- text_box.render
598
- contents = PDF::Inspector::Text.analyze(@pdf.render)
599
- expect(contents.character_spacing[0]).to eq(7)
600
- end
601
- it "should draw the character spacing to the document" do
602
- create_pdf
603
- array = [{ :text => "hello world",
604
- :font => "Courier",
605
- :character_spacing => 10 }]
606
- options = { :document => @pdf,
607
- :width => 100,
608
- :overflow => :expand }
609
- text_box = Prawn::Text::Formatted::Box.new(array, options)
610
- text_box.render
611
- expect(text_box.text).to eq("hello\nworld")
612
- end
613
- end
614
-
615
- describe "Text::Formatted::Box#render with :align => :justify" do
616
- it "should not justify the last line of a paragraph" do
617
- create_pdf
618
- array = [{ :text => "hello world " },
619
- { :text => "\n" },
620
- { :text => "goodbye" }]
621
- options = { :document => @pdf, :align => :justify }
622
- text_box = Prawn::Text::Formatted::Box.new(array, options)
623
- text_box.render
624
- contents = PDF::Inspector::Text.analyze(@pdf.render)
625
- expect(contents.word_spacing).to be_empty
626
- end
627
- end
628
-
629
- describe "Text::Formatted::Box#render with :valign => :center" do
630
- it "should have a bottom gap equal to baseline and bottom of box" do
631
- create_pdf
632
- box_height = 100
633
- y = 450
634
- array = [{ :text => 'Vertical Align' }]
635
- options = {
636
- :document => @pdf,
637
- :valign => :center,
638
- :at => [0, y],
639
- :width => 100,
640
- :height => box_height,
641
- :size => 16
642
- }
643
- text_box = Prawn::Text::Formatted::Box.new(array, options)
644
- text_box.render
645
- line_padding = (box_height - text_box.height + text_box.descender) * 0.5
646
- baseline = y - line_padding
647
-
648
- expect(text_box.at[1]).to be_within(0.01).of(baseline)
649
- end
650
- end
651
-
652
- describe "Text::Formatted::Box#render with :valign => :bottom" do
653
- it "should not render a gap between the text and bottom of box" do
654
- create_pdf
655
- box_height = 100
656
- y = 450
657
- array = [{ :text => 'Vertical Align' }]
658
- options = {
659
- :document => @pdf,
660
- :valign => :bottom,
661
- :at => [0, y],
662
- :width => 100,
663
- :height => box_height,
664
- :size => 16
665
- }
666
- text_box = Prawn::Text::Formatted::Box.new(array, options)
667
- text_box.render
668
- top_padding = y - (box_height - text_box.height)
669
-
670
- expect(text_box.at[1]).to be_within(0.01).of(top_padding)
671
- end
672
- end
673
-
674
- class TestFragmentCallback
675
- def initialize(string, number, options)
676
- @document = options[:document]
677
- end
678
-
679
- def render_behind(fragment)
680
- end
681
-
682
- def render_in_front(fragment)
683
- end
684
- end
685
-
686
- class TestFragmentCallbackBehind
687
- def initialize(string, number, options)
688
- @document = options[:document]
689
- end
690
-
691
- def render_behind(fragment)
692
- end
693
- end
694
-
695
- class TestFragmentCallbackInFront
696
- def initialize(string, number, options)
697
- @document = options[:document]
698
- end
699
-
700
- def render_in_front(fragment)
701
- end
702
- end
703
-
704
- module TestFormattedWrapOverride
705
- def wrap(array)
706
- initialize_wrap([{ :text => 'all your base are belong to us' }])
707
- line_to_print = @line_wrap.wrap_line(:document => @document,
708
- :kerning => @kerning,
709
- :width => 10000,
710
- :arranger => @arranger)
711
- fragment = @arranger.retrieve_fragment
712
- format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)
713
-
714
- []
715
- end
716
- end