prawn 2.0.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/GPLv2 +20 -21
  5. data/Gemfile +3 -9
  6. data/Rakefile +20 -23
  7. data/lib/prawn.rb +37 -49
  8. data/lib/prawn/document.rb +181 -133
  9. data/lib/prawn/document/bounding_box.rb +41 -29
  10. data/lib/prawn/document/column_box.rb +7 -7
  11. data/lib/prawn/document/internals.rb +18 -8
  12. data/lib/prawn/document/span.rb +21 -16
  13. data/lib/prawn/encoding.rb +69 -68
  14. data/lib/prawn/errors.rb +12 -7
  15. data/lib/prawn/font.rb +115 -69
  16. data/lib/prawn/font_metric_cache.rb +14 -8
  17. data/lib/prawn/{font → fonts}/afm.rb +102 -68
  18. data/lib/prawn/{font → fonts}/dfont.rb +5 -11
  19. data/lib/prawn/fonts/otf.rb +11 -0
  20. data/lib/prawn/fonts/ttc.rb +36 -0
  21. data/lib/prawn/{font → fonts}/ttf.rb +87 -68
  22. data/lib/prawn/graphics.rb +120 -80
  23. data/lib/prawn/graphics/blend_mode.rb +65 -0
  24. data/lib/prawn/graphics/cap_style.rb +3 -3
  25. data/lib/prawn/graphics/color.rb +27 -25
  26. data/lib/prawn/graphics/dash.rb +23 -11
  27. data/lib/prawn/graphics/join_style.rb +9 -3
  28. data/lib/prawn/graphics/patterns.rb +197 -67
  29. data/lib/prawn/graphics/transformation.rb +17 -8
  30. data/lib/prawn/graphics/transparency.rb +17 -13
  31. data/lib/prawn/grid.rb +48 -47
  32. data/lib/prawn/image_handler.rb +5 -5
  33. data/lib/prawn/images.rb +39 -30
  34. data/lib/prawn/images/image.rb +2 -1
  35. data/lib/prawn/images/jpg.rb +28 -22
  36. data/lib/prawn/images/png.rb +107 -66
  37. data/lib/prawn/measurement_extensions.rb +10 -9
  38. data/lib/prawn/measurements.rb +19 -15
  39. data/lib/prawn/outline.rb +97 -77
  40. data/lib/prawn/repeater.rb +14 -10
  41. data/lib/prawn/security.rb +81 -61
  42. data/lib/prawn/security/arcfour.rb +2 -2
  43. data/lib/prawn/soft_mask.rb +26 -26
  44. data/lib/prawn/stamp.rb +20 -13
  45. data/lib/prawn/text.rb +68 -52
  46. data/lib/prawn/text/box.rb +11 -8
  47. data/lib/prawn/text/formatted.rb +5 -5
  48. data/lib/prawn/text/formatted/arranger.rb +78 -49
  49. data/lib/prawn/text/formatted/box.rb +134 -100
  50. data/lib/prawn/text/formatted/fragment.rb +11 -14
  51. data/lib/prawn/text/formatted/line_wrap.rb +121 -63
  52. data/lib/prawn/text/formatted/parser.rb +139 -117
  53. data/lib/prawn/text/formatted/wrap.rb +43 -31
  54. data/lib/prawn/transformation_stack.rb +44 -0
  55. data/lib/prawn/utilities.rb +7 -22
  56. data/lib/prawn/version.rb +2 -2
  57. data/lib/prawn/view.rb +17 -7
  58. data/manual/basic_concepts/adding_pages.rb +6 -7
  59. data/manual/basic_concepts/basic_concepts.rb +31 -22
  60. data/manual/basic_concepts/creation.rb +10 -11
  61. data/manual/basic_concepts/cursor.rb +4 -5
  62. data/manual/basic_concepts/measurement.rb +6 -7
  63. data/manual/basic_concepts/origin.rb +5 -6
  64. data/manual/basic_concepts/other_cursor_helpers.rb +11 -12
  65. data/manual/basic_concepts/view.rb +22 -16
  66. data/manual/bounding_box/bounding_box.rb +29 -24
  67. data/manual/bounding_box/bounds.rb +11 -12
  68. data/manual/bounding_box/canvas.rb +4 -5
  69. data/manual/bounding_box/creation.rb +6 -7
  70. data/manual/bounding_box/indentation.rb +14 -15
  71. data/manual/bounding_box/nesting.rb +24 -17
  72. data/manual/bounding_box/russian_boxes.rb +14 -13
  73. data/manual/bounding_box/stretchy.rb +12 -13
  74. data/manual/contents.rb +28 -22
  75. data/manual/cover.rb +33 -28
  76. data/manual/document_and_page_options/background.rb +11 -13
  77. data/manual/document_and_page_options/document_and_page_options.rb +25 -20
  78. data/manual/document_and_page_options/metadata.rb +18 -16
  79. data/manual/document_and_page_options/page_margins.rb +18 -20
  80. data/manual/document_and_page_options/page_size.rb +13 -12
  81. data/manual/document_and_page_options/print_scaling.rb +17 -15
  82. data/manual/example_helper.rb +5 -4
  83. data/manual/graphics/blend_mode.rb +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 +4 -5
  88. data/manual/graphics/fill_rules.rb +9 -10
  89. data/manual/graphics/gradients.rb +27 -21
  90. data/manual/graphics/graphics.rb +48 -39
  91. data/manual/graphics/helper.rb +12 -9
  92. data/manual/graphics/line_width.rb +8 -7
  93. data/manual/graphics/lines_and_curves.rb +7 -8
  94. data/manual/graphics/polygon.rb +6 -8
  95. data/manual/graphics/rectangle.rb +4 -5
  96. data/manual/graphics/rotate.rb +6 -7
  97. data/manual/graphics/scale.rb +14 -15
  98. data/manual/graphics/soft_masks.rb +4 -5
  99. data/manual/graphics/stroke_cap.rb +6 -7
  100. data/manual/graphics/stroke_dash.rb +11 -12
  101. data/manual/graphics/stroke_join.rb +5 -6
  102. data/manual/graphics/translate.rb +9 -10
  103. data/manual/graphics/transparency.rb +7 -8
  104. data/manual/how_to_read_this_manual.rb +6 -6
  105. data/manual/images/absolute_position.rb +6 -7
  106. data/manual/images/fit.rb +7 -8
  107. data/manual/images/horizontal.rb +9 -10
  108. data/manual/images/images.rb +28 -24
  109. data/manual/images/plain_image.rb +5 -6
  110. data/manual/images/scale.rb +9 -10
  111. data/manual/images/vertical.rb +13 -14
  112. data/manual/images/width_and_height.rb +10 -11
  113. data/manual/layout/boxes.rb +5 -6
  114. data/manual/layout/content.rb +7 -8
  115. data/manual/layout/layout.rb +18 -16
  116. data/manual/layout/simple_grid.rb +6 -7
  117. data/manual/outline/add_subsection_to.rb +20 -21
  118. data/manual/outline/insert_section_after.rb +15 -16
  119. data/manual/outline/outline.rb +21 -17
  120. data/manual/outline/sections_and_pages.rb +17 -18
  121. data/manual/repeatable_content/alternate_page_numbering.rb +21 -17
  122. data/manual/repeatable_content/page_numbering.rb +17 -16
  123. data/manual/repeatable_content/repeatable_content.rb +25 -19
  124. data/manual/repeatable_content/repeater.rb +14 -15
  125. data/manual/repeatable_content/stamp.rb +14 -15
  126. data/manual/security/encryption.rb +9 -10
  127. data/manual/security/permissions.rb +19 -14
  128. data/manual/security/security.rb +19 -16
  129. data/manual/table.rb +3 -3
  130. data/manual/text/alignment.rb +16 -17
  131. data/manual/text/color.rb +12 -11
  132. data/manual/text/column_box.rb +9 -10
  133. data/manual/text/fallback_fonts.rb +25 -21
  134. data/manual/text/font.rb +11 -12
  135. data/manual/text/font_size.rb +13 -14
  136. data/manual/text/font_style.rb +7 -8
  137. data/manual/text/formatted_callbacks.rb +25 -21
  138. data/manual/text/formatted_text.rb +33 -25
  139. data/manual/text/free_flowing_text.rb +20 -21
  140. data/manual/text/inline.rb +18 -19
  141. data/manual/text/kerning_and_character_spacing.rb +14 -15
  142. data/manual/text/leading.rb +7 -8
  143. data/manual/text/line_wrapping.rb +37 -18
  144. data/manual/text/paragraph_indentation.rb +13 -14
  145. data/manual/text/positioned_text.rb +15 -16
  146. data/manual/text/registering_families.rb +20 -21
  147. data/manual/text/rendering_and_color.rb +9 -10
  148. data/manual/text/right_to_left_text.rb +26 -19
  149. data/manual/text/rotation.rb +28 -23
  150. data/manual/text/single_usage.rb +8 -9
  151. data/manual/text/text.rb +57 -52
  152. data/manual/text/text_box_excess.rb +20 -17
  153. data/manual/text/text_box_extensions.rb +18 -15
  154. data/manual/text/text_box_overflow.rb +18 -19
  155. data/manual/text/utf8.rb +11 -12
  156. data/manual/text/win_ansi_charset.rb +21 -19
  157. data/prawn.gemspec +45 -33
  158. data/spec/extensions/encoding_helpers.rb +3 -3
  159. data/spec/prawn/document/bounding_box_spec.rb +546 -0
  160. data/spec/prawn/document/column_box_spec.rb +75 -0
  161. data/spec/prawn/document/security_spec.rb +176 -0
  162. data/spec/prawn/document_annotations_spec.rb +76 -0
  163. data/spec/prawn/document_destinations_spec.rb +15 -0
  164. data/spec/prawn/document_grid_spec.rb +99 -0
  165. data/spec/prawn/document_reference_spec.rb +27 -0
  166. data/spec/prawn/document_span_spec.rb +36 -0
  167. data/spec/prawn/document_spec.rb +802 -0
  168. data/spec/prawn/font_metric_cache_spec.rb +54 -0
  169. data/spec/prawn/font_spec.rb +542 -0
  170. data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
  171. data/spec/prawn/graphics/transparency_spec.rb +81 -0
  172. data/spec/prawn/graphics_spec.rb +837 -0
  173. data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
  174. data/spec/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 +224 -0
  178. data/spec/prawn/measurements_extensions_spec.rb +24 -0
  179. data/spec/prawn/outline_spec.rb +412 -0
  180. data/spec/prawn/repeater_spec.rb +165 -0
  181. data/spec/prawn/soft_mask_spec.rb +74 -0
  182. data/spec/prawn/stamp_spec.rb +172 -0
  183. data/spec/prawn/text/box_spec.rb +1112 -0
  184. data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
  185. data/spec/prawn/text/formatted/box_spec.rb +846 -0
  186. data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
  187. data/spec/prawn/text/formatted/line_wrap_spec.rb +494 -0
  188. data/spec/prawn/text/formatted/parser_spec.rb +697 -0
  189. data/spec/prawn/text_draw_text_spec.rb +149 -0
  190. data/spec/prawn/text_rendering_mode_spec.rb +48 -0
  191. data/spec/prawn/text_spacing_spec.rb +95 -0
  192. data/spec/prawn/text_spec.rb +603 -0
  193. data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
  194. data/spec/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 -23
  198. metadata +145 -185
  199. metadata.gz.sig +4 -0
  200. data/data/images/16bit.alpha +0 -0
  201. data/data/images/16bit.color +0 -0
  202. data/data/images/16bit.png +0 -0
  203. data/data/images/arrow.png +0 -0
  204. data/data/images/arrow2.png +0 -0
  205. data/data/images/dice.alpha +0 -0
  206. data/data/images/dice.color +0 -0
  207. data/data/images/dice.png +0 -0
  208. data/data/images/dice_interlaced.png +0 -0
  209. data/data/images/fractal.jpg +0 -0
  210. data/data/images/indexed_color.dat +0 -0
  211. data/data/images/indexed_color.png +0 -0
  212. data/data/images/letterhead.jpg +0 -0
  213. data/data/images/license.md +0 -8
  214. data/data/images/page_white_text.alpha +0 -0
  215. data/data/images/page_white_text.color +0 -0
  216. data/data/images/page_white_text.png +0 -0
  217. data/data/images/pal_bk.png +0 -0
  218. data/data/images/pigs.jpg +0 -0
  219. data/data/images/prawn.png +0 -0
  220. data/data/images/ruport.png +0 -0
  221. data/data/images/ruport_data.dat +0 -0
  222. data/data/images/ruport_transparent.png +0 -0
  223. data/data/images/ruport_type0.png +0 -0
  224. data/data/images/stef.jpg +0 -0
  225. data/data/images/tru256.bmp +0 -0
  226. data/data/images/web-links.dat +0 -1
  227. data/data/images/web-links.png +0 -0
  228. data/data/pdfs/complex_template.pdf +0 -0
  229. data/data/pdfs/contains_ttf_font.pdf +0 -0
  230. data/data/pdfs/encrypted.pdf +0 -0
  231. data/data/pdfs/form.pdf +1 -819
  232. data/data/pdfs/hexagon.pdf +0 -61
  233. data/data/pdfs/indirect_reference.pdf +0 -86
  234. data/data/pdfs/multipage_template.pdf +0 -127
  235. data/data/pdfs/nested_pages.pdf +0 -118
  236. data/data/pdfs/page_without_mediabox.pdf +0 -193
  237. data/data/pdfs/resources_as_indirect_object.pdf +0 -83
  238. data/data/pdfs/two_hexagons.pdf +0 -90
  239. data/data/pdfs/version_1_6.pdf +0 -61
  240. data/data/shift_jis_text.txt +0 -1
  241. data/spec/acceptance/png.rb +0 -24
  242. data/spec/annotations_spec.rb +0 -67
  243. data/spec/bounding_box_spec.rb +0 -501
  244. data/spec/column_box_spec.rb +0 -59
  245. data/spec/destinations_spec.rb +0 -13
  246. data/spec/document_spec.rb +0 -742
  247. data/spec/extensions/mocha.rb +0 -45
  248. data/spec/font_metric_cache_spec.rb +0 -52
  249. data/spec/font_spec.rb +0 -475
  250. data/spec/formatted_text_arranger_spec.rb +0 -423
  251. data/spec/formatted_text_box_spec.rb +0 -716
  252. data/spec/formatted_text_fragment_spec.rb +0 -299
  253. data/spec/graphics_spec.rb +0 -666
  254. data/spec/grid_spec.rb +0 -95
  255. data/spec/image_handler_spec.rb +0 -53
  256. data/spec/images_spec.rb +0 -167
  257. data/spec/inline_formatted_text_parser_spec.rb +0 -568
  258. data/spec/jpg_spec.rb +0 -23
  259. data/spec/line_wrap_spec.rb +0 -366
  260. data/spec/measurement_units_spec.rb +0 -22
  261. data/spec/outline_spec.rb +0 -409
  262. data/spec/png_spec.rb +0 -235
  263. data/spec/reference_spec.rb +0 -25
  264. data/spec/repeater_spec.rb +0 -154
  265. data/spec/security_spec.rb +0 -151
  266. data/spec/soft_mask_spec.rb +0 -78
  267. data/spec/span_spec.rb +0 -43
  268. data/spec/stamp_spec.rb +0 -179
  269. data/spec/stroke_styles_spec.rb +0 -208
  270. data/spec/text_at_spec.rb +0 -142
  271. data/spec/text_box_spec.rb +0 -1038
  272. data/spec/text_rendering_mode_spec.rb +0 -45
  273. data/spec/text_spacing_spec.rb +0 -93
  274. data/spec/text_spec.rb +0 -549
  275. data/spec/text_with_inline_formatting_spec.rb +0 -35
  276. data/spec/transparency_spec.rb +0 -91
  277. data/spec/view_spec.rb +0 -42
@@ -1,45 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
-
5
- describe "#text_rendering_mode" do
6
- it "should draw the text rendering mode to the document" do
7
- create_pdf
8
- @pdf.text_rendering_mode(:stroke) do
9
- @pdf.text("hello world")
10
- end
11
- contents = PDF::Inspector::Text.analyze(@pdf.render)
12
- expect(contents.text_rendering_mode.first).to eq(1)
13
- end
14
- it "should not draw the text rendering mode to the document" \
15
- " when the new mode matches the old" do
16
- create_pdf
17
- @pdf.text_rendering_mode(:fill) do
18
- @pdf.text("hello world")
19
- end
20
- contents = PDF::Inspector::Text.analyze(@pdf.render)
21
- expect(contents.text_rendering_mode).to be_empty
22
- end
23
- it "should restore character spacing to 0" do
24
- create_pdf
25
- @pdf.text_rendering_mode(:stroke) do
26
- @pdf.text("hello world")
27
- end
28
- contents = PDF::Inspector::Text.analyze(@pdf.render)
29
- expect(contents.text_rendering_mode).to eq([1, 0])
30
- end
31
- it "should function as an accessor when no parameter given" do
32
- create_pdf
33
- @pdf.text_rendering_mode(:fill_stroke) do
34
- @pdf.text("hello world")
35
- expect(@pdf.text_rendering_mode).to eq(:fill_stroke)
36
- end
37
- expect(@pdf.text_rendering_mode).to eq(:fill)
38
- end
39
- it "should raise_error an exception when passed an invalid mode" do
40
- create_pdf
41
- expect { @pdf.text_rendering_mode(-1) }.to raise_error(ArgumentError)
42
- expect { @pdf.text_rendering_mode(8) }.to raise_error(ArgumentError)
43
- expect { @pdf.text_rendering_mode(:flil) }.to raise_error(ArgumentError)
44
- end
45
- end
@@ -1,93 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
-
5
- describe "#character_spacing" do
6
- it "should draw the character spacing to the document" do
7
- create_pdf
8
- @pdf.character_spacing(10.555555) do
9
- @pdf.text("hello world")
10
- end
11
- contents = PDF::Inspector::Text.analyze(@pdf.render)
12
- expect(contents.character_spacing.first).to eq(10.5556)
13
- end
14
- it "should not draw the character spacing to the document" \
15
- " when the new character spacing matches the old" do
16
- create_pdf
17
- @pdf.character_spacing(0) do
18
- @pdf.text("hello world")
19
- end
20
- contents = PDF::Inspector::Text.analyze(@pdf.render)
21
- expect(contents.character_spacing).to be_empty
22
- end
23
- it "should restore character spacing to 0" do
24
- create_pdf
25
- @pdf.character_spacing(10.555555) do
26
- @pdf.text("hello world")
27
- end
28
- contents = PDF::Inspector::Text.analyze(@pdf.render)
29
- expect(contents.character_spacing.last).to eq(0)
30
- end
31
- it "should function as an accessor when no parameter given" do
32
- create_pdf
33
- @pdf.character_spacing(10.555555) do
34
- @pdf.text("hello world")
35
- expect(@pdf.character_spacing).to eq(10.555555)
36
- end
37
- expect(@pdf.character_spacing).to eq(0)
38
- end
39
-
40
- # ensure that we properly internationalize by using the number of characters
41
- # in a string, not the number of bytes, to insert character spaces
42
- #
43
- it "should calculate character spacing widths by characters, not bytes" do
44
- create_pdf
45
- @pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
46
-
47
- str = "こんにちは世界"
48
- @pdf.character_spacing(0) do
49
- @raw_width = @pdf.width_of(str)
50
- end
51
-
52
- @pdf.character_spacing(10) do
53
- # the new width should include seven 10-pt character spaces.
54
- expect(@pdf.width_of(str)).to be_within(0.001).of(@raw_width + (10 * 7))
55
- end
56
- end
57
- end
58
-
59
- describe "#word_spacing" do
60
- it "should draw the word spacing to the document" do
61
- create_pdf
62
- @pdf.word_spacing(10.555555) do
63
- @pdf.text("hello world")
64
- end
65
- contents = PDF::Inspector::Text.analyze(@pdf.render)
66
- expect(contents.word_spacing.first).to eq(10.5556)
67
- end
68
- it "should draw the word spacing to the document" \
69
- " when the new word spacing matches the old" do
70
- create_pdf
71
- @pdf.word_spacing(0) do
72
- @pdf.text("hello world")
73
- end
74
- contents = PDF::Inspector::Text.analyze(@pdf.render)
75
- expect(contents.word_spacing).to be_empty
76
- end
77
- it "should restore word spacing to 0" do
78
- create_pdf
79
- @pdf.word_spacing(10.555555) do
80
- @pdf.text("hello world")
81
- end
82
- contents = PDF::Inspector::Text.analyze(@pdf.render)
83
- expect(contents.word_spacing.last).to eq(0)
84
- end
85
- it "should function as an accessor when no parameter given" do
86
- create_pdf
87
- @pdf.word_spacing(10.555555) do
88
- @pdf.text("hello world")
89
- expect(@pdf.word_spacing).to eq(10.555555)
90
- end
91
- expect(@pdf.word_spacing).to eq(0)
92
- end
93
- end
@@ -1,549 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
-
5
- describe "Prawn::Text::NBSP" do
6
- it "should be defined" do
7
- expect(Prawn::Text::NBSP).to eq(" ")
8
- end
9
- end
10
-
11
- describe "#height_of" do
12
- before(:each) { create_pdf }
13
-
14
- it "should return the height that would be required to print a" \
15
- "particular string of text" do
16
- original_y = @pdf.y
17
- @pdf.text("Foo")
18
- new_y = @pdf.y
19
- expect(@pdf.height_of("Foo")).to be_within(0.0001).of(original_y - new_y)
20
- end
21
-
22
- it "should omit the gap below the last descender if :final_gap => false " \
23
- "is given" do
24
- original_y = @pdf.y
25
- @pdf.text("Foo", :final_gap => false)
26
- new_y = @pdf.y
27
- expect(@pdf.height_of("Foo", :final_gap => false)).to be_within(0.0001).of(original_y - new_y)
28
- end
29
-
30
- it "should raise_error CannotFit if a too-small width is given" do
31
- expect do
32
- @pdf.height_of("text", :width => 1)
33
- end.to raise_error(Prawn::Errors::CannotFit)
34
- end
35
-
36
- it "should raise_error NotImplementedError if :indent_paragraphs option is provided" do
37
- expect {
38
- @pdf.height_of("hai", :width => 300,
39
- :indent_paragraphs => 60)
40
- }.to raise_error(NotImplementedError)
41
- end
42
-
43
- it "should_not raise_error Prawn::Errors::UnknownOption if :final_gap option is provided" do
44
- @pdf.height_of("hai", :width => 300, :final_gap => true)
45
- end
46
- end
47
-
48
- describe "#text" do
49
- before(:each) { create_pdf }
50
-
51
- it "should not fail when @output is nil when PDF::Core::Text::LineWrap#finalize_line is called" do
52
- # need a document with margins for these particulars to produce the
53
- # condition that was throwing the error
54
- pdf = Prawn::Document.new
55
- pdf.text "transparency " * 150, :size => 18
56
- end
57
-
58
- it "should allow drawing empty strings to the page" do
59
- @pdf.text " "
60
- text = PDF::Inspector::Text.analyze(@pdf.render)
61
- # If anything is rendered to the page, it should be whitespace.
62
- text.strings.each { |str| expect(str).to match(/\A\s*\z/) }
63
- end
64
-
65
- it "should ignore call when string is nil" do
66
- expect(@pdf.text(nil)).to be_false
67
- end
68
-
69
- it "should correctly render empty paragraphs" do
70
- @pdf.text "text\n\ntext"
71
- text = PDF::Inspector::Text.analyze(@pdf.render)
72
- expect(@pdf.page_count).to eq(1)
73
- expect(text.strings.reject(&:empty?)).to eq(["text", "text"])
74
- end
75
-
76
- it "should correctly render empty paragraphs with :indent_paragraphs" do
77
- @pdf.text "text\n\ntext", :indent_paragraphs => 5
78
- text = PDF::Inspector::Text.analyze(@pdf.render)
79
- expect(@pdf.page_count).to eq(1)
80
- expect(text.strings.reject(&:empty?)).to eq(["text", "text"])
81
- end
82
-
83
- it "should correctly render strings ending with empty paragraphs and " \
84
- ":inline_format and :indent_paragraphs" do
85
- @pdf.text "text\n\n", :inline_format => true, :indent_paragraphs => 5
86
- text = PDF::Inspector::Text.analyze(@pdf.render)
87
- expect(@pdf.page_count).to eq(1)
88
- expect(text.strings).to eq(["text"])
89
- end
90
-
91
- it "should default to use kerning information" do
92
- @pdf.text "hello world"
93
- text = PDF::Inspector::Text.analyze(@pdf.render)
94
- expect(text.kerned[0]).to be_true
95
- end
96
-
97
- it "should be able to disable kerning with an option" do
98
- @pdf.text "hello world", :kerning => false
99
- text = PDF::Inspector::Text.analyze(@pdf.render)
100
- expect(text.kerned[0]).to be_false
101
- end
102
-
103
- it "should be able to disable kerning document-wide" do
104
- @pdf.default_kerning(false)
105
- @pdf.default_kerning = false
106
- @pdf.text "hello world"
107
- text = PDF::Inspector::Text.analyze(@pdf.render)
108
- expect(text.kerned[0]).to be_false
109
- end
110
-
111
- it "option should be able to override document-wide kerning disabling" do
112
- @pdf.default_kerning = false
113
- @pdf.text "hello world", :kerning => true
114
- text = PDF::Inspector::Text.analyze(@pdf.render)
115
- expect(text.kerned[0]).to be_true
116
- end
117
-
118
- it "should raise_error ArgumentError if :at option included" do
119
- expect { @pdf.text("hai", :at => [0, 0]) }.to raise_error(ArgumentError)
120
- end
121
-
122
- it "should advance down the document based on font_height" do
123
- position = @pdf.y
124
- @pdf.text "Foo"
125
-
126
- expect(@pdf.y).to be_within(0.0001).of(position - @pdf.font.height)
127
-
128
- position = @pdf.y
129
- @pdf.text "Foo\nBar\nBaz"
130
- expect(@pdf.y).to be_within(0.0001).of(position - 3 * @pdf.font.height)
131
- end
132
-
133
- it "should advance down the document based on font_height with size option" do
134
- position = @pdf.y
135
- @pdf.text "Foo", :size => 15
136
-
137
- @pdf.font_size = 15
138
- expect(@pdf.y).to be_within(0.0001).of(position - @pdf.font.height)
139
-
140
- position = @pdf.y
141
- @pdf.text "Foo\nBar\nBaz"
142
- expect(@pdf.y).to be_within(0.0001).of(position - 3 * @pdf.font.height)
143
- end
144
-
145
- it "should advance down the document based on font_height with leading option" do
146
- position = @pdf.y
147
- leading = 2
148
- @pdf.text "Foo", :leading => leading
149
-
150
- expect(@pdf.y).to be_within(0.0001).of(position - @pdf.font.height - leading)
151
-
152
- position = @pdf.y
153
- @pdf.text "Foo\nBar\nBaz"
154
- expect(@pdf.y).to be_within(0.0001).of(position - 3 * @pdf.font.height)
155
- end
156
-
157
- it "should advance only to the bottom of the final descender if final_gap is false" do
158
- position = @pdf.y
159
- @pdf.text "Foo", :final_gap => false
160
-
161
- expect(@pdf.y).to be_within(0.0001).of(position - @pdf.font.ascender - @pdf.font.descender)
162
-
163
- position = @pdf.y
164
- @pdf.text "Foo\nBar\nBaz", :final_gap => false
165
- expect(@pdf.y).to be_within(0.0001).of(position - 2 * @pdf.font.height - @pdf.font.ascender - @pdf.font.descender)
166
- end
167
-
168
- it "should be able to print text starting at the last line of a page" do
169
- @pdf.move_cursor_to(@pdf.font.height)
170
- @pdf.text("hello world")
171
- pages = PDF::Inspector::Page.analyze(@pdf.render).pages
172
- expect(pages.size).to eq(1)
173
- end
174
-
175
- it "should default to 12 point helvetica" do
176
- @pdf.text "Blah"
177
- text = PDF::Inspector::Text.analyze(@pdf.render)
178
- expect(text.font_settings[0][:name]).to eq(:Helvetica)
179
- expect(text.font_settings[0][:size]).to eq(12)
180
- expect(text.strings.first).to eq("Blah")
181
- end
182
-
183
- it "should allow setting font size" do
184
- @pdf.text "Blah", :size => 16
185
- text = PDF::Inspector::Text.analyze(@pdf.render)
186
- expect(text.font_settings[0][:size]).to eq(16)
187
- end
188
-
189
- it "should allow setting a default font size" do
190
- @pdf.font_size = 16
191
- @pdf.text "Blah"
192
- text = PDF::Inspector::Text.analyze(@pdf.render)
193
- expect(text.font_settings[0][:size]).to eq(16)
194
- end
195
-
196
- it "should allow overriding default font for a single instance" do
197
- @pdf.font_size = 16
198
-
199
- @pdf.text "Blah", :size => 11
200
- @pdf.text "Blaz"
201
- text = PDF::Inspector::Text.analyze(@pdf.render)
202
- expect(text.font_settings[0][:size]).to eq(11)
203
- expect(text.font_settings[1][:size]).to eq(16)
204
- end
205
-
206
- it "should allow setting a font size transaction with a block" do
207
- @pdf.font_size 16 do
208
- @pdf.text 'Blah'
209
- end
210
-
211
- @pdf.text 'blah'
212
-
213
- text = PDF::Inspector::Text.analyze(@pdf.render)
214
- expect(text.font_settings[0][:size]).to eq(16)
215
- expect(text.font_settings[1][:size]).to eq(12)
216
- end
217
-
218
- it "should allow manual setting the font size when in a font size block" do
219
- @pdf.font_size(16) do
220
- @pdf.text 'Foo'
221
- @pdf.text 'Blah', :size => 11
222
- @pdf.text 'Blaz'
223
- end
224
- text = PDF::Inspector::Text.analyze(@pdf.render)
225
- expect(text.font_settings[0][:size]).to eq(16)
226
- expect(text.font_settings[1][:size]).to eq(11)
227
- expect(text.font_settings[2][:size]).to eq(16)
228
- end
229
-
230
- it "should allow registering of built-in font_settings on the fly" do
231
- @pdf.font "Times-Roman"
232
- @pdf.text "Blah"
233
- @pdf.font "Courier"
234
- @pdf.text "Blaz"
235
- text = PDF::Inspector::Text.analyze(@pdf.render)
236
- expect(text.font_settings[0][:name]).to eq(:"Times-Roman")
237
- expect(text.font_settings[1][:name]).to eq(:Courier)
238
- end
239
-
240
- it "should utilise the same default font across multiple pages" do
241
- @pdf.text "Blah"
242
- @pdf.start_new_page
243
- @pdf.text "Blaz"
244
- text = PDF::Inspector::Text.analyze(@pdf.render)
245
-
246
- expect(text.font_settings.size).to eq(2)
247
- expect(text.font_settings[0][:name]).to eq(:Helvetica)
248
- expect(text.font_settings[1][:name]).to eq(:Helvetica)
249
- end
250
-
251
- it "should raise_error an exception when an unknown font is used" do
252
- expect { @pdf.font "Pao bu" }.to raise_error(Prawn::Errors::UnknownFont)
253
- end
254
-
255
- it "should_not raise_error an exception when providing Pathname instance as font" do
256
- @pdf.font Pathname.new("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
257
- end
258
-
259
- it "should correctly render a utf-8 string when using a built-in font" do
260
- str = "©" # copyright symbol
261
- @pdf.text str
262
-
263
- # grab the text from the rendered PDF and ensure it matches
264
- text = PDF::Inspector::Text.analyze(@pdf.render)
265
- expect(text.strings.first).to eq(str)
266
- end
267
-
268
- it "should correctly render a utf-8 string when using a TTF font" do
269
- str = "©" # copyright symbol
270
- @pdf.font "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
271
- @pdf.text str
272
-
273
- # grab the text from the rendered PDF and ensure it matches
274
- text = PDF::Inspector::Text.analyze(@pdf.render)
275
- expect(text.strings.first).to eq(str)
276
- end
277
-
278
- it "subsets mixed low-ASCII and non-ASCII characters when they can be subsetted together" do
279
- str = "It’s super effective!"
280
- @pdf.font "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
281
- @pdf.text str
282
-
283
- text = PDF::Inspector::Text.analyze(@pdf.render)
284
- expect(text.strings.first).to eq(str)
285
- end
286
-
287
- it "should correctly render a string with higher bit characters across a page break when using a built-in font" do
288
- str = "©"
289
- @pdf.move_cursor_to(@pdf.font.height)
290
- @pdf.text(str + "\n" + str)
291
-
292
- pages = PDF::Inspector::Page.analyze(@pdf.render).pages
293
- expect(pages.size).to eq(2)
294
- expect(pages[0][:strings]).to eq([str])
295
- expect(pages[1][:strings]).to eq([str])
296
- end
297
-
298
- it "should correctly render a string with higher bit characters across" \
299
- " a page break when using a built-in font and :indent_paragraphs option" do
300
- str = "©"
301
- @pdf.move_cursor_to(@pdf.font.height)
302
- @pdf.text(str + "\n" + str, :indent_paragraphs => 20)
303
-
304
- pages = PDF::Inspector::Page.analyze(@pdf.render).pages
305
- expect(pages.size).to eq(2)
306
- expect(pages[0][:strings]).to eq([str])
307
- expect(pages[1][:strings]).to eq([str])
308
- end
309
-
310
- it "should raise_error an exception when a utf-8 incompatible string is rendered" do
311
- str = "Blah \xDD"
312
- expect { @pdf.text str }.to raise_error(
313
- Prawn::Errors::IncompatibleStringEncoding)
314
- end
315
-
316
- it "should_not raise_error an exception when a shift-jis string is rendered" do
317
- datafile = "#{Prawn::DATADIR}/shift_jis_text.txt"
318
- sjis_str = File.open(datafile, "r:shift_jis") { |f| f.gets }
319
- @pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
320
-
321
- # Expect that the call to text will not raise an encoding error
322
- @pdf.text(sjis_str)
323
- end
324
-
325
- it "should call move_past_bottom when printing more text than can fit" \
326
- " between the current document.y and bounds.bottom" do
327
- @pdf.y = @pdf.font.height
328
- @pdf.text "Hello"
329
- @pdf.text "World"
330
- pages = PDF::Inspector::Page.analyze(@pdf.render).pages
331
- expect(pages.size).to eq(2)
332
- expect(pages[0][:strings]).to eq(["Hello"])
333
- expect(pages[1][:strings]).to eq(["World"])
334
- end
335
-
336
- describe "with :indent_paragraphs option" do
337
- it "should indent the paragraphs" do
338
- hello = "hello " * 50
339
- hello2 = "hello " * 50
340
- @pdf.text(hello + "\n" + hello2, :indent_paragraphs => 60)
341
- text = PDF::Inspector::Text.analyze(@pdf.render)
342
- expect(text.strings[0]).to eq(("hello " * 19).strip)
343
- expect(text.strings[1]).to eq(("hello " * 21).strip)
344
- expect(text.strings[3]).to eq(("hello " * 19).strip)
345
- expect(text.strings[4]).to eq(("hello " * 21).strip)
346
- end
347
-
348
- it "should indent from right side when using :rtl direction" do
349
- para1 = "The rain in spain falls mainly on the plains " * 3
350
- para2 = "The rain in spain falls mainly on the plains " * 3
351
-
352
- @pdf.text(para1 + "\n" + para2, :indent_paragraphs => 60, :direction => :rtl)
353
-
354
- text = PDF::Inspector::Text.analyze(@pdf.render)
355
-
356
- lines = text.strings
357
- x_positions = text.positions.map { |e| e[0] }
358
-
359
- # NOTE: The code below reflects Prawn's current kerning behavior for RTL
360
- # text, which isn't necessarily correct. If we change that behavior,
361
- # this test will need to be updated.
362
-
363
- expect(x_positions[0]).to(
364
- be_within(0.001).of(@pdf.bounds.absolute_right - 60 -
365
- @pdf.width_of(lines[0].reverse, :kerning => true)))
366
-
367
- expect(x_positions[1]).to(
368
- be_within(0.001).of(@pdf.bounds.absolute_right -
369
- @pdf.width_of(lines[1].reverse, :kerning => true)))
370
-
371
- expect(x_positions[2]).to(
372
- be_within(0.001).of(@pdf.bounds.absolute_right - 60 -
373
- @pdf.width_of(lines[2].reverse, :kerning => true)))
374
-
375
- expect(x_positions[3]).to(
376
- be_within(0.001).of(@pdf.bounds.absolute_right -
377
- @pdf.width_of(lines[3].reverse, :kerning => true)))
378
- end
379
-
380
- it "should indent from right side when document has :rtl direction" do
381
- para1 = "The rain in spain falls mainly on the plains " * 3
382
- para2 = "The rain in spain falls mainly on the plains " * 3
383
-
384
- @pdf.text_direction = :rtl
385
- @pdf.text(para1 + "\n" + para2, :indent_paragraphs => 60)
386
-
387
- text = PDF::Inspector::Text.analyze(@pdf.render)
388
-
389
- lines = text.strings
390
- x_positions = text.positions.map { |e| e[0] }
391
-
392
- # NOTE: The code below reflects Prawn's current kerning behavior for RTL
393
- # text, which isn't necessarily correct. If we change that behavior,
394
- # this test will need to be updated.
395
-
396
- expect(x_positions[0]).to(
397
- be_within(0.001).of(@pdf.bounds.absolute_right - 60 -
398
- @pdf.width_of(lines[0].reverse, :kerning => true)))
399
-
400
- expect(x_positions[1]).to(
401
- be_within(0.001).of(@pdf.bounds.absolute_right -
402
- @pdf.width_of(lines[1].reverse, :kerning => true)))
403
-
404
- expect(x_positions[2]).to(
405
- be_within(0.001).of(@pdf.bounds.absolute_right - 60 -
406
- @pdf.width_of(lines[2].reverse, :kerning => true)))
407
-
408
- expect(x_positions[3]).to(
409
- be_within(0.001).of(@pdf.bounds.absolute_right -
410
- @pdf.width_of(lines[3].reverse, :kerning => true)))
411
- end
412
-
413
- it "should indent from left side when using :ltr direction" do
414
- para1 = "The rain in spain falls mainly on the plains " * 3
415
- para2 = "The rain in spain falls mainly on the plains " * 3
416
-
417
- @pdf.text(para1 + "\n" + para2, :indent_paragraphs => 60, :direction => :ltr)
418
-
419
- text = PDF::Inspector::Text.analyze(@pdf.render)
420
-
421
- x_positions = text.positions.map { |e| e[0] }
422
-
423
- expect(x_positions[0]).to eq(60)
424
- expect(x_positions[1]).to eq(0)
425
-
426
- expect(x_positions[2]).to eq(60)
427
- expect(x_positions[3]).to eq(0)
428
- end
429
-
430
- it "should indent from left side when document has :ltr direction" do
431
- para1 = "The rain in spain falls mainly on the plains " * 3
432
- para2 = "The rain in spain falls mainly on the plains " * 3
433
-
434
- @pdf.text_direction = :ltr
435
- @pdf.text(para1 + "\n" + para2, :indent_paragraphs => 60)
436
-
437
- text = PDF::Inspector::Text.analyze(@pdf.render)
438
-
439
- x_positions = text.positions.map { |e| e[0] }
440
-
441
- expect(x_positions[0]).to eq(60)
442
- expect(x_positions[1]).to eq(0)
443
-
444
- expect(x_positions[2]).to eq(60)
445
- expect(x_positions[3]).to eq(0)
446
- end
447
-
448
- describe "when wrap to new page, and first line of new page" \
449
- " is not the start of a new paragraph, that line should" \
450
- " not be indented" do
451
- it "should indent the paragraphs" do
452
- hello = "hello " * 50
453
- hello2 = "hello " * 50
454
- @pdf.move_cursor_to(@pdf.font.height)
455
- @pdf.text(hello + "\n" + hello2, :indent_paragraphs => 60)
456
- text = PDF::Inspector::Text.analyze(@pdf.render)
457
- expect(text.strings[0]).to eq(("hello " * 19).strip)
458
- expect(text.strings[1]).to eq(("hello " * 21).strip)
459
- expect(text.strings[3]).to eq(("hello " * 19).strip)
460
- expect(text.strings[4]).to eq(("hello " * 21).strip)
461
- end
462
- end
463
- describe "when wrap to new page, and first line of new page" \
464
- " is the start of a new paragraph, that line should" \
465
- " be indented" do
466
- it "should indent the paragraphs" do
467
- hello = "hello " * 50
468
- hello2 = "hello " * 50
469
- @pdf.move_cursor_to(@pdf.font.height * 3)
470
- @pdf.text(hello + "\n" + hello2, :indent_paragraphs => 60)
471
- text = PDF::Inspector::Text.analyze(@pdf.render)
472
- expect(text.strings[0]).to eq(("hello " * 19).strip)
473
- expect(text.strings[1]).to eq(("hello " * 21).strip)
474
- expect(text.strings[3]).to eq(("hello " * 19).strip)
475
- expect(text.strings[4]).to eq(("hello " * 21).strip)
476
- end
477
- end
478
- end
479
-
480
- describe "kerning" do
481
- it "should respect text kerning setting (document default)" do
482
- create_pdf
483
- @pdf.font.expects(:compute_width_of).with do |str, options|
484
- str == "VAT" && options[:kerning] == true
485
- end.at_least_once.returns(10)
486
- @pdf.text "VAT"
487
- end
488
-
489
- it "should respect text kerning setting (kerning=true)" do
490
- create_pdf
491
- @pdf.font.expects(:compute_width_of).with do |str, options|
492
- str == "VAT" && options[:kerning] == true
493
- end.at_least_once.returns(10)
494
- @pdf.text "VAT", :kerning => true
495
- end
496
-
497
- it "should respect text kerning setting (kerning=false)" do
498
- create_pdf
499
- @pdf.font.expects(:compute_width_of).with do |str, options|
500
- str == "VAT" && options[:kerning] == false
501
- end.at_least_once.returns(10)
502
- @pdf.text "VAT", :kerning => false
503
- end
504
- end
505
-
506
- describe "#shrink_to_fit with special utf-8 text" do
507
- it "Should not throw an exception", :unresolved, :issue => 603 do
508
- pages = 0
509
- doc = Prawn::Document.new(page_size: 'A4', margin: [2, 2, 2, 2]) do |pdf|
510
- add_unicode_fonts(pdf)
511
- pdf.bounding_box([1, 1], :width => 90, :height => 50) do
512
- broken_text = " Sample Text\nSAMPLE SAMPLE SAMPLEoddělení ZMĚN\nSAMPLE"
513
- pdf.text broken_text, :overflow => :shrink_to_fit
514
- end
515
- end
516
- end
517
- end
518
-
519
- def add_unicode_fonts(pdf)
520
- dejavu = "#{::Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
521
- pdf.font_families.update(
522
- "dejavu" => {
523
- :normal => dejavu,
524
- :italic => dejavu,
525
- :bold => dejavu,
526
- :bold_italic => dejavu
527
- }
528
- )
529
- pdf.fallback_fonts = ["dejavu"]
530
- end
531
-
532
- describe "fallback_fonts" do
533
- it "should preserve font style" do
534
- create_pdf
535
-
536
- @pdf.fallback_fonts ["Helvetica"]
537
- @pdf.font "Times-Roman", :style => :italic do
538
- @pdf.text "hello"
539
- end
540
-
541
- text = PDF::Inspector::Text.analyze(@pdf.render)
542
- fonts_used = text.font_settings.map { |e| e[:name] }
543
-
544
- expect(fonts_used.length).to eq(1)
545
- expect(fonts_used[0]).to eq(:"Times-Italic")
546
- expect(text.strings[0]).to eq("hello")
547
- end
548
- end
549
- end