prawn 1.1.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +1 -0
  4. data/GPLv2 +20 -21
  5. data/Gemfile +3 -9
  6. data/Rakefile +9 -40
  7. data/lib/prawn/document/bounding_box.rb +54 -40
  8. data/lib/prawn/document/column_box.rb +8 -10
  9. data/lib/prawn/document/internals.rb +39 -146
  10. data/lib/prawn/document/span.rb +23 -17
  11. data/lib/prawn/document.rb +217 -182
  12. data/lib/prawn/encoding.rb +69 -101
  13. data/lib/prawn/errors.rb +47 -43
  14. data/lib/prawn/font.rb +124 -104
  15. data/lib/prawn/font_metric_cache.rb +23 -21
  16. data/lib/prawn/fonts/afm.rb +292 -0
  17. data/lib/prawn/{font → fonts}/dfont.rb +5 -12
  18. data/lib/prawn/fonts/otf.rb +11 -0
  19. data/lib/prawn/fonts/ttc.rb +36 -0
  20. data/lib/prawn/{font → fonts}/ttf.rb +140 -88
  21. data/lib/prawn/graphics/blend_mode.rb +65 -0
  22. data/lib/prawn/graphics/cap_style.rb +5 -5
  23. data/lib/prawn/graphics/color.rb +46 -44
  24. data/lib/prawn/graphics/dash.rb +27 -11
  25. data/lib/prawn/graphics/join_style.rb +11 -6
  26. data/lib/prawn/graphics/patterns.rb +220 -78
  27. data/lib/prawn/graphics/transformation.rb +20 -12
  28. data/lib/prawn/graphics/transparency.rb +20 -18
  29. data/lib/prawn/graphics.rb +153 -115
  30. data/lib/prawn/grid.rb +93 -50
  31. data/lib/prawn/image_handler.rb +4 -4
  32. data/lib/prawn/images/image.rb +3 -2
  33. data/lib/prawn/images/jpg.rb +31 -24
  34. data/lib/prawn/images/png.rb +101 -68
  35. data/lib/prawn/images.rb +64 -56
  36. data/lib/prawn/measurement_extensions.rb +10 -9
  37. data/lib/prawn/measurements.rb +20 -23
  38. data/lib/prawn/outline.rb +96 -75
  39. data/lib/prawn/repeater.rb +16 -16
  40. data/lib/prawn/security/arcfour.rb +2 -2
  41. data/lib/prawn/security.rb +100 -85
  42. data/lib/prawn/soft_mask.rb +37 -38
  43. data/lib/prawn/stamp.rb +28 -13
  44. data/lib/prawn/text/box.rb +24 -29
  45. data/lib/prawn/text/formatted/arranger.rb +108 -63
  46. data/lib/prawn/text/formatted/box.rb +187 -124
  47. data/lib/prawn/text/formatted/fragment.rb +24 -20
  48. data/lib/prawn/text/formatted/line_wrap.rb +133 -73
  49. data/lib/prawn/text/formatted/parser.rb +147 -127
  50. data/lib/prawn/text/formatted/wrap.rb +48 -35
  51. data/lib/prawn/text/formatted.rb +5 -5
  52. data/lib/prawn/text.rb +103 -68
  53. data/lib/prawn/transformation_stack.rb +44 -0
  54. data/lib/prawn/utilities.rb +10 -22
  55. data/lib/prawn/version.rb +5 -0
  56. data/lib/prawn/view.rb +101 -0
  57. data/lib/prawn.rb +39 -54
  58. data/manual/basic_concepts/adding_pages.rb +6 -7
  59. data/manual/basic_concepts/basic_concepts.rb +34 -25
  60. data/manual/basic_concepts/creation.rb +10 -11
  61. data/manual/basic_concepts/cursor.rb +4 -5
  62. data/manual/basic_concepts/measurement.rb +8 -9
  63. data/manual/basic_concepts/origin.rb +5 -6
  64. data/manual/basic_concepts/other_cursor_helpers.rb +11 -12
  65. data/manual/basic_concepts/view.rb +48 -0
  66. data/manual/bounding_box/bounding_box.rb +30 -28
  67. data/manual/bounding_box/bounds.rb +12 -13
  68. data/manual/bounding_box/canvas.rb +7 -8
  69. data/manual/bounding_box/creation.rb +6 -7
  70. data/manual/bounding_box/indentation.rb +14 -15
  71. data/manual/bounding_box/nesting.rb +25 -18
  72. data/manual/bounding_box/russian_boxes.rb +18 -18
  73. data/manual/bounding_box/stretchy.rb +12 -14
  74. data/manual/contents.rb +28 -22
  75. data/manual/cover.rb +33 -32
  76. data/manual/document_and_page_options/background.rb +15 -13
  77. data/manual/document_and_page_options/document_and_page_options.rb +24 -22
  78. data/manual/document_and_page_options/metadata.rb +20 -18
  79. data/manual/document_and_page_options/page_margins.rb +18 -20
  80. data/manual/document_and_page_options/page_size.rb +13 -13
  81. data/manual/document_and_page_options/print_scaling.rb +18 -15
  82. data/manual/example_helper.rb +5 -4
  83. data/manual/graphics/blend_mode.rb +52 -0
  84. data/manual/graphics/circle_and_ellipse.rb +4 -5
  85. data/manual/graphics/color.rb +7 -9
  86. data/manual/graphics/common_lines.rb +7 -8
  87. data/manual/graphics/fill_and_stroke.rb +5 -6
  88. data/manual/graphics/fill_rules.rb +12 -11
  89. data/manual/graphics/gradients.rb +27 -21
  90. data/manual/graphics/graphics.rb +46 -40
  91. data/manual/graphics/helper.rb +19 -9
  92. data/manual/graphics/line_width.rb +8 -7
  93. data/manual/graphics/lines_and_curves.rb +8 -9
  94. data/manual/graphics/polygon.rb +6 -8
  95. data/manual/graphics/rectangle.rb +4 -5
  96. data/manual/graphics/rotate.rb +6 -9
  97. data/manual/graphics/scale.rb +14 -13
  98. data/manual/graphics/soft_masks.rb +4 -6
  99. data/manual/graphics/stroke_cap.rb +7 -8
  100. data/manual/graphics/stroke_dash.rb +15 -16
  101. data/manual/graphics/stroke_join.rb +6 -7
  102. data/manual/graphics/translate.rb +10 -10
  103. data/manual/graphics/transparency.rb +7 -9
  104. data/manual/how_to_read_this_manual.rb +8 -9
  105. data/manual/images/absolute_position.rb +6 -7
  106. data/manual/images/fit.rb +7 -8
  107. data/manual/images/horizontal.rb +10 -11
  108. data/manual/images/images.rb +28 -27
  109. data/manual/images/plain_image.rb +5 -6
  110. data/manual/images/scale.rb +9 -10
  111. data/manual/images/vertical.rb +16 -14
  112. data/manual/images/width_and_height.rb +10 -11
  113. data/manual/layout/boxes.rb +10 -11
  114. data/manual/layout/content.rb +9 -10
  115. data/manual/layout/layout.rb +17 -18
  116. data/manual/layout/simple_grid.rb +6 -7
  117. data/manual/outline/add_subsection_to.rb +20 -21
  118. data/manual/outline/insert_section_after.rb +15 -16
  119. data/manual/outline/outline.rb +22 -21
  120. data/manual/outline/sections_and_pages.rb +17 -18
  121. data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
  122. data/manual/repeatable_content/page_numbering.rb +17 -16
  123. data/manual/repeatable_content/repeatable_content.rb +27 -23
  124. data/manual/repeatable_content/repeater.rb +15 -16
  125. data/manual/repeatable_content/stamp.rb +14 -15
  126. data/manual/security/encryption.rb +8 -11
  127. data/manual/security/permissions.rb +20 -15
  128. data/manual/security/security.rb +18 -18
  129. data/manual/table.rb +16 -0
  130. data/manual/text/alignment.rb +16 -17
  131. data/manual/text/color.rb +12 -12
  132. data/manual/text/column_box.rb +9 -11
  133. data/manual/text/fallback_fonts.rb +25 -21
  134. data/manual/text/font.rb +11 -12
  135. data/manual/text/font_size.rb +13 -14
  136. data/manual/text/font_style.rb +10 -8
  137. data/manual/text/formatted_callbacks.rb +33 -23
  138. data/manual/text/formatted_text.rb +36 -25
  139. data/manual/text/free_flowing_text.rb +22 -23
  140. data/manual/text/inline.rb +18 -19
  141. data/manual/text/kerning_and_character_spacing.rb +14 -15
  142. data/manual/text/leading.rb +7 -8
  143. data/manual/text/line_wrapping.rb +37 -18
  144. data/manual/text/paragraph_indentation.rb +15 -10
  145. data/manual/text/positioned_text.rb +16 -17
  146. data/manual/text/registering_families.rb +27 -24
  147. data/manual/text/rendering_and_color.rb +9 -10
  148. data/manual/text/right_to_left_text.rb +30 -19
  149. data/manual/text/rotation.rb +33 -24
  150. data/manual/text/single_usage.rb +8 -9
  151. data/manual/text/text.rb +56 -54
  152. data/manual/text/text_box_excess.rb +20 -17
  153. data/manual/text/text_box_extensions.rb +18 -15
  154. data/manual/text/text_box_overflow.rb +24 -17
  155. data/manual/text/utf8.rb +12 -13
  156. data/manual/text/win_ansi_charset.rb +28 -25
  157. data/prawn.gemspec +45 -50
  158. data/spec/extensions/encoding_helpers.rb +3 -3
  159. data/spec/prawn/document/bounding_box_spec.rb +550 -0
  160. data/spec/prawn/document/column_box_spec.rb +75 -0
  161. data/spec/prawn/document/security_spec.rb +176 -0
  162. data/spec/prawn/document_annotations_spec.rb +76 -0
  163. data/spec/prawn/document_destinations_spec.rb +15 -0
  164. data/spec/prawn/document_grid_spec.rb +99 -0
  165. data/spec/prawn/document_reference_spec.rb +27 -0
  166. data/spec/prawn/document_span_spec.rb +44 -0
  167. data/spec/prawn/document_spec.rb +805 -0
  168. data/spec/prawn/font_metric_cache_spec.rb +54 -0
  169. data/spec/prawn/font_spec.rb +544 -0
  170. data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
  171. data/spec/prawn/graphics/transparency_spec.rb +81 -0
  172. data/spec/prawn/graphics_spec.rb +872 -0
  173. data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
  174. data/spec/prawn/image_handler_spec.rb +53 -0
  175. data/spec/prawn/images/jpg_spec.rb +20 -0
  176. data/spec/prawn/images/png_spec.rb +283 -0
  177. data/spec/prawn/images_spec.rb +229 -0
  178. data/spec/prawn/measurements_extensions_spec.rb +24 -0
  179. data/spec/prawn/outline_spec.rb +512 -0
  180. data/spec/prawn/repeater_spec.rb +166 -0
  181. data/spec/prawn/soft_mask_spec.rb +74 -0
  182. data/spec/prawn/stamp_spec.rb +173 -0
  183. data/spec/prawn/text/box_spec.rb +1110 -0
  184. data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
  185. data/spec/prawn/text/formatted/box_spec.rb +849 -0
  186. data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
  187. data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
  188. data/spec/prawn/text/formatted/parser_spec.rb +697 -0
  189. data/spec/prawn/text_draw_text_spec.rb +150 -0
  190. data/spec/prawn/text_rendering_mode_spec.rb +48 -0
  191. data/spec/prawn/text_spacing_spec.rb +95 -0
  192. data/spec/prawn/text_spec.rb +603 -0
  193. data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
  194. data/spec/prawn/transformation_stack_spec.rb +66 -0
  195. data/spec/prawn/view_spec.rb +63 -0
  196. data/spec/prawn_manual_spec.rb +35 -0
  197. data/spec/spec_helper.rb +19 -25
  198. data.tar.gz.sig +0 -0
  199. metadata +113 -276
  200. metadata.gz.sig +0 -0
  201. data/data/encodings/win_ansi.txt +0 -29
  202. data/data/images/16bit.alpha +0 -0
  203. data/data/images/16bit.color +0 -0
  204. data/data/images/16bit.png +0 -0
  205. data/data/images/arrow.png +0 -0
  206. data/data/images/arrow2.png +0 -0
  207. data/data/images/dice.alpha +0 -0
  208. data/data/images/dice.color +0 -0
  209. data/data/images/dice.png +0 -0
  210. data/data/images/dice_interlaced.png +0 -0
  211. data/data/images/fractal.jpg +0 -0
  212. data/data/images/indexed_color.dat +0 -0
  213. data/data/images/indexed_color.png +0 -0
  214. data/data/images/letterhead.jpg +0 -0
  215. data/data/images/license.md +0 -8
  216. data/data/images/page_white_text.alpha +0 -0
  217. data/data/images/page_white_text.color +0 -0
  218. data/data/images/page_white_text.png +0 -0
  219. data/data/images/pigs.jpg +0 -0
  220. data/data/images/prawn.png +0 -0
  221. data/data/images/ruport.png +0 -0
  222. data/data/images/ruport_data.dat +0 -0
  223. data/data/images/ruport_transparent.png +0 -0
  224. data/data/images/ruport_type0.png +0 -0
  225. data/data/images/stef.jpg +0 -0
  226. data/data/images/tru256.bmp +0 -0
  227. data/data/images/web-links.dat +0 -1
  228. data/data/images/web-links.png +0 -0
  229. data/data/pdfs/complex_template.pdf +0 -0
  230. data/data/pdfs/contains_ttf_font.pdf +0 -0
  231. data/data/pdfs/encrypted.pdf +0 -0
  232. data/data/pdfs/form.pdf +1 -819
  233. data/data/pdfs/hexagon.pdf +0 -61
  234. data/data/pdfs/indirect_reference.pdf +0 -86
  235. data/data/pdfs/multipage_template.pdf +0 -127
  236. data/data/pdfs/nested_pages.pdf +0 -118
  237. data/data/pdfs/page_without_mediabox.pdf +0 -193
  238. data/data/pdfs/resources_as_indirect_object.pdf +0 -83
  239. data/data/pdfs/two_hexagons.pdf +0 -90
  240. data/data/pdfs/version_1_6.pdf +0 -61
  241. data/data/shift_jis_text.txt +0 -1
  242. data/lib/prawn/document/graphics_state.rb +0 -73
  243. data/lib/prawn/font/afm.rb +0 -247
  244. data/lib/prawn/table/cell/image.rb +0 -69
  245. data/lib/prawn/table/cell/in_table.rb +0 -33
  246. data/lib/prawn/table/cell/span_dummy.rb +0 -93
  247. data/lib/prawn/table/cell/subtable.rb +0 -66
  248. data/lib/prawn/table/cell/text.rb +0 -154
  249. data/lib/prawn/table/cell.rb +0 -772
  250. data/lib/prawn/table/cells.rb +0 -255
  251. data/lib/prawn/table/column_width_calculator.rb +0 -182
  252. data/lib/prawn/table.rb +0 -644
  253. data/manual/table/basic_block.rb +0 -53
  254. data/manual/table/before_rendering_page.rb +0 -26
  255. data/manual/table/cell_border_lines.rb +0 -24
  256. data/manual/table/cell_borders_and_bg.rb +0 -31
  257. data/manual/table/cell_dimensions.rb +0 -30
  258. data/manual/table/cell_text.rb +0 -38
  259. data/manual/table/column_widths.rb +0 -30
  260. data/manual/table/content_and_subtables.rb +0 -39
  261. data/manual/table/creation.rb +0 -27
  262. data/manual/table/filtering.rb +0 -36
  263. data/manual/table/flow_and_header.rb +0 -17
  264. data/manual/table/image_cells.rb +0 -33
  265. data/manual/table/position.rb +0 -29
  266. data/manual/table/row_colors.rb +0 -20
  267. data/manual/table/span.rb +0 -30
  268. data/manual/table/style.rb +0 -22
  269. data/manual/table/table.rb +0 -52
  270. data/manual/table/width.rb +0 -27
  271. data/spec/acceptance/png.rb +0 -25
  272. data/spec/annotations_spec.rb +0 -74
  273. data/spec/bounding_box_spec.rb +0 -510
  274. data/spec/cell_spec.rb +0 -629
  275. data/spec/column_box_spec.rb +0 -65
  276. data/spec/destinations_spec.rb +0 -15
  277. data/spec/document_spec.rb +0 -730
  278. data/spec/extensions/mocha.rb +0 -46
  279. data/spec/font_metric_cache_spec.rb +0 -52
  280. data/spec/font_spec.rb +0 -449
  281. data/spec/formatted_text_arranger_spec.rb +0 -421
  282. data/spec/formatted_text_box_spec.rb +0 -639
  283. data/spec/formatted_text_fragment_spec.rb +0 -298
  284. data/spec/graphics_spec.rb +0 -669
  285. data/spec/grid_spec.rb +0 -96
  286. data/spec/image_handler_spec.rb +0 -54
  287. data/spec/images_spec.rb +0 -153
  288. data/spec/inline_formatted_text_parser_spec.rb +0 -564
  289. data/spec/jpg_spec.rb +0 -25
  290. data/spec/line_wrap_spec.rb +0 -344
  291. data/spec/measurement_units_spec.rb +0 -25
  292. data/spec/outline_spec.rb +0 -430
  293. data/spec/png_spec.rb +0 -237
  294. data/spec/reference_spec.rb +0 -25
  295. data/spec/repeater_spec.rb +0 -160
  296. data/spec/security_spec.rb +0 -158
  297. data/spec/soft_mask_spec.rb +0 -79
  298. data/spec/span_spec.rb +0 -44
  299. data/spec/stamp_spec.rb +0 -160
  300. data/spec/stroke_styles_spec.rb +0 -211
  301. data/spec/table/span_dummy_spec.rb +0 -17
  302. data/spec/table_spec.rb +0 -1527
  303. data/spec/text_at_spec.rb +0 -115
  304. data/spec/text_box_spec.rb +0 -1034
  305. data/spec/text_rendering_mode_spec.rb +0 -45
  306. data/spec/text_spacing_spec.rb +0 -93
  307. data/spec/text_spec.rb +0 -437
  308. data/spec/text_with_inline_formatting_spec.rb +0 -35
  309. data/spec/transparency_spec.rb +0 -91
@@ -0,0 +1,292 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Implements AFM font support for Prawn
4
+ #
5
+ # Copyright May 2008, Gregory Brown / James Healy. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+
9
+ require_relative '../encoding'
10
+
11
+ module Prawn
12
+ module Fonts
13
+ # @private
14
+
15
+ class AFM < Font
16
+ class << self
17
+ attr_accessor :hide_m17n_warning
18
+ end
19
+
20
+ self.hide_m17n_warning = false
21
+
22
+ BUILT_INS = %w[
23
+ Courier Helvetica Times-Roman Symbol ZapfDingbats
24
+ Courier-Bold Courier-Oblique Courier-BoldOblique
25
+ Times-Bold Times-Italic Times-BoldItalic
26
+ Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique
27
+ ].freeze
28
+
29
+ def unicode?
30
+ false
31
+ end
32
+
33
+ def self.metrics_path
34
+ @metrics_path ||=
35
+ if ENV['METRICS']
36
+ ENV['METRICS'].split(':')
37
+ else
38
+ [
39
+ '.', '/usr/lib/afm',
40
+ '/usr/local/lib/afm',
41
+ '/usr/openwin/lib/fonts/afm',
42
+ "#{Prawn::DATADIR}/fonts"
43
+ ]
44
+ end
45
+ end
46
+
47
+ attr_reader :attributes #:nodoc:
48
+
49
+ # parse each ATM font file once only
50
+ def self.font_data
51
+ @font_data ||= SynchronizedCache.new
52
+ end
53
+
54
+ def initialize(document, name, options = {}) #:nodoc:
55
+ name ||= options[:family]
56
+ unless BUILT_INS.include?(name)
57
+ raise Prawn::Errors::UnknownFont,
58
+ "#{name} (#{options[:style] || 'normal'}) is not a known font."
59
+ end
60
+
61
+ super
62
+
63
+ file_name = @name.dup
64
+ file_name << '.afm' unless /\.afm$/.match?(file_name)
65
+ file_name = file_name[0] == '/' ? file_name : find_font(file_name)
66
+
67
+ font_data = self.class.font_data[file_name] ||= parse_afm(file_name)
68
+ @glyph_widths = font_data[:glyph_widths]
69
+ @glyph_table = font_data[:glyph_table]
70
+ @bounding_boxes = font_data[:bounding_boxes]
71
+ @kern_pairs = font_data[:kern_pairs]
72
+ @kern_pair_table = font_data[:kern_pair_table]
73
+ @attributes = font_data[:attributes]
74
+
75
+ @ascender = @attributes['ascender'].to_i
76
+ @descender = @attributes['descender'].to_i
77
+ @line_gap = Float(bbox[3] - bbox[1]) - (@ascender - @descender)
78
+ end
79
+
80
+ # The font bbox, as an array of integers
81
+ #
82
+ def bbox
83
+ @bbox ||= @attributes['fontbbox'].split(/\s+/).map { |e| Integer(e) }
84
+ end
85
+
86
+ # NOTE: String *must* be encoded as WinAnsi
87
+ def compute_width_of(string, options = {}) #:nodoc:
88
+ scale = (options[:size] || size) / 1000.0
89
+
90
+ if options[:kerning]
91
+ strings, numbers = kern(string).partition { |e| e.is_a?(String) }
92
+ total_kerning_offset = numbers.sum
93
+ (unscaled_width_of(strings.join) - total_kerning_offset) * scale
94
+ else
95
+ unscaled_width_of(string) * scale
96
+ end
97
+ end
98
+
99
+ # Returns true if the font has kerning data, false otherwise
100
+ #
101
+ # rubocop: disable Naming/PredicateName
102
+ def has_kerning_data?
103
+ @kern_pairs.any?
104
+ end
105
+ # rubocop: enable Naming/PredicateName
106
+
107
+ # built-in fonts only work with winansi encoding, so translate the
108
+ # string. Changes the encoding in-place, so the argument itself
109
+ # is replaced with a string in WinAnsi encoding.
110
+ #
111
+ def normalize_encoding(text)
112
+ text.encode('windows-1252')
113
+ rescue ::Encoding::InvalidByteSequenceError,
114
+ ::Encoding::UndefinedConversionError
115
+
116
+ raise Prawn::Errors::IncompatibleStringEncoding,
117
+ "Your document includes text that's not compatible with the " \
118
+ "Windows-1252 character set.\n" \
119
+ 'If you need full UTF-8 support, use external fonts instead of ' \
120
+ "PDF's built-in fonts.\n"
121
+ end
122
+
123
+ def to_utf8(text)
124
+ text.encode('UTF-8')
125
+ end
126
+
127
+ # Returns the number of characters in +str+ (a WinAnsi-encoded string).
128
+ #
129
+ def character_count(str)
130
+ str.length
131
+ end
132
+
133
+ # Perform any changes to the string that need to happen
134
+ # before it is rendered to the canvas. Returns an array of
135
+ # subset "chunks", where each chunk is an array of two elements.
136
+ # The first element is the font subset number, and the second
137
+ # is either a string or an array (for kerned text).
138
+ #
139
+ # For Adobe fonts, there is only ever a single subset, so
140
+ # the first element of the array is "0", and the second is
141
+ # the string itself (or an array, if kerning is performed).
142
+ #
143
+ # The +text+ parameter must be in WinAnsi encoding (cp1252).
144
+ #
145
+ def encode_text(text, options = {})
146
+ [[0, options[:kerning] ? kern(text) : text]]
147
+ end
148
+
149
+ def glyph_present?(char)
150
+ !normalize_encoding(char).nil?
151
+ rescue Prawn::Errors::IncompatibleStringEncoding
152
+ false
153
+ end
154
+
155
+ private
156
+
157
+ def register(_subset)
158
+ font_dict = {
159
+ Type: :Font,
160
+ Subtype: :Type1,
161
+ BaseFont: name.to_sym
162
+ }
163
+
164
+ # Symbolic AFM fonts (Symbol, ZapfDingbats) have their own encodings
165
+ font_dict[:Encoding] = :WinAnsiEncoding unless symbolic?
166
+
167
+ @document.ref!(font_dict)
168
+ end
169
+
170
+ def symbolic?
171
+ attributes['characterset'] == 'Special'
172
+ end
173
+
174
+ def find_font(file)
175
+ self.class.metrics_path.find { |f| File.exist? "#{f}/#{file}" } +
176
+ "/#{file}"
177
+ rescue NoMethodError
178
+ raise Prawn::Errors::UnknownFont,
179
+ "Couldn't find the font: #{file} in any of:\n" +
180
+ self.class.metrics_path.join("\n")
181
+ end
182
+
183
+ def parse_afm(file_name)
184
+ data = {
185
+ glyph_widths: {},
186
+ bounding_boxes: {},
187
+ kern_pairs: {},
188
+ attributes: {}
189
+ }
190
+ section = []
191
+
192
+ File.foreach(file_name) do |line|
193
+ case line
194
+ when /^Start(\w+)/
195
+ section.push Regexp.last_match(1)
196
+ next
197
+ when /^End(\w+)/
198
+ section.pop
199
+ next
200
+ end
201
+
202
+ case section
203
+ when %w[FontMetrics CharMetrics]
204
+ next unless /^CH?\s/.match?(line)
205
+
206
+ name = line[/\bN\s+(\.?\w+)\s*;/, 1]
207
+ data[:glyph_widths][name] = line[/\bWX\s+(\d+)\s*;/, 1].to_i
208
+ data[:bounding_boxes][name] = line[/\bB\s+([^;]+);/, 1].to_s.rstrip
209
+ when %w[FontMetrics KernData KernPairs]
210
+ next unless line =~ /^KPX\s+(\.?\w+)\s+(\.?\w+)\s+(-?\d+)/
211
+
212
+ data[:kern_pairs][[Regexp.last_match(1), Regexp.last_match(2)]] =
213
+ Regexp.last_match(3).to_i
214
+ when %w[FontMetrics KernData TrackKern],
215
+ %w[FontMetrics Composites]
216
+ next
217
+ else
218
+ parse_generic_afm_attribute(line, data)
219
+ end
220
+ end
221
+
222
+ # process data parsed from AFM file to build tables which
223
+ # will be used when measuring and kerning text
224
+ data[:glyph_table] =
225
+ (0..255).map do |i|
226
+ data[:glyph_widths][Encoding::WinAnsi::CHARACTERS[i]].to_i
227
+ end
228
+
229
+ character_hash = Hash[
230
+ Encoding::WinAnsi::CHARACTERS.zip(
231
+ (0..Encoding::WinAnsi::CHARACTERS.size).to_a
232
+ )
233
+ ]
234
+ data[:kern_pair_table] =
235
+ data[:kern_pairs].each_with_object({}) do |p, h|
236
+ h[p[0].map { |n| character_hash[n] }] = p[1]
237
+ end
238
+
239
+ data.each_value(&:freeze)
240
+ data.freeze
241
+ end
242
+
243
+ def parse_generic_afm_attribute(line, hash)
244
+ line =~ /(^\w+)\s+(.*)/
245
+ key = Regexp.last_match(1).to_s.downcase
246
+ value = Regexp.last_match(2)
247
+
248
+ hash[:attributes][key] =
249
+ if hash[:attributes][key]
250
+ Array(hash[:attributes][key]) << value
251
+ else
252
+ value
253
+ end
254
+ end
255
+
256
+ # converts a string into an array with spacing offsets
257
+ # bewteen characters that need to be kerned
258
+ #
259
+ # String *must* be encoded as WinAnsi
260
+ #
261
+ def kern(string)
262
+ kerned = [[]]
263
+ last_byte = nil
264
+
265
+ string.each_byte do |byte|
266
+ k = last_byte && @kern_pair_table[[last_byte, byte]]
267
+ if k
268
+ kerned << -k << [byte]
269
+ else
270
+ kerned.last << byte
271
+ end
272
+ last_byte = byte
273
+ end
274
+
275
+ kerned.map do |e|
276
+ e = e.is_a?(Array) ? e.pack('C*') : e
277
+ if e.respond_to?(:force_encoding)
278
+ e.force_encoding(::Encoding::Windows_1252)
279
+ else
280
+ e
281
+ end
282
+ end
283
+ end
284
+
285
+ def unscaled_width_of(string)
286
+ string.bytes.reduce(0) do |s, r|
287
+ s + @glyph_table[r]
288
+ end
289
+ end
290
+ end
291
+ end
292
+ end
@@ -1,18 +1,11 @@
1
- # encoding: utf-8
2
- #
3
- # font.rb : The Prawn font class
4
- #
5
- # Copyright November 2008, Jamis Buck. All Rights Reserved.
6
- #
7
- # This is free software. Please see the LICENSE and COPYING files for details.
8
- #
1
+ # frozen_string_literal: true
2
+
9
3
  require_relative 'ttf'
10
4
 
11
5
  module Prawn
12
- class Font
6
+ module Fonts
13
7
  # @private
14
8
  class DFont < TTF
15
-
16
9
  # Returns a list of the names of all named fonts in the given dfont file.
17
10
  # Note that fonts are not required to be named in a dfont file, so the
18
11
  # list may be empty even if the file does contain fonts. Also, note that
@@ -21,7 +14,7 @@ module Prawn
21
14
  #
22
15
  def self.named_fonts(file)
23
16
  TTFunk::ResourceFile.open(file) do |f|
24
- return f.resources_for("sfnt")
17
+ return f.resources_for('sfnt')
25
18
  end
26
19
  end
27
20
 
@@ -29,7 +22,7 @@ module Prawn
29
22
  #
30
23
  def self.font_count(file)
31
24
  TTFunk::ResourceFile.open(file) do |f|
32
- return f.map["sfnt"][:list].length
25
+ return f.map['sfnt'][:list].length
33
26
  end
34
27
  end
35
28
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ttf'
4
+
5
+ module Prawn
6
+ module Fonts
7
+ # @private
8
+ class OTF < TTF
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ttf'
4
+
5
+ module Prawn
6
+ module Fonts
7
+ # @private
8
+ class TTC < TTF
9
+ # Returns a list of the names of all named fonts in the given ttc file.
10
+ # They are returned in order of their appearance in the file.
11
+ #
12
+ def self.font_names(file)
13
+ TTFunk::Collection.open(file) do |ttc|
14
+ ttc.map { |font| font.name.font_name.first }
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def read_ttf_file
21
+ TTFunk::File.from_ttc(
22
+ @name,
23
+ font_option_to_index(@name, @options[:font])
24
+ )
25
+ end
26
+
27
+ def font_option_to_index(file, option)
28
+ if option.is_a?(Numeric)
29
+ option
30
+ else
31
+ self.class.font_names(file).index { |n| n == option } || 0
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end