ttfunk 1.7.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +74 -0
  4. data/README.md +17 -15
  5. data/lib/ttfunk/aggregate.rb +5 -0
  6. data/lib/ttfunk/bin_utils.rb +27 -8
  7. data/lib/ttfunk/bit_field.rb +25 -2
  8. data/lib/ttfunk/collection.rb +27 -3
  9. data/lib/ttfunk/directory.rb +7 -1
  10. data/lib/ttfunk/encoded_string.rb +58 -4
  11. data/lib/ttfunk/max.rb +14 -0
  12. data/lib/ttfunk/min.rb +14 -0
  13. data/lib/ttfunk/one_based_array.rb +20 -0
  14. data/lib/ttfunk/otf_encoder.rb +5 -14
  15. data/lib/ttfunk/placeholder.rb +15 -1
  16. data/lib/ttfunk/reader.rb +6 -4
  17. data/lib/ttfunk/resource_file.rb +29 -5
  18. data/lib/ttfunk/sci_form.rb +20 -3
  19. data/lib/ttfunk/sub_table.rb +29 -4
  20. data/lib/ttfunk/subset/base.rb +48 -0
  21. data/lib/ttfunk/subset/code_page.rb +49 -2
  22. data/lib/ttfunk/subset/mac_roman.rb +2 -0
  23. data/lib/ttfunk/subset/unicode.rb +32 -0
  24. data/lib/ttfunk/subset/unicode_8bit.rb +32 -0
  25. data/lib/ttfunk/subset/windows_1252.rb +2 -0
  26. data/lib/ttfunk/subset.rb +8 -0
  27. data/lib/ttfunk/subset_collection.rb +39 -14
  28. data/lib/ttfunk/sum.rb +13 -0
  29. data/lib/ttfunk/table/cff/charset.rb +96 -18
  30. data/lib/ttfunk/table/cff/charsets/expert.rb +3 -2
  31. data/lib/ttfunk/table/cff/charsets/expert_subset.rb +3 -2
  32. data/lib/ttfunk/table/cff/charsets/iso_adobe.rb +3 -2
  33. data/lib/ttfunk/table/cff/charsets/standard_strings.rb +3 -2
  34. data/lib/ttfunk/table/cff/charsets.rb +1 -0
  35. data/lib/ttfunk/table/cff/charstring.rb +33 -12
  36. data/lib/ttfunk/table/cff/charstrings_index.rb +17 -11
  37. data/lib/ttfunk/table/cff/dict.rb +53 -23
  38. data/lib/ttfunk/table/cff/encoding.rb +82 -24
  39. data/lib/ttfunk/table/cff/encodings/expert.rb +3 -2
  40. data/lib/ttfunk/table/cff/encodings/standard.rb +3 -2
  41. data/lib/ttfunk/table/cff/encodings.rb +1 -0
  42. data/lib/ttfunk/table/cff/fd_selector.rb +61 -21
  43. data/lib/ttfunk/table/cff/font_dict.rb +30 -18
  44. data/lib/ttfunk/table/cff/font_index.rb +22 -10
  45. data/lib/ttfunk/table/cff/header.rb +16 -3
  46. data/lib/ttfunk/table/cff/index.rb +97 -65
  47. data/lib/ttfunk/table/cff/one_based_index.rb +11 -1
  48. data/lib/ttfunk/table/cff/path.rb +43 -4
  49. data/lib/ttfunk/table/cff/private_dict.rb +31 -11
  50. data/lib/ttfunk/table/cff/subr_index.rb +7 -2
  51. data/lib/ttfunk/table/cff/top_dict.rb +82 -59
  52. data/lib/ttfunk/table/cff/top_index.rb +10 -6
  53. data/lib/ttfunk/table/cff.rb +41 -21
  54. data/lib/ttfunk/table/cmap/format00.rb +27 -6
  55. data/lib/ttfunk/table/cmap/format04.rb +34 -14
  56. data/lib/ttfunk/table/cmap/format06.rb +28 -1
  57. data/lib/ttfunk/table/cmap/format10.rb +29 -2
  58. data/lib/ttfunk/table/cmap/format12.rb +29 -2
  59. data/lib/ttfunk/table/cmap/subtable.rb +50 -6
  60. data/lib/ttfunk/table/cmap.rb +21 -0
  61. data/lib/ttfunk/table/dsig.rb +47 -6
  62. data/lib/ttfunk/table/glyf/compound.rb +73 -6
  63. data/lib/ttfunk/table/glyf/path_based.rb +40 -3
  64. data/lib/ttfunk/table/glyf/simple.rb +50 -5
  65. data/lib/ttfunk/table/glyf.rb +15 -7
  66. data/lib/ttfunk/table/head.rb +84 -6
  67. data/lib/ttfunk/table/hhea.rb +71 -10
  68. data/lib/ttfunk/table/hmtx.rb +32 -5
  69. data/lib/ttfunk/table/kern/format0.rb +25 -7
  70. data/lib/ttfunk/table/kern.rb +16 -4
  71. data/lib/ttfunk/table/loca.rb +21 -8
  72. data/lib/ttfunk/table/maxp.rb +195 -10
  73. data/lib/ttfunk/table/name.rb +126 -9
  74. data/lib/ttfunk/table/os2.rb +150 -26
  75. data/lib/ttfunk/table/post/format10.rb +7 -0
  76. data/lib/ttfunk/table/post/format20.rb +9 -0
  77. data/lib/ttfunk/table/post/format30.rb +6 -0
  78. data/lib/ttfunk/table/post/format40.rb +5 -0
  79. data/lib/ttfunk/table/post.rb +63 -7
  80. data/lib/ttfunk/table/sbix.rb +50 -14
  81. data/lib/ttfunk/table/simple.rb +5 -0
  82. data/lib/ttfunk/table/vorg.rb +31 -3
  83. data/lib/ttfunk/table.rb +20 -1
  84. data/lib/ttfunk/ttf_encoder.rb +39 -41
  85. data/lib/ttfunk.rb +154 -1
  86. data.tar.gz.sig +0 -0
  87. metadata +50 -28
  88. metadata.gz.sig +0 -0
@@ -4,19 +4,37 @@ require_relative '../table'
4
4
 
5
5
  module TTFunk
6
6
  class Table
7
+ # Vertical Origin (`VORG`) table.
7
8
  class Vorg < Table
9
+ # Table tag.
8
10
  TAG = 'VORG'
9
11
 
10
- attr_reader :major_version, :minor_version
11
- attr_reader :default_vert_origin_y, :count
12
+ # Table major version.
13
+ # @return [Integer]
14
+ attr_reader :major_version
12
15
 
16
+ # Table minor version.
17
+ # @return [Integer]
18
+ attr_reader :minor_version
19
+
20
+ # The default y coordinate of a glyph’s vertical origin.
21
+ # @return [Integer]
22
+ attr_reader :default_vert_origin_y
23
+
24
+ # Number of vertical origin metrics.
25
+ # @return [Integer]
26
+ attr_reader :count
27
+
28
+ # Encode table.
29
+ #
30
+ # @return [String]
13
31
  def self.encode(vorg)
14
32
  return unless vorg
15
33
 
16
34
  ''.b.tap do |table|
17
35
  table << [
18
36
  vorg.major_version, vorg.minor_version,
19
- vorg.default_vert_origin_y, vorg.count
37
+ vorg.default_vert_origin_y, vorg.count,
20
38
  ].pack('n*')
21
39
 
22
40
  vorg.origins.each_pair do |glyph_id, vert_origin_y|
@@ -25,14 +43,24 @@ module TTFunk
25
43
  end
26
44
  end
27
45
 
46
+ # Get vertical origina for glyph by ID.
47
+ #
48
+ # @param glyph_id [Integer]
49
+ # @return [Integer]
28
50
  def for(glyph_id)
29
51
  @origins.fetch(glyph_id, default_vert_origin_y)
30
52
  end
31
53
 
54
+ # Table tag.
55
+ #
56
+ # @return [String]
32
57
  def tag
33
58
  TAG
34
59
  end
35
60
 
61
+ # Origins map.
62
+ #
63
+ # @return [Hash{Integer => Integer}]
36
64
  def origins
37
65
  @origins ||= {}
38
66
  end
data/lib/ttfunk/table.rb CHANGED
@@ -3,13 +3,23 @@
3
3
  require_relative 'reader'
4
4
 
5
5
  module TTFunk
6
+ # SFNT table
6
7
  class Table
7
8
  include Reader
8
9
 
10
+ # File this table is in.
11
+ # @return [TTFunk::File]
9
12
  attr_reader :file
13
+
14
+ # This table's offset from the file beginning.
15
+ # @return [Integer]
10
16
  attr_reader :offset
17
+
18
+ # This table's length in byes.
19
+ # @return [Integer, nil]
11
20
  attr_reader :length
12
21
 
22
+ # @param file [TTFunk::File]
13
23
  def initialize(file)
14
24
  @file = file
15
25
  @offset = nil
@@ -25,18 +35,27 @@ module TTFunk
25
35
  end
26
36
  end
27
37
 
38
+ # Does this table exist in the file?
39
+ #
40
+ # @return [Boolean]
28
41
  def exists?
29
42
  !@offset.nil?
30
43
  end
31
44
 
45
+ # Raw bytes of this table in the file.
46
+ #
47
+ # @return [String, nil]
32
48
  def raw
33
49
  if exists?
34
50
  parse_from(offset) { io.read(length) }
35
51
  end
36
52
  end
37
53
 
54
+ # Table tag.
55
+ #
56
+ # @return [String]
38
57
  def tag
39
- self.class.name.split(/::/).last.downcase
58
+ self.class.name.split('::').last.downcase
40
59
  end
41
60
 
42
61
  private
@@ -1,26 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTFunk
4
+ # Encodes a TrueType font subset to its binary representation.
4
5
  class TTFEncoder
6
+ # Optimal table order according to TrueType specification.
5
7
  OPTIMAL_TABLE_ORDER = [
6
8
  'head', 'hhea', 'maxp', 'OS/2', 'hmtx', 'LTSH', 'VDMX',
7
9
  'hdmx', 'cmap', 'fpgm', 'prep', 'cvt ', 'loca', 'glyf',
8
- 'kern', 'name', 'post', 'gasp', 'PCLT'
10
+ 'kern', 'name', 'post', 'gasp', 'PCLT',
9
11
  ].freeze
10
12
 
11
- attr_reader :original, :subset, :options
13
+ # Original font.
14
+ # @return [TTFunk::File]
15
+ attr_reader :original
12
16
 
17
+ # Subset to encode.
18
+ # @return [TTFunk::Subset]
19
+ attr_reader :subset
20
+
21
+ # Encoding options.
22
+ # @return [Hash]
23
+ attr_reader :options
24
+
25
+ # @param original [TTFunk::File]
26
+ # @param subset [TTFunk::Subset]
27
+ # @param options [Hash]
28
+ # @option options :kerning [Boolean] whether to encode Kerning (`kern`)
29
+ # table.
13
30
  def initialize(original, subset, options = {})
14
31
  @original = original
15
32
  @subset = subset
16
33
  @options = options
17
34
  end
18
35
 
36
+ # Encode the font subset.
37
+ #
38
+ # @return [String]
19
39
  def encode
20
40
  # https://www.microsoft.com/typography/otspec/otff.htm#offsetTable
21
- search_range = 2**Math.log2(tables.length).floor * 16
22
- entry_selector = Math.log2(2**Math.log2(tables.length).floor).to_i
23
- range_shift = tables.length * 16 - search_range
41
+ search_range = (2**Math.log2(tables.length).floor) * 16
42
+ entry_selector = Integer(Math.log2(2**Math.log2(tables.length).floor))
43
+ range_shift = (tables.length * 16) - search_range
24
44
  range_shift = 0 if range_shift.negative?
25
45
 
26
46
  newfont = EncodedString.new
@@ -30,7 +50,7 @@ module TTFunk
30
50
  tables.length,
31
51
  search_range,
32
52
  entry_selector,
33
- range_shift
53
+ range_shift,
34
54
  ].pack('Nn*')
35
55
 
36
56
  # Tables are supposed to be listed in ascending order whereas there is a
@@ -71,51 +91,35 @@ module TTFunk
71
91
  end
72
92
 
73
93
  def glyf_table
74
- @glyf_table ||= TTFunk::Table::Glyf.encode(
75
- glyphs, new_to_old_glyph, old_to_new_glyph
76
- )
94
+ @glyf_table ||= TTFunk::Table::Glyf.encode(glyphs, new_to_old_glyph, old_to_new_glyph)
77
95
  end
78
96
 
79
97
  def loca_table
80
- @loca_table ||= TTFunk::Table::Loca.encode(
81
- glyf_table[:offsets]
82
- )
98
+ @loca_table ||= TTFunk::Table::Loca.encode(glyf_table[:offsets])
83
99
  end
84
100
 
85
101
  def hmtx_table
86
- @hmtx_table ||= TTFunk::Table::Hmtx.encode(
87
- original.horizontal_metrics, new_to_old_glyph
88
- )
102
+ @hmtx_table ||= TTFunk::Table::Hmtx.encode(original.horizontal_metrics, new_to_old_glyph)
89
103
  end
90
104
 
91
105
  def hhea_table
92
- @hhea_table = TTFunk::Table::Hhea.encode(
93
- original.horizontal_header, hmtx_table, original, new_to_old_glyph
94
- )
106
+ @hhea_table = TTFunk::Table::Hhea.encode(original.horizontal_header, hmtx_table, original, new_to_old_glyph)
95
107
  end
96
108
 
97
109
  def maxp_table
98
- @maxp_table ||= TTFunk::Table::Maxp.encode(
99
- original.maximum_profile, old_to_new_glyph
100
- )
110
+ @maxp_table ||= TTFunk::Table::Maxp.encode(original.maximum_profile, old_to_new_glyph)
101
111
  end
102
112
 
103
113
  def post_table
104
- @post_table ||= TTFunk::Table::Post.encode(
105
- original.postscript, new_to_old_glyph
106
- )
114
+ @post_table ||= TTFunk::Table::Post.encode(original.postscript, new_to_old_glyph)
107
115
  end
108
116
 
109
117
  def name_table
110
- @name_table ||= TTFunk::Table::Name.encode(
111
- original.name, glyf_table.fetch(:table, '')
112
- )
118
+ @name_table ||= TTFunk::Table::Name.encode(original.name, glyf_table.fetch(:table, ''))
113
119
  end
114
120
 
115
121
  def head_table
116
- @head_table ||= TTFunk::Table::Head.encode(
117
- original.header, loca_table, new_to_old_glyph
118
- )
122
+ @head_table ||= TTFunk::Table::Head.encode(original.header, loca_table, new_to_old_glyph)
119
123
  end
120
124
 
121
125
  # "optional" tables. Fonts may omit these if they do not need them.
@@ -149,22 +153,16 @@ module TTFunk
149
153
  # generated subfont may need a kerning table... in that case, you need
150
154
  # to opt into it.
151
155
  if options[:kerning]
152
- @kern_table ||= TTFunk::Table::Kern.encode(
153
- original.kerning, old_to_new_glyph
154
- )
156
+ @kern_table ||= TTFunk::Table::Kern.encode(original.kerning, old_to_new_glyph)
155
157
  end
156
158
  end
157
159
 
158
160
  def vorg_table
159
- @vorg_table ||= TTFunk::Table::Vorg.encode(
160
- original.vertical_origins
161
- )
161
+ @vorg_table ||= TTFunk::Table::Vorg.encode(original.vertical_origins)
162
162
  end
163
163
 
164
164
  def dsig_table
165
- @dsig_table ||= TTFunk::Table::Dsig.encode(
166
- original.digital_signature
167
- )
165
+ @dsig_table ||= TTFunk::Table::Dsig.encode(original.digital_signature)
168
166
  end
169
167
 
170
168
  def tables
@@ -185,7 +183,7 @@ module TTFunk
185
183
  'cvt ' => cvt_table,
186
184
  'VORG' => vorg_table,
187
185
  'DSIG' => dsig_table,
188
- 'gasp' => gasp_table
186
+ 'gasp' => gasp_table,
189
187
  }.compact
190
188
  end
191
189
 
@@ -211,7 +209,7 @@ module TTFunk
211
209
 
212
210
  def align(data, width)
213
211
  if (data.length % width).positive?
214
- data + "\0" * (width - data.length % width)
212
+ data + ("\0" * (width - (data.length % width)))
215
213
  else
216
214
  data
217
215
  end
data/lib/ttfunk.rb CHANGED
@@ -20,25 +20,81 @@ require_relative 'ttfunk/max'
20
20
  require_relative 'ttfunk/sum'
21
21
  require_relative 'ttfunk/one_based_array'
22
22
 
23
+ # TTFunk is a TrueType and OpenType font library written in pure ruby. It
24
+ # supports both parsing and encoding of fonts. Also provides limited font
25
+ # subsetting.
26
+ #
27
+ # It supports a veriety of SFNT-based formats:
28
+ # * TrueType fonts (ttf)
29
+ # * OpenType fonts (otf), with both TrueType and CFF glyph outlines
30
+ # * DFont resources (dfont)
31
+ # * TrueType Collections (ttc)
32
+ #
33
+ # While not all TrueType and OpenType tables are implemented the most common
34
+ # ones are.
23
35
  module TTFunk
36
+ # TTFunk-specific exceptions
24
37
  class Error < StandardError; end
25
38
 
39
+ # File represents an individual font. It can represents both TrueType and
40
+ # OpenType fonts.
26
41
  class File
42
+ # Raw content of the font.
43
+ # @return [String]
27
44
  attr_reader :contents
45
+
46
+ # Font tables directory.
47
+ # @return [TTFunk::Directory]
28
48
  attr_reader :directory
29
49
 
50
+ # Open font file
51
+ #
52
+ # @overload open(io)
53
+ # @param io [IO] IO to read font content from. IO position and binmode
54
+ # might change.
55
+ # @return [TTFunk::File]
56
+ # @overload open(path)
57
+ # @param path [String, Pathname] Path to file to read the font from.
58
+ # @return [TTFunk::File]
30
59
  def self.open(io_or_path)
31
- new verify_and_open(io_or_path).read
60
+ new(verify_and_read(io_or_path))
32
61
  end
33
62
 
63
+ # Load a font from a resource file.
64
+ #
65
+ # @param file [String, Pathname] Path to the resource file.
66
+ # @param which [Integer, String] index or name of the font to load
67
+ # @return [TTFunk::File]]
34
68
  def self.from_dfont(file, which = 0)
35
69
  new(ResourceFile.open(file) { |dfont| dfont['sfnt', which] })
36
70
  end
37
71
 
72
+ # Load a font from a TrueType collection.
73
+ #
74
+ # @overload from_ttc(io, which = 0)
75
+ # @param file [IO] IO to read the collection from.
76
+ # @param which [Integer] index of the font to load
77
+ # @return [TTFunk::File]
78
+ # @overload from_ttc(file_path, which = 0)
79
+ # @param file_path [String, Pathname] Path to the resource file.
80
+ # @param which [Integer] index of the font to load
81
+ # @return [TTFunk::File]
38
82
  def self.from_ttc(file, which = 0)
39
83
  Collection.open(file) { |ttc| ttc[which] }
40
84
  end
41
85
 
86
+ # Turn a path or IO into an IO convenient for TTFunk. The resulting IO is
87
+ # going to be in bin mode and its position set to the beginning.
88
+ #
89
+ # @overload verify_and_open(io)
90
+ # @param io [IO] IO to prepare. Its position and binmode might
91
+ # change.
92
+ # @return [io]
93
+ # @overload verify_and_open(path)
94
+ # @param path [String, Pathname] path of the file to turn into an IO.
95
+ # @return [IO] newly opened IO for the path
96
+ # @deprecated This method might retain open files for longer than necessary.
97
+ # @see .verify_and_read
42
98
  def self.verify_and_open(io_or_path)
43
99
  # File or IO
44
100
  if io_or_path.respond_to?(:rewind)
@@ -58,86 +114,175 @@ module TTFunk
58
114
  io_or_path.open('rb')
59
115
  end
60
116
 
117
+ # Read contents of a path or IO.
118
+ #
119
+ # @overload verify_and_read(io)
120
+ # @param io [IO] IO to read from. Its position and binmode might
121
+ # change. IO is read from the beginning regardless of its initial
122
+ # position.
123
+ # @return [String]
124
+ # @overload verify_and_read(path)
125
+ # @param path [String, Pathname] path of the file to read.
126
+ # @return [String]
127
+ def self.verify_and_read(io_or_path)
128
+ # File or IO
129
+ if io_or_path.respond_to?(:rewind)
130
+ io = io_or_path
131
+ # Rewind if the object we're passed is an IO, so that multiple embeds of
132
+ # the same IO object will work
133
+ io.rewind
134
+ # read the file as binary so the size is calculated correctly
135
+ # guard binmode because some objects acting io-like don't implement it
136
+ io.binmode if io.respond_to?(:binmode)
137
+ return io.read
138
+ end
139
+ # String or Pathname
140
+ io_or_path = Pathname.new(io_or_path)
141
+ raise ArgumentError, "#{io_or_path} not found" unless io_or_path.file?
142
+
143
+ io_or_path.binread
144
+ end
145
+
146
+ # @param contents [String] binary string containg the font data
147
+ # @param offset [Integer] offset at which the font data starts
61
148
  def initialize(contents, offset = 0)
62
149
  @contents = StringIO.new(contents)
63
150
  @directory = Directory.new(@contents, offset)
64
151
  end
65
152
 
153
+ # Glyphs ascent as defined for in the font.
154
+ #
155
+ # @return [Integer]
66
156
  def ascent
67
157
  @ascent ||= (os2.exists? && os2.ascent && os2.ascent.nonzero?) ||
68
158
  horizontal_header.ascent
69
159
  end
70
160
 
161
+ # Glyphs descent as defined in the font.
162
+ #
163
+ # @return [Integer]
71
164
  def descent
72
165
  @descent ||= (os2.exists? && os2.descent && os2.descent.nonzero?) ||
73
166
  horizontal_header.descent
74
167
  end
75
168
 
169
+ # Line gap as defined in the font.
170
+ #
171
+ # @return [Integer]
76
172
  def line_gap
77
173
  @line_gap ||= (os2.exists? && os2.line_gap && os2.line_gap.nonzero?) ||
78
174
  horizontal_header.line_gap
79
175
  end
80
176
 
177
+ # Glyps bounding box as defined in the font.
178
+ #
179
+ # @return [Array(Integer, Integer, Integer, Integer)]
81
180
  def bbox
82
181
  [header.x_min, header.y_min, header.x_max, header.y_max]
83
182
  end
84
183
 
184
+ # Font directory entry for the table with the provided tag.
185
+ #
186
+ # @param tag [String] table tab
187
+ # @return [Hash, nil]
85
188
  def directory_info(tag)
86
189
  directory.tables[tag.to_s]
87
190
  end
88
191
 
192
+ # Font Header (`head`) table
193
+ #
194
+ # @return [TTFunk::Table::Head, nil]
89
195
  def header
90
196
  @header ||= TTFunk::Table::Head.new(self)
91
197
  end
92
198
 
199
+ # Character to Glyph Index Mapping (`cmap`) table
200
+ #
201
+ # @return [TTFunk::Tbale::Cmap, nil]
93
202
  def cmap
94
203
  @cmap ||= TTFunk::Table::Cmap.new(self)
95
204
  end
96
205
 
206
+ # Horizontal Header (`hhea`) table
207
+ #
208
+ # @return [TTFunk::Table::Hhea, nil]
97
209
  def horizontal_header
98
210
  @horizontal_header ||= TTFunk::Table::Hhea.new(self)
99
211
  end
100
212
 
213
+ # Horizontal Metrics (`hmtx`) table
214
+ #
215
+ # @return [TTFunk::Table::Hmtx, nil]
101
216
  def horizontal_metrics
102
217
  @horizontal_metrics ||= TTFunk::Table::Hmtx.new(self)
103
218
  end
104
219
 
220
+ # Maximum Profile (`maxp`) table
221
+ #
222
+ # @return [TTFunk::Table::Maxp, nil]
105
223
  def maximum_profile
106
224
  @maximum_profile ||= TTFunk::Table::Maxp.new(self)
107
225
  end
108
226
 
227
+ # Kerning (`kern`) table
228
+ #
229
+ # @return [TTFunk::Table::Kern, nil]
109
230
  def kerning
110
231
  @kerning ||= TTFunk::Table::Kern.new(self)
111
232
  end
112
233
 
234
+ # Naming (`name`) table
235
+ #
236
+ # @return [TTFunk::Table::Name, nil]
113
237
  def name
114
238
  @name ||= TTFunk::Table::Name.new(self)
115
239
  end
116
240
 
241
+ # OS/2 and Windows Metrics (`OS/2`) table
242
+ #
243
+ # @return [TTFunk::Table:OS2, nil]
117
244
  def os2
118
245
  @os2 ||= TTFunk::Table::OS2.new(self)
119
246
  end
120
247
 
248
+ # PostScript (`post`) table
249
+ #
250
+ # @return [TTFunk::Table::Post, nil]
121
251
  def postscript
122
252
  @postscript ||= TTFunk::Table::Post.new(self)
123
253
  end
124
254
 
255
+ # Index to Location (`loca`) table
256
+ #
257
+ # @return [TTFunk::Table::Loca, nil]
125
258
  def glyph_locations
126
259
  @glyph_locations ||= TTFunk::Table::Loca.new(self)
127
260
  end
128
261
 
262
+ # Glyph Data (`glyf`) table
263
+ #
264
+ # @return [TTFunk::Table::Glyf, nil]
129
265
  def glyph_outlines
130
266
  @glyph_outlines ||= TTFunk::Table::Glyf.new(self)
131
267
  end
132
268
 
269
+ # Standard Bitmap Graphics (`sbix`) table
270
+ #
271
+ # @return [TTFunk::Table::Sbix, nil]
133
272
  def sbix
134
273
  @sbix ||= TTFunk::Table::Sbix.new(self)
135
274
  end
136
275
 
276
+ # Compact Font Format (`CFF `) table
277
+ #
278
+ # @return [Table::Table::Cff, nil]
137
279
  def cff
138
280
  @cff ||= TTFunk::Table::Cff.new(self)
139
281
  end
140
282
 
283
+ # Vertical Origin (`VORG`) table
284
+ #
285
+ # @return [TTFunk::Table::Vorg, nil]
141
286
  def vertical_origins
142
287
  @vertical_origins ||=
143
288
  if directory.tables.include?(TTFunk::Table::Vorg::TAG)
@@ -145,6 +290,9 @@ module TTFunk
145
290
  end
146
291
  end
147
292
 
293
+ # Digital Signature (`DSIG`) table
294
+ #
295
+ # @return [TTFunk::Table::Dsig, nil]
148
296
  def digital_signature
149
297
  @digital_signature ||=
150
298
  if directory.tables.include?(TTFunk::Table::Dsig::TAG)
@@ -152,6 +300,11 @@ module TTFunk
152
300
  end
153
301
  end
154
302
 
303
+ # Find glyph by its index.
304
+ #
305
+ # @return [TTFunk::Table::Cff::Charstring] if it's a CFF-based OpenType font
306
+ # @return [TTFunk::Table::Glyf::Simple, TTFunk::Table::Glyf::Compound]
307
+ # if it's a TrueType font
155
308
  def find_glyph(glyph_id)
156
309
  if cff.exists?
157
310
  cff.top_index[0].charstrings_index[glyph_id].glyph
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,9 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ttfunk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
+ - Alexander Mankuta
7
8
  - Gregory Brown
8
9
  - Brad Ediger
9
10
  - Daniel Nelson
@@ -15,43 +16,58 @@ bindir: bin
15
16
  cert_chain:
16
17
  - |
17
18
  -----BEGIN CERTIFICATE-----
18
- MIIDODCCAiCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhhbGV4
19
- L0RDPXBvaW50bGVzcy9EQz1vbmUwHhcNMjAwODAxMTQxMjE1WhcNMjEwODAxMTQx
20
- MjE1WjAjMSEwHwYDVQQDDBhhbGV4L0RDPXBvaW50bGVzcy9EQz1vbmUwggEiMA0G
21
- CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPOVLPGEK+eaP6zJfifrpWvPTg4qo3
22
- XNJJPom80SwqX2hVCVsRDK4RYgKUQqKRQzHhlx14wZHwWLETBVbNDGX3uqyCnTWU
23
- JUKh3ydiZShXpNHoV/NW7hhEYvNsDcBAjYTmbvXOhuYCo0Tz/0N2Oiun/0wIICtP
24
- vytY9TY0/lklWjAbsqJjNOu3o8IYkJBAN/rU96E/6WhFwjnxLcTnV9RfFRXdjG5j
25
- CughoB2xSwKX8gwbQ8fsnaZRmdyDGYNpz6sGF0zycfiLkTttbLA2nYATCALy98CH
26
- nsyZNsTjb4WINCuY2yEDjwesw9f/ROkNC68EgQ5M+aMjp+D0WcYGfzojAgMBAAGj
27
- dzB1MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBRPgIwSVbeonua/
28
- Ny/8576oxdUbrjAdBgNVHREEFjAUgRJhbGV4QHBvaW50bGVzcy5vbmUwHQYDVR0S
29
- BBYwFIESYWxleEBwb2ludGxlc3Mub25lMA0GCSqGSIb3DQEBCwUAA4IBAQAzhGxF
30
- M0bXJ9GWD9vdVHOyzBQBJcJAvnsz2yV3+r4eJBsQynFIscsea8lHFL/d1eHYP0mN
31
- k0fhK+WDcPlrj0Sn/Ezhk2qogTIekwDOK6pZkGRQzD45leJqQMnYd+/TXK3ri485
32
- Gi4oJ6NitnnUT59SQnjD5JcENfc0EcRzclmVRFE8W4O+ORgo4Dypq1rwYUzxeyUk
33
- mP5jNBWtH+hGUph28GQb0Hph6YnQb8zEFB88Xq80PK1SzkIPHpbTBk9mwPf6ypeX
34
- Un1TJEahAlgENVml6CyDXSwk0H8N1V3gm1mb9Fe1T2Z/kAzvjo0qTDEtMVLU7Bxh
35
- uqMUrdETjTnRYCVq
19
+ MIIDMjCCAhqgAwIBAgIBAzANBgkqhkiG9w0BAQsFADA/MQ0wCwYDVQQDDARhbGV4
20
+ MRkwFwYKCZImiZPyLGQBGRYJcG9pbnRsZXNzMRMwEQYKCZImiZPyLGQBGRYDb25l
21
+ MB4XDTI0MDMwNDIwMTIyOFoXDTI1MDMwNDIwMTIyOFowPzENMAsGA1UEAwwEYWxl
22
+ eDEZMBcGCgmSJomT8ixkARkWCXBvaW50bGVzczETMBEGCgmSJomT8ixkARkWA29u
23
+ ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM85Us8YQr55o/rMl+J+
24
+ ula89ODiqjdc0kk+ibzRLCpfaFUJWxEMrhFiApRCopFDMeGXHXjBkfBYsRMFVs0M
25
+ Zfe6rIKdNZQlQqHfJ2JlKFek0ehX81buGERi82wNwECNhOZu9c6G5gKjRPP/Q3Y6
26
+ K6f/TAggK0+/K1j1NjT+WSVaMBuyomM067ejwhiQkEA3+tT3oT/paEXCOfEtxOdX
27
+ 1F8VFd2MbmMK6CGgHbFLApfyDBtDx+ydplGZ3IMZg2nPqwYXTPJx+IuRO21ssDad
28
+ gBMIAvL3wIeezJk2xONvhYg0K5jbIQOPB6zD1/9E6Q0LrwSBDkz5oyOn4PRZxgZ/
29
+ OiMCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFE+A
30
+ jBJVt6ie5r83L/znvqjF1RuuMA0GCSqGSIb3DQEBCwUAA4IBAQAam5ZgizC0Pknb
31
+ nm7O8fY6+0rdvIP9Zhzbigvfjy664xyZYJ2hJLnvN64wKewcYeYIrC/OEOVbkjWl
32
+ YUDqUfy59JAYvJNQJDi2ZbJPji17WlQaz/x/0QlwWnsYIjOBw0Jyi5Hv41pkMAcO
33
+ +YgdSby0qLIu8sNoTP4YXxRyBuHNBgAUexf3x+dvMyHuM+Q/lKiKmJLwzUlcYr0F
34
+ luk6Jow2lBzuzfjss07L5THk162mtlWVIdtbLsAvcxwTwVZ7W0bKQkyJnTj8gnye
35
+ +ucJ3nnxbYV+GcYHgWdTMu39wjP8z+w+PYLBxpaVjThblqhDQpmIjT4zJvAQALi9
36
+ auxR4ast
36
37
  -----END CERTIFICATE-----
37
- date: 2020-12-29 00:00:00.000000000 Z
38
+ date: 2024-03-04 00:00:00.000000000 Z
38
39
  dependencies:
40
+ - !ruby/object:Gem::Dependency
41
+ name: bigdecimal
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.1'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.1'
39
54
  - !ruby/object:Gem::Dependency
40
55
  name: prawn-dev
41
56
  requirement: !ruby/object:Gem::Requirement
42
57
  requirements:
43
58
  - - "~>"
44
59
  - !ruby/object:Gem::Version
45
- version: 0.1.0
60
+ version: 0.4.0
46
61
  type: :development
47
62
  prerelease: false
48
63
  version_requirements: !ruby/object:Gem::Requirement
49
64
  requirements:
50
65
  - - "~>"
51
66
  - !ruby/object:Gem::Version
52
- version: 0.1.0
67
+ version: 0.4.0
53
68
  description: Font Metrics Parser for the Prawn PDF generator
54
69
  email:
70
+ - alex@pointless.one
55
71
  - gregory.t.brown@gmail.com
56
72
  - brad@bradediger.com
57
73
  - dnelson@bluejade.com
@@ -149,12 +165,18 @@ files:
149
165
  - lib/ttfunk/table/simple.rb
150
166
  - lib/ttfunk/table/vorg.rb
151
167
  - lib/ttfunk/ttf_encoder.rb
152
- homepage: https://prawnpdf.org
168
+ homepage: http://prawnpdf.org/
153
169
  licenses:
154
170
  - Nonstandard
155
- - GPL-2.0
156
- - GPL-3.0
157
- metadata: {}
171
+ - GPL-2.0-only
172
+ - GPL-3.0-only
173
+ metadata:
174
+ rubygems_mfa_required: 'true'
175
+ homepage_uri: http://prawnpdf.org/
176
+ changelog_uri: https://github.com/prawnpdf/ttfunk/blob/1.8.0/CHANGELOG.md
177
+ source_code_uri: https://github.com/prawnpdf/ttfunk
178
+ documentation_uri: https://prwnpdf.org/docs/ttfunk/1.8.0/
179
+ bug_tracker_uri: https://github.com/prawnpdf/ttfunk/issues
158
180
  post_install_message:
159
181
  rdoc_options: []
160
182
  require_paths:
@@ -163,14 +185,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
185
  requirements:
164
186
  - - ">="
165
187
  - !ruby/object:Gem::Version
166
- version: '2.5'
188
+ version: '2.7'
167
189
  required_rubygems_version: !ruby/object:Gem::Requirement
168
190
  requirements:
169
191
  - - ">="
170
192
  - !ruby/object:Gem::Version
171
193
  version: '0'
172
194
  requirements: []
173
- rubygems_version: 3.2.3
195
+ rubygems_version: 3.5.3
174
196
  signing_key:
175
197
  specification_version: 4
176
198
  summary: TrueType Font Metrics Parser
metadata.gz.sig CHANGED
Binary file