#! /usr/local/bin/perl 'di '; 'ds 00 \"'; 'ig 00 '; # # This is a dumper of TrueType font by using FreeType library. $rcsid = q$Id: ftinfo.pl,v 1.16 1998/12/14 05:12:08 jam Exp $; # # Copyright (c) 1998 Kazushi (Jam) Marukawa # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice in the documentation and/or other materials provided with # the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # use FreeTypeWrapper; require "jcode.pl"; require 'getopts.pl'; Getopts('daclhinopMm:s:'); die "Usage: $0 [-daclhinopM] [-m char] [-s scale (point)] font-names... -d: debug mode -a: dump all -c: dump charmap -l: dump list of properties -h: dump all header -i: dump all horizontal header -n: dump all names -o: dump all os/2 -p: dump all postscript -M: dump metrics of instance -m char: dump metrics of character -m perl-exp: dump each metrics of characters, e.g. -m '\"a\"..\"z\"' -s point: scale glyph into # point " unless @ARGV; $opt_c = 1 if $opt_a; $opt_l = 1 if $opt_a; $opt_h = 1 if $opt_a; $opt_i = 1 if $opt_a; $opt_n = 1 if $opt_a; $opt_o = 1 if $opt_a; $opt_p = 1 if $opt_a; $opt_s = 10 unless defined $opt_s; foreach $fn (@ARGV) { $font = new FreeTypeWrapper($fn); warn "open failed: $fn\n" unless defined $font; next unless defined $font; for ($i = 0; $i < $font->facenum; $i++) { $face = $font->open_collection($i); warn "open_collection failed: $fn\n" unless defined $face; next unless defined $face; $count = $face->namenum; $prop = $face->TT_Get_Face_Properties(); print "$fn: $i face\n"; if ($opt_c) { my $charmapnum = $face->charmapnum; for (my $j = 0; $j < $charmapnum; $j++) { my $charmap = new FreeTypeCharMap($face, $j); if (!defined $charmap) { printf("$fn: $i: $j charmap: NONE\n"); next; } printf("$fn: $i: $j charmap: platformID=%d encoding=%d\n", $charmap->platformID, $charmap->encodingID) if $opt_d; printf("$fn: $i: $j charmap: %s, %s\n", $charmap->platform, $charmap->encoding) unless $opt_d; } } if ($opt_l) { foreach $j (sort (keys %{$prop})) { print "$fn: $i: $j: $prop->{$j}\n"; } } if ($opt_h) { foreach $j (sort (keys %{$prop->{header}})) { print "$fn: $i: header: $j: $prop->{header}->{$j}\n"; } } if ($opt_i) { foreach $j (sort (keys %{$prop->{horizontal}})) { print "$fn: $i: horizontal: $j: $prop->{horizontal}->{$j}\n"; } } if ($opt_n) { for ($j = 0; $j < $count; $j++) { $name = new FreeTypeName($face, $j); $string = $name->string(); jcode::convert(*string, 'euc', 'sjis'); printf("$fn: $i: $j name: platformID=%d encoding=%d languageID=%d nameID=%d, name=\"%s\"\n", $name->platformID, $name->encodingID, $name->languageID, $name->namedescID, $string) if $opt_d; printf("$fn: $i: $j name: %s, %s, %s, %s: %s\n", $name->platform, $name->encoding, $name->language, $name->namedesc, $string) unless $opt_d; } } if ($opt_o) { print("$fn: $i: os2: code page range: ", $face->get_codepagerange, "\n"); print("$fn: $i: os2: unicode range: ", $face->get_unicoderange, "\n"); printf("$fn: $i: os2: xAvgCharWidth = %d\n", $prop->{os2}->{xAvgCharWidth}); print("$fn: $i: os2: usWeightClass: ", $face->get_weightclass, "\n"); print("$fn: $i: os2: usWidthClass : ", $face->get_widthclass, "\n"); print("$fn: $i: os2: fsSelection : ", $face->get_selection, "\n"); foreach $j (sort (keys %{$prop->{os2}})) { if ($j eq "panose") { ($a = $prop->{os2}->{$j}) =~ s/(.)/sprintf("0x%02x ", ord($1))/ge; print "$fn: $i: os2: $j: $a\n"; } elsif ($j eq "achVendID") { ($a = $prop->{os2}->{$j}) =~ s/(\s|\0)*$//; print "$fn: $i: os2: $j: $a\n"; } else { print "$fn: $i: os2: $j: $prop->{os2}->{$j}\n"; } } } if ($opt_p) { foreach $j (sort (keys %{$prop->{postscript}})) { print "$fn: $i: postscript: $j: $prop->{postscript}->{$j}\n"; } } if ($opt_M) { my $charmapnum = $face->charmapnum; my $charmap; my $j; for ($j = 0; $j < $charmapnum; $j++) { $charmap = new FreeTypeCharMap($face, $j); last if $charmap->platform =~ /Microsoft/ && $charmap->encoding =~ /Unicode/; } die "Cannot find Microsoft Unicode character map\n" if $j == $charmapnum; my $instance = $face->new_instance(); $instance->set_resolutions(100, 100); $instance->set_flags(1, 1); $instance->set_charsize($opt_s * 64); my $metrics = $instance->metrics(); foreach $mval (sort (keys %{$metrics})) { printf("$fn: $i: Instance Metrics: %s -> %s\n", $mval, $metrics->{$mval}); } } if ($opt_m) { my $charmapnum = $face->charmapnum; my $charmap; my $j; for ($j = 0; $j < $charmapnum; $j++) { $charmap = new FreeTypeCharMap($face, $j); last if $charmap->platform =~ /Microsoft/ && $charmap->encoding =~ /Unicode/; } die "Cannot find Microsoft Unicode character map\n" if $j == $charmapnum; my $instance = $face->new_instance(); $instance->set_resolutions(100, 100); $instance->set_flags(1, 1); $instance->set_charsize($opt_s * 64); $opt_m = "\"$opt_m\"" if length $opt_m == 1; foreach $val (eval $opt_m) { $val = ord($val) if $val !~ /^\d/; $val = oct($val) if $val =~ /^0/; my $code = $charmap->convert($val); printf("$fn: $i: char 0x%x: converted into 0x%x, %d " . "pt scaled\n", $val, $code, $opt_s); my $g = new FreeTypeGlyph($instance, $code); my $metrics = $g->metrics(); printf("$fn: $i: char 0x%x: Metrics: aw %d -> %g, " . "bX %d -> %g, bY %d -> %g\n", $val, $metrics->{advance}, $metrics->{advance} / 64, $metrics->{bearingX}, $metrics->{bearingX} / 64, $metrics->{bearingY}, $metrics->{bearingY} / 64); # foreach $mval (sort (keys %{$metrics})) { # printf("$fn: $i: char 0x%x: Metrics: %s -> %s\n", # $val, $mval, $metrics->{$mval}); # } my $outline = $g->outline(); # $outline->{OUTLINE}->{dropout_mode} = 2; my %matrix = ( "xx" => 180 / 180 * 65536, "xy" => 0, "yx" => 0, "yy" => 180 / 180 * 65536 ); $outline->transform(\%matrix); $bbox = $outline->get_bbox(); printf("$fn: $i: char 0x%x: BBox is (%d, %d), (%d, %d) -> " . "(%g, %g), (%g, %g)\n", $val, $bbox->{xMin}, $bbox->{yMin}, $bbox->{xMax}, $bbox->{yMax}, $bbox->{xMin} / 64, $bbox->{yMin} / 64, $bbox->{xMax} / 64, $bbox->{yMax} / 64); } } } } ############################################################################## # These next few lines are legal in both Perl and nroff. # finish .ig .00 ; 'di \" finish diversion--previous line must be blank .nr nl 0-1 \" fake up transition to first page again .nr % 0 \" start at page 1 ';<<'.ex'; #__END__ ############# From here on it's a standard manual page ############ .TH FTINFO 1 "May 10, 1998" .AT 3 .SH NAME ftinfo \- display FreeType information of TrueType font files. .SH SYNOPSIS .B ftinfo [-daclhinop] [-mchar] [-sscale] font-names ... .SH DESCRIPTION .I Ftinfo displays information of each font file by using FreeType library. .sp .SH OPTIONS .IP -d Enter debug mode. .IP -a Dump all information about each TrueType font file. .IP -c Dump charmap information. .IP -l Dump list of properties. .IP -h Dump all information in header property. .IP -i Dump all information in horizontal header property. .IP -n Dump all information in name property. .IP -o Dump all information in os/2 property. .IP -p Dump all information in postscript property. .IP -m\fIchar\fP Calculate and show the metrics of a character. .IP -m\fIperl-exp\fP Calculate and show the each metrics of a characters represented by perl-exp, e.g. -m '"a".."z"' show all metrics from a to z. .IP -s\fIscale\fP Use scale as point-size of calculation of the metrics. .SH COPYRIGHT Copyright (c) 1998 Kazushi (Jam) Marukawa .br Comments to: jam@pobox.com .ex