prawn 2.3.0 → 2.5.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 (203) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/prawn/document/bounding_box.rb +223 -143
  4. data/lib/prawn/document/column_box.rb +61 -26
  5. data/lib/prawn/document/internals.rb +25 -16
  6. data/lib/prawn/document/span.rb +21 -18
  7. data/lib/prawn/document.rb +273 -182
  8. data/lib/prawn/encoding.rb +2 -5
  9. data/lib/prawn/errors.rb +23 -34
  10. data/lib/prawn/font.rb +254 -139
  11. data/lib/prawn/font_metric_cache.rb +18 -16
  12. data/lib/prawn/fonts/afm.rb +99 -57
  13. data/lib/prawn/fonts/dfont.rb +7 -1
  14. data/lib/prawn/fonts/otf.rb +4 -1
  15. data/lib/prawn/fonts/to_unicode_cmap.rb +151 -0
  16. data/lib/prawn/fonts/ttc.rb +7 -2
  17. data/lib/prawn/fonts/ttf.rb +345 -107
  18. data/lib/prawn/fonts.rb +14 -0
  19. data/lib/prawn/graphics/blend_mode.rb +25 -28
  20. data/lib/prawn/graphics/cap_style.rb +9 -12
  21. data/lib/prawn/graphics/color.rb +75 -50
  22. data/lib/prawn/graphics/dash.rb +45 -42
  23. data/lib/prawn/graphics/join_style.rb +18 -12
  24. data/lib/prawn/graphics/patterns.rb +239 -110
  25. data/lib/prawn/graphics/transformation.rb +51 -44
  26. data/lib/prawn/graphics/transparency.rb +16 -40
  27. data/lib/prawn/graphics.rb +370 -260
  28. data/lib/prawn/grid.rb +219 -57
  29. data/lib/prawn/image_handler.rb +27 -10
  30. data/lib/prawn/images/image.rb +8 -10
  31. data/lib/prawn/images/jpg.rb +46 -20
  32. data/lib/prawn/images/png.rb +94 -42
  33. data/lib/prawn/images.rb +70 -81
  34. data/lib/prawn/measurement_extensions.rb +39 -8
  35. data/lib/prawn/measurements.rb +60 -5
  36. data/lib/prawn/outline.rb +120 -113
  37. data/lib/prawn/repeater.rb +52 -36
  38. data/lib/prawn/security/arcfour.rb +4 -4
  39. data/lib/prawn/security.rb +106 -98
  40. data/lib/prawn/soft_mask.rb +42 -30
  41. data/lib/prawn/stamp.rb +38 -42
  42. data/lib/prawn/text/box.rb +156 -105
  43. data/lib/prawn/text/formatted/arranger.rb +121 -41
  44. data/lib/prawn/text/formatted/box.rb +239 -163
  45. data/lib/prawn/text/formatted/fragment.rb +130 -14
  46. data/lib/prawn/text/formatted/line_wrap.rb +49 -38
  47. data/lib/prawn/text/formatted/parser.rb +116 -74
  48. data/lib/prawn/text/formatted/wrap.rb +25 -26
  49. data/lib/prawn/text/formatted.rb +75 -0
  50. data/lib/prawn/text.rb +456 -211
  51. data/lib/prawn/transformation_stack.rb +29 -10
  52. data/lib/prawn/utilities.rb +13 -13
  53. data/lib/prawn/version.rb +2 -1
  54. data/lib/prawn/view.rb +69 -54
  55. data/lib/prawn.rb +24 -18
  56. data.tar.gz.sig +0 -0
  57. metadata +55 -262
  58. metadata.gz.sig +3 -4
  59. data/.yardopts +0 -10
  60. data/Gemfile +0 -5
  61. data/Rakefile +0 -54
  62. data/manual/absolute_position.pdf +0 -0
  63. data/manual/basic_concepts/adding_pages.rb +0 -26
  64. data/manual/basic_concepts/basic_concepts.rb +0 -43
  65. data/manual/basic_concepts/creation.rb +0 -38
  66. data/manual/basic_concepts/cursor.rb +0 -32
  67. data/manual/basic_concepts/measurement.rb +0 -24
  68. data/manual/basic_concepts/origin.rb +0 -37
  69. data/manual/basic_concepts/other_cursor_helpers.rb +0 -39
  70. data/manual/basic_concepts/view.rb +0 -48
  71. data/manual/bounding_box/bounding_box.rb +0 -41
  72. data/manual/bounding_box/bounds.rb +0 -48
  73. data/manual/bounding_box/canvas.rb +0 -23
  74. data/manual/bounding_box/creation.rb +0 -22
  75. data/manual/bounding_box/indentation.rb +0 -45
  76. data/manual/bounding_box/nesting.rb +0 -52
  77. data/manual/bounding_box/russian_boxes.rb +0 -40
  78. data/manual/bounding_box/stretchy.rb +0 -29
  79. data/manual/contents.rb +0 -35
  80. data/manual/cover.rb +0 -43
  81. data/manual/document_and_page_options/background.rb +0 -25
  82. data/manual/document_and_page_options/document_and_page_options.rb +0 -34
  83. data/manual/document_and_page_options/metadata.rb +0 -25
  84. data/manual/document_and_page_options/page_margins.rb +0 -36
  85. data/manual/document_and_page_options/page_size.rb +0 -34
  86. data/manual/document_and_page_options/print_scaling.rb +0 -22
  87. data/manual/example_helper.rb +0 -8
  88. data/manual/graphics/blend_mode.rb +0 -52
  89. data/manual/graphics/circle_and_ellipse.rb +0 -21
  90. data/manual/graphics/color.rb +0 -22
  91. data/manual/graphics/common_lines.rb +0 -29
  92. data/manual/graphics/fill_and_stroke.rb +0 -41
  93. data/manual/graphics/fill_rules.rb +0 -37
  94. data/manual/graphics/gradients.rb +0 -43
  95. data/manual/graphics/graphics.rb +0 -64
  96. data/manual/graphics/helper.rb +0 -27
  97. data/manual/graphics/line_width.rb +0 -36
  98. data/manual/graphics/lines_and_curves.rb +0 -40
  99. data/manual/graphics/polygon.rb +0 -27
  100. data/manual/graphics/rectangle.rb +0 -20
  101. data/manual/graphics/rotate.rb +0 -25
  102. data/manual/graphics/scale.rb +0 -42
  103. data/manual/graphics/soft_masks.rb +0 -44
  104. data/manual/graphics/stroke_cap.rb +0 -30
  105. data/manual/graphics/stroke_dash.rb +0 -47
  106. data/manual/graphics/stroke_join.rb +0 -29
  107. data/manual/graphics/translate.rb +0 -28
  108. data/manual/graphics/transparency.rb +0 -33
  109. data/manual/how_to_read_this_manual.rb +0 -39
  110. data/manual/images/absolute_position.rb +0 -22
  111. data/manual/images/fit.rb +0 -20
  112. data/manual/images/horizontal.rb +0 -24
  113. data/manual/images/images.rb +0 -41
  114. data/manual/images/plain_image.rb +0 -17
  115. data/manual/images/scale.rb +0 -21
  116. data/manual/images/vertical.rb +0 -27
  117. data/manual/images/width_and_height.rb +0 -24
  118. data/manual/layout/boxes.rb +0 -26
  119. data/manual/layout/content.rb +0 -24
  120. data/manual/layout/layout.rb +0 -27
  121. data/manual/layout/simple_grid.rb +0 -22
  122. data/manual/outline/add_subsection_to.rb +0 -60
  123. data/manual/outline/insert_section_after.rb +0 -46
  124. data/manual/outline/outline.rb +0 -33
  125. data/manual/outline/sections_and_pages.rb +0 -66
  126. data/manual/repeatable_content/alternate_page_numbering.rb +0 -36
  127. data/manual/repeatable_content/page_numbering.rb +0 -55
  128. data/manual/repeatable_content/repeatable_content.rb +0 -35
  129. data/manual/repeatable_content/repeater.rb +0 -54
  130. data/manual/repeatable_content/stamp.rb +0 -40
  131. data/manual/security/encryption.rb +0 -28
  132. data/manual/security/permissions.rb +0 -41
  133. data/manual/security/security.rb +0 -28
  134. data/manual/table.rb +0 -16
  135. data/manual/text/alignment.rb +0 -43
  136. data/manual/text/color.rb +0 -24
  137. data/manual/text/column_box.rb +0 -30
  138. data/manual/text/fallback_fonts.rb +0 -41
  139. data/manual/text/font.rb +0 -40
  140. data/manual/text/font_size.rb +0 -44
  141. data/manual/text/font_style.rb +0 -22
  142. data/manual/text/formatted_callbacks.rb +0 -65
  143. data/manual/text/formatted_text.rb +0 -58
  144. data/manual/text/free_flowing_text.rb +0 -50
  145. data/manual/text/inline.rb +0 -40
  146. data/manual/text/kerning_and_character_spacing.rb +0 -38
  147. data/manual/text/leading.rb +0 -24
  148. data/manual/text/line_wrapping.rb +0 -60
  149. data/manual/text/paragraph_indentation.rb +0 -32
  150. data/manual/text/positioned_text.rb +0 -37
  151. data/manual/text/registering_families.rb +0 -51
  152. data/manual/text/rendering_and_color.rb +0 -36
  153. data/manual/text/right_to_left_text.rb +0 -54
  154. data/manual/text/rotation.rb +0 -47
  155. data/manual/text/single_usage.rb +0 -36
  156. data/manual/text/text.rb +0 -75
  157. data/manual/text/text_box_excess.rb +0 -35
  158. data/manual/text/text_box_extensions.rb +0 -48
  159. data/manual/text/text_box_overflow.rb +0 -49
  160. data/manual/text/utf8.rb +0 -27
  161. data/manual/text/win_ansi_charset.rb +0 -62
  162. data/prawn.gemspec +0 -57
  163. data/spec/data/curves.pdf +0 -66
  164. data/spec/extensions/encoding_helpers.rb +0 -11
  165. data/spec/prawn/document/bounding_box_spec.rb +0 -546
  166. data/spec/prawn/document/column_box_spec.rb +0 -75
  167. data/spec/prawn/document/security_spec.rb +0 -176
  168. data/spec/prawn/document_annotations_spec.rb +0 -76
  169. data/spec/prawn/document_destinations_spec.rb +0 -15
  170. data/spec/prawn/document_grid_spec.rb +0 -99
  171. data/spec/prawn/document_reference_spec.rb +0 -27
  172. data/spec/prawn/document_span_spec.rb +0 -36
  173. data/spec/prawn/document_spec.rb +0 -802
  174. data/spec/prawn/font_metric_cache_spec.rb +0 -54
  175. data/spec/prawn/font_spec.rb +0 -542
  176. data/spec/prawn/graphics/blend_mode_spec.rb +0 -63
  177. data/spec/prawn/graphics/transparency_spec.rb +0 -81
  178. data/spec/prawn/graphics_spec.rb +0 -837
  179. data/spec/prawn/graphics_stroke_styles_spec.rb +0 -229
  180. data/spec/prawn/image_handler_spec.rb +0 -53
  181. data/spec/prawn/images/jpg_spec.rb +0 -20
  182. data/spec/prawn/images/png_spec.rb +0 -283
  183. data/spec/prawn/images_spec.rb +0 -224
  184. data/spec/prawn/measurements_extensions_spec.rb +0 -24
  185. data/spec/prawn/outline_spec.rb +0 -412
  186. data/spec/prawn/repeater_spec.rb +0 -165
  187. data/spec/prawn/soft_mask_spec.rb +0 -74
  188. data/spec/prawn/stamp_spec.rb +0 -172
  189. data/spec/prawn/text/box_spec.rb +0 -1112
  190. data/spec/prawn/text/formatted/arranger_spec.rb +0 -466
  191. data/spec/prawn/text/formatted/box_spec.rb +0 -846
  192. data/spec/prawn/text/formatted/fragment_spec.rb +0 -343
  193. data/spec/prawn/text/formatted/line_wrap_spec.rb +0 -494
  194. data/spec/prawn/text/formatted/parser_spec.rb +0 -697
  195. data/spec/prawn/text_draw_text_spec.rb +0 -149
  196. data/spec/prawn/text_rendering_mode_spec.rb +0 -48
  197. data/spec/prawn/text_spacing_spec.rb +0 -95
  198. data/spec/prawn/text_spec.rb +0 -603
  199. data/spec/prawn/text_with_inline_formatting_spec.rb +0 -35
  200. data/spec/prawn/transformation_stack_spec.rb +0 -66
  201. data/spec/prawn/view_spec.rb +0 -63
  202. data/spec/prawn_manual_spec.rb +0 -35
  203. data/spec/spec_helper.rb +0 -48
@@ -1,1112 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Prawn::Text::Box do
6
- let(:pdf) { create_pdf }
7
-
8
- it 'is able to set leading document-wide' do
9
- pdf.default_leading(7)
10
- pdf.default_leading = 7
11
- text_box = described_class.new('hello world', document: pdf)
12
- expect(text_box.leading).to eq(7)
13
- end
14
-
15
- it 'option should be able to override document-wide leading' do
16
- pdf.default_leading = 7
17
- text_box = described_class.new(
18
- 'hello world',
19
- document: pdf,
20
- leading: 20
21
- )
22
- expect(text_box.leading).to eq(20)
23
- end
24
-
25
- it 'is able to set text direction document-wide' do
26
- pdf.text_direction(:rtl)
27
- pdf.text_direction = :rtl
28
- string = "Hello world, how are you?\nI'm fine, thank you."
29
- text_box = described_class.new(string, document: pdf)
30
- text_box.render
31
- text = PDF::Inspector::Text.analyze(pdf.render)
32
- expect(text.strings[0]).to eq('?uoy era woh ,dlrow olleH')
33
- expect(text.strings[1]).to eq(".uoy knaht ,enif m'I")
34
- end
35
-
36
- it 'is able to reverse multi-byte text' do
37
- pdf.text_direction(:rtl)
38
- pdf.text_direction = :rtl
39
- pdf.text_direction = :rtl
40
- pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf", size: 16) do
41
- pdf.text '写个小'
42
- end
43
- text = PDF::Inspector::Text.analyze(pdf.render)
44
- expect(text.strings[0]).to eq('小个写')
45
- end
46
-
47
- it 'option should be able to override document-wide text direction' do
48
- pdf.text_direction = :rtl
49
- string = "Hello world, how are you?\nI'm fine, thank you."
50
- text_box = described_class.new(
51
- string,
52
- document: pdf,
53
- direction: :ltr
54
- )
55
- text_box.render
56
- text = PDF::Inspector::Text.analyze(pdf.render)
57
- expect(text.strings[0]).to eq('Hello world, how are you?')
58
- expect(text.strings[1]).to eq("I'm fine, thank you.")
59
- end
60
-
61
- it 'only requires enough space for the descender and the ascender '\
62
- 'when determining whether a line can fit' do
63
- text = 'Oh hai text rect'
64
- options = {
65
- document: pdf,
66
- height: pdf.font.ascender + pdf.font.descender
67
- }
68
- text_box = described_class.new(text, options)
69
- text_box.render
70
- expect(text_box.text).to eq('Oh hai text rect')
71
-
72
- text = "Oh hai text rect\nOh hai text rect"
73
- options = {
74
- document: pdf,
75
- height: pdf.font.height + pdf.font.ascender + pdf.font.descender
76
- }
77
- text_box = described_class.new(text, options)
78
- text_box.render
79
- expect(text_box.text).to eq("Oh hai text rect\nOh hai text rect")
80
- end
81
-
82
- describe '#nothing_printed?' do
83
- it 'returns true when nothing printed' do
84
- string = "Hello world, how are you?\nI'm fine, thank you."
85
- text_box = described_class.new(string, height: 2, document: pdf)
86
- text_box.render
87
- expect(text_box.nothing_printed?).to eq true
88
- end
89
-
90
- it 'returns false when something printed' do
91
- string = "Hello world, how are you?\nI'm fine, thank you."
92
- text_box = described_class.new(string, height: 14, document: pdf)
93
- text_box.render
94
- expect(text_box.nothing_printed?).to eq false
95
- end
96
- end
97
-
98
- describe '#everything_printed?' do
99
- it 'returns false when not everything printed' do
100
- string = "Hello world, how are you?\nI'm fine, thank you."
101
- text_box = described_class.new(string, height: 14, document: pdf)
102
- text_box.render
103
- expect(text_box.everything_printed?).to eq false
104
- end
105
-
106
- it 'returns true when everything printed' do
107
- string = "Hello world, how are you?\nI'm fine, thank you."
108
- text_box = described_class.new(string, document: pdf)
109
- text_box.render
110
- expect(text_box.everything_printed?).to eq true
111
- end
112
- end
113
-
114
- describe '#line_gap' do
115
- it '==S the line gap of the font when using a single font and font size' do
116
- string = "Hello world, how are you?\nI'm fine, thank you."
117
- text_box = described_class.new(string, document: pdf)
118
- text_box.render
119
- expect(text_box.line_gap).to be_within(0.0001).of(pdf.font.line_gap)
120
- end
121
- end
122
-
123
- describe '#render with :align => :justify' do
124
- it 'draws the word spacing to the document' do
125
- string = 'hello world ' * 20
126
- options = { document: pdf, align: :justify }
127
- text_box = described_class.new(string, options)
128
- text_box.render
129
- contents = PDF::Inspector::Text.analyze(pdf.render)
130
- expect(contents.word_spacing[0]).to be > 0
131
- end
132
-
133
- it 'does not justify the last line of a paragraph' do
134
- string = 'hello world '
135
- options = { document: pdf, align: :justify }
136
- text_box = described_class.new(string, options)
137
- text_box.render
138
- contents = PDF::Inspector::Text.analyze(pdf.render)
139
- expect(contents.word_spacing).to be_empty
140
- end
141
- end
142
-
143
- describe '#height without leading' do
144
- it 'is the sum of the height of each line, not including the space below '\
145
- 'the last line' do
146
- text = "Oh hai text rect.\nOh hai text rect."
147
- options = { document: pdf }
148
- text_box = described_class.new(text, options)
149
- text_box.render
150
- expect(text_box.height).to be_within(0.001)
151
- .of(pdf.font.height * 2 - pdf.font.line_gap)
152
- end
153
- end
154
-
155
- describe '#height with leading' do
156
- it 'is the sum of the height of each line plus leading, but not including '\
157
- 'the space below the last line' do
158
- text = "Oh hai text rect.\nOh hai text rect."
159
- leading = 12
160
- options = { document: pdf, leading: leading }
161
- text_box = described_class.new(text, options)
162
- text_box.render
163
- expect(text_box.height).to be_within(0.001).of(
164
- (pdf.font.height + leading) * 2 - pdf.font.line_gap - leading
165
- )
166
- end
167
- end
168
-
169
- context 'with :draw_text_callback' do
170
- it 'hits the callback whenever text is drawn' do
171
- draw_block = instance_spy('Draw block')
172
-
173
- pdf.text_box 'this text is long enough to span two lines',
174
- width: 150,
175
- draw_text_callback: ->(text, _) { draw_block.kick(text) }
176
-
177
- expect(draw_block).to have_received(:kick)
178
- .with('this text is long enough to')
179
- expect(draw_block).to have_received(:kick).with('span two lines')
180
- end
181
-
182
- it 'hits the callback once per fragment for :inline_format' do
183
- draw_block = instance_spy('Draw block')
184
-
185
- pdf.text_box 'this text has <b>fancy</b> formatting',
186
- inline_format: true, width: 500,
187
- draw_text_callback: ->(text, _) { draw_block.kick(text) }
188
-
189
- expect(draw_block).to have_received(:kick).with('this text has ')
190
- expect(draw_block).to have_received(:kick).with('fancy')
191
- expect(draw_block).to have_received(:kick).with(' formatting')
192
- end
193
-
194
- it 'does not call #draw_text!' do
195
- allow(pdf).to receive(:draw_text!)
196
- pdf.text_box 'some text', width: 500,
197
- draw_text_callback: ->(_, _) {}
198
- expect(pdf).to_not have_received(:draw_text!)
199
- end
200
- end
201
-
202
- describe '#valid_options' do
203
- it 'returns an array' do
204
- text_box = described_class.new('', document: pdf)
205
- expect(text_box.valid_options).to be_a_kind_of(Array)
206
- end
207
- end
208
-
209
- describe '#render' do
210
- it 'does not fail if height is smaller than 1 line' do
211
- text = 'Oh hai text rect. ' * 10
212
- options = {
213
- height: pdf.font.height * 0.5,
214
- document: pdf
215
- }
216
- text_box = described_class.new(text, options)
217
- text_box.render
218
- expect(text_box.text).to eq('')
219
- end
220
-
221
- it 'draws content to the page' do
222
- text = 'Oh hai text rect. ' * 10
223
- options = { document: pdf }
224
- text_box = described_class.new(text, options)
225
- text_box.render
226
- text = PDF::Inspector::Text.analyze(pdf.render)
227
- expect(text.strings).to_not be_empty
228
- end
229
-
230
- it 'does not draw a transformation matrix' do
231
- text = 'Oh hai text rect. ' * 10
232
- options = { document: pdf }
233
- text_box = described_class.new(text, options)
234
- text_box.render
235
- matrices = PDF::Inspector::Graphics::Matrix.analyze(pdf.render)
236
- expect(matrices.matrices.length).to eq(0)
237
- end
238
- end
239
-
240
- describe '#render(:single_line => true)' do
241
- it 'draws only one line to the page' do
242
- text = 'Oh hai text rect. ' * 10
243
- options = {
244
- document: pdf,
245
- single_line: true
246
- }
247
- text_box = described_class.new(text, options)
248
- text_box.render
249
- text = PDF::Inspector::Text.analyze(pdf.render)
250
- expect(text.strings.length).to eq(1)
251
- end
252
- end
253
-
254
- describe '#render(:dry_run => true)' do
255
- it 'does not draw any content to the page' do
256
- text = 'Oh hai text rect. ' * 10
257
- options = { document: pdf }
258
- text_box = described_class.new(text, options)
259
- text_box.render(dry_run: true)
260
- text = PDF::Inspector::Text.analyze(pdf.render)
261
- expect(text.strings).to be_empty
262
- end
263
-
264
- it 'subsequent calls to render do not raise an ArgumentError exception' do
265
- text = '™©'
266
- options = { document: pdf }
267
- text_box = described_class.new(text, options)
268
- text_box.render(dry_run: true)
269
-
270
- expect do
271
- text_box.render
272
- end.to_not raise_exception
273
- end
274
- end
275
-
276
- describe '#render(:valign => :bottom)' do
277
- it '#at should be the same from one dry run to the next' do
278
- text = 'this is center text ' * 12
279
- options = {
280
- width: 162,
281
- valign: :bottom,
282
- document: pdf
283
- }
284
- text_box = described_class.new(text, options)
285
-
286
- text_box.render(dry_run: true)
287
- original_at = text_box.at.dup
288
-
289
- text_box.render(dry_run: true)
290
- expect(text_box.at).to eq(original_at)
291
- end
292
- end
293
-
294
- describe '#render(:valign => :center)' do
295
- it '#at should be the same from one dry run to the next' do
296
- text = 'this is center text ' * 12
297
- options = {
298
- width: 162,
299
- valign: :center,
300
- document: pdf
301
- }
302
- text_box = described_class.new(text, options)
303
-
304
- text_box.render(dry_run: true)
305
- original_at = text_box.at.dup
306
-
307
- text_box.render(dry_run: true)
308
- expect(text_box.at).to eq(original_at)
309
- end
310
- end
311
-
312
- describe '#render with :rotate option of 30)' do
313
- let(:angle) { 30 }
314
- let(:x) { 300 }
315
- let(:y) { 70 }
316
- let(:width) { 100 }
317
- let(:height) { 50 }
318
- let(:cos) { Math.cos(angle * Math::PI / 180) }
319
- let(:sin) { Math.sin(angle * Math::PI / 180) }
320
- let(:text) { 'Oh hai text rect. ' * 10 }
321
- let(:options) do
322
- {
323
- document: pdf,
324
- rotate: angle,
325
- at: [x, y],
326
- width: width,
327
- height: height
328
- }
329
- end
330
-
331
- context 'with :rotate_around option of :center' do
332
- it 'draws content to the page rotated about the center of the text' do
333
- options[:rotate_around] = :center
334
- text_box = described_class.new(text, options)
335
- text_box.render
336
-
337
- matrices = PDF::Inspector::Graphics::Matrix.analyze(pdf.render)
338
- x_ = x + width / 2
339
- y_ = y - height / 2
340
- x_prime = x_ * cos - y_ * sin
341
- y_prime = x_ * sin + y_ * cos
342
- expect(matrices.matrices[0]).to eq([
343
- 1, 0, 0, 1,
344
- reduce_precision(x_ - x_prime),
345
- reduce_precision(y_ - y_prime)
346
- ])
347
- expect(matrices.matrices[1]).to eq([
348
- reduce_precision(cos),
349
- reduce_precision(sin),
350
- reduce_precision(-sin),
351
- reduce_precision(cos),
352
- 0, 0
353
- ])
354
-
355
- text = PDF::Inspector::Text.analyze(pdf.render)
356
- expect(text.strings).to_not be_empty
357
- end
358
- end
359
-
360
- context 'with :rotate_around option of :upper_left' do
361
- it 'draws content to the page rotated about the upper left corner of '\
362
- 'the text' do
363
- options[:rotate_around] = :upper_left
364
- text_box = described_class.new(text, options)
365
- text_box.render
366
-
367
- matrices = PDF::Inspector::Graphics::Matrix.analyze(pdf.render)
368
- x_prime = x * cos - y * sin
369
- y_prime = x * sin + y * cos
370
- expect(matrices.matrices[0]).to eq([
371
- 1, 0, 0, 1,
372
- reduce_precision(x - x_prime),
373
- reduce_precision(y - y_prime)
374
- ])
375
- expect(matrices.matrices[1]).to eq([
376
- reduce_precision(cos),
377
- reduce_precision(sin),
378
- reduce_precision(-sin),
379
- reduce_precision(cos),
380
- 0, 0
381
- ])
382
-
383
- text = PDF::Inspector::Text.analyze(pdf.render)
384
- expect(text.strings).to_not be_empty
385
- end
386
- end
387
-
388
- context 'with default :rotate_around' do
389
- it 'draws content to the page rotated about the upper left corner of '\
390
- 'the text' do
391
- text_box = described_class.new(text, options)
392
- text_box.render
393
-
394
- matrices = PDF::Inspector::Graphics::Matrix.analyze(pdf.render)
395
- x_prime = x * cos - y * sin
396
- y_prime = x * sin + y * cos
397
- expect(matrices.matrices[0]).to eq([
398
- 1, 0, 0, 1,
399
- reduce_precision(x - x_prime),
400
- reduce_precision(y - y_prime)
401
- ])
402
- expect(matrices.matrices[1]).to eq([
403
- reduce_precision(cos),
404
- reduce_precision(sin),
405
- reduce_precision(-sin),
406
- reduce_precision(cos),
407
- 0, 0
408
- ])
409
-
410
- text = PDF::Inspector::Text.analyze(pdf.render)
411
- expect(text.strings).to_not be_empty
412
- end
413
- end
414
-
415
- context 'with :rotate_around option of :upper_right' do
416
- it 'draws content to the page rotated about the upper right corner of '\
417
- 'the text' do
418
- options[:rotate_around] = :upper_right
419
- text_box = described_class.new(text, options)
420
- text_box.render
421
-
422
- matrices = PDF::Inspector::Graphics::Matrix.analyze(pdf.render)
423
- x_ = x + width
424
- y_ = y
425
- x_prime = x_ * cos - y_ * sin
426
- y_prime = x_ * sin + y_ * cos
427
- expect(matrices.matrices[0]).to eq([
428
- 1, 0, 0, 1,
429
- reduce_precision(x_ - x_prime),
430
- reduce_precision(y_ - y_prime)
431
- ])
432
- expect(matrices.matrices[1]).to eq([
433
- reduce_precision(cos),
434
- reduce_precision(sin),
435
- reduce_precision(-sin),
436
- reduce_precision(cos),
437
- 0, 0
438
- ])
439
-
440
- text = PDF::Inspector::Text.analyze(pdf.render)
441
- expect(text.strings).to_not be_empty
442
- end
443
- end
444
-
445
- context 'with :rotate_around option of :lower_right' do
446
- it 'draws content to the page rotated about the lower right corner of '\
447
- 'the text' do
448
- options[:rotate_around] = :lower_right
449
- text_box = described_class.new(text, options)
450
- text_box.render
451
-
452
- matrices = PDF::Inspector::Graphics::Matrix.analyze(pdf.render)
453
- x_ = x + width
454
- y_ = y - height
455
- x_prime = x_ * cos - y_ * sin
456
- y_prime = x_ * sin + y_ * cos
457
- expect(matrices.matrices[0]).to eq([
458
- 1, 0, 0, 1,
459
- reduce_precision(x_ - x_prime),
460
- reduce_precision(y_ - y_prime)
461
- ])
462
- expect(matrices.matrices[1]).to eq([
463
- reduce_precision(cos),
464
- reduce_precision(sin),
465
- reduce_precision(-sin),
466
- reduce_precision(cos),
467
- 0, 0
468
- ])
469
-
470
- text = PDF::Inspector::Text.analyze(pdf.render)
471
- expect(text.strings).to_not be_empty
472
- end
473
- end
474
-
475
- context 'with :rotate_around option of :lower_left' do
476
- it 'draws content to the page rotated about the lower left corner of '\
477
- 'the text' do
478
- options[:rotate_around] = :lower_left
479
- text_box = described_class.new(text, options)
480
- text_box.render
481
-
482
- matrices = PDF::Inspector::Graphics::Matrix.analyze(pdf.render)
483
- x_ = x
484
- y_ = y - height
485
- x_prime = x_ * cos - y_ * sin
486
- y_prime = x_ * sin + y_ * cos
487
- expect(matrices.matrices[0]).to eq([
488
- 1, 0, 0, 1,
489
- reduce_precision(x_ - x_prime),
490
- reduce_precision(y_ - y_prime)
491
- ])
492
- expect(matrices.matrices[1]).to eq([
493
- reduce_precision(cos),
494
- reduce_precision(sin),
495
- reduce_precision(-sin),
496
- reduce_precision(cos),
497
- 0, 0
498
- ])
499
-
500
- text = PDF::Inspector::Text.analyze(pdf.render)
501
- expect(text.strings).to_not be_empty
502
- end
503
- end
504
- end
505
-
506
- describe 'default height' do
507
- it 'is the height from the bottom bound to document.y' do
508
- target_height = pdf.y - pdf.bounds.bottom
509
- text = "Oh hai\n" * 60
510
- text_box = described_class.new(text, document: pdf)
511
- text_box.render
512
- expect(text_box.height).to be_within(pdf.font.height).of(target_height)
513
- end
514
-
515
- it 'uses the margin-box bottom if only in a stretchy bbox' do
516
- pdf.bounding_box([0, pdf.cursor], width: pdf.bounds.width) do
517
- target_height = pdf.y - pdf.bounds.bottom
518
- text = "Oh hai\n" * 60
519
- text_box = described_class.new(text, document: pdf)
520
- text_box.render
521
- expect(text_box.height).to be_within(pdf.font.height).of(target_height)
522
- end
523
- end
524
-
525
- it 'uses the parent-box bottom if in a stretchy bbox and overflow is '\
526
- ':expand, even with an explicit height' do
527
- pdf.bounding_box([0, pdf.cursor], width: pdf.bounds.width) do
528
- target_height = pdf.y - pdf.bounds.bottom
529
- text = "Oh hai\n" * 60
530
- text_box = described_class.new(
531
- text,
532
- document: pdf,
533
- height: 100,
534
- overflow: :expand
535
- )
536
- text_box.render
537
- expect(text_box.height).to be_within(pdf.font.height).of(target_height)
538
- end
539
- end
540
-
541
- it 'uses the innermost non-stretchy bbox, not the margin box' do
542
- pdf.bounding_box(
543
- [0, pdf.cursor],
544
- width: pdf.bounds.width,
545
- height: 200
546
- ) do
547
- pdf.bounding_box([0, pdf.cursor], width: pdf.bounds.width) do
548
- text = "Oh hai\n" * 60
549
- text_box = described_class.new(text, document: pdf)
550
- text_box.render
551
- expect(text_box.height).to be_within(pdf.font.height).of(200)
552
- end
553
- end
554
- end
555
- end
556
-
557
- describe 'default at' do
558
- it 'is the left corner of the bounds, and the current document.y' do
559
- target_at = [pdf.bounds.left, pdf.y]
560
- text = 'Oh hai text rect. ' * 100
561
- options = { document: pdf }
562
- text_box = described_class.new(text, options)
563
- text_box.render
564
- expect(text_box.at).to eq(target_at)
565
- end
566
- end
567
-
568
- context 'with text than can fit in the box' do
569
- let(:text) { 'Oh hai text rect. ' * 10 }
570
- let(:options) do
571
- {
572
- width: 162.0,
573
- height: 162.0,
574
- document: pdf
575
- }
576
- end
577
-
578
- it 'printed text should match requested text, except that preceding and ' \
579
- 'trailing white space will be stripped from each line, and newlines ' \
580
- 'may be inserted' do
581
- text_box = described_class.new(' ' + text, options)
582
- text_box.render
583
- expect(text_box.text.tr("\n", ' ')).to eq(text.strip)
584
- end
585
-
586
- it 'render returns an empty string because no text remains unprinted' do
587
- text_box = described_class.new(text, options)
588
- expect(text_box.render).to eq('')
589
- end
590
-
591
- it 'is truncated when the leading is set high enough to prevent all the '\
592
- 'lines from being printed' do
593
- options[:leading] = 40
594
- text_box = described_class.new(text, options)
595
- text_box.render
596
- expect(text_box.text.tr("\n", ' ')).to_not eq(text.strip)
597
- end
598
- end
599
-
600
- context 'with text that fits exactly in the box' do
601
- let(:lines) { 3 }
602
- let(:interlines) { lines - 1 }
603
- let(:text) { (1..lines).to_a.join("\n") }
604
- let(:options) do
605
- {
606
- width: 162.0,
607
- height: pdf.font.ascender + pdf.font.height * interlines +
608
- pdf.font.descender,
609
- document: pdf
610
- }
611
- end
612
-
613
- it 'has the expected height' do
614
- expected_height = options.delete(:height)
615
- text_box = described_class.new(text, options)
616
- text_box.render
617
- expect(text_box.height).to be_within(0.0001).of(expected_height)
618
- end
619
-
620
- it 'prints everything' do
621
- text_box = described_class.new(text, options)
622
- text_box.render
623
- expect(text_box.text).to eq(text)
624
- end
625
-
626
- describe 'with leading' do
627
- before do
628
- options[:leading] = 15
629
- end
630
-
631
- it 'does not overflow when enough height is added' do
632
- options[:height] += options[:leading] * interlines
633
- text_box = described_class.new(text, options)
634
- text_box.render
635
- expect(text_box.text).to eq(text)
636
- end
637
-
638
- it 'overflows when insufficient height is added' do
639
- options[:height] += options[:leading] * interlines - 1
640
- text_box = described_class.new(text, options)
641
- text_box.render
642
- expect(text_box.text).to_not eq(text)
643
- end
644
- end
645
-
646
- context 'with negative leading' do
647
- before do
648
- options[:leading] = -4
649
- end
650
-
651
- it 'does not overflow when enough height is removed' do
652
- options[:height] += options[:leading] * interlines
653
- text_box = described_class.new(text, options)
654
- text_box.render
655
- expect(text_box.text).to eq(text)
656
- end
657
-
658
- it 'overflows when too much height is removed' do
659
- options[:height] += options[:leading] * interlines - 1
660
- text_box = described_class.new(text, options)
661
- text_box.render
662
- expect(text_box.text).to_not eq(text)
663
- end
664
- end
665
- end
666
-
667
- context 'when printing UTF-8 string with higher bit characters' do
668
- let(:text) { '©' }
669
-
670
- let(:text_box) do
671
- # not enough height to print any text, so we can directly compare against
672
- # the input string
673
- bounding_height = 1.0
674
- options = {
675
- height: bounding_height,
676
- document: pdf
677
- }
678
- described_class.new(text, options)
679
- end
680
-
681
- before do
682
- file = "#{Prawn::DATADIR}/fonts/Panic+Sans.dfont"
683
- pdf.font_families['Panic Sans'] = {
684
- normal: { file: file, font: 'PanicSans' },
685
- italic: { file: file, font: 'PanicSans-Italic' },
686
- bold: { file: file, font: 'PanicSans-Bold' },
687
- bold_italic: { file: file, font: 'PanicSans-BoldItalic' }
688
- }
689
- end
690
-
691
- describe 'when using a TTF font' do
692
- it 'unprinted text should be in UTF-8 encoding' do
693
- pdf.font('Panic Sans')
694
- remaining_text = text_box.render
695
- expect(remaining_text).to eq(text)
696
- end
697
- end
698
-
699
- describe 'when using an AFM font' do
700
- it 'unprinted text should be in UTF-8 encoding' do
701
- remaining_text = text_box.render
702
- expect(remaining_text).to eq(text)
703
- end
704
- end
705
- end
706
-
707
- context 'with more text than can fit in the box' do
708
- let(:text) { 'Oh hai text rect. ' * 30 }
709
- let(:bounding_height) { 162.0 }
710
- let(:options) do
711
- {
712
- width: 162.0,
713
- height: bounding_height,
714
- document: pdf
715
- }
716
- end
717
-
718
- context 'when truncated overflow' do
719
- let(:text_box) do
720
- described_class.new(text, options.merge(overflow: :truncate))
721
- end
722
-
723
- it 'is truncated' do
724
- text_box.render
725
- expect(text_box.text.tr("\n", ' ')).to_not eq(text.strip)
726
- end
727
-
728
- it 'render does not return an empty string because some text remains '\
729
- 'unprinted' do
730
- expect(text_box.render).to_not be_empty
731
- end
732
-
733
- it '#height should be no taller than the specified height' do
734
- text_box.render
735
- expect(text_box.height).to be <= bounding_height
736
- end
737
-
738
- it '#height should be within one font height of the specified height' do
739
- text_box.render
740
- expect(bounding_height).to be_within(pdf.font.height)
741
- .of(text_box.height)
742
- end
743
-
744
- context 'with :rotate option' do
745
- it 'unrendered text should be the same as when not rotated' do
746
- remaining_text = text_box.render
747
-
748
- rotate = 30
749
- x = 300
750
- y = 70
751
- options[:document] = pdf
752
- options[:rotate] = rotate
753
- options[:at] = [x, y]
754
- rotated_text_box = described_class.new(text, options)
755
- expect(rotated_text_box.render).to eq(remaining_text)
756
- end
757
- end
758
- end
759
-
760
- context 'when truncated with text and size taken from the manual' do
761
- it 'returns the right text' do
762
- text = 'This is the beginning of the text. It will be cut somewhere ' \
763
- 'and the rest of the text will procede to be rendered this time by '\
764
- 'calling another method.' + ' . ' * 50
765
- options[:width] = 300
766
- options[:height] = 50
767
- options[:size] = 18
768
- text_box = described_class.new(text, options)
769
- remaining_text = text_box.render
770
- expect(remaining_text).to eq(
771
- 'text will procede to be rendered this time by calling another ' \
772
- 'method. . . . . . . . . . . . . . . . . . . . ' \
773
- '. . . . . . . . . . . . . . . . . . . . . . ' \
774
- '. . . . . . . . . '
775
- )
776
- end
777
- end
778
-
779
- context 'when expand overflow' do
780
- let(:text_box) do
781
- described_class.new(text, options.merge(overflow: :expand))
782
- end
783
-
784
- it 'height expands to encompass all the text '\
785
- '(but not exceed the height of the page)' do
786
- text_box.render
787
- expect(text_box.height).to be > bounding_height
788
- end
789
-
790
- it 'displays the entire string (as long as there was space remaining on '\
791
- 'the page to print all the text)' do
792
- text_box.render
793
- expect(text_box.text.tr("\n", ' ')).to eq(text.strip)
794
- end
795
-
796
- it 'render returns an empty string because no text remains unprinted '\
797
- '(as long as there was space remaining on the page to print all '\
798
- 'the text)' do
799
- expect(text_box.render).to eq('')
800
- end
801
- end
802
-
803
- context 'when shrink_to_fit overflow' do
804
- let(:text_box) do
805
- described_class.new(
806
- text,
807
- options.merge(
808
- overflow: :shrink_to_fit,
809
- min_font_size: 2
810
- )
811
- )
812
- end
813
-
814
- it 'displays the entire text' do
815
- text_box.render
816
- expect(text_box.text.tr("\n", ' ')).to eq(text.strip)
817
- end
818
-
819
- it 'render returns an empty string because no text remains unprinted' do
820
- expect(text_box.render).to eq('')
821
- end
822
-
823
- it 'does not drop below the minimum font size' do
824
- options[:overflow] = :shrink_to_fit
825
- options[:min_font_size] = 10.1
826
- text_box = described_class.new(text, options)
827
- text_box.render
828
-
829
- actual_text = PDF::Inspector::Text.analyze(pdf.render)
830
- expect(actual_text.font_settings[0][:size]).to eq(10.1)
831
- end
832
- end
833
- end
834
-
835
- context 'with enough space to fit the text but using the ' \
836
- 'shrink_to_fit overflow' do
837
- it 'does not shrink the text when there is no need to' do
838
- bounding_height = 162.0
839
- options = {
840
- width: 162.0,
841
- height: bounding_height,
842
- overflow: :shrink_to_fit,
843
- min_font_size: 5,
844
- document: pdf
845
- }
846
- text_box = described_class.new("hello\nworld", options)
847
- text_box.render
848
-
849
- text = PDF::Inspector::Text.analyze(pdf.render)
850
- expect(text.font_settings[0][:size]).to eq(12)
851
- end
852
- end
853
-
854
- context 'with a solid block of Chinese characters' do
855
- it 'printed text should match requested text, except for newlines' do
856
- text = '写中国字' * 10
857
- options = {
858
- width: 162.0,
859
- height: 162.0,
860
- document: pdf,
861
- overflow: :truncate
862
- }
863
- pdf.font "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
864
- text_box = described_class.new(text, options)
865
- text_box.render
866
- expect(text_box.text.delete("\n")).to eq(text)
867
- end
868
- end
869
-
870
- describe 'drawing bounding boxes' do
871
- it 'restores the margin box when bounding box exits' do
872
- margin_box = pdf.bounds
873
-
874
- pdf.text_box 'Oh hai text box. ' * 11, height: pdf.font.height * 10
875
-
876
- expect(pdf.bounds).to eq(margin_box)
877
- end
878
- end
879
-
880
- describe '#render with :character_spacing option' do
881
- it 'draws the character spacing to the document' do
882
- string = 'hello world'
883
- options = { document: pdf, character_spacing: 10 }
884
- text_box = described_class.new(string, options)
885
- text_box.render
886
- contents = PDF::Inspector::Text.analyze(pdf.render)
887
- expect(contents.character_spacing[0]).to eq(10)
888
- end
889
-
890
- it 'takes character spacing into account when wrapping' do
891
- pdf.font 'Courier'
892
- text_box = described_class.new(
893
- 'hello world',
894
- width: 100,
895
- overflow: :expand,
896
- character_spacing: 10,
897
- document: pdf
898
- )
899
- text_box.render
900
- expect(text_box.text).to eq("hello\nworld")
901
- end
902
- end
903
-
904
- describe 'wrapping' do
905
- it 'wraps text' do
906
- text = 'Please wrap this text about HERE. ' \
907
- 'More text that should be wrapped'
908
- expect = "Please wrap this text about\n"\
909
- "HERE. More text that should be\nwrapped"
910
-
911
- pdf.font 'Courier'
912
- text_box = described_class.new(
913
- text,
914
- width: 220,
915
- overflow: :expand,
916
- document: pdf
917
- )
918
- text_box.render
919
- expect(text_box.text).to eq(expect)
920
- end
921
-
922
- # white space was being stripped after the entire line was generated,
923
- # meaning that leading white space characters reduced the amount of space on
924
- # the line for other characters, so wrapping "hello hello" resulted in
925
- # "hello\n\nhello", rather than "hello\nhello"
926
- #
927
- it 'white space at beginning of line should not be taken into account ' \
928
- 'when computing line width' do
929
- text = 'hello hello'
930
- expect = "hello\nhello"
931
-
932
- pdf.font 'Courier'
933
- text_box = described_class.new(
934
- text,
935
- width: 40,
936
- overflow: :expand,
937
- document: pdf
938
- )
939
- text_box.render
940
- expect(text_box.text).to eq(expect)
941
- end
942
-
943
- it 'respects end of line when wrapping text' do
944
- text = "Please wrap only before\nTHIS word. Don't wrap this"
945
- expect = text
946
-
947
- pdf.font 'Courier'
948
- text_box = described_class.new(
949
- text,
950
- width: 220,
951
- overflow: :expand,
952
- document: pdf
953
- )
954
- text_box.render
955
- expect(text_box.text).to eq(expect)
956
- end
957
-
958
- it 'respects multiple newlines when wrapping text' do
959
- text = "Please wrap only before THIS\n\nword. Don't wrap this"
960
- expect = "Please wrap only before\nTHIS\n\nword. Don't wrap this"
961
-
962
- pdf.font 'Courier'
963
- text_box = described_class.new(
964
- text,
965
- width: 200,
966
- overflow: :expand,
967
- document: pdf
968
- )
969
- text_box.render
970
- expect(text_box.text).to eq(expect)
971
- end
972
-
973
- it 'respects multiple newlines when wrapping text when those newlines '\
974
- 'coincide with a line break' do
975
- text = "Please wrap only before\n\nTHIS word. Don't wrap this"
976
- expect = text
977
-
978
- pdf.font 'Courier'
979
- text_box = described_class.new(
980
- text,
981
- width: 220,
982
- overflow: :expand,
983
- document: pdf
984
- )
985
- text_box.render
986
- expect(text_box.text).to eq(expect)
987
- end
988
-
989
- it 'respects initial newlines' do
990
- text = "\nThis should be on line 2"
991
- expect = text
992
-
993
- pdf.font 'Courier'
994
- text_box = described_class.new(
995
- text,
996
- width: 220,
997
- overflow: :expand,
998
- document: pdf
999
- )
1000
- text_box.render
1001
- expect(text_box.text).to eq(expect)
1002
- end
1003
-
1004
- it 'wraps lines comprised of a single word of the bounds when '\
1005
- 'wrapping text' do
1006
- text = 'You_can_wrap_this_text_HERE'
1007
- expect = "You_can_wrap_this_text_HE\nRE"
1008
-
1009
- pdf.font 'Courier'
1010
- text_box = described_class.new(
1011
- text,
1012
- width: 180,
1013
- overflow: :expand,
1014
- document: pdf
1015
- )
1016
- text_box.render
1017
- expect(text_box.text).to eq(expect)
1018
- end
1019
-
1020
- it 'wraps lines comprised of a single non-alpha word of the bounds when '\
1021
- 'wrapping text' do
1022
- text = '©' * 30
1023
-
1024
- pdf.font 'Courier'
1025
- text_box = described_class.new(
1026
- text, width: 180,
1027
- overflow: :expand,
1028
- document: pdf
1029
- )
1030
-
1031
- text_box.render
1032
-
1033
- expected = +'©' * 25 + "\n" + '©' * 5
1034
- expected = pdf.font.normalize_encoding(expected)
1035
- expected = expected.force_encoding(Encoding::UTF_8)
1036
- expect(text_box.text).to eq(expected)
1037
- end
1038
-
1039
- it 'wraps non-unicode strings using single-byte word-wrapping' do
1040
- text = 'continúa esforzandote ' * 5
1041
- text_box = described_class.new(
1042
- text, width: 180,
1043
- document: pdf
1044
- )
1045
- text_box.render
1046
- results_with_accent = text_box.text
1047
-
1048
- text = 'continua esforzandote ' * 5
1049
- text_box = described_class.new(
1050
- text, width: 180,
1051
- document: pdf
1052
- )
1053
- text_box.render
1054
- results_without_accent = text_box.text
1055
-
1056
- expect(first_line(results_with_accent).length)
1057
- .to eq(first_line(results_without_accent).length)
1058
- end
1059
-
1060
- it 'allows you to disable wrapping by char' do
1061
- text = 'You_cannot_wrap_this_text_at_all_because_we_are_disabling_' \
1062
- 'wrapping_by_char_and_there_are_no_word_breaks'
1063
-
1064
- pdf.font 'Courier'
1065
- text_box = described_class.new(
1066
- text,
1067
- width: 180,
1068
- overflow: :shrink_to_fit,
1069
- disable_wrap_by_char: true,
1070
- document: pdf
1071
- )
1072
- expect { text_box.render }.to raise_error(Prawn::Errors::CannotFit)
1073
- end
1074
-
1075
- it 'retains full words with :shrink_to_fit if char wrapping is disabled' do
1076
- text = 'Wrapped_words'
1077
- expect = 'Wrapped_words'
1078
-
1079
- pdf.font 'Courier'
1080
- text_box = described_class.new(
1081
- text,
1082
- width: 50,
1083
- height: 50,
1084
- size: 50,
1085
- overflow: :shrink_to_fit,
1086
- disable_wrap_by_char: true,
1087
- document: pdf
1088
- )
1089
- text_box.render
1090
- expect(text_box.text).to eq(expect)
1091
- end
1092
- end
1093
-
1094
- describe 'Text::Box#render with :mode option' do
1095
- it 'alters the text rendering mode of the document' do
1096
- string = 'hello world'
1097
- options = { document: pdf, mode: :fill_stroke }
1098
- text_box = described_class.new(string, options)
1099
- text_box.render
1100
- contents = PDF::Inspector::Text.analyze(pdf.render)
1101
- expect(contents.text_rendering_mode).to eq([2, 0])
1102
- end
1103
- end
1104
-
1105
- def reduce_precision(float)
1106
- float.round(5)
1107
- end
1108
-
1109
- def first_line(str)
1110
- str.each_line { |line| return line }
1111
- end
1112
- end