prawn 0.13.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +10 -0
  4. data/GPLv2 +20 -21
  5. data/Gemfile +3 -16
  6. data/Rakefile +17 -39
  7. data/lib/prawn/document/bounding_box.rb +85 -42
  8. data/lib/prawn/document/column_box.rb +21 -11
  9. data/lib/prawn/document/internals.rb +40 -147
  10. data/lib/prawn/document/span.rb +25 -17
  11. data/lib/prawn/document.rb +286 -245
  12. data/lib/prawn/encoding.rb +68 -101
  13. data/lib/prawn/errors.rb +47 -43
  14. data/lib/prawn/font.rb +204 -155
  15. data/lib/prawn/font_metric_cache.rb +25 -21
  16. data/lib/prawn/fonts/afm.rb +292 -0
  17. data/lib/prawn/{font → fonts}/dfont.rb +7 -13
  18. data/lib/prawn/fonts/otf.rb +11 -0
  19. data/lib/prawn/fonts/ttc.rb +36 -0
  20. data/lib/prawn/{font → fonts}/ttf.rb +142 -80
  21. data/lib/prawn/graphics/blend_mode.rb +65 -0
  22. data/lib/prawn/graphics/cap_style.rb +6 -5
  23. data/lib/prawn/graphics/color.rb +47 -44
  24. data/lib/prawn/graphics/dash.rb +30 -13
  25. data/lib/prawn/graphics/join_style.rb +13 -6
  26. data/lib/prawn/graphics/patterns.rb +221 -90
  27. data/lib/prawn/graphics/transformation.rb +21 -12
  28. data/lib/prawn/graphics/transparency.rb +21 -17
  29. data/lib/prawn/graphics.rb +155 -128
  30. data/lib/prawn/{layout/grid.rb → grid.rb} +110 -47
  31. data/lib/prawn/image_handler.rb +16 -2
  32. data/lib/prawn/images/image.rb +4 -2
  33. data/lib/prawn/images/jpg.rb +39 -30
  34. data/lib/prawn/images/png.rb +132 -169
  35. data/lib/prawn/images.rb +70 -62
  36. data/lib/prawn/measurement_extensions.rb +15 -10
  37. data/lib/prawn/measurements.rb +22 -23
  38. data/lib/prawn/outline.rb +301 -13
  39. data/lib/prawn/repeater.rb +19 -17
  40. data/lib/prawn/security/arcfour.rb +54 -0
  41. data/lib/prawn/security.rb +108 -86
  42. data/lib/prawn/soft_mask.rb +40 -41
  43. data/lib/prawn/stamp.rb +29 -12
  44. data/lib/prawn/text/box.rb +27 -29
  45. data/lib/prawn/text/formatted/arranger.rb +110 -67
  46. data/lib/prawn/text/formatted/box.rb +233 -165
  47. data/lib/prawn/text/formatted/fragment.rb +27 -27
  48. data/lib/prawn/text/formatted/line_wrap.rb +137 -97
  49. data/lib/prawn/text/formatted/parser.rb +149 -127
  50. data/lib/prawn/text/formatted/wrap.rb +57 -37
  51. data/lib/prawn/text/formatted.rb +6 -4
  52. data/lib/prawn/text.rb +105 -73
  53. data/lib/prawn/transformation_stack.rb +44 -0
  54. data/lib/prawn/utilities.rb +11 -21
  55. data/lib/prawn/version.rb +5 -0
  56. data/lib/prawn/view.rb +101 -0
  57. data/lib/prawn.rb +42 -68
  58. data/{data/images/fractal.jpg → manual/absolute_position.pdf} +0 -0
  59. data/manual/basic_concepts/adding_pages.rb +9 -10
  60. data/manual/basic_concepts/basic_concepts.rb +33 -24
  61. data/manual/basic_concepts/creation.rb +10 -11
  62. data/manual/basic_concepts/cursor.rb +9 -10
  63. data/manual/basic_concepts/measurement.rb +10 -11
  64. data/manual/basic_concepts/origin.rb +8 -9
  65. data/manual/basic_concepts/other_cursor_helpers.rb +17 -18
  66. data/manual/basic_concepts/view.rb +48 -0
  67. data/manual/bounding_box/bounding_box.rb +31 -29
  68. data/manual/bounding_box/bounds.rb +17 -18
  69. data/manual/bounding_box/canvas.rb +8 -9
  70. data/manual/bounding_box/creation.rb +8 -9
  71. data/manual/bounding_box/indentation.rb +22 -23
  72. data/manual/bounding_box/nesting.rb +32 -25
  73. data/manual/bounding_box/russian_boxes.rb +19 -19
  74. data/manual/bounding_box/stretchy.rb +18 -20
  75. data/manual/contents.rb +35 -0
  76. data/manual/cover.rb +43 -0
  77. data/manual/document_and_page_options/background.rb +16 -14
  78. data/manual/document_and_page_options/document_and_page_options.rb +26 -23
  79. data/manual/document_and_page_options/metadata.rb +21 -19
  80. data/manual/document_and_page_options/page_margins.rb +20 -22
  81. data/manual/document_and_page_options/page_size.rb +15 -15
  82. data/manual/document_and_page_options/print_scaling.rb +23 -0
  83. data/manual/example_helper.rb +5 -408
  84. data/manual/graphics/blend_mode.rb +52 -0
  85. data/manual/graphics/circle_and_ellipse.rb +8 -9
  86. data/manual/graphics/color.rb +11 -13
  87. data/manual/graphics/common_lines.rb +13 -12
  88. data/manual/graphics/fill_and_stroke.rb +10 -11
  89. data/manual/graphics/fill_rules.rb +13 -12
  90. data/manual/graphics/gradients.rb +28 -22
  91. data/manual/graphics/graphics.rb +52 -46
  92. data/manual/graphics/helper.rb +20 -10
  93. data/manual/graphics/line_width.rb +13 -12
  94. data/manual/graphics/lines_and_curves.rb +13 -14
  95. data/manual/graphics/polygon.rb +10 -12
  96. data/manual/graphics/rectangle.rb +7 -8
  97. data/manual/graphics/rotate.rb +9 -12
  98. data/manual/graphics/scale.rb +19 -18
  99. data/manual/graphics/soft_masks.rb +5 -7
  100. data/manual/graphics/stroke_cap.rb +10 -11
  101. data/manual/graphics/stroke_dash.rb +16 -17
  102. data/manual/graphics/stroke_join.rb +10 -11
  103. data/manual/graphics/translate.rb +13 -13
  104. data/manual/graphics/transparency.rb +11 -13
  105. data/manual/{manual/how_to_read_this_manual.rb → how_to_read_this_manual.rb} +23 -25
  106. data/manual/images/absolute_position.rb +9 -10
  107. data/manual/images/fit.rb +9 -10
  108. data/manual/images/horizontal.rb +13 -14
  109. data/manual/images/images.rb +31 -30
  110. data/manual/images/plain_image.rb +6 -7
  111. data/manual/images/scale.rb +12 -13
  112. data/manual/images/vertical.rb +19 -17
  113. data/manual/images/width_and_height.rb +13 -14
  114. data/manual/layout/boxes.rb +14 -15
  115. data/manual/layout/content.rb +12 -13
  116. data/manual/layout/layout.rb +19 -20
  117. data/manual/layout/simple_grid.rb +8 -9
  118. data/manual/outline/add_subsection_to.rb +26 -27
  119. data/manual/outline/insert_section_after.rb +19 -20
  120. data/manual/outline/outline.rb +23 -22
  121. data/manual/outline/sections_and_pages.rb +24 -25
  122. data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
  123. data/manual/repeatable_content/page_numbering.rb +20 -19
  124. data/manual/repeatable_content/repeatable_content.rb +26 -22
  125. data/manual/repeatable_content/repeater.rb +18 -19
  126. data/manual/repeatable_content/stamp.rb +18 -19
  127. data/manual/security/encryption.rb +8 -11
  128. data/manual/security/permissions.rb +20 -15
  129. data/manual/security/security.rb +20 -20
  130. data/manual/table.rb +16 -0
  131. data/manual/text/alignment.rb +17 -18
  132. data/manual/text/color.rb +13 -13
  133. data/manual/text/column_box.rb +10 -12
  134. data/manual/text/fallback_fonts.rb +29 -25
  135. data/manual/text/font.rb +17 -18
  136. data/manual/text/font_size.rb +21 -22
  137. data/manual/text/font_style.rb +12 -10
  138. data/manual/text/formatted_callbacks.rb +36 -26
  139. data/manual/text/formatted_text.rb +41 -34
  140. data/manual/text/free_flowing_text.rb +28 -29
  141. data/manual/text/inline.rb +23 -26
  142. data/manual/text/kerning_and_character_spacing.rb +20 -21
  143. data/manual/text/leading.rb +10 -11
  144. data/manual/text/line_wrapping.rb +40 -21
  145. data/manual/text/paragraph_indentation.rb +17 -12
  146. data/manual/text/positioned_text.rb +19 -20
  147. data/manual/text/registering_families.rb +33 -30
  148. data/manual/text/rendering_and_color.rb +11 -12
  149. data/manual/text/right_to_left_text.rb +31 -20
  150. data/manual/text/rotation.rb +36 -27
  151. data/manual/text/single_usage.rb +13 -14
  152. data/manual/text/text.rb +62 -62
  153. data/manual/text/text_box_excess.rb +22 -19
  154. data/manual/text/text_box_extensions.rb +21 -18
  155. data/manual/text/text_box_overflow.rb +28 -21
  156. data/manual/text/utf8.rb +16 -17
  157. data/manual/text/win_ansi_charset.rb +29 -26
  158. data/prawn.gemspec +45 -43
  159. data/spec/extensions/encoding_helpers.rb +4 -3
  160. data/spec/prawn/document/bounding_box_spec.rb +550 -0
  161. data/spec/prawn/document/column_box_spec.rb +75 -0
  162. data/spec/prawn/document/security_spec.rb +176 -0
  163. data/spec/prawn/document_annotations_spec.rb +76 -0
  164. data/spec/prawn/document_destinations_spec.rb +15 -0
  165. data/spec/prawn/document_grid_spec.rb +99 -0
  166. data/spec/prawn/document_reference_spec.rb +27 -0
  167. data/spec/prawn/document_span_spec.rb +44 -0
  168. data/spec/prawn/document_spec.rb +805 -0
  169. data/spec/prawn/font_metric_cache_spec.rb +54 -0
  170. data/spec/prawn/font_spec.rb +544 -0
  171. data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
  172. data/spec/prawn/graphics/transparency_spec.rb +81 -0
  173. data/spec/prawn/graphics_spec.rb +872 -0
  174. data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
  175. data/spec/prawn/image_handler_spec.rb +53 -0
  176. data/spec/prawn/images/jpg_spec.rb +20 -0
  177. data/spec/prawn/images/png_spec.rb +283 -0
  178. data/spec/prawn/images_spec.rb +229 -0
  179. data/spec/prawn/measurements_extensions_spec.rb +24 -0
  180. data/spec/prawn/outline_spec.rb +512 -0
  181. data/spec/prawn/repeater_spec.rb +166 -0
  182. data/spec/prawn/soft_mask_spec.rb +74 -0
  183. data/spec/prawn/stamp_spec.rb +173 -0
  184. data/spec/prawn/text/box_spec.rb +1110 -0
  185. data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
  186. data/spec/prawn/text/formatted/box_spec.rb +849 -0
  187. data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
  188. data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
  189. data/spec/prawn/text/formatted/parser_spec.rb +697 -0
  190. data/spec/prawn/text_draw_text_spec.rb +150 -0
  191. data/spec/prawn/text_rendering_mode_spec.rb +48 -0
  192. data/spec/prawn/text_spacing_spec.rb +95 -0
  193. data/spec/prawn/text_spec.rb +603 -0
  194. data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
  195. data/spec/prawn/transformation_stack_spec.rb +66 -0
  196. data/spec/prawn/view_spec.rb +63 -0
  197. data/spec/prawn_manual_spec.rb +35 -0
  198. data/spec/spec_helper.rb +22 -21
  199. data.tar.gz.sig +0 -0
  200. metadata +168 -307
  201. metadata.gz.sig +0 -0
  202. data/README.md +0 -109
  203. data/data/encodings/win_ansi.txt +0 -29
  204. data/data/images/16bit.alpha +0 -0
  205. data/data/images/16bit.dat +0 -0
  206. data/data/images/16bit.png +0 -0
  207. data/data/images/arrow.png +0 -0
  208. data/data/images/arrow2.png +0 -0
  209. data/data/images/barcode_issue.png +0 -0
  210. data/data/images/dice.alpha +0 -0
  211. data/data/images/dice.dat +0 -0
  212. data/data/images/dice.png +0 -0
  213. data/data/images/dice_interlaced.png +0 -0
  214. data/data/images/indexed_color.dat +0 -0
  215. data/data/images/indexed_color.png +0 -0
  216. data/data/images/letterhead.jpg +0 -0
  217. data/data/images/page_white_text.alpha +0 -0
  218. data/data/images/page_white_text.dat +0 -0
  219. data/data/images/page_white_text.png +0 -0
  220. data/data/images/pigs.jpg +0 -0
  221. data/data/images/prawn.png +0 -0
  222. data/data/images/ruport.png +0 -0
  223. data/data/images/ruport_data.dat +0 -0
  224. data/data/images/ruport_transparent.png +0 -0
  225. data/data/images/ruport_type0.png +0 -0
  226. data/data/images/stef.jpg +0 -0
  227. data/data/images/tru256.bmp +0 -0
  228. data/data/images/web-links.dat +0 -1
  229. data/data/images/web-links.png +0 -0
  230. data/data/pdfs/complex_template.pdf +0 -0
  231. data/data/pdfs/contains_ttf_font.pdf +0 -0
  232. data/data/pdfs/encrypted.pdf +0 -0
  233. data/data/pdfs/form.pdf +1 -819
  234. data/data/pdfs/hexagon.pdf +0 -61
  235. data/data/pdfs/indirect_reference.pdf +0 -86
  236. data/data/pdfs/multipage_template.pdf +0 -127
  237. data/data/pdfs/nested_pages.pdf +0 -118
  238. data/data/pdfs/page_without_mediabox.pdf +0 -193
  239. data/data/pdfs/resources_as_indirect_object.pdf +0 -83
  240. data/data/pdfs/two_hexagons.pdf +0 -90
  241. data/data/pdfs/version_1_6.pdf +0 -61
  242. data/data/shift_jis_text.txt +0 -1
  243. data/lib/pdf/core/annotations.rb +0 -60
  244. data/lib/pdf/core/byte_string.rb +0 -9
  245. data/lib/pdf/core/destinations.rb +0 -90
  246. data/lib/pdf/core/document_state.rb +0 -78
  247. data/lib/pdf/core/filter_list.rb +0 -51
  248. data/lib/pdf/core/filters.rb +0 -36
  249. data/lib/pdf/core/graphics_state.rb +0 -68
  250. data/lib/pdf/core/literal_string.rb +0 -16
  251. data/lib/pdf/core/name_tree.rb +0 -177
  252. data/lib/pdf/core/object_store.rb +0 -320
  253. data/lib/pdf/core/outline.rb +0 -315
  254. data/lib/pdf/core/page.rb +0 -212
  255. data/lib/pdf/core/page_geometry.rb +0 -126
  256. data/lib/pdf/core/pdf_object.rb +0 -124
  257. data/lib/pdf/core/reference.rb +0 -103
  258. data/lib/pdf/core/stream.rb +0 -98
  259. data/lib/pdf/core/text.rb +0 -275
  260. data/lib/pdf/core.rb +0 -35
  261. data/lib/prawn/compatibility.rb +0 -91
  262. data/lib/prawn/document/graphics_state.rb +0 -73
  263. data/lib/prawn/document/snapshot.rb +0 -89
  264. data/lib/prawn/font/afm.rb +0 -203
  265. data/lib/prawn/layout.rb +0 -20
  266. data/lib/prawn/table/cell/image.rb +0 -70
  267. data/lib/prawn/table/cell/in_table.rb +0 -27
  268. data/lib/prawn/table/cell/span_dummy.rb +0 -92
  269. data/lib/prawn/table/cell/subtable.rb +0 -65
  270. data/lib/prawn/table/cell/text.rb +0 -153
  271. data/lib/prawn/table/cell.rb +0 -770
  272. data/lib/prawn/table/cells.rb +0 -295
  273. data/lib/prawn/table.rb +0 -643
  274. data/manual/example_file.rb +0 -116
  275. data/manual/example_package.rb +0 -53
  276. data/manual/example_section.rb +0 -46
  277. data/manual/manual/cover.rb +0 -35
  278. data/manual/manual/foreword.rb +0 -85
  279. data/manual/manual/manual.rb +0 -35
  280. data/manual/syntax_highlight.rb +0 -52
  281. data/manual/table/basic_block.rb +0 -53
  282. data/manual/table/before_rendering_page.rb +0 -26
  283. data/manual/table/cell_border_lines.rb +0 -24
  284. data/manual/table/cell_borders_and_bg.rb +0 -31
  285. data/manual/table/cell_dimensions.rb +0 -30
  286. data/manual/table/cell_text.rb +0 -38
  287. data/manual/table/column_widths.rb +0 -30
  288. data/manual/table/content_and_subtables.rb +0 -39
  289. data/manual/table/creation.rb +0 -27
  290. data/manual/table/filtering.rb +0 -36
  291. data/manual/table/flow_and_header.rb +0 -17
  292. data/manual/table/image_cells.rb +0 -33
  293. data/manual/table/position.rb +0 -29
  294. data/manual/table/row_colors.rb +0 -20
  295. data/manual/table/span.rb +0 -30
  296. data/manual/table/style.rb +0 -22
  297. data/manual/table/table.rb +0 -52
  298. data/manual/table/width.rb +0 -27
  299. data/manual/templates/full_template.rb +0 -25
  300. data/manual/templates/page_template.rb +0 -48
  301. data/manual/templates/templates.rb +0 -27
  302. data/manual/text/group.rb +0 -29
  303. data/spec/acceptance/png.rb +0 -23
  304. data/spec/annotations_spec.rb +0 -74
  305. data/spec/bounding_box_spec.rb +0 -493
  306. data/spec/cell_spec.rb +0 -628
  307. data/spec/column_box_spec.rb +0 -33
  308. data/spec/destinations_spec.rb +0 -15
  309. data/spec/document_spec.rb +0 -761
  310. data/spec/extensions/mocha.rb +0 -44
  311. data/spec/filters_spec.rb +0 -34
  312. data/spec/font_metric_cache_spec.rb +0 -52
  313. data/spec/font_spec.rb +0 -464
  314. data/spec/formatted_text_arranger_spec.rb +0 -421
  315. data/spec/formatted_text_box_spec.rb +0 -650
  316. data/spec/formatted_text_fragment_spec.rb +0 -298
  317. data/spec/graphics_spec.rb +0 -651
  318. data/spec/grid_spec.rb +0 -85
  319. data/spec/image_handler_spec.rb +0 -42
  320. data/spec/images_spec.rb +0 -157
  321. data/spec/inline_formatted_text_parser_spec.rb +0 -564
  322. data/spec/jpg_spec.rb +0 -25
  323. data/spec/line_wrap_spec.rb +0 -333
  324. data/spec/measurement_units_spec.rb +0 -23
  325. data/spec/name_tree_spec.rb +0 -112
  326. data/spec/object_store_spec.rb +0 -170
  327. data/spec/outline_spec.rb +0 -448
  328. data/spec/pdf_object_spec.rb +0 -172
  329. data/spec/png_spec.rb +0 -240
  330. data/spec/reference_spec.rb +0 -82
  331. data/spec/repeater_spec.rb +0 -158
  332. data/spec/security_spec.rb +0 -158
  333. data/spec/snapshot_spec.rb +0 -186
  334. data/spec/soft_mask_spec.rb +0 -117
  335. data/spec/span_spec.rb +0 -44
  336. data/spec/stamp_spec.rb +0 -158
  337. data/spec/stream_spec.rb +0 -58
  338. data/spec/stroke_styles_spec.rb +0 -211
  339. data/spec/table/span_dummy_spec.rb +0 -17
  340. data/spec/table_spec.rb +0 -1355
  341. data/spec/template_spec.rb +0 -351
  342. data/spec/text_at_spec.rb +0 -130
  343. data/spec/text_box_spec.rb +0 -1030
  344. data/spec/text_rendering_mode_spec.rb +0 -45
  345. data/spec/text_spacing_spec.rb +0 -93
  346. data/spec/text_spec.rb +0 -425
  347. data/spec/text_with_inline_formatting_spec.rb +0 -35
  348. data/spec/transparency_spec.rb +0 -89
@@ -0,0 +1,495 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Prawn::Text::Formatted::LineWrap do
6
+ let(:pdf) { create_pdf }
7
+ let(:arranger) do
8
+ Prawn::Text::Formatted::Arranger.new(pdf).tap do |a|
9
+ a.format_array = [
10
+ { text: "hello\nworld\n\n\nhow are you?" },
11
+ { text: "\n" },
12
+ { text: "\n" },
13
+ { text: '' },
14
+ { text: 'fine, thanks. ' * 4 },
15
+ { text: '' },
16
+ { text: "\n" },
17
+ { text: '' }
18
+ ]
19
+ end
20
+ end
21
+ let(:line_wrap) { described_class.new }
22
+
23
+ it 'only returns an empty string if nothing fit or there' \
24
+ 'was nothing to wrap' do
25
+ 8.times do
26
+ line = line_wrap.wrap_line(
27
+ arranger: arranger,
28
+ width: 200,
29
+ document: pdf
30
+ )
31
+ expect(line).to_not be_empty
32
+ end
33
+ line = line_wrap.wrap_line(
34
+ arranger: arranger,
35
+ width: 200,
36
+ document: pdf
37
+ )
38
+ expect(line).to be_empty
39
+ end
40
+
41
+ it 'tokenizes a string using the scan_pattern' do
42
+ tokens = line_wrap.tokenize('one two three')
43
+ expect(tokens.length).to eq(5)
44
+ end
45
+
46
+ describe 'Core::Text::Formatted::LineWrap#wrap_line' do
47
+ let(:arranger) { Prawn::Text::Formatted::Arranger.new(pdf) }
48
+ let(:one_word_width) { 50 }
49
+
50
+ it 'strips leading and trailing spaces' do
51
+ array = [
52
+ { text: ' hello world, ' },
53
+ { text: 'goodbye ', style: [:bold] }
54
+ ]
55
+ arranger.format_array = array
56
+ string = line_wrap.wrap_line(
57
+ arranger: arranger,
58
+ width: 300,
59
+ document: pdf
60
+ )
61
+ expect(string).to eq('hello world, goodbye')
62
+ end
63
+
64
+ it 'strips trailing spaces when a white-space-only fragment was' \
65
+ ' successfully pushed onto the end of a line but no other non-white' \
66
+ ' space fragment fits after it' do
67
+ array = [
68
+ { text: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ' },
69
+ { text: ' ', style: [:bold] },
70
+ { text: ' bbbbbbbbbbbbbbbbbbbbbbbbbbbb' }
71
+ ]
72
+ arranger.format_array = array
73
+ string = line_wrap.wrap_line(
74
+ arranger: arranger,
75
+ width: 300,
76
+ document: pdf
77
+ )
78
+ expect(string).to eq('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
79
+ end
80
+
81
+ it 'raise_errors CannotFit if a too-small width is given' do
82
+ array = [
83
+ { text: ' hello world, ' },
84
+ { text: 'goodbye ', style: [:bold] }
85
+ ]
86
+ arranger.format_array = array
87
+ expect do
88
+ line_wrap.wrap_line(
89
+ arranger: arranger,
90
+ width: 1,
91
+ document: pdf
92
+ )
93
+ end.to raise_error(Prawn::Errors::CannotFit)
94
+ end
95
+
96
+ it 'breaks on space' do
97
+ array = [{ text: 'hello world' }]
98
+ arranger.format_array = array
99
+ string = line_wrap.wrap_line(
100
+ arranger: arranger,
101
+ width: one_word_width,
102
+ document: pdf
103
+ )
104
+ expect(string).to eq('hello')
105
+ end
106
+
107
+ it 'breaks on zero-width space' do
108
+ pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
109
+ array = [{ text: "hello#{Prawn::Text::ZWSP}world" }]
110
+ arranger.format_array = array
111
+ string = line_wrap.wrap_line(
112
+ arranger: arranger,
113
+ width: one_word_width,
114
+ document: pdf
115
+ )
116
+ expect(string).to eq('hello')
117
+ end
118
+
119
+ it 'does not display zero-width space' do
120
+ pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
121
+ array = [{ text: "hello#{Prawn::Text::ZWSP}world" }]
122
+ arranger.format_array = array
123
+ string = line_wrap.wrap_line(
124
+ arranger: arranger,
125
+ width: 300,
126
+ document: pdf
127
+ )
128
+ expect(string).to eq('helloworld')
129
+ end
130
+
131
+ it 'does not raise CannotFit if first fragment is a zero-width space' do
132
+ pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
133
+ array = [{ text: Prawn::Text::ZWSP }, { text: 'stringofchars' }]
134
+ arranger.format_array = array
135
+ string = line_wrap.wrap_line(
136
+ arranger: arranger,
137
+ width: 50,
138
+ document: pdf
139
+ )
140
+ expect(string).to eq('stringof')
141
+ end
142
+
143
+ it 'breaks on tab' do
144
+ array = [{ text: "hello\tworld" }]
145
+ arranger.format_array = array
146
+ string = line_wrap.wrap_line(
147
+ arranger: arranger,
148
+ width: one_word_width,
149
+ document: pdf
150
+ )
151
+ expect(string).to eq('hello')
152
+ end
153
+
154
+ it 'does not break on NBSP' do
155
+ array = [{ text: "hello#{Prawn::Text::NBSP}world" }]
156
+ arranger.format_array = array
157
+ string = line_wrap.wrap_line(
158
+ arranger: arranger,
159
+ width: one_word_width,
160
+ document: pdf
161
+ )
162
+ expect(string).to eq("hello#{Prawn::Text::NBSP}wor")
163
+ end
164
+
165
+ it 'does not break on NBSP in a Win-1252 encoded string' do
166
+ array = [{
167
+ text: "hello#{Prawn::Text::NBSP}world".encode(Encoding::Windows_1252)
168
+ }]
169
+ arranger.format_array = array
170
+ string = line_wrap.wrap_line(
171
+ arranger: arranger,
172
+ width: one_word_width,
173
+ document: pdf
174
+ )
175
+ expect(string).to eq("hello#{Prawn::Text::NBSP}wor")
176
+ end
177
+
178
+ it 'breaks on hyphens' do
179
+ array = [{ text: 'hello-world' }]
180
+ arranger.format_array = array
181
+ string = line_wrap.wrap_line(
182
+ arranger: arranger,
183
+ width: one_word_width,
184
+ document: pdf
185
+ )
186
+ expect(string).to eq('hello-')
187
+ end
188
+
189
+ it 'does not break after a hyphen that follows white space and' \
190
+ 'precedes a word' do
191
+ array = [{ text: 'hello -' }]
192
+ arranger.format_array = array
193
+ string = line_wrap.wrap_line(
194
+ arranger: arranger,
195
+ width: one_word_width,
196
+ document: pdf
197
+ )
198
+ expect(string).to eq('hello -')
199
+
200
+ array = [{ text: 'hello -world' }]
201
+ arranger.format_array = array
202
+ string = line_wrap.wrap_line(
203
+ arranger: arranger,
204
+ width: one_word_width,
205
+ document: pdf
206
+ )
207
+ expect(string).to eq('hello')
208
+ end
209
+
210
+ it 'breaks on a soft hyphen' do
211
+ string = pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}world")
212
+ array = [{ text: string }]
213
+ arranger.format_array = array
214
+ string = line_wrap.wrap_line(
215
+ arranger: arranger,
216
+ width: one_word_width,
217
+ document: pdf
218
+ )
219
+ expect(string).to eq("hello#{Prawn::Text::SHY}")
220
+
221
+ pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
222
+ line_wrap = described_class.new
223
+
224
+ string = "hello#{Prawn::Text::SHY}world"
225
+ array = [{ text: string }]
226
+ arranger.format_array = array
227
+ string = line_wrap.wrap_line(
228
+ arranger: arranger,
229
+ width: one_word_width,
230
+ document: pdf
231
+ )
232
+ expect(string).to eq("hello#{Prawn::Text::SHY}")
233
+ end
234
+
235
+ it 'ignores width of a soft-hyphen during adding fragments to line',
236
+ issue: 775 do
237
+ hyphen_string = "Hy#{Prawn::Text::SHY}phe#{Prawn::Text::SHY}nat"\
238
+ "#{Prawn::Text::SHY}ions "
239
+ string1 = pdf.font.normalize_encoding(hyphen_string * 5)
240
+ string2 = pdf.font.normalize_encoding('Hyphenations ' * 3 + hyphen_string)
241
+
242
+ array1 = [{ text: string1 }]
243
+ array2 = [{ text: string2 }]
244
+
245
+ arranger.format_array = array1
246
+
247
+ res1 = line_wrap.wrap_line(
248
+ arranger: arranger,
249
+ width: 300,
250
+ document: pdf
251
+ )
252
+
253
+ line_wrap = described_class.new
254
+
255
+ arranger.format_array = array2
256
+
257
+ res2 = line_wrap.wrap_line(
258
+ arranger: arranger,
259
+ width: 300,
260
+ document: pdf
261
+ )
262
+ expect(res1).to eq(res2)
263
+ end
264
+
265
+ it 'does not display soft hyphens except at the end of a line ' \
266
+ 'for more than one element in format_array',
267
+ issue: 347 do
268
+ pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
269
+ line_wrap = described_class.new
270
+
271
+ string1 = pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}world ")
272
+ string2 = pdf.font.normalize_encoding("hi#{Prawn::Text::SHY}earth")
273
+ array = [{ text: string1 }, { text: string2 }]
274
+ arranger.format_array = array
275
+ string = line_wrap.wrap_line(
276
+ arranger: arranger,
277
+ width: 300,
278
+ document: pdf
279
+ )
280
+ expect(string).to eq('helloworld hiearth')
281
+ end
282
+
283
+ it 'does not break before a hard hyphen that follows a word' do
284
+ enough_width_for_hello_world = 60
285
+
286
+ array = [{ text: 'hello world' }]
287
+ arranger.format_array = array
288
+ string = line_wrap.wrap_line(
289
+ arranger: arranger,
290
+ width: enough_width_for_hello_world,
291
+ document: pdf
292
+ )
293
+ expect(string).to eq('hello world')
294
+
295
+ array = [{ text: 'hello world-' }]
296
+ arranger.format_array = array
297
+ string = line_wrap.wrap_line(
298
+ arranger: arranger,
299
+ width: enough_width_for_hello_world,
300
+ document: pdf
301
+ )
302
+ expect(string).to eq('hello')
303
+
304
+ pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
305
+ line_wrap = described_class.new
306
+ enough_width_for_hello_world = 68
307
+
308
+ array = [{ text: 'hello world' }]
309
+ arranger.format_array = array
310
+ string = line_wrap.wrap_line(
311
+ arranger: arranger,
312
+ width: enough_width_for_hello_world,
313
+ document: pdf
314
+ )
315
+ expect(string).to eq('hello world')
316
+
317
+ array = [{ text: 'hello world-' }]
318
+ arranger.format_array = array
319
+ string = line_wrap.wrap_line(
320
+ arranger: arranger,
321
+ width: enough_width_for_hello_world,
322
+ document: pdf
323
+ )
324
+ expect(string).to eq('hello')
325
+ end
326
+
327
+ it 'does not break after a hard hyphen that follows a soft hyphen and' \
328
+ 'precedes a word' do
329
+ string = pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}-")
330
+ array = [{ text: string }]
331
+ arranger.format_array = array
332
+ string = line_wrap.wrap_line(
333
+ arranger: arranger,
334
+ width: one_word_width,
335
+ document: pdf
336
+ )
337
+ expect(string).to eq('hello-')
338
+
339
+ string = pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}-world")
340
+ array = [{ text: string }]
341
+ arranger.format_array = array
342
+ string = line_wrap.wrap_line(
343
+ arranger: arranger,
344
+ width: one_word_width,
345
+ document: pdf
346
+ )
347
+ expect(string).to eq("hello#{Prawn::Text::SHY}")
348
+
349
+ pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
350
+ line_wrap = described_class.new
351
+
352
+ string = "hello#{Prawn::Text::SHY}-"
353
+ array = [{ text: string }]
354
+ arranger.format_array = array
355
+ string = line_wrap.wrap_line(
356
+ arranger: arranger,
357
+ width: one_word_width,
358
+ document: pdf
359
+ )
360
+ expect(string).to eq('hello-')
361
+
362
+ string = "hello#{Prawn::Text::SHY}-world"
363
+ array = [{ text: string }]
364
+ arranger.format_array = array
365
+ string = line_wrap.wrap_line(
366
+ arranger: arranger,
367
+ width: one_word_width,
368
+ document: pdf
369
+ )
370
+ expect(string).to eq("hello#{Prawn::Text::SHY}")
371
+ end
372
+
373
+ it 'does not process UTF-8 chars with default font', issue: 693 do
374
+ array = [{ text: 'Test' }]
375
+ arranger.format_array = array
376
+
377
+ expect do
378
+ line_wrap.wrap_line(
379
+ arranger: arranger,
380
+ width: 300,
381
+ document: pdf
382
+ )
383
+ end.to raise_exception(Prawn::Errors::IncompatibleStringEncoding)
384
+ end
385
+
386
+ it 'processes UTF-8 chars with UTF-8 font', issue: 693 do
387
+ array = [{ text: 'Test' }]
388
+ arranger.format_array = array
389
+
390
+ pdf.font Pathname.new("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
391
+ string = line_wrap.wrap_line(
392
+ arranger: arranger,
393
+ width: 300,
394
+ document: pdf
395
+ )
396
+
397
+ expect(string).to eq('Test')
398
+ end
399
+ end
400
+
401
+ describe '#space_count' do
402
+ let(:arranger) { Prawn::Text::Formatted::Arranger.new(pdf) }
403
+
404
+ it 'returns the number of spaces in the last wrapped line' do
405
+ array = [
406
+ { text: 'hello world, ' },
407
+ { text: 'goodbye', style: [:bold] }
408
+ ]
409
+ arranger.format_array = array
410
+ line_wrap.wrap_line(
411
+ arranger: arranger,
412
+ width: 300,
413
+ document: pdf
414
+ )
415
+ expect(line_wrap.space_count).to eq(2)
416
+ end
417
+
418
+ it 'excludes preceding and trailing spaces from the count' do
419
+ array = [
420
+ { text: ' hello world, ' },
421
+ { text: 'goodbye ', style: [:bold] }
422
+ ]
423
+ arranger.format_array = array
424
+ line_wrap.wrap_line(
425
+ arranger: arranger,
426
+ width: 300,
427
+ document: pdf
428
+ )
429
+ expect(line_wrap.space_count).to eq(2)
430
+ end
431
+ end
432
+
433
+ describe '#paragraph_finished?' do
434
+ let(:arranger) { Prawn::Text::Formatted::Arranger.new(pdf) }
435
+ let(:line_wrap) { described_class.new }
436
+ let(:one_word_width) { 50 }
437
+
438
+ it 'is false when the last printed line is not the end of the paragraph' do
439
+ array = [{ text: 'hello world' }]
440
+ arranger.format_array = array
441
+ line_wrap.wrap_line(
442
+ arranger: arranger,
443
+ width: one_word_width,
444
+ document: pdf
445
+ )
446
+
447
+ expect(line_wrap.paragraph_finished?).to eq(false)
448
+ end
449
+
450
+ it 'is true when the last printed line is the last fragment to print' do
451
+ array = [{ text: 'hello world' }]
452
+ arranger.format_array = array
453
+ line_wrap.wrap_line(
454
+ arranger: arranger,
455
+ width: one_word_width,
456
+ document: pdf
457
+ )
458
+ line_wrap.wrap_line(
459
+ arranger: arranger,
460
+ width: one_word_width,
461
+ document: pdf
462
+ )
463
+
464
+ expect(line_wrap.paragraph_finished?).to eq(true)
465
+ end
466
+
467
+ it 'be_trues when a newline exists on the current line' do
468
+ array = [{ text: "hello\n world" }]
469
+ arranger.format_array = array
470
+ line_wrap.wrap_line(
471
+ arranger: arranger,
472
+ width: one_word_width,
473
+ document: pdf
474
+ )
475
+
476
+ expect(line_wrap.paragraph_finished?).to eq(true)
477
+ end
478
+
479
+ it 'be_trues when a newline exists in the next fragment' do
480
+ array = [
481
+ { text: 'hello ' },
482
+ { text: " \n" },
483
+ { text: 'world' }
484
+ ]
485
+ arranger.format_array = array
486
+ line_wrap.wrap_line(
487
+ arranger: arranger,
488
+ width: one_word_width,
489
+ document: pdf
490
+ )
491
+
492
+ expect(line_wrap.paragraph_finished?).to eq(true)
493
+ end
494
+ end
495
+ end