#!/usr/bin/env ruby #-- # Last Change: Tue May 16 18:10:52 2006 #++ =begin rdoc == afm2tfm using the ruby font installer library This is a re-implementation of afm2tfm that is part of dvips. This does not aim for a 100% compatible output. There are some differences in the calculation of the font metrics, which, in my opinion, are reasonable. The -u and -o switch are missing from this implementation. Usage: afm2tfm.rb [options] FILE[.afm,.ttf] ... [FILE[.tfm]] -c REAL use REAL for height of small caps made with -V [0.8] -d DIRNAME Set the base output directory to DIRNAME -e REAL widen (extend) characters by a factor of REAL -l Include ligature and kerning information in tfm file -p ENCFILE read/download ENCFILE for the PostScript encoding -s REAL oblique (slant) characters by REAL, generally <<1 -t ENCFILE read ENCFILE for the encoding of the vf file -T ENCFILE equivalent to -p ENCFILE -t ENCFILE -v [FILE] make a VF file with filename FILE -V [SCFILE] like -v, but synthesize smallcaps as lowercase --help print this message and exit. --version print version number and exit. = Usage See the documentation of the original afm2tfm for an explanation of the parameters -c, -e, -s, -p, -t, -T, -v and -V. afm2tfm.rb creates a tfm (tex font metric) file from the font given as the first argument. This font can be a Postscript Type 1 font metric file (afm) or a TrueType font. (So the name of the program is a bit misleading, it is not restricted to Type 1 font metric files.) The tfm file is written assuming that the underlying TeX text is encoded in the encoding given with the -p parameter. [-d DIRNAME] Set the base directory to DIRNAME. All files are written to the base directory. If unset, use the current directory. [-l] Don't discard the ligature and kerning information when writing the tfm file. [-v, -V FILE] The filename of the virtual fonts is optional. When unset, construct a name such as ec-savorg__-capitalized-800. --- Remark: this is not the reimplementation I mentioned at the 35th NTG meeting. Author:: Patrick Gundlach License:: Copyright (c) 2005 Patrick Gundlach. Released under the terms of the GNU General Public License =end # :enddoc: # font metric differences between afm2tfm and afm2tfm.rb # tfm: fix_height is applied before writing out the tfm file, so the height # of the glpyphs are different. # slant: charic calculation in the vpl file is not affected by the # texheight in afm2tfm.c, but in afm2tfm.rb the height is changed # before cahric calculation # other: # in my testfont, the hyphen has a different height in the tfm # file: 732 (afm2tfm.c) vs. 240 (afm2tfm.rb) require 'optparse' require 'ostruct' require 'rfil/font' include RFIL options=OpenStruct.new ARGV.options { |opt| opt.banner = "Usage: #{File.basename($0)} [options] FILE[.afm] ... [FILE[.tfm]]" opt.on("-c REAL", Float, "use REAL for height of small caps made with -V [0.8]") {|c| if c and c >= 0.01 options.capheight=c else puts "! Bad small caps height" exit -1 end } opt.on("-d DIRNAME", String, "Set the base output directory to DIRNAME") {|d| if File.exists?(d) and File.directory?(d) options.dirname=d else puts "! #{d} does not exist or is not a directory" exit -1 end } opt.on("-e REAL", Float, "widen (extend) characters by a factor of REAL") {|e| # this test should be in class AFM if e and e >= 0.01 options.efactor=e else puts "! Bad extension factor" exit -1 end } opt.on("-l", "Include ligature and kerning information in tfm file") { options.ligkern=true } opt.on("-p ENCFILE", "read/download ENCFILE for the PostScript encoding") {|e| options.mapenc = e } opt.on("-s REAL",Float,"oblique (slant) characters by REAL, generally <<1") {|s| if s options.slant=s else puts "! Bad slant parameter" exit -1 end } opt.on("-t ENCFILE", "read ENCFILE for the encoding of the vf file") {|e| options.texenc = e } opt.on("-T ENCFILE",String,"equivalent to -p ENCFILE -t ENCFILE") {|e| options.mapenc = e options.texenc = e } opt.on("-v [FILE]", String, "make a VF file with filename FILE") { |v| options.write_vf=true options.vffile=v } opt.on("-V [SCFILE]","like -v, but synthesize smallcaps as lowercase") { |v| options.vffile=v options.write_vf=true options.fakecaps=true } opt.on("--help","print this message and exit.") { puts opt; exit 0 } opt.on("--version","print version number and exit.") { puts "#{File.basename($0)}: Version 0.9" puts "Uses RFI Library (https://foundry.supelec.fr/projects/rfil)" puts "[Based on afm2tfm(k) (dvips(k) 5.95a) 8.1 (C) 2005 Radical Eye Software.]" exit } opt.parse! } if ARGV.size == 0 puts "#{File.basename($0)}: Need at least one file argument." puts "Try `#{File.basename($0)} --help' for more information." exit 0 end inputfile=ARGV.shift if ARGV.size >0 options.outputfilename=ARGV.shift end font = RFI::Font.new font.write_vf = options.write_vf if options.dirname font.set_dirs(options.dirname) end begin font.load_variant(inputfile) rescue Errno::ENOENT puts "! Cannot find file #{inputfile}" exit -1 end font.texenc=options.texenc || "8a.enc" font.mapenc=options.mapenc || "8a.enc" font.apply_ligkern_instructions(RFI::STDLIGKERN) font.efactor=options.efactor || 1.0 font.slant =options.slant || 0.0 ploptions=options.ligkern==true ? {:noligs=>false} : {:noligs=>true} fn=font.map_fontname(font.mapenc) + ".tfm" f=font.to_tfm(font.mapenc,ploptions) f.tfmpathname=File.join(font.get_dir(:tfm),fn) f.save(true) if options.fakecaps fc = font.load_variant(inputfile) font.fake_caps(fc,options.capheight || 0.8) font.copy(fc,:lowercase,:ligkern=>true) end if options.write_vf vffilename=if options.vffile options.vffile else font.tex_fontname(font.texenc[0]) end vf= File.join(font.get_dir(:vf) ,vffilename+".vf") tfm=File.join(font.get_dir(:tfm),vffilename+ ".tfm") vpl=font.to_vf(font.mapenc,font.texenc[0]) vpl.tfmpathname=File.join(font.get_dir(:tfm) ,vffilename + ".tfm") vpl.vfpathname=File.join(font.get_dir(:vpl) ,vffilename + ".vf") vpl.save(true) # vplfile= File.join(font.get_dir(:vpl) ,vffilename + ".vpl") # vpl.write_vpl(vplfile) # vpl.write_vf(vf,tfm) end puts font.maplines