summaryrefslogtreecommitdiff
path: root/support/rfil/examples/afminfo
diff options
context:
space:
mode:
Diffstat (limited to 'support/rfil/examples/afminfo')
-rwxr-xr-xsupport/rfil/examples/afminfo249
1 files changed, 249 insertions, 0 deletions
diff --git a/support/rfil/examples/afminfo b/support/rfil/examples/afminfo
new file mode 100755
index 0000000000..b0f279a3ac
--- /dev/null
+++ b/support/rfil/examples/afminfo
@@ -0,0 +1,249 @@
+#!/usr/bin/env ruby
+#--
+# Last Change: Tue May 16 18:09:09 2006
+#++
+=begin rdoc
+
+== afminfo - print out information about an afm or truetype font file
+
+ Usage: afminfo [options] afm-file.afm | truetypefont.ttf
+ -m, --metrics show global metrics information
+ -v, --verbose verbose output
+ --[no-]info list general information (default)
+ -l, --list-glyphs list all available glyphs
+ -g, --glyphinfo g information about a specific glyph
+ -h, --help Show this help
+
+---
+Author:: Patrick Gundlach <patrick@gundla.ch>
+License:: Copyright (c) 2005 Patrick Gundlach.
+ Released under the terms of the GNU General Public License
+=end
+
+# :enddoc:
+
+require 'optparse'
+require 'ostruct'
+require 'rfil/font/afm'
+
+
+# sorry for german - one day I'll change that into engish. --pg
+class TextTable # :nodoc:
+ def initialize (data,maxchars=80)
+ raise "Data must be an array of strings" unless data.kind_of? Array
+ @data = data
+
+ @maxchars = 90
+ @maxwidth = 0
+ @data.each { |elt|
+ @maxwidth = @maxwidth > elt.length ? @maxwidth : elt.length
+ }
+ @spalten = (@maxchars/(@maxwidth + 1)).floor
+ end
+
+ def zeilenweise
+ (0...@data.size).each { |x|
+ print sprintf("%-" + @maxwidth.to_s + "s",@data[x]) +
+ if (x+1) % @spalten == 0
+ "\n"
+ else
+ " "
+ end
+ }
+ puts
+ end
+
+ def spaltenweise
+ zeilenmin = (@data.size * 1.0 / @spalten).floor
+ zeilenmax = (@data.size * 1.0 / @spalten).ceil
+ anz_volle_spalten = @data.size % @spalten
+
+ verteilung=Array.new()
+ verteilung[0]=0
+ count = 0
+ (0...@spalten).each { |col|
+ if col < anz_volle_spalten
+ count += zeilenmax
+ else
+ count += zeilenmin
+ end
+ verteilung[col]= count
+ }
+ verteilung.unshift 0
+ (0...zeilenmax).each { |zeile|
+ puts((0...@spalten).collect { |spalte|
+ w = @data[verteilung[spalte] + zeile]
+ if (spalte >= anz_volle_spalten) and (zeile >= zeilenmin)
+ w = ""
+ end
+ sprintf("%-" + @maxwidth.to_s + "s",w)
+ }.join(' '))
+ }
+ end
+end
+
+class AFMinfo # :nodoc:
+ def initialize (afm)
+ @afm = afm
+ @uppercase_letters = ('A'..'Z').collect { |l| l }
+ @lowercase_letters = ('a'..'z').collect { |l| l }
+ @digits = %w(one two three four five six seven eight nine zero)
+ end
+ def stdformat
+ "%-18s "
+ end
+ def printout (str,value)
+ puts sprintf(stdformat + "%s", str + ":" ,value.to_s)
+ end
+
+ def num_to_string (num,reservespace=true)
+ formatstring = "%"
+ formatstring << " " if reservespace
+ formatstring << (num.to_i == num ? "d" : "f")
+ # output "integer" if value after decimal point is 0
+ sprintf(formatstring,num)
+ end
+
+ def dump_maininfo
+ puts "General font information:"
+ puts "========================="
+ printout("Filename",@afm.filename)
+ [
+ ["Fontname",:fontname],
+ ["FullName",:fullname],
+ ["Family name",:familyname],
+ ["Weight",:weight],
+ ["EncodingScheme",:encodingscheme],
+# ["·","·"],
+ ].each { |s,m|
+ printout(s,@afm.send(m))
+ }
+ puts sprintf(stdformat,'Number of gylphs:') + @afm.count_charmetrics.to_s +
+ " (encoded: " + @afm.count_charmetrics_encoded.to_s + ", unencoded: " + @afm.count_charmetrics_unencoded.to_s + ")"
+
+ end
+ def dump_metrics
+ puts "\n\nGlobal metrics information:"
+ puts "=========================="
+ puts sprintf(stdformat,"FontBBox:") + @afm.fontbbox.collect { |f|
+ num_to_string(f)
+ }.join(' ') + ' (llx,lly,urx,ury)'
+ printout('IsFixedPitch',@afm.isfixedpitch)
+
+ [
+ ["ItalicAngle", :italicangle],
+ ["UnderlinePosition", :underlineposition],
+ ["UnderlineThickness", :underlinethickness],
+ ["CapHeight", :capheight],
+ ["XHeight", :xheight],
+ ["Ascender", :ascender],
+ ["Descender", :descender]
+ ].each { |s,m|
+ puts sprintf(stdformat,s) + num_to_string(@afm.send(m))
+ }
+ end
+ def dump_glyphinfo (glyph)
+ chars=@afm.chars[glyph]
+ puts "\n\nGlyph information (" + glyph + ")"
+ puts "===================="
+ puts sprintf(stdformat,"Encoding pos:") +
+ if chars.c == -1
+ "--"
+ else
+ sprintf("%d (dec), %x (hex), %o (oct)",chars.c,chars.c,chars.c)
+ end
+ puts sprintf(stdformat,"Width x (wx)") + chars.wx.to_s
+ puts sprintf(stdformat,"Bounding box") + chars.b.collect { |f|
+ num_to_string(f,false)
+ }.join(' ') + ' (llx,lly,urx,ury)'
+ puts "Kerning pairs: (x,y)"
+ puts "--------------------"
+ chars.kern_data.each { |k,v|
+ puts sprintf(stdformat," " + k) + num_to_string(v[0]) + "," +
+ num_to_string(v[1])
+ }
+ end
+ def dump_glyphs
+ chars=@afm.chars
+ puts "\n\nList of glyphs"
+ puts "================"
+ removefromlist=[]
+ if @uppercase_letters.all? { |glyph|
+ chars[glyph]
+ }
+ puts sprintf(stdformat,"A-Z") + "available"
+ removefromlist += @uppercase_letters
+ else
+ puts sprintf(stdformat,"A-Z") + "some missing"
+ end
+ if @lowercase_letters.all? { |glyph|
+ chars[glyph]
+ }
+ puts sprintf(stdformat,"a-z") + "available"
+ removefromlist += @lowercase_letters
+ else
+ puts sprintf(stdformat,"a-z") + "some missing"
+ end
+ if @digits.all? { |glyph|
+ chars[glyph]
+ }
+ puts sprintf(stdformat,"one, two, .., zero") + "available"
+ removefromlist += @digits
+ else
+ puts sprintf(stdformat,"one, two, .., zero") + "some missing"
+ end
+ puts
+ glyphlist=[]
+ chars.each { |glyph,h|
+ glyphlist.push(glyph + (h.c == -1 ? "*" : ""))
+ }
+ glyphlist = glyphlist - removefromlist
+ glyphlist.sort! { |a,b|
+ a.casecmp b
+ }
+ t = TextTable.new(glyphlist - removefromlist)
+ t.spaltenweise
+ puts "\n* = unencoded - only glyphs not mentioned above listed"
+ end
+
+end
+
+options=OpenStruct.new
+options.verbose = false
+options.metrics = false
+options.glyph = nil
+options.listglyphs = false
+options.generalinfo = true
+
+ARGV.options { |opt|
+ opt.banner = "Usage: #{File.basename($0)} [options] afm-file[.afm]"
+ opt.on("--metrics", "-m", "show global metrics information") { options.metrics=true}
+ opt.on("--verbose", "-v", "verbose output") { options.verbose=true }
+ opt.on("--[no-]info", "list general information (default)") { |x|
+ options.generalinfo=x }
+ opt.on("--list-glyphs", "-l", "list all available glyphs") { options.listglyphs=true }
+ opt.on("--glyphinfo g" , "-g",
+ "information about a specific glyph") { |arg|
+ options.glyph = arg
+ }
+
+ opt.on("--help", "-h", "Show this help") { puts opt; exit 0 }
+ opt.separator ""
+ opt.separator "Copyright (c) 2005 Patrick Gundlach"
+ opt.parse!
+}
+
+unless ARGV.size==1
+ puts "Please specify one afm-file to read" if ARGV
+ exit 1
+end
+
+
+# afm=Font::AFM.new(:verbose => options.verbose)
+afm=RFIL::Font::Metric.read(ARGV[0],:verbose => options.verbose)
+
+ai = AFMinfo.new(afm)
+ai.dump_maininfo if options.generalinfo
+ai.dump_metrics if options.metrics
+options.glyph && ai.dump_glyphinfo(options.glyph)
+ai.dump_glyphs if options.listglyphs