39: def self.open(font_name)
40: file = font_name.gsub(/\\/o, "/")
41: dir = File.dirname(file)
42: name = File.basename(file)
43:
44: metrics_path = []
45:
46:
47: if dir == "."
48: metrics_path << dir << METRICS_PATH << $LOAD_PATH
49: elsif dir !~ %r{^(\w:|/)}o and dir.index("/")
50: METRICS_PATH.each { |path| metrics_path << File.join(path, dir) }
51: $LOAD_PATH.each { |path| metrics_path << File.join(path, dir) }
52: else
53: metric_path = [ dir ]
54: end
55: metrics_path.flatten!
56:
57: font = nil
58: afm = nil
59:
60: metrics_path.each do |path|
61: afm_file = File.join(path, "#{name}.afm").gsub(/\.afm\.afm$/o, ".afm")
62: rfm_file = "#{afm_file}.rfm"
63:
64:
65:
66: begin
67: if File.exists?(rfm_file)
68: data = File.open(rfm_file, "rb") { |file| file.read }
69: font = Marshal.load(data)
70: return font
71: end
72: rescue
73: nil
74: end
75:
76:
77: File.open(afm_file, "rb") do |file|
78: font = PDF::Writer::FontMetrics.new
79:
80:
81: file.each do |line|
82: line.chomp!
83: line.strip!
84: key, *values = line.split
85: op = "#{key.downcase}=".to_sym
86:
87:
88:
89:
90:
91:
92:
93:
94:
95: case key
96: when 'FontName', 'FullName', 'FamilyName', 'Weight',
97: 'IsFixedPitch', 'CharacterSet', 'Version', 'EncodingScheme'
98:
99: font.__send__(op, values.join(" "))
100: when 'ItalicAngle', 'UnderlinePosition', 'UnderlineThickness',
101: 'CapHeight', 'XHeight', 'Ascender', 'Descender', 'StdHW',
102: 'StdVW', 'StartCharMetrics'
103:
104: font.__send__(op, values.join(" ").to_f)
105: when 'FontBBox'
106:
107: font.fontbbox = values.map { |el| el.to_f }
108: when 'C', 'CH'
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152: bits = line.chomp.strip.split(/;/).collect { |r| r.strip }
153: dtmp = {}
154:
155: bits.each do |bit|
156: b = bit.split
157: if b.size > 2
158: dtmp[b[0]] = []
159: b[1..-1].each do |z|
160: if z =~ NUMBER
161: dtmp[b[0]] << z.to_f
162: else
163: dtmp[b[0]] << z
164: end
165: end
166: elsif b.size == 2
167: if b[0] == 'C' and b[1] =~ NUMBER
168: dtmp[b[0]] = b[1].to_i
169: elsif b[0] == 'CH'
170: dtmp['C'] = b[1].to_i(16)
171: elsif b[1] =~ NUMBER
172: dtmp[b[0]] = b[1].to_f
173: else
174: dtmp[b[0]] = b[1]
175: end
176: end
177: end
178:
179: font.c[dtmp['N']] = dtmp
180: font.c[dtmp['C']] = dtmp unless dtmp['C'].nil?
181: when 'KPX'
182:
183: font.kpx[values[0]] = { }
184: font.kpx[values[0]][values[1]] = values[2].to_f
185: end
186: end
187: font.path = afm_file
188: end rescue nil
189: break unless font.nil?
190: end
191:
192: raise ArgumentError, "Font #{font_name} not found." if font.nil?
193: font
194: end