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
- # Allow speccing things when an expectation matcher runs. Similar to #with, but
4
- # always succeeds.
5
- #
6
- # @pdf.expects(:stroke_line).checking do |from, to|
7
- # @pdf.map_to_absolute(from).should == [0, 0]
8
- # end
9
- #
10
- # Note that the outer expectation does *not* fail only because the inner one
11
- # does; in the above example, the outer expectation would only fail if
12
- # stroke_line were not called.
13
-
14
- class ParameterChecker < Mocha::ParametersMatcher
15
- def initialize(&matching_block)
16
- @expected_parameters = [Mocha::ParameterMatchers::AnyParameters.new]
17
- @matching_block = matching_block
18
- end
19
-
20
- def match?(actual_parameters = [])
21
- @matching_block.call(*actual_parameters)
22
-
23
- true # always succeed
24
- end
25
- end
26
-
27
- class Mocha::Expectation
28
- def checking(&block)
29
- @parameters_matcher = ParameterChecker.new(&block)
30
- self
31
- end
32
- end
33
-
34
- # Equivalent to expects(method_name).at_least(0). More useful when combined
35
- # with parameter matchers to ignore certain calls for the sake of parameter
36
- # matching.
37
- #
38
- # @pdf.ignores(:stroke_color=).with("000000")
39
- # @pdf.expects(:stroke_color=).with("ff0000")
40
- #
41
- module Mocha::ObjectMethods
42
- def ignores(method_name)
43
- expects(method_name).at_least(0)
44
- end
45
- end
@@ -1,52 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
- require 'pathname'
5
-
6
- describe "Font metrics caching" do
7
- let(:document) { Prawn::Document.new }
8
-
9
- subject { Prawn::FontMetricCache.new(document) }
10
-
11
- it "should start with an empty cache" do
12
- expect(subject.instance_variable_get(:@cache)).to be_empty
13
- end
14
-
15
- it "should cache the width of the provided string" do
16
- subject.width_of('M', {})
17
-
18
- expect(subject.instance_variable_get(:@cache).size).to eq(1)
19
- end
20
-
21
- it "should only cache a single copy of the same string" do
22
- subject.width_of('M', {})
23
- subject.width_of('M', {})
24
-
25
- expect(subject.instance_variable_get(:@cache).size).to eq(1)
26
- end
27
-
28
- it "should cache different copies for different strings" do
29
- subject.width_of('M', {})
30
- subject.width_of('W', {})
31
-
32
- expect(subject.instance_variable_get(:@cache).entries.size).to eq(2)
33
- end
34
-
35
- it "should cache different copies of the same string with different font sizes" do
36
- subject.width_of('M', {})
37
-
38
- document.font_size 24
39
- subject.width_of('M', {})
40
-
41
- expect(subject.instance_variable_get(:@cache).entries.size).to eq(2)
42
- end
43
-
44
- it "should cache different copies of the same string with different fonts" do
45
- subject.width_of('M', {})
46
-
47
- document.font 'Courier'
48
- subject.width_of('M', {})
49
-
50
- expect(subject.instance_variable_get(:@cache).entries.size).to eq(2)
51
- end
52
- end
@@ -1,475 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
- require 'pathname'
5
-
6
- describe "Font behavior" do
7
- it "should default to Helvetica if no font is specified" do
8
- @pdf = Prawn::Document.new
9
- expect(@pdf.font.name).to eq("Helvetica")
10
- end
11
- end
12
-
13
- describe "Font objects" do
14
- it "should be equal" do
15
- font1 = Prawn::Document.new.font
16
- font2 = Prawn::Document.new.font
17
-
18
- expect(font1).to eql(font2)
19
- end
20
-
21
- it "should always be the same key" do
22
- font1 = Prawn::Document.new.font
23
- font2 = Prawn::Document.new.font
24
-
25
- hash = {}
26
-
27
- hash[ font1 ] = "Original"
28
- hash[ font2 ] = "Overwritten"
29
-
30
- expect(hash.size).to eq(1)
31
-
32
- expect(hash[ font1 ]).to eq("Overwritten")
33
- expect(hash[ font2 ]).to eq("Overwritten")
34
- end
35
- end
36
-
37
- describe "#width_of" do
38
- it "should take character spacing into account" do
39
- create_pdf
40
- original_width = @pdf.width_of("hello world")
41
- @pdf.character_spacing(7) do
42
- expect(@pdf.width_of("hello world")).to eq(original_width + 11 * 7)
43
- end
44
- end
45
-
46
- it "should exclude newlines" do
47
- create_pdf
48
- # Use a TTF font that has a non-zero width for \n
49
- @pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
50
-
51
- expect(@pdf.width_of("\nhello world\n")).to eq(
52
- @pdf.width_of("hello world")
53
- )
54
- end
55
-
56
- it "should take formatting into account" do
57
- create_pdf
58
-
59
- normal_hello = @pdf.width_of("hello")
60
- inline_bold_hello = @pdf.width_of("<b>hello</b>", :inline_format => true)
61
- @pdf.font("Helvetica", :style => :bold) {
62
- @bold_hello = @pdf.width_of("hello")
63
- }
64
-
65
- expect(inline_bold_hello).to be > normal_hello
66
- expect(inline_bold_hello).to eq(@bold_hello)
67
- end
68
-
69
- it "should accept :style as an argument" do
70
- create_pdf
71
-
72
- styled_bold_hello = @pdf.width_of("hello", :style => :bold)
73
- @pdf.font("Helvetica", :style => :bold) {
74
- @bold_hello = @pdf.width_of("hello")
75
- }
76
-
77
- expect(styled_bold_hello).to eq(@bold_hello)
78
- end
79
-
80
- it "should calculate styled widths correctly using TTFs" do
81
- create_pdf
82
-
83
- @pdf.font_families.update(
84
- 'DejaVu Sans' => {
85
- :normal => "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf",
86
- :bold => "#{Prawn::DATADIR}/fonts/DejaVuSans-Bold.ttf"
87
- }
88
- )
89
- @pdf.font("DejaVu Sans") {
90
- @styled_bold_hello = @pdf.width_of("hello", :style => :bold)
91
- }
92
- @pdf.font("DejaVu Sans", :style => :bold) {
93
- @bold_hello = @pdf.width_of("hello")
94
- }
95
-
96
- @pdf.font("DejaVu Sans") {
97
- @plain_hello = @pdf.width_of("hello")
98
- }
99
-
100
- expect(@plain_hello).not_to eq(@bold_hello)
101
-
102
- expect(@styled_bold_hello).to eq(@bold_hello)
103
- end
104
-
105
- it "should not treat minus as if it were a hyphen", :issue => 578 do
106
- create_pdf
107
-
108
- expect(@pdf.width_of("-0.75")).to be < @pdf.width_of("25.00")
109
- end
110
- end
111
-
112
- describe "#font_size" do
113
- it "should allow setting font size in DSL style" do
114
- create_pdf
115
- @pdf.font_size 20
116
- expect(@pdf.font_size).to eq(20)
117
- end
118
- end
119
-
120
- describe "font style support" do
121
- before(:each) { create_pdf }
122
-
123
- it "should complain if there is no @current_page" do
124
- pdf_without_page = Prawn::Document.new(:skip_page_creation => true)
125
-
126
- expect{ pdf_without_page.font "Helvetica" }.
127
- to raise_error(Prawn::Errors::NotOnPage)
128
- end
129
-
130
- it "should allow specifying font style by style name and font family" do
131
- @pdf.font "Courier", :style => :bold
132
- @pdf.text "In Courier bold"
133
-
134
- @pdf.font "Courier", :style => :bold_italic
135
- @pdf.text "In Courier bold-italic"
136
-
137
- @pdf.font "Courier", :style => :italic
138
- @pdf.text "In Courier italic"
139
-
140
- @pdf.font "Courier", :style => :normal
141
- @pdf.text "In Normal Courier"
142
-
143
- @pdf.font "Helvetica"
144
- @pdf.text "In Normal Helvetica"
145
-
146
- text = PDF::Inspector::Text.analyze(@pdf.render)
147
- expect(text.font_settings.map { |e| e[:name] }).to eq(
148
- [
149
- :"Courier-Bold", :"Courier-BoldOblique", :"Courier-Oblique",
150
- :Courier, :Helvetica
151
- ]
152
- )
153
- end
154
-
155
- it "should allow font familes to be defined in a single dfont" do
156
- file = "#{Prawn::DATADIR}/fonts/Panic+Sans.dfont"
157
- @pdf.font_families["Panic Sans"] = {
158
- :normal => { :file => file, :font => "PanicSans" },
159
- :italic => { :file => file, :font => "PanicSans-Italic" },
160
- :bold => { :file => file, :font => "PanicSans-Bold" },
161
- :bold_italic => { :file => file, :font => "PanicSans-BoldItalic" }
162
- }
163
-
164
- @pdf.font "Panic Sans", :style => :italic
165
- @pdf.text "In PanicSans-Italic"
166
-
167
- text = PDF::Inspector::Text.analyze(@pdf.render)
168
- name = text.font_settings.map { |e| e[:name] }.first.to_s
169
- name = name.sub(/\w+\+/, "subset+")
170
- expect(name).to eq("subset+PanicSans-Italic")
171
- end
172
-
173
- it "should accept Pathname objects for font files" do
174
- file = Pathname.new("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
175
- @pdf.font_families["DejaVu Sans"] = {
176
- :normal => file
177
- }
178
-
179
- @pdf.font "DejaVu Sans"
180
- @pdf.text "In DejaVu Sans"
181
-
182
- text = PDF::Inspector::Text.analyze(@pdf.render)
183
- name = text.font_settings.map { |e| e[:name] }.first.to_s
184
- name = name.sub(/\w+\+/, "subset+")
185
- expect(name).to eq("subset+DejaVuSans")
186
- end
187
-
188
- it "should accept IO objects for font files" do
189
- io = File.open "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
190
- @pdf.font_families["DejaVu Sans"] = {
191
- normal: Prawn::Font.load(@pdf, io)
192
- }
193
-
194
- @pdf.font "DejaVu Sans"
195
- @pdf.text "In DejaVu Sans"
196
-
197
- text = PDF::Inspector::Text.analyze(@pdf.render)
198
- name = text.font_settings.map { |e| e[:name] }.first.to_s
199
- name = name.sub(/\w+\+/, "subset+")
200
- expect(name).to eq("subset+DejaVuSans")
201
- end
202
- end
203
-
204
- describe "Transactional font handling" do
205
- before(:each) { create_pdf }
206
-
207
- it "should allow setting of size directly when font is created" do
208
- @pdf.font "Courier", :size => 16
209
- expect(@pdf.font_size).to eq(16)
210
- end
211
-
212
- it "should allow temporary setting of a new font using a transaction" do
213
- @pdf.font "Helvetica", :size => 12
214
-
215
- @pdf.font "Courier", :size => 16 do
216
- expect(@pdf.font.name).to eq("Courier")
217
- expect(@pdf.font_size).to eq(16)
218
- end
219
-
220
- expect(@pdf.font.name).to eq("Helvetica")
221
- expect(@pdf.font_size).to eq(12)
222
- end
223
-
224
- it "should mask font size when using a transacation" do
225
- @pdf.font "Courier", :size => 16 do
226
- expect(@pdf.font_size).to eq(16)
227
- end
228
-
229
- @pdf.font "Times-Roman"
230
- @pdf.font "Courier"
231
-
232
- expect(@pdf.font_size).to eq(12)
233
- end
234
- end
235
-
236
- describe "Document#page_fonts" do
237
- before(:each) { create_pdf }
238
-
239
- it "should register fonts properly by page" do
240
- @pdf.font "Courier"
241
- @pdf.text("hello")
242
-
243
- @pdf.font "Helvetica"
244
- @pdf.text("hello")
245
-
246
- @pdf.font "Times-Roman"
247
- @pdf.text("hello")
248
-
249
- ["Courier", "Helvetica", "Times-Roman"].each { |f|
250
- page_should_include_font(f)
251
- }
252
-
253
- @pdf.start_new_page
254
-
255
- @pdf.font "Helvetica"
256
- @pdf.text("hello")
257
-
258
- page_should_include_font("Helvetica")
259
- page_should_not_include_font("Courier")
260
- page_should_not_include_font("Times-Roman")
261
- end
262
-
263
- def page_includes_font?(font)
264
- @pdf.page.fonts.values.map { |e| e.data[:BaseFont] }.include?(font.to_sym)
265
- end
266
-
267
- def page_should_include_font(font)
268
- expect(page_includes_font?(font)).to be_true
269
- end
270
-
271
- def page_should_not_include_font(font)
272
- expect(page_includes_font?(font)).to be_false
273
- end
274
- end
275
-
276
- describe "AFM fonts" do
277
- before do
278
- create_pdf
279
- @times = @pdf.find_font "Times-Roman"
280
- end
281
-
282
- it "should calculate string width taking into account accented characters" do
283
- input = win1252_string("\xE9") # é in win-1252
284
- expect(@times.compute_width_of(input, :size => 12)).to eq(@times.compute_width_of("e", :size => 12))
285
- end
286
-
287
- it "should calculate string width taking into account kerning pairs" do
288
- expect(@times.compute_width_of(win1252_string("To"), :size => 12)).to eq(13.332)
289
- expect(@times.compute_width_of(win1252_string("To"), :size => 12, :kerning => true)).to eq(12.372)
290
-
291
- input = win1252_string("T\xF6") # Tö in win-1252
292
- expect(@times.compute_width_of(input, :size => 12, :kerning => true)).to eq(12.372)
293
- end
294
-
295
- it "should encode text without kerning by default" do
296
- expect(@times.encode_text(win1252_string("To"))).to eq([[0, "To"]])
297
- input = win1252_string("T\xE9l\xE9") # Télé in win-1252
298
- expect(@times.encode_text(input)).to eq([[0, input]])
299
- expect(@times.encode_text(win1252_string("Technology"))).to eq([[0, "Technology"]])
300
- expect(@times.encode_text(win1252_string("Technology..."))).to eq([[0, "Technology..."]])
301
- end
302
-
303
- it "should encode text with kerning if requested" do
304
- expect(@times.encode_text(win1252_string("To"), :kerning => true)).to eq([[0, ["T", 80, "o"]]])
305
- input = win1252_string("T\xE9l\xE9") # Télé in win-1252
306
- output = win1252_string("\xE9l\xE9") # élé in win-1252
307
- expect(@times.encode_text(input, :kerning => true)).to eq([[0, ["T", 70, output]]])
308
- expect(@times.encode_text(win1252_string("Technology"), :kerning => true)).to eq([[0, ["T", 70, "echnology"]]])
309
- expect(@times.encode_text(win1252_string("Technology..."), :kerning => true)).to eq([[0, ["T", 70, "echnology", 65, "..."]]])
310
- end
311
-
312
- describe "when normalizing encoding" do
313
- it "should not modify the original string when normalize_encoding() is used" do
314
- original = "Foo"
315
- normalized = @times.normalize_encoding(original)
316
- expect(original.equal?(normalized)).to be_false
317
- end
318
-
319
- it "should modify the original string when normalize_encoding!() is used" do
320
- original = "Foo"
321
- normalized = @times.normalize_encoding!(original)
322
- expect(original.equal?(normalized)).to be_true
323
- end
324
- end
325
-
326
- it "should omit /Encoding for symbolic fonts" do
327
- zapf = @pdf.find_font "ZapfDingbats"
328
- font_dict = zapf.send(:register, nil)
329
- expect(font_dict.data[:Encoding]).to be_nil
330
- end
331
- end
332
-
333
- describe "#glyph_present" do
334
- before(:each) { create_pdf }
335
-
336
- it "should return true when present in an AFM font" do
337
- font = @pdf.find_font("Helvetica")
338
- expect(font.glyph_present?("H")).to be_true
339
- end
340
-
341
- it "should return false when absent in an AFM font" do
342
- font = @pdf.find_font("Helvetica")
343
- expect(font.glyph_present?("再")).to be_false
344
- end
345
-
346
- it "should return true when present in a TTF font" do
347
- font = @pdf.find_font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
348
- expect(font.glyph_present?("H")).to be_true
349
- end
350
-
351
- it "should return false when absent in a TTF font" do
352
- font = @pdf.find_font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
353
- expect(font.glyph_present?("再")).to be_false
354
-
355
- font = @pdf.find_font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
356
- expect(font.glyph_present?("€")).to be_false
357
- end
358
- end
359
-
360
- describe "TTF fonts" do
361
- before do
362
- create_pdf
363
- @font = @pdf.find_font "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
364
- end
365
-
366
- it "should calculate string width taking into account accented characters" do
367
- expect(@font.compute_width_of("é", :size => 12)).to eq(@font.compute_width_of("e", :size => 12))
368
- end
369
-
370
- it "should calculate string width taking into account kerning pairs" do
371
- expect(@font.compute_width_of("To", :size => 12)).to be_within(0.01).of(14.65)
372
- expect(@font.compute_width_of("To", :size => 12, :kerning => true)).to be_within(0.01).of(12.61)
373
- end
374
-
375
- it "should encode text without kerning by default" do
376
- expect(@font.encode_text("To")).to eq([[0, "To"]])
377
-
378
- tele = "T\216l\216"
379
- result = @font.encode_text("Télé")
380
- expect(result.length).to eq(1)
381
- expect(result[0][0]).to eq(0)
382
- expect(result[0][1].bytes.to_a).to eq(tele.bytes.to_a)
383
-
384
- expect(@font.encode_text("Technology")).to eq([[0, "Technology"]])
385
- expect(@font.encode_text("Technology...")).to eq([[0, "Technology..."]])
386
- expect(@font.encode_text("Teχnology...")).to eq([[0, "Te"], [1, "!"], [0, "nology..."]])
387
- end
388
-
389
- it "should encode text with kerning if requested" do
390
- expect(@font.encode_text("To", :kerning => true)).to eq([[0, ["T", 169.921875, "o"]]])
391
- expect(@font.encode_text("Technology", :kerning => true)).to eq([[0, ["T", 169.921875, "echnology"]]])
392
- expect(@font.encode_text("Technology...", :kerning => true)).to eq([[0, ["T", 169.921875, "echnology", 142.578125, "..."]]])
393
- expect(@font.encode_text("Teχnology...", :kerning => true)).to eq([[0, ["T", 169.921875, "e"]], [1, "!"], [0, ["nology", 142.578125, "..."]]])
394
- end
395
-
396
- it "should use the ascender, descender, and cap height from the TTF verbatim" do
397
- # These metrics are relative to the font's own bbox. They should not be
398
- # scaled with font size.
399
- ref = @pdf.ref!({})
400
- @font.send :embed, ref, 0
401
-
402
- # Pull out the embedded font descriptor
403
- descriptor = ref.data[:FontDescriptor].data
404
- expect(descriptor[:Ascent]).to eq(759)
405
- expect(descriptor[:Descent]).to eq(-240)
406
- expect(descriptor[:CapHeight]).to eq(759)
407
- end
408
-
409
- describe "when normalizing encoding" do
410
- it "should not modify the original string when normalize_encoding() is used" do
411
- original = "Foo"
412
- normalized = @font.normalize_encoding(original)
413
- expect(original.equal?(normalized)).to be_false
414
- end
415
-
416
- it "should modify the original string when normalize_encoding!() is used" do
417
- original = "Foo"
418
- normalized = @font.normalize_encoding!(original)
419
- expect(original.equal?(normalized)).to be_true
420
- end
421
- end
422
- end
423
-
424
- describe "DFont fonts" do
425
- before do
426
- create_pdf
427
- @file = "#{Prawn::DATADIR}/fonts/Panic+Sans.dfont"
428
- end
429
-
430
- it "should list all named fonts" do
431
- list = Prawn::Font::DFont.named_fonts(@file)
432
- expect(list.sort).to eq(%w(PanicSans PanicSans-Italic PanicSans-Bold PanicSans-BoldItalic).sort)
433
- end
434
-
435
- it "should count the number of fonts in the file" do
436
- expect(Prawn::Font::DFont.font_count(@file)).to eq(4)
437
- end
438
-
439
- it "should default selected font to the first one if not specified" do
440
- font = @pdf.find_font(@file)
441
- expect(font.basename).to eq("PanicSans")
442
- end
443
-
444
- it "should allow font to be selected by index" do
445
- font = @pdf.find_font(@file, :font => 2)
446
- expect(font.basename).to eq("PanicSans-Italic")
447
- end
448
-
449
- it "should allow font to be selected by name" do
450
- font = @pdf.find_font(@file, :font => "PanicSans-BoldItalic")
451
- expect(font.basename).to eq("PanicSans-BoldItalic")
452
- end
453
-
454
- it "should cache font object based on selected font" do
455
- f1 = @pdf.find_font(@file, :font => "PanicSans")
456
- f2 = @pdf.find_font(@file, :font => "PanicSans-Bold")
457
- expect(f2.object_id).not_to eq(f1.object_id)
458
- expect(@pdf.find_font(@file, :font => "PanicSans").object_id).to eq(f1.object_id)
459
- expect(@pdf.find_font(@file, :font => "PanicSans-Bold").object_id).to eq(f2.object_id)
460
- end
461
- end
462
-
463
- describe "#character_count(text)" do
464
- it "should work on TTF fonts" do
465
- create_pdf
466
- @pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
467
- expect(@pdf.font.character_count("こんにちは世界")).to eq(7)
468
- expect(@pdf.font.character_count("Hello, world!")).to eq(13)
469
- end
470
-
471
- it "should work on AFM fonts" do
472
- create_pdf
473
- expect(@pdf.font.character_count("Hello, world!")).to eq(13)
474
- end
475
- end