ttfunk 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/README.rdoc +39 -0
- data/data/fonts/DejaVuSans.ttf +0 -0
- data/data/fonts/comicsans.ttf +0 -0
- data/examples/metrics.rb +46 -0
- data/lib/ttfunk/directory.rb +17 -0
- data/lib/ttfunk/encoding/mac_roman.rb +88 -0
- data/lib/ttfunk/encoding/windows_1252.rb +69 -0
- data/lib/ttfunk/reader.rb +44 -0
- data/lib/ttfunk/resource_file.rb +78 -0
- data/lib/ttfunk/subset/base.rb +141 -0
- data/lib/ttfunk/subset/mac_roman.rb +50 -0
- data/lib/ttfunk/subset/unicode.rb +48 -0
- data/lib/ttfunk/subset/unicode_8bit.rb +63 -0
- data/lib/ttfunk/subset/windows_1252.rb +55 -0
- data/lib/ttfunk/subset.rb +18 -0
- data/lib/ttfunk/subset_collection.rb +72 -0
- data/lib/ttfunk/table/cmap/format00.rb +54 -0
- data/lib/ttfunk/table/cmap/format04.rb +126 -0
- data/lib/ttfunk/table/cmap/subtable.rb +79 -0
- data/lib/ttfunk/table/cmap.rb +34 -0
- data/lib/ttfunk/table/glyf/compound.rb +81 -0
- data/lib/ttfunk/table/glyf/simple.rb +37 -0
- data/lib/ttfunk/table/glyf.rb +64 -0
- data/lib/ttfunk/table/head.rb +44 -0
- data/lib/ttfunk/table/hhea.rb +41 -0
- data/lib/ttfunk/table/hmtx.rb +47 -0
- data/lib/ttfunk/table/kern/format0.rb +62 -0
- data/lib/ttfunk/table/kern.rb +79 -0
- data/lib/ttfunk/table/loca.rb +43 -0
- data/lib/ttfunk/table/maxp.rb +40 -0
- data/lib/ttfunk/table/name.rb +125 -0
- data/lib/ttfunk/table/os2.rb +78 -0
- data/lib/ttfunk/table/post/format10.rb +43 -0
- data/lib/ttfunk/table/post/format20.rb +35 -0
- data/lib/ttfunk/table/post/format25.rb +23 -0
- data/lib/ttfunk/table/post/format30.rb +17 -0
- data/lib/ttfunk/table/post/format40.rb +17 -0
- data/lib/ttfunk/table/post.rb +91 -0
- data/lib/ttfunk/table/simple.rb +14 -0
- data/lib/ttfunk/table.rb +46 -0
- data/lib/ttfunk.rb +102 -0
- metadata +121 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'ttfunk/table'
|
2
|
+
|
3
|
+
module TTFunk
|
4
|
+
class Table
|
5
|
+
class Post < Table
|
6
|
+
attr_reader :format
|
7
|
+
attr_reader :italic_angle
|
8
|
+
attr_reader :underline_position
|
9
|
+
attr_reader :underline_thickness
|
10
|
+
attr_reader :fixed_pitch
|
11
|
+
attr_reader :min_mem_type42
|
12
|
+
attr_reader :max_mem_type42
|
13
|
+
attr_reader :min_mem_type1
|
14
|
+
attr_reader :max_mem_type1
|
15
|
+
|
16
|
+
attr_reader :subtable
|
17
|
+
|
18
|
+
def self.encode(post, mapping)
|
19
|
+
return nil unless post.exists?
|
20
|
+
post.recode(mapping)
|
21
|
+
end
|
22
|
+
|
23
|
+
def fixed_pitch?
|
24
|
+
@fixed_pitch != 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def glyph_for(code)
|
28
|
+
".notdef"
|
29
|
+
end
|
30
|
+
|
31
|
+
def recode(mapping)
|
32
|
+
return raw if format == 0x00030000
|
33
|
+
|
34
|
+
table = raw[0,32]
|
35
|
+
table[0,4] = [0x00020000].pack("N")
|
36
|
+
|
37
|
+
index = []
|
38
|
+
strings = []
|
39
|
+
|
40
|
+
mapping.keys.sort.each do |new_id|
|
41
|
+
post_glyph = glyph_for(mapping[new_id])
|
42
|
+
position = Format10::POSTSCRIPT_GLYPHS.index(post_glyph)
|
43
|
+
if position
|
44
|
+
index << position
|
45
|
+
else
|
46
|
+
index << 257 + strings.length
|
47
|
+
strings << post_glyph
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
table << [mapping.length, *index].pack("n*")
|
52
|
+
strings.each do |string|
|
53
|
+
table << [string.length, string].pack("CA*")
|
54
|
+
end
|
55
|
+
|
56
|
+
return table
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def parse!
|
62
|
+
@format, @italic_angle, @underline_position, @underline_thickness,
|
63
|
+
@fixed_pitch, @min_mem_type42, @max_mem_type42,
|
64
|
+
@min_mem_type1, @max_mem_type1 = read(32, "N2n2N*")
|
65
|
+
|
66
|
+
end_of_table = offset + length
|
67
|
+
|
68
|
+
@subtable = case @format
|
69
|
+
when 0x00010000 then extend(Post::Format10)
|
70
|
+
when 0x00020000 then extend(Post::Format20)
|
71
|
+
when 0x00025000 then extend(Post::Format25)
|
72
|
+
when 0x00030000 then extend(Post::Format30)
|
73
|
+
when 0x00040000 then extend(Post::Format40)
|
74
|
+
end
|
75
|
+
|
76
|
+
parse_format!
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse_format!
|
80
|
+
warn "postscript table format 0x%08X is not supported" % @format
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
require 'ttfunk/table/post/format10'
|
88
|
+
require 'ttfunk/table/post/format20'
|
89
|
+
require 'ttfunk/table/post/format25'
|
90
|
+
require 'ttfunk/table/post/format30'
|
91
|
+
require 'ttfunk/table/post/format40'
|
data/lib/ttfunk/table.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'ttfunk/reader'
|
2
|
+
|
3
|
+
module TTFunk
|
4
|
+
class Table
|
5
|
+
include Reader
|
6
|
+
|
7
|
+
attr_reader :file
|
8
|
+
attr_reader :offset
|
9
|
+
attr_reader :length
|
10
|
+
|
11
|
+
def initialize(file)
|
12
|
+
@file = file
|
13
|
+
|
14
|
+
info = file.directory_info(tag)
|
15
|
+
|
16
|
+
if info
|
17
|
+
@offset = info[:offset]
|
18
|
+
@length = info[:length]
|
19
|
+
|
20
|
+
parse_from(@offset) { parse! }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def exists?
|
25
|
+
!@offset.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def raw
|
29
|
+
if exists?
|
30
|
+
parse_from(offset) { io.read(length) }
|
31
|
+
else
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def tag
|
37
|
+
self.class.name.split(/::/).last.downcase
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def parse!
|
43
|
+
# do nothing, by default
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/ttfunk.rb
ADDED
@@ -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 && os2.ascent.nonzero?) || horizontal_header.ascent
|
26
|
+
end
|
27
|
+
|
28
|
+
def descent
|
29
|
+
@descent ||= (os2.exists? && os2.descent && os2.descent.nonzero?) || horizontal_header.descent
|
30
|
+
end
|
31
|
+
|
32
|
+
def line_gap
|
33
|
+
@line_gap ||= (os2.exists? && os2.line_gap && os2.line_gap.nonzero?) || 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
|
+
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ttfunk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 21
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Gregory Brown
|
14
|
+
- Brad Ediger
|
15
|
+
- Daniel Nelson
|
16
|
+
- Jonathen Greenberg
|
17
|
+
- James Healy
|
18
|
+
autorequire:
|
19
|
+
bindir: bin
|
20
|
+
cert_chain: []
|
21
|
+
|
22
|
+
date: 2011-04-02 00:00:00 -05:00
|
23
|
+
default_executable:
|
24
|
+
dependencies: []
|
25
|
+
|
26
|
+
description: Get Ya TrueType Funk On! (Font Metrics Parser for Prawn)
|
27
|
+
email:
|
28
|
+
- gregory.t.brown@gmail.com
|
29
|
+
- brad@bradediger.com
|
30
|
+
- dnelson@bluejade.com
|
31
|
+
- greenberg@entryway.net
|
32
|
+
- jimmy@deefa.com
|
33
|
+
executables: []
|
34
|
+
|
35
|
+
extensions: []
|
36
|
+
|
37
|
+
extra_rdoc_files: []
|
38
|
+
|
39
|
+
files:
|
40
|
+
- lib/ttfunk.rb
|
41
|
+
- lib/ttfunk/encoding/windows_1252.rb
|
42
|
+
- lib/ttfunk/encoding/mac_roman.rb
|
43
|
+
- lib/ttfunk/resource_file.rb
|
44
|
+
- lib/ttfunk/subset.rb
|
45
|
+
- lib/ttfunk/directory.rb
|
46
|
+
- lib/ttfunk/subset/unicode.rb
|
47
|
+
- lib/ttfunk/subset/windows_1252.rb
|
48
|
+
- lib/ttfunk/subset/unicode_8bit.rb
|
49
|
+
- lib/ttfunk/subset/mac_roman.rb
|
50
|
+
- lib/ttfunk/subset/base.rb
|
51
|
+
- lib/ttfunk/table/hhea.rb
|
52
|
+
- lib/ttfunk/table/post.rb
|
53
|
+
- lib/ttfunk/table/kern/format0.rb
|
54
|
+
- lib/ttfunk/table/os2.rb
|
55
|
+
- lib/ttfunk/table/glyf/compound.rb
|
56
|
+
- lib/ttfunk/table/glyf/simple.rb
|
57
|
+
- lib/ttfunk/table/simple.rb
|
58
|
+
- lib/ttfunk/table/hmtx.rb
|
59
|
+
- lib/ttfunk/table/loca.rb
|
60
|
+
- lib/ttfunk/table/cmap/format04.rb
|
61
|
+
- lib/ttfunk/table/cmap/format00.rb
|
62
|
+
- lib/ttfunk/table/cmap/subtable.rb
|
63
|
+
- lib/ttfunk/table/cmap.rb
|
64
|
+
- lib/ttfunk/table/maxp.rb
|
65
|
+
- lib/ttfunk/table/post/format40.rb
|
66
|
+
- lib/ttfunk/table/post/format20.rb
|
67
|
+
- lib/ttfunk/table/post/format25.rb
|
68
|
+
- lib/ttfunk/table/post/format30.rb
|
69
|
+
- lib/ttfunk/table/post/format10.rb
|
70
|
+
- lib/ttfunk/table/name.rb
|
71
|
+
- lib/ttfunk/table/kern.rb
|
72
|
+
- lib/ttfunk/table/glyf.rb
|
73
|
+
- lib/ttfunk/table/head.rb
|
74
|
+
- lib/ttfunk/reader.rb
|
75
|
+
- lib/ttfunk/subset_collection.rb
|
76
|
+
- lib/ttfunk/table.rb
|
77
|
+
- data/fonts/comicsans.ttf
|
78
|
+
- data/fonts/DejaVuSans.ttf
|
79
|
+
- examples/metrics.rb
|
80
|
+
- CHANGELOG
|
81
|
+
- README.rdoc
|
82
|
+
has_rdoc: true
|
83
|
+
homepage:
|
84
|
+
licenses: []
|
85
|
+
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
hash: 57
|
97
|
+
segments:
|
98
|
+
- 1
|
99
|
+
- 8
|
100
|
+
- 7
|
101
|
+
version: 1.8.7
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
hash: 23
|
108
|
+
segments:
|
109
|
+
- 1
|
110
|
+
- 3
|
111
|
+
- 6
|
112
|
+
version: 1.3.6
|
113
|
+
requirements: []
|
114
|
+
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 1.5.2
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: TrueType Font Metrics Parser
|
120
|
+
test_files: []
|
121
|
+
|