diff options
author | Karl Berry <karl@freefriends.org> | 2017-06-06 22:02:27 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-06-06 22:02:27 +0000 |
commit | e475dfed3e42316a82b5102a9c3f5349683231cc (patch) | |
tree | ebed2aa523daa7d0ed99632ca5ce3fc01ea94b7c /Master/texmf-dist/scripts/dviinfox | |
parent | 289116fcf3cec3b7fe8d462c6563c1c46ba9e13f (diff) |
dviinfox (5jun17)
git-svn-id: svn://tug.org/texlive/trunk@44515 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/dviinfox')
-rwxr-xr-x | Master/texmf-dist/scripts/dviinfox/dviinfox.pl | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/dviinfox/dviinfox.pl b/Master/texmf-dist/scripts/dviinfox/dviinfox.pl new file mode 100755 index 00000000000..39330951047 --- /dev/null +++ b/Master/texmf-dist/scripts/dviinfox/dviinfox.pl @@ -0,0 +1,366 @@ +#!/usr/bin/env perl + +# dviinfox +# ======== +# +# This script is a joint effort of +# Dag Langmyhr, Department of Informatics, University of Oslo +# (dag at ifi.uio.no) +# and +# Hironobu Yamashita, Japanese TeX Development Community +# (h.y.acetaminophen at gmail.com) +# +# A program to print information about a DVI file. +# +# Usage: dviinfox [options] file1 file2 ... +# where the flags indicate which information is desired. +# -f Give information about the fonts used. +# -p Give information about the number of pages. +# -v List the program version number. +# -h Show help message. +# No options will provide all information available. +# +# Example: +# % dviinfox alltt.dvi +# alltt.dvi: DVI format 2; 3 pages +# Magnification: 1000/1000 +# Size unit: 1000x25400000/(1000x473628672)dum = 0.054dum = 1.000sp +# Page size: 407ptx682pt = 14.340cmx23.970cm +# Stack size: 8 +# Comment: " TeX output 1995.07.07:1513" +# Font 27: cmr9 at 9.000 (design size 9.000, checksum=1874103239) +# Font 26: cmsy6 at 6.000 (design size 6.000, checksum=1906386187) +# Font 21: cmr8 at 8.000 (design size 8.000, checksum=2088458503) +# Font 20: cmsy10 at 12.000 (design size 10.000, checksum=555887770) +# Font 16: cmr12 at 12.000 (design size 12.000, checksum=1487622411) +# Font 15: cmtt12 at 17.280 (design size 12.000, checksum=3750147412) +# Font 14: cmr17 at 17.280 (design size 17.280, checksum=1154739572) +# Font 13: cmsy10 at 10.000 (design size 10.000, checksum=555887770) +# Font 7: cmr10 at 10.000 (design size 10.000, checksum=1274110073) +# Font 6: cmr7 at 7.000 (design size 7.000, checksum=3650330706) + +use strict; + +my $Prog = "dviinfox"; +my $Version = "1.04"; +my $Author = "Dag Langmyhr and Hironobu Yamashita"; + +my $True = 1; +my $False = 0; + +my $List_all = $True; +my $List_fonts = $False; +my $List_pages = $False; + +# DVI commands: +my $DVI_Filler = "\337"; # 223 = 0xdf +my $DVI_Font = "\363"; # 243 = 0xf3 +my $DVI_Post = "\370"; # 248 = 0xf8 +my $DVI_Post_post = "\371"; # 249 = 0xf9 +my $DVI_Pre = "\367"; # 247 = 0xf7 +my $XDV_Font = "\374"; # 252 = 0xfc + +my $Unit; + +if (!@ARGV) { + show_usage(); + print "Try \"$Prog -h\" for more information.\n"; +} + +Param: +foreach (@ARGV) { + /^-f$/ && do { + $List_fonts = $True; $List_all = $False; next Param; }; + /^-p$/ && do { + $List_pages = $True; $List_all = $False; next Param; }; + /^-v$/ && do { + show_version(); next Param; }; + /^-h$/ && do { + show_help(); next Param; }; + /^-/ && do { + print STDERR "$Prog: Unknown option '$_' ignored.\n"; next Param; }; + + &Read_DVI_file($_); +} + +exit 0; + +# Only sub definitions from here on + +sub show_version { + print "This is $Prog $Version, by $Author\n"; +} + +sub show_usage { + show_version(); + print "Usage: $Prog [-f][-p][-v] file...\n"; +} + +sub show_help { + show_usage(); + print "A program to print information about a DVI file.\n"; + print "Options:\n"; + print " -f Give information about the fonts used.\n"; + print " -p Give information about the number of pages.\n"; + print " -v List the program version number.\n"; + print " -h Show help message.\n"; + exit 0; +} + +sub Read_DVI_file { + local($_) = @_; + my ($c, $cn); + my $IS_XDV = 0; + + print "$_: "; + + open(F, $_) || do { print STDERR "Could not open!\n\n"; exit 1; }; + + # First, read info at start of DVI file: + + if (($c = getc(F)) ne $DVI_Pre) { + printf STDERR ("Not a DVI file (first byte is 0x%02x, not 0x%02x)!\n\n", + ord($c), ord($DVI_Pre)); + close F; exit 1; + }; + + my $Format = ord(getc(F)); + my $Numer = &Read4; + my $Denom = &Read4; + my $Magni = &Read4; + my $Comment = &Read_text; + + # Then, read information at the end of the DVI file: + + seek(F, -1, 2); + while (($c = getc(F)) eq $DVI_Filler) { seek(F, -2, 1); }; + my $VersionID = ord($c); + # Previously we required equality ($VersionID == $Format). However, + # it seems ok even when format id (pre) and version id (post_post) + # are different. TeX4ht allows $VersionID <= 10, so we follow it + if (($VersionID != $Format) && ($VersionID > 10)) { + print STDERR "DVI format error (format: $Format vs id: $VersionID)!\n\n"; + close F; exit 1; + }; + $IS_XDV = 1 if ($Format > 2); + + seek(F, -6, 1); + if (($c = getc(F)) ne $DVI_Post_post) { + $cn = ord($c); + printf STDERR ("DVI error: Expected POST_POST command, not 0x%02x!\n\n", $cn); + close F; exit 1; + }; + + my $Last_post = &Read4; + seek(F, $Last_post, 0) || do { + print STDERR "Could not locate position $Last_post!\n\n"; + close F; exit 1; + }; + if (($c = getc(F)) ne $DVI_Post) { + $cn = ord($c); + printf STDERR ("DVI error: Expected POST command, not 0x%02x!\n\n", $cn); + close F; exit 1; + }; + + my $Final_page = &Read4; + my $Numer2 = &Read4; + my $Denom2 = &Read4; + my $Magni2 = &Read4; + my $Height = &Read4; + my $Width = &Read4; + my $Stack = &Read2_u; + my $Pages = &Read2_u; + + if ($List_all) { + print "DVI format $Format"; + print "; id $VersionID" if ($VersionID != $Format); + print " (pTeX DVI)" if (($Format == 2) && ($VersionID == 3)); + print " (XeTeX XDV)" if ($Format > 2); + print "; "; + } + if ($List_all || $List_pages) { + print "$Pages page"; + print "s" if ($Pages > 1); + }; + + $Unit = $Magni*$Numer/(1000*$Denom); + if ($List_all) { + print "\n Magnification: $Magni/1000"; + printf("\n Size unit: %dx$Numer/(1000x$Denom)dum = %5.3fdum = %5.3fsp", + $Magni, $Unit, &Scale_to_sp(1)); + printf("\n Page size: %dptx%dpt = %5.3fcmx%5.3fcm", + &Scale_to_pt($Width), &Scale_to_pt($Height), + &Scale_to_cm($Width), &Scale_to_cm($Height)); + print "\n Stack size: $Stack"; + print "\n Comment: \"$Comment\""; + } + print "\n"; + + if ($List_all || $List_fonts) { + my ($F_count, $F_check, $F_scale, $F_design, $F_name); + my ($F_flag, $F_index, $F_colored, $F_extend, $F_slant, $F_embolden); + my $F_tempswa; + while (($c = getc(F)) eq $DVI_Font || $c eq $XDV_Font) { + # initialize + $F_count = 0; + $F_check = 0; + $F_scale = 0; + $F_design = 0; + $F_name = ''; + $F_flag = 0; + $F_index = 0; + $F_colored = 0; + $F_extend = 0; + $F_slant = 0; + $F_embolden = 0; + if ($c eq $DVI_Font) { + # standard DVI: TFM font definition command + $F_count = ord(getc(F)); + $F_check = &Read4_u; + $F_scale = &Read4; + $F_design = &Read4; + $F_name = &Read_text2; + printf(" Font %3d: %9s at %6.3f", + $F_count, $F_name, &Scale_to_pt($F_scale)); + printf(" (design size %6.3f, ", &Scale_to_pt($F_design)); + print "checksum=$F_check)\n"; + } else { # $c eq $XDV_Font + # extended XDV for XeTeX: Native font definition command + if (!$IS_XDV) { + printf STDERR ("Erorr: Command %d used in non-XDV file!\n", ord($XDV_Font)); + close F; exit 1; + } + $F_count = &Read4_u; + $F_scale = &Read4; + $F_flag = &Read2_u; + $F_name = &Read_text; + $F_index = &Read4_u; + $F_colored = &Read4_u if ($F_flag & 512); + $F_extend = &Read4_u if ($F_flag & 4096); + $F_slant = &Read4_u if ($F_flag & 8192); + $F_embolden = &Read4_u if ($F_flag & 16384); + printf(" Native Font %3d: %s at %6.3f", + $F_count, $F_name, &Scale_to_pt($F_scale)); + printf(" (flags 0x%04x, face index %d)\n", $F_flag, $F_index); + if ($F_flag) { + print(" +features: "); + $F_tempswa = 0; + if ($F_colored) { + printf("Colored=0x%x", $F_colored); + $F_tempswa = 1; + } + if ($F_extend) { + print(", ") if ($F_tempswa); + printf("Extend=0x%x", $F_extend); + $F_tempswa = 1; + } + if ($F_slant) { + print(", ") if ($F_tempswa); + printf("Slant=0x%x", $F_slant); + $F_tempswa = 1; + } + if ($F_embolden) { + print(", ") if ($F_tempswa); + printf("Embolden=0x%x", $F_embolden); + $F_tempswa = 1; + } + print("\n"); + } + } + }; + + if ($c ne $DVI_Post_post) { + $cn = ord($c); + printf STDERR ("DVI error: Expected POST_POST command, not 0x%02x!\n", $cn); + close F; exit 1; + }; + + print "\n"; + }; + + close F; +} + + +# Scale_to_pt (Size) +# ----- +# Give the Size (which is in dum, the standard DVI size) in pt. +sub Scale_to_pt { + return $Unit*$_[0]*72.27/254000; +} + + +# Scale_to_cm (Size) +# ----------- +# Give the Size (which is in dum, the standard DVI size) in cm. +sub Scale_to_cm { + return &Scale_to_pt($_[0])*2.54/72.27; +} + + +# Scale_to_sp (Size) +# ----------- +# Give the Size (which is in dum, the standard DVI size) in sp. +sub Scale_to_sp { + return &Scale_to_pt($_[0])*65536; +} + + +# Read2_u +# ------- +# Read an unsigned two-byte value. +sub Read2_u { + return ord(getc(F))*256 + ord(getc(F)); +} + + +# Read4 +# ----- +# Read a four-byte value. +# (I assume the value is positive and less than 2^31, so the sign bit +# won't matter.) +sub Read4 { + return ((ord(getc(F))*256+ord(getc(F)))*256+ord(getc(F)))*256+ord(getc(F)); +} + + +# Read4_u +# ----- +# Read an unsigned four-byte value. +# (I don't know why this works for values >=2^31, and Read4 does not, +# but as long as it works...) +sub Read4_u { + my (@bytes, @sum); + + $bytes[0] = ord(getc(F)); $bytes[1] = ord(getc(F)); + $bytes[2] = ord(getc(F)); $bytes[3] = ord(getc(F)); + + $sum[0] = $bytes[0]*256 + $bytes[1]; + $sum[1] = $bytes[2]*256 + $bytes[3]; + + return $sum[0]*65536 + $sum[1]; +} + + +# Read_text +# --------- +# Read a text (a one-byte length and the the text byte). +sub Read_text { + local($_); + my ($Leng, $Res); + + $Leng = ord(getc(F)); read(F, $Res, $Leng); + return $Res; +} + + +# Read_text2 +# ---------- +# Like 'Read_text', but the length is the sum of two bytes. +sub Read_text2 { + local($_); + my ($Leng, $Res); + + $Leng = ord(getc(F)) + ord(getc(F)); read(F, $Res, $Leng); + return $Res; +} |