rfil 0.2
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.
- data/COPYING +340 -0
- data/README +77 -0
- data/examples/afm2tfm.rb +204 -0
- data/examples/afminfo +305 -0
- data/examples/encodingtable +65 -0
- data/examples/pldiff +295 -0
- data/examples/plinfo +108 -0
- data/examples/rfii +257 -0
- data/examples/rfont +188 -0
- data/lib/rfil/font.rb +722 -0
- data/lib/rfil/font/afm.rb +414 -0
- data/lib/rfil/font/glyph.rb +198 -0
- data/lib/rfil/font/metric.rb +135 -0
- data/lib/rfil/font/truetype.rb +35 -0
- data/lib/rfil/fontcollection.rb +182 -0
- data/lib/rfil/helper.rb +155 -0
- data/lib/rfil/rfi.rb +472 -0
- data/lib/rfil/rfi_plugin_context.rb +90 -0
- data/lib/rfil/rfi_plugin_latex.rb +95 -0
- data/lib/rfil/version.rb +3 -0
- data/lib/tex/enc.rb +223 -0
- data/lib/tex/kpathsea.rb +63 -0
- data/lib/tex/tfm.rb +1198 -0
- data/lib/tex/vf.rb +846 -0
- metadata +86 -0
data/examples/afminfo
ADDED
@@ -0,0 +1,305 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Last Change: Mon May 22 12:38:42 2006
|
4
|
+
#++
|
5
|
+
=begin rdoc
|
6
|
+
|
7
|
+
== afminfo - print out information about an afm or truetype font file
|
8
|
+
|
9
|
+
Usage: afminfo [options] afm-file[.afm]
|
10
|
+
-m, --metrics show global metrics information
|
11
|
+
-v, --verbose verbose output
|
12
|
+
--[no-]info list general information (default)
|
13
|
+
-l, --list-glyphs list all available glyphs
|
14
|
+
-g, --glyphinfo g information about a specific glyph
|
15
|
+
-h, --help Show this help
|
16
|
+
--version Show version information
|
17
|
+
|
18
|
+
---
|
19
|
+
Author:: Patrick Gundlach <patrick@gundla.ch>
|
20
|
+
License:: Copyright (c) 2006 Patrick Gundlach.
|
21
|
+
Released under the terms of the GNU General Public License
|
22
|
+
=end
|
23
|
+
|
24
|
+
# :enddoc:
|
25
|
+
|
26
|
+
AFMINFO_VERSION="0.1"
|
27
|
+
|
28
|
+
require 'optparse'
|
29
|
+
require 'ostruct'
|
30
|
+
require 'rfil/font/afm'
|
31
|
+
require 'rfil/version'
|
32
|
+
|
33
|
+
################################################## texttable.rb follows
|
34
|
+
|
35
|
+
# Render a list of data column-wise or row-wise. TextTable is used to
|
36
|
+
# print a table to the console, without a GUI.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
# data=%w(one two three four five six seven eight nine ten)
|
40
|
+
# puts TextTable.do_columns(data)
|
41
|
+
#
|
42
|
+
# This will print out this table:
|
43
|
+
# one five eight
|
44
|
+
# two six nine
|
45
|
+
# three seven ten
|
46
|
+
# four
|
47
|
+
# see that the order is column one first, then second column ...
|
48
|
+
#
|
49
|
+
# Another posibility would be:
|
50
|
+
# puts TextTable.do_rows(data)
|
51
|
+
# which outputs
|
52
|
+
# one two three
|
53
|
+
# four five six
|
54
|
+
# seven eight nine
|
55
|
+
# ten
|
56
|
+
|
57
|
+
|
58
|
+
class TextTable
|
59
|
+
class << self
|
60
|
+
# def columns(data,maxchars=80)
|
61
|
+
# m,c=count_columns=calculate_maxwidth_columns(data,maxchars)
|
62
|
+
# return c
|
63
|
+
# end
|
64
|
+
|
65
|
+
# def maxwidth(data,maxchars=80)
|
66
|
+
# m,c=count_columns=calculate_maxwidth_columns(data,maxchars)
|
67
|
+
# return m
|
68
|
+
# end
|
69
|
+
|
70
|
+
# Arrange the data in columns. The total width is <= maxchars.
|
71
|
+
def do_columns(data,maxchars=80)
|
72
|
+
maxwidth,count_columns=calculate_maxwidth_columns(data,maxchars)
|
73
|
+
|
74
|
+
tmp=""
|
75
|
+
# amount of data(rows) in each column. The first
|
76
|
+
# count_full_columns columns might have more rows then the last
|
77
|
+
# columns.
|
78
|
+
rowsmin = (data.size * 1.0 / count_columns).floor
|
79
|
+
rowsmax = (data.size * 1.0 / count_columns).ceil
|
80
|
+
count_full_columns = data.size % count_columns
|
81
|
+
|
82
|
+
distribution=Array.new()
|
83
|
+
distribution[0]=0
|
84
|
+
count = 0
|
85
|
+
(0...count_columns).each { |col|
|
86
|
+
if col < count_full_columns
|
87
|
+
count += rowsmax
|
88
|
+
else
|
89
|
+
count += rowsmin
|
90
|
+
end
|
91
|
+
distribution[col]= count
|
92
|
+
}
|
93
|
+
|
94
|
+
distribution.unshift 0
|
95
|
+
(0...rowsmax).each { |row|
|
96
|
+
tmp <<((0...count_columns).collect { |column|
|
97
|
+
w = data[distribution[column] + row]
|
98
|
+
if (column >= count_full_columns) and (row >= rowsmin)
|
99
|
+
w = ""
|
100
|
+
end
|
101
|
+
sprintf("%-#{maxwidth}s",w)
|
102
|
+
}.join(' '))
|
103
|
+
tmp << "\n"
|
104
|
+
}
|
105
|
+
tmp
|
106
|
+
end
|
107
|
+
|
108
|
+
# Arrange the data in rows.
|
109
|
+
def do_rows(data,maxchars=80)
|
110
|
+
maxwidth,count_columns=calculate_maxwidth_columns(data,maxchars)
|
111
|
+
tmp=""
|
112
|
+
(0...data.size).each { |x|
|
113
|
+
tmp << sprintf("%-#{maxwidth}s",data[x]) +
|
114
|
+
if (x+1) % count_columns == 0
|
115
|
+
"\n"
|
116
|
+
else
|
117
|
+
" "
|
118
|
+
end
|
119
|
+
}
|
120
|
+
tmp << "\n"
|
121
|
+
tmp
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def calculate_maxwidth_columns(data,maxchars)
|
127
|
+
maxwidth = 0
|
128
|
+
data.each { |elt|
|
129
|
+
maxwidth = maxwidth > elt.length ? maxwidth : elt.length
|
130
|
+
}
|
131
|
+
columns = (maxchars/(maxwidth + 1)).floor
|
132
|
+
raise ArgumentError,"calculated columns == 0, need wider table" if columns==0
|
133
|
+
return maxwidth,columns
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
################################################## texttable.rb ends here
|
139
|
+
|
140
|
+
class AFMinfo # :nodoc:
|
141
|
+
def initialize (afm)
|
142
|
+
@afm = afm
|
143
|
+
@uppercase_letters = ('A'..'Z').collect { |l| l }
|
144
|
+
@lowercase_letters = ('a'..'z').collect { |l| l }
|
145
|
+
@digits = %w(one two three four five six seven eight nine zero)
|
146
|
+
end
|
147
|
+
def stdformat
|
148
|
+
"%-18s "
|
149
|
+
end
|
150
|
+
def printout (str,value)
|
151
|
+
puts sprintf(stdformat + "%s", str + ":" ,value.to_s)
|
152
|
+
end
|
153
|
+
|
154
|
+
def num_to_string (num,reservespace=true)
|
155
|
+
formatstring = "%"
|
156
|
+
formatstring << " " if reservespace
|
157
|
+
formatstring << (num.to_i == num ? "d" : "f")
|
158
|
+
# output "integer" if value after decimal point is 0
|
159
|
+
sprintf(formatstring,num)
|
160
|
+
end
|
161
|
+
|
162
|
+
def dump_maininfo
|
163
|
+
puts "General font information:"
|
164
|
+
puts "========================="
|
165
|
+
printout("Filename",@afm.filename)
|
166
|
+
[
|
167
|
+
["Fontname",:fontname],
|
168
|
+
["FullName",:fullname],
|
169
|
+
["Family name",:familyname],
|
170
|
+
["Weight",:weight],
|
171
|
+
["EncodingScheme",:encodingscheme],
|
172
|
+
# ["�","�"],
|
173
|
+
].each { |s,m|
|
174
|
+
printout(s,@afm.send(m))
|
175
|
+
}
|
176
|
+
puts sprintf(stdformat,'Number of gylphs:') + @afm.count_charmetrics.to_s +
|
177
|
+
" (encoded: " + @afm.count_charmetrics_encoded.to_s + ", unencoded: " + @afm.count_charmetrics_unencoded.to_s + ")"
|
178
|
+
|
179
|
+
end
|
180
|
+
def dump_metrics
|
181
|
+
puts "\n\nGlobal metrics information:"
|
182
|
+
puts "=========================="
|
183
|
+
puts sprintf(stdformat,"FontBBox:") + @afm.fontbbox.collect { |f|
|
184
|
+
num_to_string(f)
|
185
|
+
}.join(' ') + ' (llx,lly,urx,ury)'
|
186
|
+
printout('IsFixedPitch',@afm.isfixedpitch)
|
187
|
+
|
188
|
+
[
|
189
|
+
["ItalicAngle", :italicangle],
|
190
|
+
["UnderlinePosition", :underlineposition],
|
191
|
+
["UnderlineThickness", :underlinethickness],
|
192
|
+
["CapHeight", :capheight],
|
193
|
+
["XHeight", :xheight],
|
194
|
+
["Ascender", :ascender],
|
195
|
+
["Descender", :descender]
|
196
|
+
].each { |s,m|
|
197
|
+
puts sprintf(stdformat,s) + num_to_string(@afm.send(m))
|
198
|
+
}
|
199
|
+
end
|
200
|
+
def dump_glyphinfo (glyph)
|
201
|
+
chars=@afm.chars[glyph]
|
202
|
+
puts "\n\nGlyph information (" + glyph + ")"
|
203
|
+
puts "===================="
|
204
|
+
puts sprintf(stdformat,"Encoding pos:") +
|
205
|
+
if chars.c == -1
|
206
|
+
"--"
|
207
|
+
else
|
208
|
+
sprintf("%d (dec), %x (hex), %o (oct)",chars.c,chars.c,chars.c)
|
209
|
+
end
|
210
|
+
puts sprintf(stdformat,"Width x (wx)") + chars.wx.to_s
|
211
|
+
puts sprintf(stdformat,"Bounding box") + chars.b.collect { |f|
|
212
|
+
num_to_string(f,false)
|
213
|
+
}.join(' ') + ' (llx,lly,urx,ury)'
|
214
|
+
puts "Kerning pairs: (x,y)"
|
215
|
+
puts "--------------------"
|
216
|
+
chars.kern_data.each { |k,v|
|
217
|
+
puts sprintf(stdformat," " + k) + num_to_string(v[0]) + "," +
|
218
|
+
num_to_string(v[1])
|
219
|
+
}
|
220
|
+
end
|
221
|
+
def dump_glyphs
|
222
|
+
chars=@afm.chars
|
223
|
+
puts "\n\nList of glyphs"
|
224
|
+
puts "================"
|
225
|
+
removefromlist=[]
|
226
|
+
if @uppercase_letters.all? { |glyph|
|
227
|
+
chars[glyph]
|
228
|
+
}
|
229
|
+
puts sprintf(stdformat,"A-Z") + "available"
|
230
|
+
removefromlist += @uppercase_letters
|
231
|
+
else
|
232
|
+
puts sprintf(stdformat,"A-Z") + "some missing"
|
233
|
+
end
|
234
|
+
if @lowercase_letters.all? { |glyph|
|
235
|
+
chars[glyph]
|
236
|
+
}
|
237
|
+
puts sprintf(stdformat,"a-z") + "available"
|
238
|
+
removefromlist += @lowercase_letters
|
239
|
+
else
|
240
|
+
puts sprintf(stdformat,"a-z") + "some missing"
|
241
|
+
end
|
242
|
+
if @digits.all? { |glyph|
|
243
|
+
chars[glyph]
|
244
|
+
}
|
245
|
+
puts sprintf(stdformat,"one, two, .., zero") + "available"
|
246
|
+
removefromlist += @digits
|
247
|
+
else
|
248
|
+
puts sprintf(stdformat,"one, two, .., zero") + "some missing"
|
249
|
+
end
|
250
|
+
puts
|
251
|
+
glyphlist=[]
|
252
|
+
chars.each { |glyph,h|
|
253
|
+
glyphlist.push(glyph + (h.c == -1 ? "*" : ""))
|
254
|
+
}
|
255
|
+
glyphlist = glyphlist - removefromlist
|
256
|
+
glyphlist.sort! { |a,b|
|
257
|
+
a.casecmp b
|
258
|
+
}
|
259
|
+
puts TextTable.do_columns(glyphlist)
|
260
|
+
puts "\n* = unencoded - only glyphs not mentioned above listed"
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
options=OpenStruct.new
|
266
|
+
options.verbose = false
|
267
|
+
options.metrics = false
|
268
|
+
options.glyph = nil
|
269
|
+
options.listglyphs = false
|
270
|
+
options.generalinfo = true
|
271
|
+
|
272
|
+
ARGV.options { |opt|
|
273
|
+
opt.banner = "Usage: #{File.basename($0)} [options] afm-file[.afm]"
|
274
|
+
opt.on("--metrics", "-m", "show global metrics information") { options.metrics=true}
|
275
|
+
opt.on("--verbose", "-v", "verbose output") { options.verbose=true }
|
276
|
+
opt.on("--[no-]info", "list general information (default)") { |x|
|
277
|
+
options.generalinfo=x }
|
278
|
+
opt.on("--list-glyphs", "-l", "list all available glyphs") { options.listglyphs=true }
|
279
|
+
opt.on("--glyphinfo g" , "-g",
|
280
|
+
"information about a specific glyph") { |arg|
|
281
|
+
options.glyph = arg
|
282
|
+
}
|
283
|
+
|
284
|
+
opt.on("--help", "-h", "Show this help") { puts opt; exit 0 }
|
285
|
+
opt.on("--version", "Show version information") {
|
286
|
+
puts %Q{This is afminfo version #{AFMINFO_VERSION}, based on rfil version #{RFIL_VERSION}\n#{COPYRIGHT}\nMore information: #{HOMEPAGE}}; exit 0 }
|
287
|
+
opt.separator ""
|
288
|
+
opt.separator COPYRIGHT
|
289
|
+
opt.parse!
|
290
|
+
}
|
291
|
+
|
292
|
+
unless ARGV.size==1
|
293
|
+
puts "Please specify one afm-file to read" if ARGV
|
294
|
+
exit 1
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
# afm=Font::AFM.new(:verbose => options.verbose)
|
299
|
+
afm=RFIL::Font::Metric.read(ARGV[0],:verbose => options.verbose)
|
300
|
+
|
301
|
+
ai = AFMinfo.new(afm)
|
302
|
+
ai.dump_maininfo if options.generalinfo
|
303
|
+
ai.dump_metrics if options.metrics
|
304
|
+
options.glyph && ai.dump_glyphinfo(options.glyph)
|
305
|
+
ai.dump_glyphs if options.listglyphs
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
#--
|
3
|
+
# Last Change: Tue May 16 18:11:49 2006
|
4
|
+
#++
|
5
|
+
=begin rdoc
|
6
|
+
= encodingtable -- print out a table with different encodings in colums
|
7
|
+
|
8
|
+
This is mainly an example how to use the ENC and Kpathsea class.
|
9
|
+
|
10
|
+
== Usage
|
11
|
+
encodingtable encoding[.enc] [encoding[.enc] ...]
|
12
|
+
|
13
|
+
|
14
|
+
== Example
|
15
|
+
|
16
|
+
$ ./encodingtable ec texnansi 8r 8a
|
17
|
+
|
18
|
+
dec | oct |hex | ECEncoding | TeXnANSIEncoding | TeXBase1Encoding | StandardEncoding |
|
19
|
+
--------------------------------------------------------------------------------------------
|
20
|
+
0 | 0 | 0 | grave | --- | --- | --- |
|
21
|
+
1 | 1 | 1 | acute | Euro | dotaccent | --- |
|
22
|
+
2 | 2 | 2 | circumflex | --- | fi | --- |
|
23
|
+
3 | 3 | 3 | tilde | --- | fl | --- |
|
24
|
+
4 | 4 | 4 | dieresis | fraction | fraction | --- |
|
25
|
+
5 | 5 | 5 | hungarumlaut | dotaccent | hungarumlaut | --- |
|
26
|
+
...
|
27
|
+
---
|
28
|
+
Author:: Patrick Gundlach <patrick@gundla.ch>
|
29
|
+
=end
|
30
|
+
|
31
|
+
# :enddoc:
|
32
|
+
|
33
|
+
require 'tex/enc'
|
34
|
+
require 'tex/kpathsea'
|
35
|
+
|
36
|
+
|
37
|
+
unless ARGV.size > 0
|
38
|
+
puts "Usage: #{File.basename($0)} encoding[.enc] ..."
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
|
42
|
+
fmt=" %-16.16s |"
|
43
|
+
|
44
|
+
encodings=[]
|
45
|
+
kpse=Kpathsea.new
|
46
|
+
ARGV.each { |e|
|
47
|
+
kpse.open_file(e.chomp('.enc')+'.enc','enc') { |f|
|
48
|
+
encodings.push(ENC.new(f))
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
|
53
|
+
print "dec | oct |hex |"
|
54
|
+
encodings.each { |e| print sprintf(fmt,e.encname) }
|
55
|
+
|
56
|
+
|
57
|
+
0.upto(255) { |slot|
|
58
|
+
print "\n"+"-"*(16 + encodings.size * 19 ) if slot % 32 == 0
|
59
|
+
|
60
|
+
print sprintf("\n%3d | %3o | %2x |", slot,slot,slot)
|
61
|
+
encodings.each { |e|
|
62
|
+
print sprintf(fmt, e[slot]==".notdef" ? "---" : e[slot])
|
63
|
+
}
|
64
|
+
}
|
65
|
+
puts
|
data/examples/pldiff
ADDED
@@ -0,0 +1,295 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Last Change: Tue May 16 18:13:36 2006
|
4
|
+
#++
|
5
|
+
=begin rdoc
|
6
|
+
|
7
|
+
== pldiff -- show the differences between two (v)pl files.
|
8
|
+
|
9
|
+
Usage: pldiff [options] file file
|
10
|
+
file can be tfm, pl, vpl or vf files.
|
11
|
+
-d, --delta DELTA Don't report differences whithin +/- DELTA percent
|
12
|
+
-c, --ignore-comments ignore comments
|
13
|
+
-k, --ignore-kern ignore difference in kerning information
|
14
|
+
-m, --mapenc ENC assume encoding ENC for destination encoding
|
15
|
+
-t, --texenc ENC assume encoding ENC for source encoding (TeX side)
|
16
|
+
-e, --encoding ENC assume encoding ENC for both in and out
|
17
|
+
-s, --skip-characters only look at fontdimen and main data
|
18
|
+
|
19
|
+
-h, --help Show this help
|
20
|
+
|
21
|
+
|
22
|
+
---
|
23
|
+
Author:: Patrick Gundlach <patrick@gundla.ch>
|
24
|
+
License:: Copyright (c) 2005 Patrick Gundlach.
|
25
|
+
Released under the terms of the GNU General Public License
|
26
|
+
|
27
|
+
=end
|
28
|
+
|
29
|
+
# :enddoc:
|
30
|
+
|
31
|
+
require 'optparse'
|
32
|
+
require 'ostruct'
|
33
|
+
|
34
|
+
require 'tex/kpathsea'
|
35
|
+
require 'tex/enc'
|
36
|
+
require 'tex/tfm'
|
37
|
+
require 'tex/vf'
|
38
|
+
|
39
|
+
|
40
|
+
def showmap(mapary)
|
41
|
+
str = ""
|
42
|
+
if mapary
|
43
|
+
mapary.each { |entry|
|
44
|
+
str << " | " << entry.join(" ") << "\n"
|
45
|
+
}
|
46
|
+
end
|
47
|
+
str
|
48
|
+
end
|
49
|
+
|
50
|
+
def plopen(filename)
|
51
|
+
case filename
|
52
|
+
when /\.tfm$/
|
53
|
+
return TFM.new.read_tfm(filename)
|
54
|
+
when /\.vf$/
|
55
|
+
# change to that dir first
|
56
|
+
currentdir=Dir.getwd
|
57
|
+
dirname=File.dirname(filename)
|
58
|
+
Dir.chdir(dirname)
|
59
|
+
fn=File.basename(filename)
|
60
|
+
vf=VF.new.read_vf(filename)
|
61
|
+
Dir.chdir(currentdir)
|
62
|
+
return vf
|
63
|
+
when /\.pl$/
|
64
|
+
return TFM.new.read_pl(filename)
|
65
|
+
when /\.vpl$/
|
66
|
+
return TFM.new.read_pl(filename)
|
67
|
+
else
|
68
|
+
puts "Unknown format: #{filename}"
|
69
|
+
exit 1
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
include TeX
|
74
|
+
options=OpenStruct.new
|
75
|
+
kpse=Kpathsea.new
|
76
|
+
|
77
|
+
ARGV.options { |opts|
|
78
|
+
opts.banner = "Usage: #{File.basename($0)} [options] file file"
|
79
|
+
opts.separator "file can be tfm, pl, vpl or vf files."
|
80
|
+
|
81
|
+
opts.on("--delta","-d DELTA", Float,
|
82
|
+
"Don't report differences whithin +/- DELTA percent") { |d|
|
83
|
+
options.delta=d
|
84
|
+
}
|
85
|
+
opts.on("--ignore-comments", "-c", "ignore comments") { |i|
|
86
|
+
options.ignore_comments=true
|
87
|
+
}
|
88
|
+
opts.on("--ignore-kern", "-k", "ignore difference in kerning information") { |k|
|
89
|
+
options.ignore_kern=true
|
90
|
+
}
|
91
|
+
|
92
|
+
opts.on("--mapenc", "-m ENC",
|
93
|
+
"assume encoding ENC for destination encoding") {|e|
|
94
|
+
options.mapencoding=e
|
95
|
+
}
|
96
|
+
|
97
|
+
opts.on("--texenc", "-t ENC",
|
98
|
+
"assume encoding ENC for source encoding (TeX side)") {|e|
|
99
|
+
options.texencoding=e
|
100
|
+
}
|
101
|
+
|
102
|
+
opts.on("--encoding", "-e ENC",
|
103
|
+
"assume encoding ENC for both in and out") {|e|
|
104
|
+
options.encoding=e
|
105
|
+
}
|
106
|
+
opts.on("--skip-characters", "-s", "only look at fontdimen and main data") {|s|
|
107
|
+
options.skip=true
|
108
|
+
}
|
109
|
+
opts.on_tail("--help", "-h", "Show this help") { puts opts; exit 0 }
|
110
|
+
opts.separator ""
|
111
|
+
opts.parse!
|
112
|
+
}
|
113
|
+
|
114
|
+
# untested:
|
115
|
+
if options.encoding
|
116
|
+
kpse.open_file(options.encoding,"enc") { |f|
|
117
|
+
options.encoding = ENC.new(f)
|
118
|
+
}
|
119
|
+
options.mapencoding=options.encoding
|
120
|
+
options.texencoding=options.encoding
|
121
|
+
end
|
122
|
+
|
123
|
+
if options.mapencoding.instance_of?(String)
|
124
|
+
kpse.open_file(options.mapencoding,"enc") { |f|
|
125
|
+
options.mapencoding = ENC.new(f)
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
if options.texencoding.instance_of?(String)
|
130
|
+
kpse.open_file(options.texencoding,"enc") { |f|
|
131
|
+
options.texencoding = ENC.new(f)
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
if ARGV.size != 2
|
136
|
+
puts "#{File.basename($0)}: Need exactly two file arguments."
|
137
|
+
puts "Try `#{File.basename($0)} --help' for more information."
|
138
|
+
exit 0
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
p1 = plopen(ARGV[0])
|
143
|
+
p2 = plopen(ARGV[1])
|
144
|
+
|
145
|
+
percent = options.delta ? options.delta/50.0 : 0
|
146
|
+
|
147
|
+
[:fontfamily,:codingscheme,:designsize].each { |sym|
|
148
|
+
if p1.send(sym) != p2.send(sym)
|
149
|
+
puts "#{sym} differ: #{p1.send(sym)} vs #{p2.send(sym)}"
|
150
|
+
end
|
151
|
+
}
|
152
|
+
|
153
|
+
|
154
|
+
fd1 = p1.params
|
155
|
+
fd2 = p2.params
|
156
|
+
str = ""
|
157
|
+
if fd1.size != fd2.size
|
158
|
+
str << "Difference in number of parameters (fontdimen)"
|
159
|
+
end
|
160
|
+
|
161
|
+
paramname=%w( X SLANT SPACE STRETCH SHRINK XHEIGHT QUAD EXTRASPACE )
|
162
|
+
if p1.codingscheme=="TeX math symbols"
|
163
|
+
paramname += %w(NUM1 NUM2 NUM3 DENOM1 DENOM2 SUP1 SUP2 SUP3
|
164
|
+
SUB1 SUB2 SUPDROP)
|
165
|
+
elsif p1.codingscheme=="TeX math extension"
|
166
|
+
paramname += %w(DEFAULT_RULE_THICKNESS BIG_OP_SPACING1
|
167
|
+
BIG_OP_SPACING2 BIG_OP_SPACING3 BIG_OP_SPACING4 BIG_OP_SPACING5)
|
168
|
+
end
|
169
|
+
|
170
|
+
for i in 1..fd1.size
|
171
|
+
next if fd1[i] == fd2[i]
|
172
|
+
if fd1[i]==nil
|
173
|
+
str << "Difference in #{paramname[i]}: nil vs. #{fd2[i]}" << "\n"
|
174
|
+
elsif
|
175
|
+
fd2[i]==nil
|
176
|
+
str << "Difference in #{paramname[i]}: #{fd1[i]} vs. nil" << "\n"
|
177
|
+
elsif (fd1[i] - fd2[i] ).abs > fd1[i] * percent
|
178
|
+
str << "Difference in #{paramname[i]}: #{fd1[i]} vs. #{fd2[i]}" << "\n"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
if str.size > 0
|
183
|
+
puts "--------------------"
|
184
|
+
puts "fondimen difference:"
|
185
|
+
puts str
|
186
|
+
puts "--------------------"
|
187
|
+
end
|
188
|
+
|
189
|
+
exit if options.skip==true
|
190
|
+
str= ""
|
191
|
+
0.upto(255) do |i|
|
192
|
+
a=p1.chars[i]
|
193
|
+
b=p2.chars[i]
|
194
|
+
next unless a and b
|
195
|
+
l1=a[:lig_kern] ? p1.lig_kern[a[:lig_kern]] : nil
|
196
|
+
l2=b[:lig_kern] ? p2.lig_kern[b[:lig_kern]] : nil
|
197
|
+
|
198
|
+
next if a==b and l1==l2
|
199
|
+
|
200
|
+
if a==nil
|
201
|
+
str << "#{i}: no character at this slot in font 1" << "\n"
|
202
|
+
elsif b==nil
|
203
|
+
str << "#{i}: no character at this slot in font 2" << "\n"
|
204
|
+
else
|
205
|
+
chr=""
|
206
|
+
[:charwd, :charht, :chardp, :charic].each { |dim|
|
207
|
+
next if a[dim].to_f==b[dim].to_f
|
208
|
+
if a[dim]==nil
|
209
|
+
chr << " Difference in #{dim}: nil vs. #{b[dim]}" << "\n"
|
210
|
+
elsif b[dim]==nil
|
211
|
+
chr << " Difference in #{dim}: #{b[dim]} vs. nil" << "\n"
|
212
|
+
elsif (a[dim] - b[dim]).abs > a[dim] * percent
|
213
|
+
chr << " Difference in #{dim}: #{a[dim]} vs. #{b[dim]}" << "\n"
|
214
|
+
end
|
215
|
+
}
|
216
|
+
if l1 != l2 and options.ignore_kern != true
|
217
|
+
chr << " Difference in kern information" << "\n"
|
218
|
+
if l1==nil
|
219
|
+
str << " no lig/kern information for first font \n"
|
220
|
+
elsif l2==nil
|
221
|
+
str << " no lig/kern information for second font \n"
|
222
|
+
else
|
223
|
+
chr << " in font1 but not in font 2:" << (l1 - l2).join(" ").to_s << "\n"
|
224
|
+
chr << " in font2 but not in font 1:" << (l2 - l1).join(" ").to_s << "\n"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# if a[:ligkern] and b[:ligkern]
|
229
|
+
# if a[:ligkern][:lig] != b[:ligkern][:lig]
|
230
|
+
# chr << " Difference in lig information" << "\n"
|
231
|
+
# if a[:ligkern][:lig]
|
232
|
+
# a[:ligkern][:lig].each { |lig|
|
233
|
+
# chr << " | " << lig.inspect << "\n"
|
234
|
+
# }
|
235
|
+
# else
|
236
|
+
# chr << "nil"
|
237
|
+
# end
|
238
|
+
# chr << " vs.\n"
|
239
|
+
# if b[:ligkern][:lig]
|
240
|
+
# b[:ligkern][:lig].each { |lig|
|
241
|
+
# chr << " | " << lig.inspect << "\n"
|
242
|
+
# }
|
243
|
+
# else
|
244
|
+
# chr << "nil"
|
245
|
+
# end
|
246
|
+
# end
|
247
|
+
# if a[:ligkern][:krn]
|
248
|
+
# (a[:ligkern][:krn] - b[:ligkern][:krn]).each { |lig|
|
249
|
+
# if options.mapencoding
|
250
|
+
# chr << " | [#{options.mapencoding[lig[0]]} #{lig[1]}]\n"
|
251
|
+
# else
|
252
|
+
# chr << " | " << lig.inspect << "\n"
|
253
|
+
# end
|
254
|
+
# }
|
255
|
+
# else
|
256
|
+
# chr << "nil"
|
257
|
+
# end
|
258
|
+
# chr << " vs.\n"
|
259
|
+
# if b[:ligkern][:krn]
|
260
|
+
# (b[:ligkern][:krn] - a[:ligkern][:krn]).each { |lig|
|
261
|
+
# if options.mapencoding
|
262
|
+
# chr << " | [#{options.mapencoding[lig[0]]} #{lig[1]}]\n"
|
263
|
+
# else
|
264
|
+
# chr << " | " << lig.inspect << "\n"
|
265
|
+
# end
|
266
|
+
# }
|
267
|
+
# else
|
268
|
+
# chr << "nil"
|
269
|
+
# end
|
270
|
+
#end
|
271
|
+
# end
|
272
|
+
if a[:dvi] != b[:dvi]
|
273
|
+
chr << " Difference in map\n"
|
274
|
+
chr << showmap(a[:map])
|
275
|
+
chr << " vs.\n"
|
276
|
+
chr << showmap(b[:map])
|
277
|
+
end
|
278
|
+
|
279
|
+
if chr.length > 0
|
280
|
+
str << "#{i}: "
|
281
|
+
if options.texencoding
|
282
|
+
str << options.texencoding[i]
|
283
|
+
end
|
284
|
+
str << "\n"
|
285
|
+
str << chr
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
if str.length > 0
|
290
|
+
puts "Character entries:"
|
291
|
+
puts "------------------"
|
292
|
+
puts str
|
293
|
+
end
|
294
|
+
|
295
|
+
|