prawn 1.1.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +1 -0
  4. data/GPLv2 +20 -21
  5. data/Gemfile +3 -9
  6. data/Rakefile +9 -40
  7. data/lib/prawn/document/bounding_box.rb +54 -40
  8. data/lib/prawn/document/column_box.rb +8 -10
  9. data/lib/prawn/document/internals.rb +39 -146
  10. data/lib/prawn/document/span.rb +23 -17
  11. data/lib/prawn/document.rb +217 -182
  12. data/lib/prawn/encoding.rb +69 -101
  13. data/lib/prawn/errors.rb +47 -43
  14. data/lib/prawn/font.rb +124 -104
  15. data/lib/prawn/font_metric_cache.rb +23 -21
  16. data/lib/prawn/fonts/afm.rb +292 -0
  17. data/lib/prawn/{font → fonts}/dfont.rb +5 -12
  18. data/lib/prawn/fonts/otf.rb +11 -0
  19. data/lib/prawn/fonts/ttc.rb +36 -0
  20. data/lib/prawn/{font → fonts}/ttf.rb +140 -88
  21. data/lib/prawn/graphics/blend_mode.rb +65 -0
  22. data/lib/prawn/graphics/cap_style.rb +5 -5
  23. data/lib/prawn/graphics/color.rb +46 -44
  24. data/lib/prawn/graphics/dash.rb +27 -11
  25. data/lib/prawn/graphics/join_style.rb +11 -6
  26. data/lib/prawn/graphics/patterns.rb +220 -78
  27. data/lib/prawn/graphics/transformation.rb +20 -12
  28. data/lib/prawn/graphics/transparency.rb +20 -18
  29. data/lib/prawn/graphics.rb +153 -115
  30. data/lib/prawn/grid.rb +93 -50
  31. data/lib/prawn/image_handler.rb +4 -4
  32. data/lib/prawn/images/image.rb +3 -2
  33. data/lib/prawn/images/jpg.rb +31 -24
  34. data/lib/prawn/images/png.rb +101 -68
  35. data/lib/prawn/images.rb +64 -56
  36. data/lib/prawn/measurement_extensions.rb +10 -9
  37. data/lib/prawn/measurements.rb +20 -23
  38. data/lib/prawn/outline.rb +96 -75
  39. data/lib/prawn/repeater.rb +16 -16
  40. data/lib/prawn/security/arcfour.rb +2 -2
  41. data/lib/prawn/security.rb +100 -85
  42. data/lib/prawn/soft_mask.rb +37 -38
  43. data/lib/prawn/stamp.rb +28 -13
  44. data/lib/prawn/text/box.rb +24 -29
  45. data/lib/prawn/text/formatted/arranger.rb +108 -63
  46. data/lib/prawn/text/formatted/box.rb +187 -124
  47. data/lib/prawn/text/formatted/fragment.rb +24 -20
  48. data/lib/prawn/text/formatted/line_wrap.rb +133 -73
  49. data/lib/prawn/text/formatted/parser.rb +147 -127
  50. data/lib/prawn/text/formatted/wrap.rb +48 -35
  51. data/lib/prawn/text/formatted.rb +5 -5
  52. data/lib/prawn/text.rb +103 -68
  53. data/lib/prawn/transformation_stack.rb +44 -0
  54. data/lib/prawn/utilities.rb +10 -22
  55. data/lib/prawn/version.rb +5 -0
  56. data/lib/prawn/view.rb +101 -0
  57. data/lib/prawn.rb +39 -54
  58. data/manual/basic_concepts/adding_pages.rb +6 -7
  59. data/manual/basic_concepts/basic_concepts.rb +34 -25
  60. data/manual/basic_concepts/creation.rb +10 -11
  61. data/manual/basic_concepts/cursor.rb +4 -5
  62. data/manual/basic_concepts/measurement.rb +8 -9
  63. data/manual/basic_concepts/origin.rb +5 -6
  64. data/manual/basic_concepts/other_cursor_helpers.rb +11 -12
  65. data/manual/basic_concepts/view.rb +48 -0
  66. data/manual/bounding_box/bounding_box.rb +30 -28
  67. data/manual/bounding_box/bounds.rb +12 -13
  68. data/manual/bounding_box/canvas.rb +7 -8
  69. data/manual/bounding_box/creation.rb +6 -7
  70. data/manual/bounding_box/indentation.rb +14 -15
  71. data/manual/bounding_box/nesting.rb +25 -18
  72. data/manual/bounding_box/russian_boxes.rb +18 -18
  73. data/manual/bounding_box/stretchy.rb +12 -14
  74. data/manual/contents.rb +28 -22
  75. data/manual/cover.rb +33 -32
  76. data/manual/document_and_page_options/background.rb +15 -13
  77. data/manual/document_and_page_options/document_and_page_options.rb +24 -22
  78. data/manual/document_and_page_options/metadata.rb +20 -18
  79. data/manual/document_and_page_options/page_margins.rb +18 -20
  80. data/manual/document_and_page_options/page_size.rb +13 -13
  81. data/manual/document_and_page_options/print_scaling.rb +18 -15
  82. data/manual/example_helper.rb +5 -4
  83. data/manual/graphics/blend_mode.rb +52 -0
  84. data/manual/graphics/circle_and_ellipse.rb +4 -5
  85. data/manual/graphics/color.rb +7 -9
  86. data/manual/graphics/common_lines.rb +7 -8
  87. data/manual/graphics/fill_and_stroke.rb +5 -6
  88. data/manual/graphics/fill_rules.rb +12 -11
  89. data/manual/graphics/gradients.rb +27 -21
  90. data/manual/graphics/graphics.rb +46 -40
  91. data/manual/graphics/helper.rb +19 -9
  92. data/manual/graphics/line_width.rb +8 -7
  93. data/manual/graphics/lines_and_curves.rb +8 -9
  94. data/manual/graphics/polygon.rb +6 -8
  95. data/manual/graphics/rectangle.rb +4 -5
  96. data/manual/graphics/rotate.rb +6 -9
  97. data/manual/graphics/scale.rb +14 -13
  98. data/manual/graphics/soft_masks.rb +4 -6
  99. data/manual/graphics/stroke_cap.rb +7 -8
  100. data/manual/graphics/stroke_dash.rb +15 -16
  101. data/manual/graphics/stroke_join.rb +6 -7
  102. data/manual/graphics/translate.rb +10 -10
  103. data/manual/graphics/transparency.rb +7 -9
  104. data/manual/how_to_read_this_manual.rb +8 -9
  105. data/manual/images/absolute_position.rb +6 -7
  106. data/manual/images/fit.rb +7 -8
  107. data/manual/images/horizontal.rb +10 -11
  108. data/manual/images/images.rb +28 -27
  109. data/manual/images/plain_image.rb +5 -6
  110. data/manual/images/scale.rb +9 -10
  111. data/manual/images/vertical.rb +16 -14
  112. data/manual/images/width_and_height.rb +10 -11
  113. data/manual/layout/boxes.rb +10 -11
  114. data/manual/layout/content.rb +9 -10
  115. data/manual/layout/layout.rb +17 -18
  116. data/manual/layout/simple_grid.rb +6 -7
  117. data/manual/outline/add_subsection_to.rb +20 -21
  118. data/manual/outline/insert_section_after.rb +15 -16
  119. data/manual/outline/outline.rb +22 -21
  120. data/manual/outline/sections_and_pages.rb +17 -18
  121. data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
  122. data/manual/repeatable_content/page_numbering.rb +17 -16
  123. data/manual/repeatable_content/repeatable_content.rb +27 -23
  124. data/manual/repeatable_content/repeater.rb +15 -16
  125. data/manual/repeatable_content/stamp.rb +14 -15
  126. data/manual/security/encryption.rb +8 -11
  127. data/manual/security/permissions.rb +20 -15
  128. data/manual/security/security.rb +18 -18
  129. data/manual/table.rb +16 -0
  130. data/manual/text/alignment.rb +16 -17
  131. data/manual/text/color.rb +12 -12
  132. data/manual/text/column_box.rb +9 -11
  133. data/manual/text/fallback_fonts.rb +25 -21
  134. data/manual/text/font.rb +11 -12
  135. data/manual/text/font_size.rb +13 -14
  136. data/manual/text/font_style.rb +10 -8
  137. data/manual/text/formatted_callbacks.rb +33 -23
  138. data/manual/text/formatted_text.rb +36 -25
  139. data/manual/text/free_flowing_text.rb +22 -23
  140. data/manual/text/inline.rb +18 -19
  141. data/manual/text/kerning_and_character_spacing.rb +14 -15
  142. data/manual/text/leading.rb +7 -8
  143. data/manual/text/line_wrapping.rb +37 -18
  144. data/manual/text/paragraph_indentation.rb +15 -10
  145. data/manual/text/positioned_text.rb +16 -17
  146. data/manual/text/registering_families.rb +27 -24
  147. data/manual/text/rendering_and_color.rb +9 -10
  148. data/manual/text/right_to_left_text.rb +30 -19
  149. data/manual/text/rotation.rb +33 -24
  150. data/manual/text/single_usage.rb +8 -9
  151. data/manual/text/text.rb +56 -54
  152. data/manual/text/text_box_excess.rb +20 -17
  153. data/manual/text/text_box_extensions.rb +18 -15
  154. data/manual/text/text_box_overflow.rb +24 -17
  155. data/manual/text/utf8.rb +12 -13
  156. data/manual/text/win_ansi_charset.rb +28 -25
  157. data/prawn.gemspec +45 -50
  158. data/spec/extensions/encoding_helpers.rb +3 -3
  159. data/spec/prawn/document/bounding_box_spec.rb +550 -0
  160. data/spec/prawn/document/column_box_spec.rb +75 -0
  161. data/spec/prawn/document/security_spec.rb +176 -0
  162. data/spec/prawn/document_annotations_spec.rb +76 -0
  163. data/spec/prawn/document_destinations_spec.rb +15 -0
  164. data/spec/prawn/document_grid_spec.rb +99 -0
  165. data/spec/prawn/document_reference_spec.rb +27 -0
  166. data/spec/prawn/document_span_spec.rb +44 -0
  167. data/spec/prawn/document_spec.rb +805 -0
  168. data/spec/prawn/font_metric_cache_spec.rb +54 -0
  169. data/spec/prawn/font_spec.rb +544 -0
  170. data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
  171. data/spec/prawn/graphics/transparency_spec.rb +81 -0
  172. data/spec/prawn/graphics_spec.rb +872 -0
  173. data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
  174. data/spec/prawn/image_handler_spec.rb +53 -0
  175. data/spec/prawn/images/jpg_spec.rb +20 -0
  176. data/spec/prawn/images/png_spec.rb +283 -0
  177. data/spec/prawn/images_spec.rb +229 -0
  178. data/spec/prawn/measurements_extensions_spec.rb +24 -0
  179. data/spec/prawn/outline_spec.rb +512 -0
  180. data/spec/prawn/repeater_spec.rb +166 -0
  181. data/spec/prawn/soft_mask_spec.rb +74 -0
  182. data/spec/prawn/stamp_spec.rb +173 -0
  183. data/spec/prawn/text/box_spec.rb +1110 -0
  184. data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
  185. data/spec/prawn/text/formatted/box_spec.rb +849 -0
  186. data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
  187. data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
  188. data/spec/prawn/text/formatted/parser_spec.rb +697 -0
  189. data/spec/prawn/text_draw_text_spec.rb +150 -0
  190. data/spec/prawn/text_rendering_mode_spec.rb +48 -0
  191. data/spec/prawn/text_spacing_spec.rb +95 -0
  192. data/spec/prawn/text_spec.rb +603 -0
  193. data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
  194. data/spec/prawn/transformation_stack_spec.rb +66 -0
  195. data/spec/prawn/view_spec.rb +63 -0
  196. data/spec/prawn_manual_spec.rb +35 -0
  197. data/spec/spec_helper.rb +19 -25
  198. data.tar.gz.sig +0 -0
  199. metadata +113 -276
  200. metadata.gz.sig +0 -0
  201. data/data/encodings/win_ansi.txt +0 -29
  202. data/data/images/16bit.alpha +0 -0
  203. data/data/images/16bit.color +0 -0
  204. data/data/images/16bit.png +0 -0
  205. data/data/images/arrow.png +0 -0
  206. data/data/images/arrow2.png +0 -0
  207. data/data/images/dice.alpha +0 -0
  208. data/data/images/dice.color +0 -0
  209. data/data/images/dice.png +0 -0
  210. data/data/images/dice_interlaced.png +0 -0
  211. data/data/images/fractal.jpg +0 -0
  212. data/data/images/indexed_color.dat +0 -0
  213. data/data/images/indexed_color.png +0 -0
  214. data/data/images/letterhead.jpg +0 -0
  215. data/data/images/license.md +0 -8
  216. data/data/images/page_white_text.alpha +0 -0
  217. data/data/images/page_white_text.color +0 -0
  218. data/data/images/page_white_text.png +0 -0
  219. data/data/images/pigs.jpg +0 -0
  220. data/data/images/prawn.png +0 -0
  221. data/data/images/ruport.png +0 -0
  222. data/data/images/ruport_data.dat +0 -0
  223. data/data/images/ruport_transparent.png +0 -0
  224. data/data/images/ruport_type0.png +0 -0
  225. data/data/images/stef.jpg +0 -0
  226. data/data/images/tru256.bmp +0 -0
  227. data/data/images/web-links.dat +0 -1
  228. data/data/images/web-links.png +0 -0
  229. data/data/pdfs/complex_template.pdf +0 -0
  230. data/data/pdfs/contains_ttf_font.pdf +0 -0
  231. data/data/pdfs/encrypted.pdf +0 -0
  232. data/data/pdfs/form.pdf +1 -819
  233. data/data/pdfs/hexagon.pdf +0 -61
  234. data/data/pdfs/indirect_reference.pdf +0 -86
  235. data/data/pdfs/multipage_template.pdf +0 -127
  236. data/data/pdfs/nested_pages.pdf +0 -118
  237. data/data/pdfs/page_without_mediabox.pdf +0 -193
  238. data/data/pdfs/resources_as_indirect_object.pdf +0 -83
  239. data/data/pdfs/two_hexagons.pdf +0 -90
  240. data/data/pdfs/version_1_6.pdf +0 -61
  241. data/data/shift_jis_text.txt +0 -1
  242. data/lib/prawn/document/graphics_state.rb +0 -73
  243. data/lib/prawn/font/afm.rb +0 -247
  244. data/lib/prawn/table/cell/image.rb +0 -69
  245. data/lib/prawn/table/cell/in_table.rb +0 -33
  246. data/lib/prawn/table/cell/span_dummy.rb +0 -93
  247. data/lib/prawn/table/cell/subtable.rb +0 -66
  248. data/lib/prawn/table/cell/text.rb +0 -154
  249. data/lib/prawn/table/cell.rb +0 -772
  250. data/lib/prawn/table/cells.rb +0 -255
  251. data/lib/prawn/table/column_width_calculator.rb +0 -182
  252. data/lib/prawn/table.rb +0 -644
  253. data/manual/table/basic_block.rb +0 -53
  254. data/manual/table/before_rendering_page.rb +0 -26
  255. data/manual/table/cell_border_lines.rb +0 -24
  256. data/manual/table/cell_borders_and_bg.rb +0 -31
  257. data/manual/table/cell_dimensions.rb +0 -30
  258. data/manual/table/cell_text.rb +0 -38
  259. data/manual/table/column_widths.rb +0 -30
  260. data/manual/table/content_and_subtables.rb +0 -39
  261. data/manual/table/creation.rb +0 -27
  262. data/manual/table/filtering.rb +0 -36
  263. data/manual/table/flow_and_header.rb +0 -17
  264. data/manual/table/image_cells.rb +0 -33
  265. data/manual/table/position.rb +0 -29
  266. data/manual/table/row_colors.rb +0 -20
  267. data/manual/table/span.rb +0 -30
  268. data/manual/table/style.rb +0 -22
  269. data/manual/table/table.rb +0 -52
  270. data/manual/table/width.rb +0 -27
  271. data/spec/acceptance/png.rb +0 -25
  272. data/spec/annotations_spec.rb +0 -74
  273. data/spec/bounding_box_spec.rb +0 -510
  274. data/spec/cell_spec.rb +0 -629
  275. data/spec/column_box_spec.rb +0 -65
  276. data/spec/destinations_spec.rb +0 -15
  277. data/spec/document_spec.rb +0 -730
  278. data/spec/extensions/mocha.rb +0 -46
  279. data/spec/font_metric_cache_spec.rb +0 -52
  280. data/spec/font_spec.rb +0 -449
  281. data/spec/formatted_text_arranger_spec.rb +0 -421
  282. data/spec/formatted_text_box_spec.rb +0 -639
  283. data/spec/formatted_text_fragment_spec.rb +0 -298
  284. data/spec/graphics_spec.rb +0 -669
  285. data/spec/grid_spec.rb +0 -96
  286. data/spec/image_handler_spec.rb +0 -54
  287. data/spec/images_spec.rb +0 -153
  288. data/spec/inline_formatted_text_parser_spec.rb +0 -564
  289. data/spec/jpg_spec.rb +0 -25
  290. data/spec/line_wrap_spec.rb +0 -344
  291. data/spec/measurement_units_spec.rb +0 -25
  292. data/spec/outline_spec.rb +0 -430
  293. data/spec/png_spec.rb +0 -237
  294. data/spec/reference_spec.rb +0 -25
  295. data/spec/repeater_spec.rb +0 -160
  296. data/spec/security_spec.rb +0 -158
  297. data/spec/soft_mask_spec.rb +0 -79
  298. data/spec/span_spec.rb +0 -44
  299. data/spec/stamp_spec.rb +0 -160
  300. data/spec/stroke_styles_spec.rb +0 -211
  301. data/spec/table/span_dummy_spec.rb +0 -17
  302. data/spec/table_spec.rb +0 -1527
  303. data/spec/text_at_spec.rb +0 -115
  304. data/spec/text_box_spec.rb +0 -1034
  305. data/spec/text_rendering_mode_spec.rb +0 -45
  306. data/spec/text_spacing_spec.rb +0 -93
  307. data/spec/text_spec.rb +0 -437
  308. data/spec/text_with_inline_formatting_spec.rb +0 -35
  309. data/spec/transparency_spec.rb +0 -91
@@ -0,0 +1,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