glyph_imager 0.0.14 → 0.1.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 (82) hide show
  1. data/VERSION +1 -1
  2. data/glyph_imager.gemspec +45 -36
  3. data/lib/glyph_imager.rb +19 -27
  4. data/test/fonts/Musica.ttf +0 -0
  5. data/test/test_glyph_imager.rb +9 -3
  6. data/vendor/ttfunk/.gitignore +1 -0
  7. data/vendor/ttfunk/data/fonts/DejaVuSans.ttf +0 -0
  8. data/vendor/ttfunk/data/fonts/comicsans.ttf +0 -0
  9. data/vendor/ttfunk/example.rb +45 -0
  10. data/vendor/ttfunk/lib/ttfunk.rb +102 -0
  11. data/vendor/ttfunk/lib/ttfunk/directory.rb +17 -0
  12. data/vendor/ttfunk/lib/ttfunk/encoding/mac_roman.rb +88 -0
  13. data/vendor/ttfunk/lib/ttfunk/encoding/windows_1252.rb +69 -0
  14. data/vendor/ttfunk/lib/ttfunk/reader.rb +44 -0
  15. data/vendor/ttfunk/lib/ttfunk/resource_file.rb +78 -0
  16. data/vendor/ttfunk/lib/ttfunk/subset.rb +18 -0
  17. data/vendor/ttfunk/lib/ttfunk/subset/base.rb +141 -0
  18. data/vendor/ttfunk/lib/ttfunk/subset/mac_roman.rb +50 -0
  19. data/vendor/ttfunk/lib/ttfunk/subset/unicode.rb +48 -0
  20. data/vendor/ttfunk/lib/ttfunk/subset/unicode_8bit.rb +63 -0
  21. data/vendor/ttfunk/lib/ttfunk/subset/windows_1252.rb +55 -0
  22. data/vendor/ttfunk/lib/ttfunk/subset_collection.rb +72 -0
  23. data/vendor/ttfunk/lib/ttfunk/table.rb +46 -0
  24. data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +34 -0
  25. data/vendor/ttfunk/lib/ttfunk/table/cmap/format00.rb +54 -0
  26. data/vendor/ttfunk/lib/ttfunk/table/cmap/format04.rb +126 -0
  27. data/vendor/ttfunk/lib/ttfunk/table/cmap/format12.rb +37 -0
  28. data/vendor/ttfunk/lib/ttfunk/table/cmap/subtable.rb +82 -0
  29. data/vendor/ttfunk/lib/ttfunk/table/glyf.rb +64 -0
  30. data/vendor/ttfunk/lib/ttfunk/table/glyf/compound.rb +81 -0
  31. data/vendor/ttfunk/lib/ttfunk/table/glyf/simple.rb +37 -0
  32. data/vendor/ttfunk/lib/ttfunk/table/head.rb +44 -0
  33. data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +41 -0
  34. data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +47 -0
  35. data/vendor/ttfunk/lib/ttfunk/table/kern.rb +79 -0
  36. data/vendor/ttfunk/lib/ttfunk/table/kern/format0.rb +62 -0
  37. data/vendor/ttfunk/lib/ttfunk/table/loca.rb +43 -0
  38. data/vendor/ttfunk/lib/ttfunk/table/maxp.rb +40 -0
  39. data/vendor/ttfunk/lib/ttfunk/table/name.rb +125 -0
  40. data/vendor/ttfunk/lib/ttfunk/table/os2.rb +78 -0
  41. data/vendor/ttfunk/lib/ttfunk/table/post.rb +91 -0
  42. data/vendor/ttfunk/lib/ttfunk/table/post/format10.rb +43 -0
  43. data/vendor/ttfunk/lib/ttfunk/table/post/format20.rb +35 -0
  44. data/vendor/ttfunk/lib/ttfunk/table/post/format25.rb +23 -0
  45. data/vendor/ttfunk/lib/ttfunk/table/post/format30.rb +17 -0
  46. data/vendor/ttfunk/lib/ttfunk/table/post/format40.rb +17 -0
  47. data/vendor/ttfunk/lib/ttfunk/table/simple.rb +14 -0
  48. metadata +46 -37
  49. data/vendor/ttf-ruby-0.1/AUTHORS +0 -1
  50. data/vendor/ttf-ruby-0.1/COPYING +0 -340
  51. data/vendor/ttf-ruby-0.1/README +0 -49
  52. data/vendor/ttf-ruby-0.1/TODO +0 -23
  53. data/vendor/ttf-ruby-0.1/VERSION +0 -1
  54. data/vendor/ttf-ruby-0.1/lib/ttf.rb +0 -20
  55. data/vendor/ttf-ruby-0.1/lib/ttf/datatypes.rb +0 -181
  56. data/vendor/ttf-ruby-0.1/lib/ttf/encodings.rb +0 -140
  57. data/vendor/ttf-ruby-0.1/lib/ttf/exceptions.rb +0 -28
  58. data/vendor/ttf-ruby-0.1/lib/ttf/font_loader.rb +0 -290
  59. data/vendor/ttf-ruby-0.1/lib/ttf/fontchunk.rb +0 -77
  60. data/vendor/ttf-ruby-0.1/lib/ttf/table/cmap.rb +0 -408
  61. data/vendor/ttf-ruby-0.1/lib/ttf/table/cvt.rb +0 -49
  62. data/vendor/ttf-ruby-0.1/lib/ttf/table/fpgm.rb +0 -48
  63. data/vendor/ttf-ruby-0.1/lib/ttf/table/gasp.rb +0 -88
  64. data/vendor/ttf-ruby-0.1/lib/ttf/table/glyf.rb +0 -452
  65. data/vendor/ttf-ruby-0.1/lib/ttf/table/head.rb +0 -86
  66. data/vendor/ttf-ruby-0.1/lib/ttf/table/hhea.rb +0 -96
  67. data/vendor/ttf-ruby-0.1/lib/ttf/table/hmtx.rb +0 -98
  68. data/vendor/ttf-ruby-0.1/lib/ttf/table/kern.rb +0 -186
  69. data/vendor/ttf-ruby-0.1/lib/ttf/table/loca.rb +0 -75
  70. data/vendor/ttf-ruby-0.1/lib/ttf/table/maxp.rb +0 -81
  71. data/vendor/ttf-ruby-0.1/lib/ttf/table/name.rb +0 -226
  72. data/vendor/ttf-ruby-0.1/lib/ttf/table/os2.rb +0 -172
  73. data/vendor/ttf-ruby-0.1/lib/ttf/table/post.rb +0 -120
  74. data/vendor/ttf-ruby-0.1/lib/ttf/table/prep.rb +0 -27
  75. data/vendor/ttf-ruby-0.1/lib/ttf/table/vhea.rb +0 -45
  76. data/vendor/ttf-ruby-0.1/lib/ttf/table/vmtx.rb +0 -36
  77. data/vendor/ttf-ruby-0.1/setup.rb +0 -1558
  78. data/vendor/ttf-ruby-0.1/tools/README +0 -44
  79. data/vendor/ttf-ruby-0.1/tools/ttfcairoglyphviewer +0 -229
  80. data/vendor/ttf-ruby-0.1/tools/ttfdump +0 -396
  81. data/vendor/ttf-ruby-0.1/tools/ttfglyph2svg +0 -144
  82. data/vendor/ttf-ruby-0.1/tools/ttfsubset +0 -273
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.14
1
+ 0.1.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{glyph_imager}
8
- s.version = "0.0.14"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["William Melody"]
12
- s.date = %q{2010-05-24}
12
+ s.date = %q{2010-05-27}
13
13
  s.description = %q{Generate images of glyphs for a specified character in a specified font}
14
14
  s.email = %q{hi@williammelody.com}
15
15
  s.extra_rdoc_files = [
@@ -26,42 +26,51 @@ Gem::Specification.new do |s|
26
26
  "glyph_imager.gemspec",
27
27
  "lib/glyph_imager.rb",
28
28
  "test/fonts/DejaVuSerif.ttf",
29
+ "test/fonts/Musica.ttf",
29
30
  "test/helper.rb",
30
31
  "test/test_glyph_imager.rb",
31
- "vendor/ttf-ruby-0.1/AUTHORS",
32
- "vendor/ttf-ruby-0.1/COPYING",
33
- "vendor/ttf-ruby-0.1/README",
34
- "vendor/ttf-ruby-0.1/TODO",
35
- "vendor/ttf-ruby-0.1/VERSION",
36
- "vendor/ttf-ruby-0.1/lib/ttf.rb",
37
- "vendor/ttf-ruby-0.1/lib/ttf/datatypes.rb",
38
- "vendor/ttf-ruby-0.1/lib/ttf/encodings.rb",
39
- "vendor/ttf-ruby-0.1/lib/ttf/exceptions.rb",
40
- "vendor/ttf-ruby-0.1/lib/ttf/font_loader.rb",
41
- "vendor/ttf-ruby-0.1/lib/ttf/fontchunk.rb",
42
- "vendor/ttf-ruby-0.1/lib/ttf/table/cmap.rb",
43
- "vendor/ttf-ruby-0.1/lib/ttf/table/cvt.rb",
44
- "vendor/ttf-ruby-0.1/lib/ttf/table/fpgm.rb",
45
- "vendor/ttf-ruby-0.1/lib/ttf/table/gasp.rb",
46
- "vendor/ttf-ruby-0.1/lib/ttf/table/glyf.rb",
47
- "vendor/ttf-ruby-0.1/lib/ttf/table/head.rb",
48
- "vendor/ttf-ruby-0.1/lib/ttf/table/hhea.rb",
49
- "vendor/ttf-ruby-0.1/lib/ttf/table/hmtx.rb",
50
- "vendor/ttf-ruby-0.1/lib/ttf/table/kern.rb",
51
- "vendor/ttf-ruby-0.1/lib/ttf/table/loca.rb",
52
- "vendor/ttf-ruby-0.1/lib/ttf/table/maxp.rb",
53
- "vendor/ttf-ruby-0.1/lib/ttf/table/name.rb",
54
- "vendor/ttf-ruby-0.1/lib/ttf/table/os2.rb",
55
- "vendor/ttf-ruby-0.1/lib/ttf/table/post.rb",
56
- "vendor/ttf-ruby-0.1/lib/ttf/table/prep.rb",
57
- "vendor/ttf-ruby-0.1/lib/ttf/table/vhea.rb",
58
- "vendor/ttf-ruby-0.1/lib/ttf/table/vmtx.rb",
59
- "vendor/ttf-ruby-0.1/setup.rb",
60
- "vendor/ttf-ruby-0.1/tools/README",
61
- "vendor/ttf-ruby-0.1/tools/ttfcairoglyphviewer",
62
- "vendor/ttf-ruby-0.1/tools/ttfdump",
63
- "vendor/ttf-ruby-0.1/tools/ttfglyph2svg",
64
- "vendor/ttf-ruby-0.1/tools/ttfsubset"
32
+ "vendor/ttfunk/.gitignore",
33
+ "vendor/ttfunk/data/fonts/DejaVuSans.ttf",
34
+ "vendor/ttfunk/data/fonts/comicsans.ttf",
35
+ "vendor/ttfunk/example.rb",
36
+ "vendor/ttfunk/lib/ttfunk.rb",
37
+ "vendor/ttfunk/lib/ttfunk/directory.rb",
38
+ "vendor/ttfunk/lib/ttfunk/encoding/mac_roman.rb",
39
+ "vendor/ttfunk/lib/ttfunk/encoding/windows_1252.rb",
40
+ "vendor/ttfunk/lib/ttfunk/reader.rb",
41
+ "vendor/ttfunk/lib/ttfunk/resource_file.rb",
42
+ "vendor/ttfunk/lib/ttfunk/subset.rb",
43
+ "vendor/ttfunk/lib/ttfunk/subset/base.rb",
44
+ "vendor/ttfunk/lib/ttfunk/subset/mac_roman.rb",
45
+ "vendor/ttfunk/lib/ttfunk/subset/unicode.rb",
46
+ "vendor/ttfunk/lib/ttfunk/subset/unicode_8bit.rb",
47
+ "vendor/ttfunk/lib/ttfunk/subset/windows_1252.rb",
48
+ "vendor/ttfunk/lib/ttfunk/subset_collection.rb",
49
+ "vendor/ttfunk/lib/ttfunk/table.rb",
50
+ "vendor/ttfunk/lib/ttfunk/table/cmap.rb",
51
+ "vendor/ttfunk/lib/ttfunk/table/cmap/format00.rb",
52
+ "vendor/ttfunk/lib/ttfunk/table/cmap/format04.rb",
53
+ "vendor/ttfunk/lib/ttfunk/table/cmap/format12.rb",
54
+ "vendor/ttfunk/lib/ttfunk/table/cmap/subtable.rb",
55
+ "vendor/ttfunk/lib/ttfunk/table/glyf.rb",
56
+ "vendor/ttfunk/lib/ttfunk/table/glyf/compound.rb",
57
+ "vendor/ttfunk/lib/ttfunk/table/glyf/simple.rb",
58
+ "vendor/ttfunk/lib/ttfunk/table/head.rb",
59
+ "vendor/ttfunk/lib/ttfunk/table/hhea.rb",
60
+ "vendor/ttfunk/lib/ttfunk/table/hmtx.rb",
61
+ "vendor/ttfunk/lib/ttfunk/table/kern.rb",
62
+ "vendor/ttfunk/lib/ttfunk/table/kern/format0.rb",
63
+ "vendor/ttfunk/lib/ttfunk/table/loca.rb",
64
+ "vendor/ttfunk/lib/ttfunk/table/maxp.rb",
65
+ "vendor/ttfunk/lib/ttfunk/table/name.rb",
66
+ "vendor/ttfunk/lib/ttfunk/table/os2.rb",
67
+ "vendor/ttfunk/lib/ttfunk/table/post.rb",
68
+ "vendor/ttfunk/lib/ttfunk/table/post/format10.rb",
69
+ "vendor/ttfunk/lib/ttfunk/table/post/format20.rb",
70
+ "vendor/ttfunk/lib/ttfunk/table/post/format25.rb",
71
+ "vendor/ttfunk/lib/ttfunk/table/post/format30.rb",
72
+ "vendor/ttfunk/lib/ttfunk/table/post/format40.rb",
73
+ "vendor/ttfunk/lib/ttfunk/table/simple.rb"
65
74
  ]
66
75
  s.homepage = %q{http://github.com/alphabetum/glyph_imager}
67
76
  s.rdoc_options = ["--charset=UTF-8"]
@@ -1,5 +1,5 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'vendor', 'ttf-ruby-0.1', 'lib'))
2
- require 'ttf'
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'vendor', 'ttfunk', 'lib'))
2
+ require 'ttfunk'
3
3
 
4
4
  module GlyphImager
5
5
 
@@ -22,55 +22,47 @@ module GlyphImager
22
22
  class FontRecord
23
23
 
24
24
  @@metadata_ids = %w[
25
- copyright_notice
26
- font_family_name
27
- font_subfamily_name
28
- unique_font_identifier
29
- full_font_name
30
- version_string
31
- postscript_name
25
+ copyright
26
+ font_family
27
+ font_subfamily
28
+ unique_subfamily
29
+ font_name
30
+ version
32
31
  trademark
33
- manufacturer_name
34
- designer_name
32
+ manufacturer
33
+ designer
35
34
  description
36
35
  vendor_url
37
36
  designer_url
38
- license_description
37
+ license
39
38
  license_url
40
- reserved
41
39
  preferred_family
42
40
  preferred_subfamily
43
41
  compatible_full
42
+ sample_text
44
43
  ]
45
44
 
46
-
47
45
  @@metadata_ids.each do |m|
48
46
  define_method(m) do
49
- name_table.find_record_by_id(@@metadata_ids.index(m)).to_s
47
+ font.name.send(m).first
50
48
  end
51
49
  end
52
50
 
53
51
  def initialize(filename)
54
- @font = TTFFont::TTF::FontLoader.new(filename)
52
+ @font = TTFunk::File.open(filename)
55
53
  end
56
54
 
57
55
  def font
58
56
  @font
59
57
  end
60
58
 
61
- def name_table
62
- @name_table ||= @font.get_table(:name)
63
- end
64
-
65
- def get_encoding_table4
66
- @enc_tbl ||= @font.get_table(:cmap).encoding_tables.find do |t|
67
- t.class == TTFFont::TTF::Table::Cmap::EncodingTable4
68
- end
69
- end
70
-
71
59
  def has_glyph_for_unicode_char?(code_point)
72
60
  return false if control_character_points.include?(code_point)
73
- get_encoding_table4.get_glyph_id_for_unicode(code_point.hex) != 0
61
+ if format12 = font.cmap.unicode.detect { |t| t.format == 12 }
62
+ format12[code_point.hex] != 0
63
+ elsif format4 = font.cmap.unicode.detect { |t| t.format == 4 }
64
+ format4[code_point.hex] != 0
65
+ end
74
66
  end
75
67
 
76
68
  def control_character_points
Binary file
@@ -7,6 +7,8 @@ class TestGlyphImager < Test::Unit::TestCase
7
7
  @font_path = File.join(@fonts_dir, 'DejaVuSerif.ttf')
8
8
  @font = GlyphImager::FontRecord.new(@font_path)
9
9
  @times = GlyphImager::FontRecord.new(File.join(@fonts_dir, 'other', 'TimesRoman.ttf'))
10
+ @musica = GlyphImager::FontRecord.new(File.join(@fonts_dir, 'Musica.ttf'))
11
+
10
12
  @output_dir = "/tmp"
11
13
  end
12
14
 
@@ -23,14 +25,18 @@ class TestGlyphImager < Test::Unit::TestCase
23
25
  end
24
26
 
25
27
  should "return font metadata" do
26
- assert_equal "DejaVu Serif", @font.full_font_name
27
- assert_equal "Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.\nDejaVu changes are in public domain\n", @font.copyright_notice
28
- assert_equal "DejaVu fonts team", @font.manufacturer_name
28
+ assert_equal "DejaVu Serif", @font.font_name
29
+ assert_equal "Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.\nDejaVu changes are in public domain\n", @font.copyright
30
+ assert_equal "DejaVu fonts team", @font.manufacturer
29
31
  end
30
32
 
31
33
  should "return true when glyph exists for character" do
32
34
  assert @font.has_glyph_for_unicode_char?("0021")
33
35
  end
36
+
37
+ should "return true when glyph exists for high cp" do
38
+ assert @musica.has_glyph_for_unicode_char?("1D032")
39
+ end
34
40
 
35
41
  should "return false when glyph is control char" do
36
42
  assert !@times.has_glyph_for_unicode_char?("0000")
@@ -0,0 +1 @@
1
+ *.swp
@@ -0,0 +1,45 @@
1
+ $LOAD_PATH << "#{File.dirname(__FILE__)}/lib"
2
+ require "ttfunk"
3
+
4
+ def character_lookup(file, character)
5
+ puts "character : #{character}"
6
+
7
+ character_code = character.unpack("U*").first
8
+ puts "character code: #{character_code}"
9
+
10
+ glyph_id = file.cmap.unicode.first[character_code]
11
+ puts "glyph id : #{glyph_id}"
12
+
13
+ glyph = file.glyph_outlines.for(glyph_id)
14
+ puts "glyph type : %s" % glyph.class.name.split(/::/).last.downcase
15
+ puts "glyph size : %db" % glyph.raw.length
16
+ puts "glyph bbox : (%d,%d)-(%d,%d)" % [glyph.x_min, glyph.y_min, glyph.x_max, glyph.y_max]
17
+
18
+ if glyph.compound?
19
+ puts "components : %d %s" % [glyph.glyph_ids.length, glyph.glyph_ids.inspect]
20
+ end
21
+ end
22
+
23
+ file = TTFunk::File.open(ARGV.first || "data/fonts/DejaVuSans.ttf")
24
+
25
+ puts "-- FONT ------------------------------------"
26
+
27
+ puts "revision : %08x" % file.header.font_revision
28
+ puts "name : #{file.name.font_name.join(', ')}"
29
+ puts "family : #{file.name.font_family.join(', ')}"
30
+ puts "subfamily : #{file.name.font_subfamily.join(', ')}"
31
+ puts "postscript: #{file.name.postscript_name}"
32
+
33
+ puts "-- FONT METRICS ----------------------------"
34
+
35
+ puts "units/em : #{file.header.units_per_em}"
36
+ puts "ascent : #{file.ascent}"
37
+ puts "descent : #{file.descent}"
38
+ puts "line gap : #{file.line_gap}"
39
+ puts "bbox : (%d,%d)-(%d,%d)" % file.bbox
40
+
41
+ puts "-- SIMPLE CHARACTER -> GLYPH LOOKUP --------"
42
+ character_lookup(file, "\xE2\x98\x9C")
43
+
44
+ puts "-- COMPOUND CHARACTER -> GLYPH LOOKUP ------"
45
+ character_lookup(file, "ë")
@@ -0,0 +1,102 @@
1
+ require 'stringio'
2
+ require 'ttfunk/directory'
3
+ require 'ttfunk/resource_file'
4
+
5
+ module TTFunk
6
+ class File
7
+ attr_reader :contents
8
+ attr_reader :directory
9
+
10
+ def self.open(file)
11
+ new(::File.open(file, "rb") { |f| f.read })
12
+ end
13
+
14
+ def self.from_dfont(file, which=0)
15
+ new(ResourceFile.open(file) { |dfont| dfont["sfnt", which] })
16
+ end
17
+
18
+ def initialize(contents)
19
+ @contents = StringIO.new(contents)
20
+ @directory = Directory.new(@contents)
21
+ end
22
+
23
+
24
+ def ascent
25
+ @ascent ||= os2.exists? && os2.ascent || horizontal_header.ascent
26
+ end
27
+
28
+ def descent
29
+ @descent ||= os2.exists? && os2.descent || horizontal_header.descent
30
+ end
31
+
32
+ def line_gap
33
+ @line_gap ||= os2.exists? && os2.line_gap || horizontal_header.line_gap
34
+ end
35
+
36
+ def bbox
37
+ [header.x_min, header.y_min, header.x_max, header.y_max]
38
+ end
39
+
40
+
41
+ def directory_info(tag)
42
+ directory.tables[tag.to_s]
43
+ end
44
+
45
+ def header
46
+ @header ||= TTFunk::Table::Head.new(self)
47
+ end
48
+
49
+ def cmap
50
+ @cmap ||= TTFunk::Table::Cmap.new(self)
51
+ end
52
+
53
+ def horizontal_header
54
+ @horizontal_header ||= TTFunk::Table::Hhea.new(self)
55
+ end
56
+
57
+ def horizontal_metrics
58
+ @horizontal_metrics ||= TTFunk::Table::Hmtx.new(self)
59
+ end
60
+
61
+ def maximum_profile
62
+ @maximum_profile ||= TTFunk::Table::Maxp.new(self)
63
+ end
64
+
65
+ def kerning
66
+ @kerning ||= TTFunk::Table::Kern.new(self)
67
+ end
68
+
69
+ def name
70
+ @name ||= TTFunk::Table::Name.new(self)
71
+ end
72
+
73
+ def os2
74
+ @os2 ||= TTFunk::Table::OS2.new(self)
75
+ end
76
+
77
+ def postscript
78
+ @postscript ||= TTFunk::Table::Post.new(self)
79
+ end
80
+
81
+ def glyph_locations
82
+ @glyph_locations ||= TTFunk::Table::Loca.new(self)
83
+ end
84
+
85
+ def glyph_outlines
86
+ @glyph_outlines ||= TTFunk::Table::Glyf.new(self)
87
+ end
88
+ end
89
+ end
90
+
91
+ require "ttfunk/table/cmap"
92
+ require "ttfunk/table/glyf"
93
+ require "ttfunk/table/head"
94
+ require "ttfunk/table/hhea"
95
+ require "ttfunk/table/hmtx"
96
+ require "ttfunk/table/kern"
97
+ require "ttfunk/table/loca"
98
+ require "ttfunk/table/maxp"
99
+ require "ttfunk/table/name"
100
+ require "ttfunk/table/os2"
101
+ require "ttfunk/table/post"
102
+
@@ -0,0 +1,17 @@
1
+ module TTFunk
2
+ class Directory
3
+ attr_reader :tables
4
+ attr_reader :scaler_type
5
+
6
+ def initialize(io)
7
+ @scaler_type, table_count, search_range,
8
+ entry_selector, range_shift = io.read(12).unpack("Nn*")
9
+
10
+ @tables = {}
11
+ table_count.times do
12
+ tag, checksum, offset, length = io.read(16).unpack("a4N*")
13
+ @tables[tag] = { :tag => tag, :checksum => checksum, :offset => offset, :length => length }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,88 @@
1
+ module TTFunk
2
+ module Encoding
3
+ class MacRoman
4
+ TO_UNICODE = Hash[*(0..255).zip(0..255).flatten]
5
+ TO_UNICODE.update(
6
+ 0x81 => 0x00C5, 0x82 => 0x00C7, 0x83 => 0x00C9, 0x84 => 0x00D1, 0x85 => 0x00D6,
7
+ 0x86 => 0x00DC, 0x87 => 0x00E1, 0x88 => 0x00E0, 0x89 => 0x00E2, 0x8A => 0x00E4,
8
+ 0x8B => 0x00E3, 0x8C => 0x00E5, 0x8D => 0x00E7, 0x8E => 0x00E9, 0x8F => 0x00E8,
9
+ 0x90 => 0x00EA, 0x91 => 0x00EB, 0x92 => 0x00ED, 0x93 => 0x00EC, 0x94 => 0x00EE,
10
+ 0x95 => 0x00EF, 0x96 => 0x00F1, 0x97 => 0x00F3, 0x98 => 0x00F2, 0x99 => 0x00F4,
11
+ 0x9A => 0x00F6, 0x9B => 0x00F5, 0x9C => 0x00FA, 0x9D => 0x00F9, 0x9E => 0x00FB,
12
+ 0x9F => 0x00FC, 0xA0 => 0x2020, 0xA1 => 0x00B0, 0xA4 => 0x00A7, 0xA5 => 0x2022,
13
+ 0xA6 => 0x00B6, 0xA7 => 0x00DF, 0xA8 => 0x00AE, 0xAA => 0x2122, 0xAB => 0x00B4,
14
+ 0xAC => 0x00A8, 0xAD => 0x2260, 0xAE => 0x00C6, 0xAF => 0x00D8, 0xB0 => 0x221E,
15
+ 0xB2 => 0x2264, 0xB3 => 0x2265, 0xB4 => 0x00A5, 0xB6 => 0x2202, 0xB7 => 0x2211,
16
+ 0xB8 => 0x220F, 0xB9 => 0x03C0, 0xBA => 0x222B, 0xBB => 0x00AA, 0xBC => 0x00BA,
17
+ 0xBD => 0x03A9, 0xBE => 0x00E6, 0xBF => 0x00F8, 0xC0 => 0x00BF, 0xC1 => 0x00A1,
18
+ 0xC2 => 0x00AC, 0xC3 => 0x221A, 0xC4 => 0x0192, 0xC5 => 0x2248, 0xC6 => 0x2206,
19
+ 0xC7 => 0x00AB, 0xC8 => 0x00BB, 0xC9 => 0x2026, 0xCA => 0x00A0, 0xCB => 0x00C0,
20
+ 0xCC => 0x00C3, 0xCD => 0x00D5, 0xCE => 0x0152, 0xCF => 0x0153, 0xD0 => 0x2013,
21
+ 0xD1 => 0x2014, 0xD2 => 0x201C, 0xD3 => 0x201D, 0xD4 => 0x2018, 0xD5 => 0x2019,
22
+ 0xD6 => 0x00F7, 0xD7 => 0x25CA, 0xD8 => 0x00FF, 0xD9 => 0x0178, 0xDA => 0x2044,
23
+ 0xDB => 0x20AC, 0xDC => 0x2039, 0xDD => 0x203A, 0xDE => 0xFB01, 0xDF => 0xFB02,
24
+ 0xE0 => 0x2021, 0xE1 => 0x00B7, 0xE2 => 0x201A, 0xE3 => 0x201E, 0xE4 => 0x2030,
25
+ 0xE5 => 0x00C2, 0xE6 => 0x00CA, 0xE7 => 0x00C1, 0xE8 => 0x00CB, 0xE9 => 0x00C8,
26
+ 0xEA => 0x00CD, 0xEB => 0x00CE, 0xEC => 0x00CF, 0xED => 0x00CC, 0xEE => 0x00D3,
27
+ 0xEF => 0x00D4, 0xF0 => 0xF8FF, 0xF1 => 0x00D2, 0xF2 => 0x00DA, 0xF3 => 0x00DB,
28
+ 0xF4 => 0x00D9, 0xF5 => 0x0131, 0xF6 => 0x02C6, 0xF7 => 0x02DC, 0xF8 => 0x00AF,
29
+ 0xF9 => 0x02D8, 0xFA => 0x02D9, 0xFB => 0x02DA, 0xFC => 0x00B8, 0xFD => 0x02DD,
30
+ 0xFE => 0x02DB, 0xFF => 0x02C7
31
+ )
32
+
33
+ FROM_UNICODE = {}
34
+ (0..255).each { |key| FROM_UNICODE[TO_UNICODE[key]] = key }
35
+
36
+ # Maps MacRoman codes to their corresponding index in the Postscript glyph
37
+ # table (see TTFunk::Table::Post::Format10). If any entry in this array is a string,
38
+ # it is a postscript glyph that is not in the standard list, and which should be
39
+ # emitted specially in the TTF postscript table ('post', see format 2).
40
+ POSTSCRIPT_GLYPH_MAPPING = [
41
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0x0F
42
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0x1F
43
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, # 0x2F
44
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, # 0x3F
45
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, # 0x4F
46
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, # 0x5F
47
+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, # 0x6F
48
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 0, # 0x7F
49
+ 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, # 0x8F
50
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, # 0x9F
51
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, # 0xAF
52
+ 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, # 0xBF
53
+ 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, # 0xCF
54
+ 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, "Euro", 190, 191, 192, 193, # 0xDF
55
+ 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, # 0xEF
56
+ 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225 # 0xFF
57
+ ]
58
+
59
+ def self.covers?(character)
60
+ !FROM_UNICODE[character].nil?
61
+ end
62
+
63
+ def self.to_utf8(string)
64
+ to_unicode_codepoints(string.unpack("C*")).pack("U*")
65
+ end
66
+
67
+ def self.to_unicode(string)
68
+ to_unicode_codepoints(string.unpack("C*")).pack("n*")
69
+ end
70
+
71
+ def self.from_utf8(string)
72
+ from_unicode_codepoints(string.unpack("U*")).pack("C*")
73
+ end
74
+
75
+ def self.from_unicode(string)
76
+ from_unicode_codepoints(string.unpack("n*")).pack("C*")
77
+ end
78
+
79
+ def self.to_unicode_codepoints(array)
80
+ array.map { |code| TO_UNICODE[code] }
81
+ end
82
+
83
+ def self.from_unicode_codepoints(array)
84
+ array.map { |code| FROM_UNICODE[code] || 0 }
85
+ end
86
+ end
87
+ end
88
+ end