Clean up output subsystem.
authorBen Pfaff <blp@gnu.org>
Mon, 3 Apr 2006 20:07:54 +0000 (20:07 +0000)
committerBen Pfaff <blp@gnu.org>
Mon, 3 Apr 2006 20:07:54 +0000 (20:07 +0000)
66 files changed:
ChangeLog
NEWS
Smake
config/ChangeLog
config/automake.mk
config/devices
config/html-prologue [deleted file]
config/ps-prologue [deleted file]
config/psfonts/Courier-Bold.afm [new file with mode: 0644]
config/psfonts/Courier-BoldOblique.afm [new file with mode: 0644]
config/psfonts/Courier-Oblique.afm [new file with mode: 0644]
config/psfonts/Courier.afm [new file with mode: 0644]
config/psfonts/Helvetica-Bold.afm [new file with mode: 0644]
config/psfonts/Helvetica-BoldOblique.afm [new file with mode: 0644]
config/psfonts/Helvetica-Oblique.afm [new file with mode: 0644]
config/psfonts/Helvetica.afm [new file with mode: 0644]
config/psfonts/Times-Bold.afm [new file with mode: 0644]
config/psfonts/Times-BoldItalic.afm [new file with mode: 0644]
config/psfonts/Times-Italic.afm [new file with mode: 0644]
config/psfonts/Times-Roman.afm [new file with mode: 0644]
doc/concept-index.texi
doc/configuring.texi
doc/installing.texi
doc/pspp.texinfo
po/en_GB.po
po/pspp.pot
src/language/ChangeLog
src/language/data-io/data-list.c
src/language/data-io/list.q
src/language/data-io/print.c
src/language/dictionary/sys-file-info.c
src/language/line-buffer.c
src/language/stats/crosstabs.q
src/language/stats/descriptives.c
src/language/stats/examine.q
src/language/stats/frequencies.q
src/language/stats/oneway.q
src/language/stats/regression.q
src/language/stats/t-test.q
src/libpspp/ChangeLog
src/libpspp/str.c
src/libpspp/str.h
src/output/ChangeLog
src/output/afm.c [new file with mode: 0644]
src/output/afm.h [new file with mode: 0644]
src/output/ascii.c
src/output/automake.mk
src/output/font.h [deleted file]
src/output/groff-font.c [deleted file]
src/output/html.c
src/output/htmlP.h
src/output/manager.c
src/output/output.c
src/output/output.h
src/output/postscript.c
src/output/table.c
src/output/table.h
src/procedure.c
tests/ChangeLog
tests/bugs/examine-missing.sh
tests/command/examine-extremes.sh
tests/command/examine.sh
tests/command/oneway.sh
tests/command/t-test-1-indep-val.sh
tests/command/t-test-pairs.sh
tests/command/trimmed-mean.sh

index ca0447e986d9047029a5af0b063b0032b9b33a16..29b868ed92730c04a46a6135269bf4210cb13b55 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Mon Apr  3 11:01:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: (GNULIB_MODULES) Add strsep.
+
 Thu Mar 30 15:50:05 2006  Ben Pfaff  <blp@gnu.org>
 
        * Smake: Enable -Wdeclaration-after-statement warning if
 Thu Mar 30 15:50:05 2006  Ben Pfaff  <blp@gnu.org>
 
        * Smake: Enable -Wdeclaration-after-statement warning if
diff --git a/NEWS b/NEWS
index db9c2f2ca999ecabd692be58107367c4cd874a7e..b2cb211cbcc46963cc77b9debc273faf907a7f16 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,11 +1,28 @@
 PSPP NEWS -- history of user-visible changes.
 PSPP NEWS -- history of user-visible changes.
-Time-stamp: <2006-01-28 19:05:46 blp>
+Time-stamp: <2006-04-03 10:56:18 blp>
 Copyright (C) 1996-9, 2000 Free Software Foundation, Inc.
 See the end for copying conditions.
 
 Please send PSPP bug reports to bug-gnu-pspp@gnu.org.
 Copyright (C) 1996-9, 2000 Free Software Foundation, Inc.
 See the end for copying conditions.
 
 Please send PSPP bug reports to bug-gnu-pspp@gnu.org.
+
 Changes since 0.4.1:
 
 Changes since 0.4.1:
 
+  Output changes:
+
+    * Output configuration options have changed.  Please refer to the
+      manual for a full description of the available options.
+
+      In consequence, you will need to reinstall your "devices" file.
+      "make install" will do this for you.
+
+    * The PostScript driver now obtains font metrics from AFM files,
+      instead of Groff-format metrics files.  It can now embed
+      PostScript fonts in its output.
+
+      In consequence, you will need to install an AFM file for each
+      font used in PostScript output.  "make install" will install AFM
+      files for the standard PostScript files, including the ones that
+      the PostScript driver uses by default.
 \f
 Changes since 0.4.0 to 0.4.1:
 
 \f
 Changes since 0.4.0 to 0.4.1:
 
@@ -21,10 +38,10 @@ Changes since 0.4.0 to 0.4.1:
 
     A new PSPP extension called "scratch files" has been implemented.
     A scratch file, like a system file, consists of a dictionary and
 
     A new PSPP extension called "scratch files" has been implemented.
     A scratch file, like a system file, consists of a dictionary and
-    any number of cases.  A sufficiently small scratch file is stored
-    in memory; if it grows too large, it is written to disk.  By
-    default, any file handle whose name begins with # is assumed to
-    refer to a scratch file.  
+    any number of cases.  Small scratch files are stored in memory;
+    one that grows too large is written to disk.  By default, any file
+    handle whose name begins with # is assumed to refer to a scratch
+    file.
 
     Scratch files can be used just about anywhere a system or portable
     file can be used.  Also, portable files are now allowed in most
 
     Scratch files can be used just about anywhere a system or portable
     file can be used.  Also, portable files are now allowed in most
diff --git a/Smake b/Smake
index 49a72f32ba21c8878bb94f83fbb30831e9e291f1..b6bedc9d9a7beb966fde31fc60212bd4201e3c16 100644 (file)
--- a/Smake
+++ b/Smake
@@ -35,6 +35,7 @@ GNULIB_MODULES = \
        strcspn \
        strerror \
        strftime \
        strcspn \
        strerror \
        strftime \
+       strsep \
        strstr \
        strtod \
        strtok_r \
        strstr \
        strtod \
        strtok_r \
index 362d2e6c3cfbe3c5c97a37675e3655ed5e59c951..57301e52d277d69966b07f1fd7d6bec8f2e5f0c3 100644 (file)
@@ -1,3 +1,19 @@
+Mon Apr  3 11:01:16 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: (pkgsysconf_DATA) Add AFM files in config/psfonts.
+       Remove config/html-prologue, config/ps-prologue.
+
+       * html-prologue: Removed.
+
+       * ps-prologue: Removed.
+
+       * psfonts/Courier-Bold.afm, psfonts/Courier-BoldOblique.afm,
+       psfonts/Courier-Oblique.afm, psfonts/Courier.afm,
+       psfonts/Helvetica-Bold.afm, psfonts/Helvetica-BoldOblique.afm,
+       psfonts/Helvetica-Oblique.afm, psfonts/Helvetica.afm,
+       psfonts/Times-Bold.afm, psfonts/Times-BoldItalic.afm,
+       psfonts/Times-Italic.afm, psfonts/Times-Roman.afm: New files.
+
 Sat Feb 11 21:58:29 2006  Ben Pfaff  <blp@gnu.org>
 
        * html-prologue: Don't use ${source-file}, which is no longer
 Sat Feb 11 21:58:29 2006  Ben Pfaff  <blp@gnu.org>
 
        * html-prologue: Don't use ${source-file}, which is no longer
index 2843c311b2537f714c78d106c7714890afafe466..a6e4697c5c3300807c36494c706ea0ba3eb49bcf 100644 (file)
@@ -3,10 +3,20 @@
 
 pkgsysconf_DATA = \
        config/devices \
 
 pkgsysconf_DATA = \
        config/devices \
-       config/html-prologue \
        config/papersize \
        config/papersize \
-       config/ps-prologue
-
+       config/psfonts/Helvetica-Bold.afm \
+       config/psfonts/Times-Bold.afm \
+       config/psfonts/Courier-Bold.afm \
+       config/psfonts/Helvetica-BoldOblique.afm \
+       config/psfonts/Times-BoldItalic.afm \
+       config/psfonts/Courier-BoldOblique.afm \
+       config/psfonts/Helvetica-Oblique.afm \
+       config/psfonts/Times-Italic.afm \
+       config/psfonts/Courier-Oblique.afm \
+       config/psfonts/Helvetica.afm \
+       config/psfonts/Times-Roman.afm \
+       config/psfonts/Courier.afm
 EXTRA_DIST += $(pkgsysconf_DATA)
 
 # A `private installation' in my terms is just having the appropriate
 EXTRA_DIST += $(pkgsysconf_DATA)
 
 # A `private installation' in my terms is just having the appropriate
@@ -14,10 +24,10 @@ EXTRA_DIST += $(pkgsysconf_DATA)
 # location.  So I let those files be installed automatically.
 
 private-install:
 # location.  So I let those files be installed automatically.
 
 private-install:
-       $(mkinstalldirs) $$HOME/.pspp
+       $(mkinstalldirs) $$HOME/.pspp $$HOME/.pspp/psfonts
        cd $(top_srcdir); cp $(pkgsysconf_DATA) $$HOME/.pspp
 
 private-uninstall:
        cd $(top_srcdir); cp $(pkgsysconf_DATA) $$HOME/.pspp
 
 private-uninstall:
-       -cd $$HOME/.pspp;  $(RM) $(notdir $(pkgsysconf_DATA))
-       -rmdir $$HOME/.pspp
+       -cd $$HOME/.pspp && rm $(notdir $(pkgsysconf_DATA))
+       -rmdir $$HOME/.pspp/psfonts $$HOME/.pspp
 
 
index d9abd198e23ecab319dcbeb0ab38a79ba2512eaa..94cba3af833d6d17ae7b7368a0aa82787c0eb90c 100644 (file)
@@ -39,8 +39,6 @@
 # Macros may not be recursive; they may not take arguments.  (However,
 # `definition' is macro-expanded *at time of definition*.)  Macros are
 # referenced with $var or ${var} syntax; the latter is preferred.
 # Macros may not be recursive; they may not take arguments.  (However,
 # `definition' is macro-expanded *at time of definition*.)  Macros are
 # referenced with $var or ${var} syntax; the latter is preferred.
-# Macro definitions on the PSPP command-line take precedence without
-# warning.
 
 # Preferred devices.
 default=tty list
 
 # Preferred devices.
 default=tty list
@@ -51,118 +49,58 @@ list=list-ascii
 define tty-output-file "/dev/tty"
 define list-output-file "pspp.list"
 
 define tty-output-file "/dev/tty"
 define list-output-file "pspp.list"
 
-define no-attributes bold-on="" italic-on="" bold-italic-on=""
-
 # Generic ASCII devices
 # Generic ASCII devices
-tty-ascii:ascii:screen:char-set=ascii output-file=${tty-output-file} \
-  ${no-attributes}
-list-ascii:ascii:listing:length=66 width=79 char-set=ascii \
-  output-file=${list-output-file} ${no-attributes}
-raw-ascii:ascii:screen:width=9999 length=9999 char-set=ascii \
-  output-file=${list-output-file} ${no-attributes} headers=off paginate=off \
-  squeeze=on top-margin=0 bottom-margin=0
+tty-ascii:ascii:screen:output-file=${tty-output-file}
+list-ascii:ascii:listing:length=66 width=79 output-file=${list-output-file}
+raw-ascii:ascii:screen:width=9999 length=9999 output-file=${list-output-file} \
+  emphasis=none headers=off paginate=off squeeze=on \
+  top-margin=0 bottom-margin=0
 
 # ASCII devices that support bold & underline via backspacing.
 
 # ASCII devices that support bold & underline via backspacing.
-tty-ascii-bi:ascii:screen:char-set=ascii output-file=${tty-output-file}
-list-ascii-bi:ascii:listing:length=66 width=79 char-set=ascii \
-  output-file=${list-output-file}
+tty-ascii-bi:ascii:screen:output-file=${tty-output-file}
+list-ascii-bi:ascii:listing:length=66 width=79 output-file=${list-output-file}
 
 # HTML device.
 html:html::
 
 
 # HTML device.
 html:html::
 
+# PostScript device.
+list-ps:postscript::
+
 # Devices that support the IBM PC line-drawing characters.
 define ibmpc-graphics \
 # Devices that support the IBM PC line-drawing characters.
 define ibmpc-graphics \
-  box[0000]='\x20' box[0001]='\xb3' box[0002]='\xba' box[0003]='\xba' \
-  box[0010]='\xc4' box[0011]='\xd9' box[0012]='\xbd' box[0013]='\xbd' \
-  box[0020]='\xcd' box[0021]='\xbe' box[0022]='\xbc' box[0023]='\xbc' \
-  box[0030]='\xf0' box[0031]='\xbe' box[0032]='\xbc' box[0033]='\xbc' \
-  box[0100]='\xb3' box[0101]='\xb3' box[0102]='\xc4' box[0103]='\xf0' \
-  box[0110]='\xbf' box[0111]='\xb4' box[0112]='\xb6' box[0113]='\xb6' \
-  box[0120]='\xb8' box[0121]='\xb5' box[0122]='\xb9' box[0123]='\xb9' \
-  box[0130]='\xb8' box[0131]='\xb5' box[0132]='\xb9' box[0133]='\xb9' \
-  box[0200]='\xba' box[0201]='\xba' box[0202]='\xba' box[0203]='\xba' \
-  box[0210]='\xb7' box[0211]='\xb6' box[0212]='\xb6' box[0213]='\xb6' \
-  box[0220]='\xbb' box[0221]='\xb9' box[0222]='\xb9' box[0223]='\xb9' \
-  box[0300]='\xb3' box[0301]='\xba' box[0302]='\xba' box[0303]='\xba' \
-  box[0310]='\xb7' box[0311]='\xb6' box[0312]='\xb6' box[0313]='\xb6' \
-  box[0320]='\xbb' box[0321]='\xb9' box[0322]='\xb9' box[0323]='\xb9' \
-  box[0330]='\xbb' box[0331]='\xb9' box[0332]='\xb9' box[0333]='\xb9' \
-  box[1000]='\xc4' box[1001]='\xc0' box[1002]='\xd3' box[1003]='\xd3' \
-  box[1010]='\xc4' box[1011]='\xc1' box[1012]='\xd0' box[1013]='\xd0' \
-  box[1020]='\xcd' box[1021]='\xcf' box[1022]='\xca' box[1023]='\xca' \
-  box[1030]='\xf0' box[1031]='\xcf' box[1032]='\xca' box[1033]='\xca' \
-  box[1100]='\xda' box[1101]='\xc3' box[1102]='\xc7' box[1103]='\xc7' \
-  box[1110]='\xc2' box[1111]='\xc5' box[1112]='\xd7' box[1113]='\xd7' \
-  box[1120]='\xd1' box[1121]='\xd8' box[1122]='\xce' box[1123]='\xce' \
-  box[1130]='\xd1' box[1131]='\xd8' box[1132]='\xce' box[1133]='\xce' \
-  box[1200]='\xd6' box[1201]='\xc7' box[1202]='\xc7' box[1203]='\xc7' \
-  box[1210]='\xd2' box[1211]='\xd7' box[1212]='\xd7' box[1213]='\xd7' \
-  box[1220]='\xca' box[1221]='\xce' box[1222]='\xce' box[1223]='\xce' \
-  box[1230]='\xca' box[1231]='\xce' box[1232]='\xce' box[1233]='\xce' \
-  box[1300]='\xd6' box[1301]='\xc7' box[1302]='\xc7' box[1303]='\xc7' \
-  box[1310]='\xd2' box[1311]='\xd7' box[1312]='\xd7' box[1313]='\xd7' \
-  box[1320]='\xca' box[1321]='\xce' box[1322]='\xce' box[1323]='\xce' \
-  box[1330]='\xca' box[1331]='\xce' box[1332]='\xce' box[1333]='\xce' \
-  box[2000]='\xcd' box[2001]='\xd4' box[2002]='\xc8' box[2003]='\xc8' \
-  box[2010]='\xcd' box[2011]='\xcf' box[2012]='\xca' box[2013]='\xca' \
-  box[2020]='\xcd' box[2021]='\xcf' box[2022]='\xca' box[2023]='\xca' \
-  box[2030]='\xf0' box[2031]='\xcf' box[2032]='\xca' box[2033]='\xca' \
-  box[2100]='\xd5' box[2101]='\xc6' box[2102]='\xcc' box[2103]='\xcc' \
-  box[2110]='\xd1' box[2111]='\xd8' box[2112]='\xce' box[2113]='\xce' \
-  box[2120]='\xd1' box[2121]='\xd8' box[2122]='\xce' box[2123]='\xce' \
-  box[2130]='\xd1' box[2131]='\xd8' box[2132]='\xce' box[2133]='\xce' \
-  box[2200]='\xc9' box[2201]='\xcc' box[2202]='\xcc' box[2203]='\xcc' \
-  box[2210]='\xcb' box[2211]='\xce' box[2212]='\xce' box[2213]='\xce' \
-  box[2220]='\xcb' box[2221]='\xce' box[2222]='\xce' box[2223]='\xce' \
-  box[2230]='\xcb' box[2231]='\xce' box[2232]='\xce' box[2233]='\xce' \
-  box[2300]='\xc9' box[2301]='\xcc' box[2302]='\xcc' box[2303]='\xce' \
-  box[2310]='\xcb' box[2311]='\xce' box[2312]='\xce' box[2313]='\xce' \
-  box[2320]='\xcb' box[2321]='\xce' box[2322]='\xce' box[2323]='\xce' \
-  box[2330]='\xcb' box[2331]='\xce' box[2332]='\xce' box[2333]='\xce' \
-  box[3000]='\xcd' box[3001]='\xd4' box[3002]='\xc8' box[3003]='\xc8' \
-  box[3010]='\xcd' box[3011]='\xcf' box[3012]='\xca' box[3013]='\xca' \
-  box[3020]='\xcd' box[3021]='\xcf' box[3022]='\xca' box[3023]='\xca' \
-  box[3030]='\xcd' box[3031]='\xcf' box[3032]='\xca' box[3033]='\xca' \
-  box[3100]='\xd5' box[3101]='\xc6' box[3102]='\xcc' box[3103]='\xcc' \
-  box[3110]='\xd1' box[3111]='\xd8' box[3112]='\xce' box[3113]='\xce' \
-  box[3120]='\xd1' box[3121]='\xd8' box[3122]='\xce' box[3123]='\xce' \
-  box[3130]='\xd1' box[3131]='\xd8' box[3132]='\xce' box[3133]='\xce' \
-  box[3200]='\xc9' box[3201]='\xcc' box[3202]='\xcc' box[3203]='\xcc' \
-  box[3210]='\xcb' box[3211]='\xce' box[3212]='\xce' box[3213]='\xce' \
-  box[3220]='\xcb' box[3221]='\xce' box[3222]='\xce' box[3223]='\xce' \
-  box[3230]='\xcb' box[3231]='\xce' box[3232]='\xce' box[3233]='\xce' \
-  box[3300]='\xc9' box[3301]='\xcc' box[3302]='\xcc' box[3303]='\xce' \
-  box[3310]='\xcb' box[3311]='\xce' box[3312]='\xce' box[3313]='\xce' \
-  box[3320]='\xcb' box[3321]='\xce' box[3322]='\xce' box[3323]='\xce' \
-  box[3330]='\xcb' box[3331]='\xce' box[3332]='\xce' box[3333]='\xce'
+  box[0000]='\x20' box[0001]='\xb3' box[0002]='\xba' \
+  box[0010]='\xc4' box[0011]='\xd9' box[0012]='\xbd' \
+  box[0020]='\xcd' box[0021]='\xbe' box[0022]='\xbc' \
+  box[0100]='\xb3' box[0101]='\xb3' box[0102]='\xc4' \
+  box[0110]='\xbf' box[0111]='\xb4' box[0112]='\xb6' \
+  box[0120]='\xb8' box[0121]='\xb5' box[0122]='\xb9' \
+  box[0200]='\xba' box[0201]='\xba' box[0202]='\xba' \
+  box[0210]='\xb7' box[0211]='\xb6' box[0212]='\xb6' \
+  box[0220]='\xbb' box[0221]='\xb9' box[0222]='\xb9' \
+  box[1000]='\xc4' box[1001]='\xc0' box[1002]='\xd3' \
+  box[1010]='\xc4' box[1011]='\xc1' box[1012]='\xd0' \
+  box[1020]='\xcd' box[1021]='\xcf' box[1022]='\xca' \
+  box[1100]='\xda' box[1101]='\xc3' box[1102]='\xc7' \
+  box[1110]='\xc2' box[1111]='\xc5' box[1112]='\xd7' \
+  box[1120]='\xd1' box[1121]='\xd8' box[1122]='\xce' \
+  box[1200]='\xd6' box[1201]='\xc7' box[1202]='\xc7' \
+  box[1210]='\xd2' box[1211]='\xd7' box[1212]='\xd7' \
+  box[1220]='\xca' box[1221]='\xce' box[1222]='\xce' \
+  box[2000]='\xcd' box[2001]='\xd4' box[2002]='\xc8' \
+  box[2010]='\xcd' box[2011]='\xcf' box[2012]='\xca' \
+  box[2020]='\xcd' box[2021]='\xcf' box[2022]='\xca' \
+  box[2100]='\xd5' box[2101]='\xc6' box[2102]='\xcc' \
+  box[2110]='\xd1' box[2111]='\xd8' box[2112]='\xce' \
+  box[2120]='\xd1' box[2121]='\xd8' box[2122]='\xce' \
+  box[2200]='\xc9' box[2201]='\xcc' box[2202]='\xcc' \
+  box[2210]='\xcb' box[2211]='\xce' box[2212]='\xce' \
+  box[2220]='\xcb' box[2221]='\xce' box[2222]='\xce'
 
 tty-ibmpc:ascii:screen:length=$viewlength width=$viewwidth ${ibmpc-graphics} \
   output-file=${tty-output-file}
 list-ibmpc:ascii:listing:length=66 width=79 output-file=${list-output-file} \
   ${ibmpc-graphics}
 
 
 tty-ibmpc:ascii:screen:length=$viewlength width=$viewwidth ${ibmpc-graphics} \
   output-file=${tty-output-file}
 list-ibmpc:ascii:listing:length=66 width=79 output-file=${list-output-file} \
   ${ibmpc-graphics}
 
-# PostScript device.  Tested with HP LaserJet 6MP.
-list-ps:postscript::
-
-# Okidata Microline 520 (these use the Microline emulation mode).
-define ml520-common output-file=${list-output-file} ${ibmpc-graphics} \
-  bold-on='\x1b\x54' bold-off='\x1b\x49' init='\x1b\x7b\x21\x1b\x23\x30'
-define ml520-italic italic-on='\x1b\x21\x2f' italic-off='\x1b\x21\x2a' \
-  bold-italic-on='\x1b\x21\x2f\x1b\x54' bold-italic-off='\x1b\x21\x2a\x1b\x49'
-define ml520-ul italic-on='\x1b\x43' italic-off='\x1b\x44' \
-  bold-italic-on='\x1b\x43\x1b\x54' bold-italic-off='\x1b\x44\x1b\x49'
-ml520=ml520-10cpi
-ml520-10cpi:ascii:printer:length=66 width=79 ${ml520-common} ${ml520-italic}
-ml520-10cpi-ul:ascii:printer:length=66 width=79 ${ml520-common} ${ml520-ul}
-ml520-17cpi:ascii:printer:length=66 width=144 ${ml520-common} ${ml520-italic} \
-  cpi=17 init='\x1b\x7b\x21\x1b\x23\x30\x1d'
-ml520-17cpi-ul:ascii:printer:length=66 width=144 ${ml520-common} ${ml520-ul} \
-  cpi=17 init='\x1b\x7b\x21\x1b\x23\x30\x1d'
-ml520-20cpi:ascii:printer:length=66 width=160 ${ml520-common} ${ml520-italic} \
-  cpi=17 init='\x1b\x7b\x21\x1b\x23\x30\x1b\x23\x33'
-ml520-20cpi-ul:ascii:printer:length=66 width=160 ${ml520-common} ${ml520-ul} \
-  cpi=17 init='\x1b\x7b\x21\x1b\x23\x30\x1b\x23\x33'
-
 # Local Variables:
 # fill-prefix: "# "
 # End:
 # Local Variables:
 # fill-prefix: "# "
 # End:
diff --git a/config/html-prologue b/config/html-prologue
deleted file mode 100644 (file)
index 8a5cbec..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-!!!
-!!! This prologue is hereby placed in the public domain.
-!!!
-!!! PSPP does not place any restrictions on the distribution terms
-!!! of its output.  You are encouraged to allow your PSPP outputs to
-!!! be freely distributed.
-!!!
-<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
-<!-- Generated ${date} by ${generator} -->
-<HTML>
-<HEAD>
-<TITLE>${title}</TITLE>                !title
-<META NAME="generator" CONTENT="${generator}">
-<META NAME="author" CONTENT="${author}">
-</HEAD>
-<BODY BGCOLOR="#ffffff" TEXT="#000000" LINK="#1f00ff" ALINK="#ff0000"
- VLINK="#9900dd">
-<H1>${title}</H1>              !title
-<H2>${subtitle}</H2>           !subtitle
-!!! Local Variables:
-!!! fill-prefix: "!!! "
-!!! End:
diff --git a/config/ps-prologue b/config/ps-prologue
deleted file mode 100644 (file)
index 3c75230..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-!!!
-!!! This prologue is hereby placed in the public domain.
-!!!
-!!! PSPP does not place any restrictions on the distribution terms
-!!! of its output.  You are encouraged to allow your PSPP outputs to
-!!! be freely distributed.
-!!!
-%!PS-Adobe-3.0 EPSF-3.0                           !eps
-%!PS-Adobe-3.0                                   !ps
-%%Pages: (atend)
-%%DocumentNeededResources: (atend)
-%%DocumentSuppliedResources: procset PSPP-Prologue 1.0 0
-!!! %%Bounding-Box: ${bounding-box}
-%%Copyright: This prologue is public domain.
-%%Creator: ${creator}
-%%CreationDate: ${date}
-%%DocumentData: ${data}
-%%DocumentMedia: Plain ${paper-width} ${paper-length} 75 white ()
-%%Orientation: ${orientation}
-%%For: ${user}@${host}
-%%Title: ${title}
-%FscoSourceFile: ${source-file}
-%%EndComments
-%%BeginDefaults
-%%PageResources:
-%%+ ${prop-font}
-%%+ ${fixed-font}
-%%EndDefaults
-%%BeginProlog
-%%BeginResource: procset PSPP-Prologue 1.0 0
-/L{moveto lineto stroke}bind def
-/TL{TW setlinewidth 0 setlinecap 
- moveto lineto stroke 
- LW setlinewidth 2 setlinecap}def
-/D{moveto lineto moveto lineto stroke}bind def
-/S{moveto show}bind def
-/T{currentpoint exch pop moveto show}bind def
-/ED{exch def}bind def
-!!! SF arguments:
-!!!    identifier      dictionary entry to save font in
-!!!    font encoding   font encoding vector
-!!!    fontsize        thousandths of a point
-!!!    font name       string
-!!! Usage example: 12000/F0 E0 (Times-Roman) SF
-/SF{
- findfont exch scalefont
- dup maxlength 1 index/FontName known not{1 add}if dict begin
- {
-  1 index/FID ne{def}{pop pop}ifelse
- }forall
- /Encoding ED
- dup/FontName ED
- currentdict end 1 index exch definefont dup setfont 
- [exch/setfont cvx] cvx bind def
-}bind def
-/F{setfont}bind def
-/EP{
- pg restore
- showpage
-}bind def
-/GB{
- /y2 ED/x2 ED/y1 ED/x1 ED
- x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto closepath
- gsave 0.9 setgray fill grestore stroke
-}bind def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: ${prop-font}
-%%IncludeResource: ${fixed-font}
-!encodings
-%%EndSetup
-!!! Local Variables:
-!!! fill-prefix: "!!! "
-!!! End:
diff --git a/config/psfonts/Courier-Bold.afm b/config/psfonts/Courier-Bold.afm
new file mode 100644 (file)
index 0000000..dbfdddb
--- /dev/null
@@ -0,0 +1,348 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1989 1990 Adobe Systems Incorporated. All rights reserved.
+Comment Creation Date: Thu Jan 18 16:13:14 1990
+Comment UniqueID 27058
+Comment VMusage 28444 40812
+FontName Courier-Bold
+FullName Courier Bold
+FamilyName Courier
+Weight Bold
+ItalicAngle 0
+IsFixedPitch true
+FontBBox -40 -206 786 801
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.003
+Notice Copyright (c) 1989 1990 Adobe Systems Incorporated. All rights reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 439
+Ascender 626
+Descender -142
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 212 -15 388 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 145 297 455 562 ;
+C 35 ; WX 600 ; N numbersign ; B 66 -45 534 651 ;
+C 36 ; WX 600 ; N dollar ; B 92 -126 509 666 ;
+C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ;
+C 38 ; WX 600 ; N ampersand ; B 46 -15 536 543 ;
+C 39 ; WX 600 ; N quoteright ; B 188 297 412 562 ;
+C 40 ; WX 600 ; N parenleft ; B 229 -102 451 616 ;
+C 41 ; WX 600 ; N parenright ; B 149 -102 371 616 ;
+C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ;
+C 43 ; WX 600 ; N plus ; B 81 0 519 439 ;
+C 44 ; WX 600 ; N comma ; B 140 -101 374 164 ;
+C 45 ; WX 600 ; N hyphen ; B 110 213 490 303 ;
+C 46 ; WX 600 ; N period ; B 206 -15 394 151 ;
+C 47 ; WX 600 ; N slash ; B 105 -77 496 626 ;
+C 48 ; WX 600 ; N zero ; B 97 -15 503 616 ;
+C 49 ; WX 600 ; N one ; B 91 0 529 616 ;
+C 50 ; WX 600 ; N two ; B 71 0 489 616 ;
+C 51 ; WX 600 ; N three ; B 73 -15 491 616 ;
+C 52 ; WX 600 ; N four ; B 63 0 497 616 ;
+C 53 ; WX 600 ; N five ; B 80 -15 511 601 ;
+C 54 ; WX 600 ; N six ; B 100 -15 511 616 ;
+C 55 ; WX 600 ; N seven ; B 65 0 484 601 ;
+C 56 ; WX 600 ; N eight ; B 93 -15 507 616 ;
+C 57 ; WX 600 ; N nine ; B 89 -15 500 616 ;
+C 58 ; WX 600 ; N colon ; B 206 -15 394 405 ;
+C 59 ; WX 600 ; N semicolon ; B 140 -101 394 405 ;
+C 60 ; WX 600 ; N less ; B 66 -15 503 453 ;
+C 61 ; WX 600 ; N equal ; B 81 89 519 349 ;
+C 62 ; WX 600 ; N greater ; B 97 -15 534 453 ;
+C 63 ; WX 600 ; N question ; B 108 -15 491 580 ;
+C 64 ; WX 600 ; N at ; B 26 -15 574 616 ;
+C 65 ; WX 600 ; N A ; B 1 0 599 562 ;
+C 66 ; WX 600 ; N B ; B 40 0 563 562 ;
+C 67 ; WX 600 ; N C ; B 32 -18 554 580 ;
+C 68 ; WX 600 ; N D ; B 40 0 584 562 ;
+C 69 ; WX 600 ; N E ; B 40 0 545 562 ;
+C 70 ; WX 600 ; N F ; B 54 0 555 562 ;
+C 71 ; WX 600 ; N G ; B 32 -18 584 580 ;
+C 72 ; WX 600 ; N H ; B 30 0 570 562 ;
+C 73 ; WX 600 ; N I ; B 87 0 513 562 ;
+C 74 ; WX 600 ; N J ; B 47 -18 591 562 ;
+C 75 ; WX 600 ; N K ; B 36 0 584 562 ;
+C 76 ; WX 600 ; N L ; B 49 0 568 562 ;
+C 77 ; WX 600 ; N M ; B 3 0 597 562 ;
+C 78 ; WX 600 ; N N ; B 18 -12 600 562 ;
+C 79 ; WX 600 ; N O ; B 32 -18 568 580 ;
+C 80 ; WX 600 ; N P ; B 58 0 549 562 ;
+C 81 ; WX 600 ; N Q ; B 32 -123 568 580 ;
+C 82 ; WX 600 ; N R ; B 34 0 589 562 ;
+C 83 ; WX 600 ; N S ; B 57 -22 543 582 ;
+C 84 ; WX 600 ; N T ; B 31 0 569 562 ;
+C 85 ; WX 600 ; N U ; B 14 -18 586 562 ;
+C 86 ; WX 600 ; N V ; B -3 0 603 562 ;
+C 87 ; WX 600 ; N W ; B -8 0 608 562 ;
+C 88 ; WX 600 ; N X ; B 22 0 578 562 ;
+C 89 ; WX 600 ; N Y ; B 22 0 579 562 ;
+C 90 ; WX 600 ; N Z ; B 72 0 529 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 255 -102 465 616 ;
+C 92 ; WX 600 ; N backslash ; B 105 -77 496 626 ;
+C 93 ; WX 600 ; N bracketright ; B 135 -102 345 616 ;
+C 94 ; WX 600 ; N asciicircum ; B 108 249 492 616 ;
+C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 188 297 412 562 ;
+C 97 ; WX 600 ; N a ; B 45 -15 560 454 ;
+C 98 ; WX 600 ; N b ; B 10 -15 574 626 ;
+C 99 ; WX 600 ; N c ; B 50 -15 539 459 ;
+C 100 ; WX 600 ; N d ; B 30 -15 581 626 ;
+C 101 ; WX 600 ; N e ; B 50 -15 553 454 ;
+C 102 ; WX 600 ; N f ; B 93 0 537 626 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 40 -146 570 454 ;
+C 104 ; WX 600 ; N h ; B 15 0 582 626 ;
+C 105 ; WX 600 ; N i ; B 87 0 513 648 ;
+C 106 ; WX 600 ; N j ; B 73 -146 430 648 ;
+C 107 ; WX 600 ; N k ; B 30 0 575 626 ;
+C 108 ; WX 600 ; N l ; B 87 0 513 626 ;
+C 109 ; WX 600 ; N m ; B -12 0 616 454 ;
+C 110 ; WX 600 ; N n ; B 28 0 582 454 ;
+C 111 ; WX 600 ; N o ; B 40 -15 560 454 ;
+C 112 ; WX 600 ; N p ; B 9 -142 560 454 ;
+C 113 ; WX 600 ; N q ; B 30 -142 581 454 ;
+C 114 ; WX 600 ; N r ; B 57 0 570 454 ;
+C 115 ; WX 600 ; N s ; B 78 -17 525 459 ;
+C 116 ; WX 600 ; N t ; B 57 -15 522 562 ;
+C 117 ; WX 600 ; N u ; B 9 -15 559 439 ;
+C 118 ; WX 600 ; N v ; B 9 0 591 439 ;
+C 119 ; WX 600 ; N w ; B -8 0 608 439 ;
+C 120 ; WX 600 ; N x ; B 16 0 584 439 ;
+C 121 ; WX 600 ; N y ; B 6 -142 591 439 ;
+C 122 ; WX 600 ; N z ; B 91 0 510 439 ;
+C 123 ; WX 600 ; N braceleft ; B 170 -102 454 616 ;
+C 124 ; WX 600 ; N bar ; B 255 -77 345 626 ;
+C 125 ; WX 600 ; N braceright ; B 146 -102 430 616 ;
+C 126 ; WX 600 ; N asciitilde ; B 81 124 520 307 ;
+C 161 ; WX 600 ; N exclamdown ; B 212 -146 388 449 ;
+C 162 ; WX 600 ; N cent ; B 76 -49 508 614 ;
+C 163 ; WX 600 ; N sterling ; B 82 -28 548 611 ;
+C 164 ; WX 600 ; N fraction ; B 30 -60 571 661 ;
+C 165 ; WX 600 ; N yen ; B 20 0 580 591 ;
+C 166 ; WX 600 ; N florin ; B -20 -131 562 616 ;
+C 167 ; WX 600 ; N section ; B 103 -70 497 580 ;
+C 168 ; WX 600 ; N currency ; B 54 49 546 517 ;
+C 169 ; WX 600 ; N quotesingle ; B 237 297 363 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 81 297 519 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ;
+C 174 ; WX 600 ; N fi ; B 22 0 583 626 ;
+C 175 ; WX 600 ; N fl ; B 22 0 583 626 ;
+C 177 ; WX 600 ; N endash ; B 75 213 525 303 ;
+C 178 ; WX 600 ; N dagger ; B 116 -70 484 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 116 -70 484 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 206 136 394 302 ;
+C 182 ; WX 600 ; N paragraph ; B 16 -70 566 580 ;
+C 183 ; WX 600 ; N bullet ; B 150 142 450 420 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 188 -140 412 125 ;
+C 185 ; WX 600 ; N quotedblbase ; B 81 -140 519 125 ;
+C 186 ; WX 600 ; N quotedblright ; B 81 297 519 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 36 -15 564 96 ;
+C 189 ; WX 600 ; N perthousand ; B -40 -15 786 616 ;
+C 191 ; WX 600 ; N questiondown ; B 109 -146 492 449 ;
+C 193 ; WX 600 ; N grave ; B 132 508 395 661 ;
+C 194 ; WX 600 ; N acute ; B 205 508 468 661 ;
+C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ;
+C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ;
+C 197 ; WX 600 ; N macron ; B 88 505 512 585 ;
+C 198 ; WX 600 ; N breve ; B 83 468 517 631 ;
+C 199 ; WX 600 ; N dotaccent ; B 240 505 360 625 ;
+C 200 ; WX 600 ; N dieresis ; B 148 505 452 625 ;
+C 202 ; WX 600 ; N ring ; B 198 481 402 678 ;
+C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 95 508 578 661 ;
+C 206 ; WX 600 ; N ogonek ; B 169 -199 367 0 ;
+C 207 ; WX 600 ; N caron ; B 103 493 497 667 ;
+C 208 ; WX 600 ; N emdash ; B 0 213 600 303 ;
+C 225 ; WX 600 ; N AE ; B -29 0 562 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ;
+C 232 ; WX 600 ; N Lslash ; B 49 0 568 562 ;
+C 233 ; WX 600 ; N Oslash ; B 32 -22 568 584 ;
+C 234 ; WX 600 ; N OE ; B 0 0 570 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ;
+C 241 ; WX 600 ; N ae ; B 6 -15 591 454 ;
+C 245 ; WX 600 ; N dotlessi ; B 87 0 513 439 ;
+C 248 ; WX 600 ; N lslash ; B 87 0 513 626 ;
+C 249 ; WX 600 ; N oslash ; B 40 -24 560 463 ;
+C 250 ; WX 600 ; N oe ; B -8 -15 601 454 ;
+C 251 ; WX 600 ; N germandbls ; B 32 -15 586 626 ;
+C -1 ; WX 600 ; N scedilla ; B 78 -206 525 459 ;
+C -1 ; WX 600 ; N notegraphic ; B 87 -15 513 572 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 32 -18 568 780 ;
+C -1 ; WX 600 ; N ll ; B -2 0 590 626 ;
+C -1 ; WX 600 ; N otilde ; B 40 -15 560 636 ;
+C -1 ; WX 600 ; N scaron ; B 78 -17 525 667 ;
+C -1 ; WX 600 ; N divide ; B 81 -15 519 453 ;
+C -1 ; WX 600 ; N Thorn ; B 58 0 547 562 ;
+C -1 ; WX 600 ; N format ; B 5 -146 95 598 ;
+C -1 ; WX 600 ; N largebullet ; B 258 239 342 323 ;
+C -1 ; WX 600 ; N Eth ; B 40 0 584 562 ;
+C -1 ; WX 600 ; N Odieresis ; B 32 -18 568 748 ;
+C -1 ; WX 600 ; N onesuperior ; B 158 230 442 616 ;
+C -1 ; WX 600 ; N dectab ; B 18 0 582 290 ;
+C -1 ; WX 600 ; N Ydieresis ; B 22 0 579 748 ;
+C -1 ; WX 600 ; N merge ; B 144 -15 456 487 ;
+C -1 ; WX 600 ; N IJ ; B 2 -18 612 562 ;
+C -1 ; WX 600 ; N ccedilla ; B 50 -206 539 459 ;
+C -1 ; WX 600 ; N multiply ; B 81 0 520 439 ;
+C -1 ; WX 600 ; N degree ; B 86 243 474 616 ;
+C -1 ; WX 600 ; N prescription ; B 34 -15 589 562 ;
+C -1 ; WX 600 ; N indent ; B 70 52 530 364 ;
+C -1 ; WX 600 ; N Otilde ; B 32 -18 568 759 ;
+C -1 ; WX 600 ; N thorn ; B -4 -142 560 626 ;
+C -1 ; WX 600 ; N mu ; B 9 -142 559 439 ;
+C -1 ; WX 600 ; N Yacute ; B 22 0 579 784 ;
+C -1 ; WX 600 ; N threesuperior ; B 148 222 423 616 ;
+C -1 ; WX 600 ; N logicalnot ; B 81 59 519 349 ;
+C -1 ; WX 600 ; N Ugrave ; B 14 -18 586 784 ;
+C -1 ; WX 600 ; N eth ; B 68 -27 533 626 ;
+C -1 ; WX 600 ; N left ; B 70 52 530 364 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 40 0 545 780 ;
+C -1 ; WX 600 ; N edieresis ; B 50 -15 553 625 ;
+C -1 ; WX 600 ; N Ograve ; B 32 -18 568 784 ;
+C -1 ; WX 600 ; N down ; B 144 -15 456 422 ;
+C -1 ; WX 600 ; N Agrave ; B 1 0 599 784 ;
+C -1 ; WX 600 ; N atilde ; B 45 -15 560 636 ;
+C -1 ; WX 600 ; N up ; B 144 0 456 437 ;
+C -1 ; WX 600 ; N eacute ; B 50 -15 553 661 ;
+C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ;
+C -1 ; WX 600 ; N lira ; B 82 -28 548 611 ;
+C -1 ; WX 600 ; N Icircumflex ; B 87 0 513 780 ;
+C -1 ; WX 600 ; N Adieresis ; B 1 0 599 748 ;
+C -1 ; WX 600 ; N yacute ; B 6 -142 591 661 ;
+C -1 ; WX 600 ; N icircumflex ; B 63 0 513 657 ;
+C -1 ; WX 600 ; N adieresis ; B 45 -15 560 625 ;
+C -1 ; WX 600 ; N zcaron ; B 91 0 510 667 ;
+C -1 ; WX 600 ; N Scaron ; B 57 -22 543 790 ;
+C -1 ; WX 600 ; N minus ; B 81 174 519 264 ;
+C -1 ; WX 600 ; N Aring ; B 1 0 599 801 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 14 -18 586 780 ;
+C -1 ; WX 600 ; N plusminus ; B 81 0 519 461 ;
+C -1 ; WX 600 ; N ograve ; B 40 -15 560 661 ;
+C -1 ; WX 600 ; N Edieresis ; B 40 0 545 748 ;
+C -1 ; WX 600 ; N brokenbar ; B 255 -77 345 626 ;
+C -1 ; WX 600 ; N Idieresis ; B 87 0 513 748 ;
+C -1 ; WX 600 ; N acircumflex ; B 45 -15 560 657 ;
+C -1 ; WX 600 ; N ydieresis ; B 6 -142 591 625 ;
+C -1 ; WX 600 ; N Oacute ; B 32 -18 568 784 ;
+C -1 ; WX 600 ; N Egrave ; B 40 0 545 784 ;
+C -1 ; WX 600 ; N center ; B 40 14 560 580 ;
+C -1 ; WX 600 ; N threequarters ; B -20 -60 675 661 ;
+C -1 ; WX 600 ; N tab ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N ecircumflex ; B 50 -15 553 657 ;
+C -1 ; WX 600 ; N Eacute ; B 40 0 545 784 ;
+C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ;
+C -1 ; WX 600 ; N square ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N onehalf ; B -20 -60 675 661 ;
+C -1 ; WX 600 ; N onequarter ; B -20 -60 692 661 ;
+C -1 ; WX 600 ; N Uacute ; B 14 -18 586 784 ;
+C -1 ; WX 600 ; N Atilde ; B 1 0 599 759 ;
+C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N Igrave ; B 87 0 513 784 ;
+C -1 ; WX 600 ; N Iacute ; B 87 0 513 784 ;
+C -1 ; WX 600 ; N Acircumflex ; B 1 0 599 780 ;
+C -1 ; WX 600 ; N Udieresis ; B 14 -18 586 748 ;
+C -1 ; WX 600 ; N Gcaron ; B 32 -18 584 790 ;
+C -1 ; WX 600 ; N Aacute ; B 1 0 599 784 ;
+C -1 ; WX 600 ; N LL ; B -35 0 635 562 ;
+C -1 ; WX 600 ; N twosuperior ; B 153 230 426 616 ;
+C -1 ; WX 600 ; N Scedilla ; B 57 -206 543 582 ;
+C -1 ; WX 600 ; N arrowboth ; B -24 143 624 455 ;
+C -1 ; WX 600 ; N udieresis ; B 9 -15 559 625 ;
+C -1 ; WX 600 ; N odieresis ; B 40 -15 560 625 ;
+C -1 ; WX 600 ; N aring ; B 45 -15 560 678 ;
+C -1 ; WX 600 ; N ij ; B 16 -146 564 648 ;
+C -1 ; WX 600 ; N arrowdown ; B 144 -15 456 608 ;
+C -1 ; WX 600 ; N igrave ; B 87 0 513 661 ;
+C -1 ; WX 600 ; N aacute ; B 45 -15 560 661 ;
+C -1 ; WX 600 ; N stop ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N ocircumflex ; B 40 -15 560 657 ;
+C -1 ; WX 600 ; N gcaron ; B 40 -146 570 667 ;
+C -1 ; WX 600 ; N iacute ; B 87 0 513 661 ;
+C -1 ; WX 600 ; N Ntilde ; B 18 -12 600 759 ;
+C -1 ; WX 600 ; N idieresis ; B 87 0 513 625 ;
+C -1 ; WX 600 ; N Ccedilla ; B 32 -206 554 580 ;
+C -1 ; WX 600 ; N arrowright ; B -24 143 624 455 ;
+C -1 ; WX 600 ; N ucircumflex ; B 9 -15 559 657 ;
+C -1 ; WX 600 ; N Idot ; B 87 0 513 748 ;
+C -1 ; WX 600 ; N agrave ; B 45 -15 560 661 ;
+C -1 ; WX 600 ; N ntilde ; B 28 0 582 636 ;
+C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N return ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N Zcaron ; B 72 0 529 790 ;
+C -1 ; WX 600 ; N uacute ; B 9 -15 559 661 ;
+C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ;
+C -1 ; WX 600 ; N egrave ; B 50 -15 553 661 ;
+C -1 ; WX 600 ; N ugrave ; B 9 -15 559 661 ;
+C -1 ; WX 600 ; N oacute ; B 40 -15 560 661 ;
+C -1 ; WX 600 ; N arrowleft ; B -24 143 624 455 ;
+C -1 ; WX 600 ; N arrowup ; B 144 0 456 623 ;
+EndCharMetrics
+StartComposites 62
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 30 123 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 123 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -20 123 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave -50 123 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring -10 123 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde -30 123 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 123 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 123 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 123 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 123 ;
+CC Gcaron 2 ; PCC G 0 0 ; PCC caron 10 123 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 123 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 123 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 123 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 123 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 123 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 123 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 123 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 123 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 123 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 123 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 123 ;
+CC Scedilla 2 ; PCC S 0 0 ; PCC cedilla 20 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 123 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 123 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 123 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 123 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 123 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 123 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 123 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC scedilla 2 ; PCC s 0 0 ; PCC cedilla 0 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Courier-BoldOblique.afm b/config/psfonts/Courier-BoldOblique.afm
new file mode 100644 (file)
index 0000000..77e50d7
--- /dev/null
@@ -0,0 +1,348 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1989 1990 Adobe Systems Incorporated. All rights reserved.
+Comment Creation Date: Thu Jan 18 17:20:38 1990
+Comment UniqueID 27068
+Comment VMusage 6910 48006
+FontName Courier-BoldOblique
+FullName Courier Bold Oblique
+FamilyName Courier
+Weight Bold
+ItalicAngle -12
+IsFixedPitch true
+FontBBox -46 -206 868 801
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.003
+Notice Copyright (c) 1989 1990 Adobe Systems Incorporated. All rights reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 439
+Ascender 626
+Descender -142
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 224 -15 484 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 226 297 574 562 ;
+C 35 ; WX 600 ; N numbersign ; B 100 -45 628 651 ;
+C 36 ; WX 600 ; N dollar ; B 97 -126 619 666 ;
+C 37 ; WX 600 ; N percent ; B 103 -15 624 616 ;
+C 38 ; WX 600 ; N ampersand ; B 72 -15 582 543 ;
+C 39 ; WX 600 ; N quoteright ; B 251 297 531 562 ;
+C 40 ; WX 600 ; N parenleft ; B 276 -102 582 616 ;
+C 41 ; WX 600 ; N parenright ; B 127 -102 434 616 ;
+C 42 ; WX 600 ; N asterisk ; B 179 219 597 601 ;
+C 43 ; WX 600 ; N plus ; B 118 0 575 439 ;
+C 44 ; WX 600 ; N comma ; B 119 -101 409 164 ;
+C 45 ; WX 600 ; N hyphen ; B 155 213 554 303 ;
+C 46 ; WX 600 ; N period ; B 219 -15 410 151 ;
+C 47 ; WX 600 ; N slash ; B 96 -77 622 626 ;
+C 48 ; WX 600 ; N zero ; B 146 -15 583 616 ;
+C 49 ; WX 600 ; N one ; B 103 0 547 616 ;
+C 50 ; WX 600 ; N two ; B 71 0 583 616 ;
+C 51 ; WX 600 ; N three ; B 82 -15 561 616 ;
+C 52 ; WX 600 ; N four ; B 92 0 544 616 ;
+C 53 ; WX 600 ; N five ; B 87 -15 611 601 ;
+C 54 ; WX 600 ; N six ; B 146 -15 642 616 ;
+C 55 ; WX 600 ; N seven ; B 157 0 612 601 ;
+C 56 ; WX 600 ; N eight ; B 125 -15 594 616 ;
+C 57 ; WX 600 ; N nine ; B 86 -15 582 616 ;
+C 58 ; WX 600 ; N colon ; B 219 -15 464 405 ;
+C 59 ; WX 600 ; N semicolon ; B 119 -101 464 405 ;
+C 60 ; WX 600 ; N less ; B 113 -15 584 453 ;
+C 61 ; WX 600 ; N equal ; B 100 89 593 349 ;
+C 62 ; WX 600 ; N greater ; B 109 -15 581 453 ;
+C 63 ; WX 600 ; N question ; B 193 -15 581 580 ;
+C 64 ; WX 600 ; N at ; B 76 -15 627 616 ;
+C 65 ; WX 600 ; N A ; B 1 0 617 562 ;
+C 66 ; WX 600 ; N B ; B 40 0 619 562 ;
+C 67 ; WX 600 ; N C ; B 85 -18 664 580 ;
+C 68 ; WX 600 ; N D ; B 40 0 654 562 ;
+C 69 ; WX 600 ; N E ; B 40 0 654 562 ;
+C 70 ; WX 600 ; N F ; B 54 0 668 562 ;
+C 71 ; WX 600 ; N G ; B 85 -18 664 580 ;
+C 72 ; WX 600 ; N H ; B 30 0 689 562 ;
+C 73 ; WX 600 ; N I ; B 87 0 632 562 ;
+C 74 ; WX 600 ; N J ; B 69 -18 710 562 ;
+C 75 ; WX 600 ; N K ; B 36 0 676 562 ;
+C 76 ; WX 600 ; N L ; B 49 0 625 562 ;
+C 77 ; WX 600 ; N M ; B 3 0 716 562 ;
+C 78 ; WX 600 ; N N ; B 18 -12 719 562 ;
+C 79 ; WX 600 ; N O ; B 84 -18 636 580 ;
+C 80 ; WX 600 ; N P ; B 58 0 634 562 ;
+C 81 ; WX 600 ; N Q ; B 84 -123 636 580 ;
+C 82 ; WX 600 ; N R ; B 34 0 607 562 ;
+C 83 ; WX 600 ; N S ; B 64 -22 662 582 ;
+C 84 ; WX 600 ; N T ; B 96 0 668 562 ;
+C 85 ; WX 600 ; N U ; B 116 -18 705 562 ;
+C 86 ; WX 600 ; N V ; B 99 0 722 562 ;
+C 87 ; WX 600 ; N W ; B 94 0 727 562 ;
+C 88 ; WX 600 ; N X ; B 22 0 679 562 ;
+C 89 ; WX 600 ; N Y ; B 124 0 698 562 ;
+C 90 ; WX 600 ; N Z ; B 72 0 626 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 233 -102 596 616 ;
+C 92 ; WX 600 ; N backslash ; B 231 -77 487 626 ;
+C 93 ; WX 600 ; N bracketright ; B 113 -102 476 616 ;
+C 94 ; WX 600 ; N asciicircum ; B 171 249 555 616 ;
+C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 251 297 531 562 ;
+C 97 ; WX 600 ; N a ; B 72 -15 578 454 ;
+C 98 ; WX 600 ; N b ; B 23 -15 626 626 ;
+C 99 ; WX 600 ; N c ; B 91 -15 621 459 ;
+C 100 ; WX 600 ; N d ; B 71 -15 634 626 ;
+C 101 ; WX 600 ; N e ; B 91 -15 594 454 ;
+C 102 ; WX 600 ; N f ; B 93 0 667 626 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 51 -146 663 454 ;
+C 104 ; WX 600 ; N h ; B 28 0 600 626 ;
+C 105 ; WX 600 ; N i ; B 87 0 531 648 ;
+C 106 ; WX 600 ; N j ; B 47 -146 568 648 ;
+C 107 ; WX 600 ; N k ; B 43 0 632 626 ;
+C 108 ; WX 600 ; N l ; B 87 0 531 626 ;
+C 109 ; WX 600 ; N m ; B -12 0 634 454 ;
+C 110 ; WX 600 ; N n ; B 28 0 600 454 ;
+C 111 ; WX 600 ; N o ; B 81 -15 612 454 ;
+C 112 ; WX 600 ; N p ; B -21 -142 612 454 ;
+C 113 ; WX 600 ; N q ; B 71 -142 674 454 ;
+C 114 ; WX 600 ; N r ; B 57 0 644 454 ;
+C 115 ; WX 600 ; N s ; B 77 -17 597 459 ;
+C 116 ; WX 600 ; N t ; B 132 -15 556 562 ;
+C 117 ; WX 600 ; N u ; B 84 -15 577 439 ;
+C 118 ; WX 600 ; N v ; B 84 0 684 439 ;
+C 119 ; WX 600 ; N w ; B 67 0 701 439 ;
+C 120 ; WX 600 ; N x ; B 16 0 660 439 ;
+C 121 ; WX 600 ; N y ; B -10 -142 684 439 ;
+C 122 ; WX 600 ; N z ; B 91 0 603 439 ;
+C 123 ; WX 600 ; N braceleft ; B 216 -102 585 616 ;
+C 124 ; WX 600 ; N bar ; B 239 -77 478 626 ;
+C 125 ; WX 600 ; N braceright ; B 124 -102 494 616 ;
+C 126 ; WX 600 ; N asciitilde ; B 120 124 573 307 ;
+C 161 ; WX 600 ; N exclamdown ; B 207 -146 468 449 ;
+C 162 ; WX 600 ; N cent ; B 131 -49 594 614 ;
+C 163 ; WX 600 ; N sterling ; B 117 -28 640 611 ;
+C 164 ; WX 600 ; N fraction ; B 27 -60 702 661 ;
+C 165 ; WX 600 ; N yen ; B 110 0 706 591 ;
+C 166 ; WX 600 ; N florin ; B -46 -131 691 616 ;
+C 167 ; WX 600 ; N section ; B 94 -70 599 580 ;
+C 168 ; WX 600 ; N currency ; B 77 49 643 517 ;
+C 169 ; WX 600 ; N quotesingle ; B 318 297 482 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 144 297 638 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 63 70 638 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 196 70 544 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 166 70 514 446 ;
+C 174 ; WX 600 ; N fi ; B 22 0 633 626 ;
+C 175 ; WX 600 ; N fl ; B 22 0 633 626 ;
+C 177 ; WX 600 ; N endash ; B 120 213 589 303 ;
+C 178 ; WX 600 ; N dagger ; B 188 -70 573 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 134 -70 574 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 251 136 442 302 ;
+C 182 ; WX 600 ; N paragraph ; B 71 -70 689 580 ;
+C 183 ; WX 600 ; N bullet ; B 207 142 513 420 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 158 -140 439 125 ;
+C 185 ; WX 600 ; N quotedblbase ; B 51 -140 546 125 ;
+C 186 ; WX 600 ; N quotedblright ; B 144 297 638 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 72 70 647 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 43 -15 574 96 ;
+C 189 ; WX 600 ; N perthousand ; B 24 -15 815 616 ;
+C 191 ; WX 600 ; N questiondown ; B 111 -146 499 449 ;
+C 193 ; WX 600 ; N grave ; B 272 508 503 661 ;
+C 194 ; WX 600 ; N acute ; B 313 508 608 661 ;
+C 195 ; WX 600 ; N circumflex ; B 212 483 606 657 ;
+C 196 ; WX 600 ; N tilde ; B 200 493 642 636 ;
+C 197 ; WX 600 ; N macron ; B 195 505 636 585 ;
+C 198 ; WX 600 ; N breve ; B 217 468 651 631 ;
+C 199 ; WX 600 ; N dotaccent ; B 359 505 482 625 ;
+C 200 ; WX 600 ; N dieresis ; B 267 505 574 625 ;
+C 202 ; WX 600 ; N ring ; B 319 481 528 678 ;
+C 203 ; WX 600 ; N cedilla ; B 169 -206 367 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 203 508 718 661 ;
+C 206 ; WX 600 ; N ogonek ; B 144 -199 350 0 ;
+C 207 ; WX 600 ; N caron ; B 238 493 632 667 ;
+C 208 ; WX 600 ; N emdash ; B 45 213 664 303 ;
+C 225 ; WX 600 ; N AE ; B -29 0 667 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 189 196 526 580 ;
+C 232 ; WX 600 ; N Lslash ; B 49 0 625 562 ;
+C 233 ; WX 600 ; N Oslash ; B 48 -22 672 584 ;
+C 234 ; WX 600 ; N OE ; B 51 0 675 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 189 196 542 580 ;
+C 241 ; WX 600 ; N ae ; B 30 -15 641 454 ;
+C 245 ; WX 600 ; N dotlessi ; B 87 0 531 439 ;
+C 248 ; WX 600 ; N lslash ; B 87 0 574 626 ;
+C 249 ; WX 600 ; N oslash ; B 54 -24 637 463 ;
+C 250 ; WX 600 ; N oe ; B 29 -15 651 454 ;
+C 251 ; WX 600 ; N germandbls ; B 32 -15 618 626 ;
+C -1 ; WX 600 ; N scedilla ; B 77 -206 597 459 ;
+C -1 ; WX 600 ; N notegraphic ; B 99 -15 609 572 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 84 -18 636 780 ;
+C -1 ; WX 600 ; N ll ; B 11 0 643 626 ;
+C -1 ; WX 600 ; N otilde ; B 81 -15 642 636 ;
+C -1 ; WX 600 ; N scaron ; B 77 -17 632 667 ;
+C -1 ; WX 600 ; N divide ; B 118 -15 575 453 ;
+C -1 ; WX 600 ; N Thorn ; B 58 0 613 562 ;
+C -1 ; WX 600 ; N format ; B -26 -146 222 598 ;
+C -1 ; WX 600 ; N largebullet ; B 317 239 403 323 ;
+C -1 ; WX 600 ; N Eth ; B 40 0 654 562 ;
+C -1 ; WX 600 ; N Odieresis ; B 84 -18 636 748 ;
+C -1 ; WX 600 ; N onesuperior ; B 218 230 506 616 ;
+C -1 ; WX 600 ; N dectab ; B 18 0 601 290 ;
+C -1 ; WX 600 ; N Ydieresis ; B 124 0 698 748 ;
+C -1 ; WX 600 ; N merge ; B 174 -15 526 487 ;
+C -1 ; WX 600 ; N IJ ; B 2 -18 731 562 ;
+C -1 ; WX 600 ; N ccedilla ; B 91 -206 621 459 ;
+C -1 ; WX 600 ; N multiply ; B 94 0 600 439 ;
+C -1 ; WX 600 ; N degree ; B 173 243 569 616 ;
+C -1 ; WX 600 ; N prescription ; B 34 -15 632 562 ;
+C -1 ; WX 600 ; N indent ; B 106 52 574 364 ;
+C -1 ; WX 600 ; N Otilde ; B 84 -18 668 759 ;
+C -1 ; WX 600 ; N thorn ; B -21 -142 612 626 ;
+C -1 ; WX 600 ; N mu ; B 60 -142 577 439 ;
+C -1 ; WX 600 ; N Yacute ; B 124 0 698 784 ;
+C -1 ; WX 600 ; N threesuperior ; B 203 222 515 616 ;
+C -1 ; WX 600 ; N logicalnot ; B 136 59 593 349 ;
+C -1 ; WX 600 ; N Ugrave ; B 116 -18 705 784 ;
+C -1 ; WX 600 ; N eth ; B 103 -27 651 626 ;
+C -1 ; WX 600 ; N left ; B 114 52 582 364 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 40 0 654 780 ;
+C -1 ; WX 600 ; N edieresis ; B 91 -15 594 625 ;
+C -1 ; WX 600 ; N Ograve ; B 84 -18 636 784 ;
+C -1 ; WX 600 ; N down ; B 174 -15 486 422 ;
+C -1 ; WX 600 ; N Agrave ; B 1 0 617 784 ;
+C -1 ; WX 600 ; N atilde ; B 72 -15 642 636 ;
+C -1 ; WX 600 ; N up ; B 204 0 516 437 ;
+C -1 ; WX 600 ; N eacute ; B 91 -15 608 661 ;
+C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ;
+C -1 ; WX 600 ; N lira ; B 117 -28 640 611 ;
+C -1 ; WX 600 ; N Icircumflex ; B 87 0 632 780 ;
+C -1 ; WX 600 ; N Adieresis ; B 1 0 617 748 ;
+C -1 ; WX 600 ; N yacute ; B -10 -142 684 661 ;
+C -1 ; WX 600 ; N icircumflex ; B 87 0 566 657 ;
+C -1 ; WX 600 ; N adieresis ; B 72 -15 578 625 ;
+C -1 ; WX 600 ; N zcaron ; B 91 0 632 667 ;
+C -1 ; WX 600 ; N Scaron ; B 64 -22 662 790 ;
+C -1 ; WX 600 ; N minus ; B 118 174 575 264 ;
+C -1 ; WX 600 ; N Aring ; B 1 0 617 801 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 116 -18 705 780 ;
+C -1 ; WX 600 ; N plusminus ; B 81 0 592 461 ;
+C -1 ; WX 600 ; N ograve ; B 81 -15 612 661 ;
+C -1 ; WX 600 ; N Edieresis ; B 40 0 654 748 ;
+C -1 ; WX 600 ; N brokenbar ; B 239 -77 478 626 ;
+C -1 ; WX 600 ; N Idieresis ; B 87 0 632 748 ;
+C -1 ; WX 600 ; N acircumflex ; B 72 -15 586 657 ;
+C -1 ; WX 600 ; N ydieresis ; B -10 -142 684 625 ;
+C -1 ; WX 600 ; N Oacute ; B 84 -18 636 784 ;
+C -1 ; WX 600 ; N Egrave ; B 40 0 654 784 ;
+C -1 ; WX 600 ; N center ; B 103 14 623 580 ;
+C -1 ; WX 600 ; N threequarters ; B 35 -60 725 661 ;
+C -1 ; WX 600 ; N tab ; B 19 0 641 562 ;
+C -1 ; WX 600 ; N ecircumflex ; B 91 -15 606 657 ;
+C -1 ; WX 600 ; N Eacute ; B 40 0 665 784 ;
+C -1 ; WX 600 ; N trademark ; B 86 230 868 562 ;
+C -1 ; WX 600 ; N square ; B 19 0 700 562 ;
+C -1 ; WX 600 ; N onehalf ; B 50 -60 742 661 ;
+C -1 ; WX 600 ; N onequarter ; B 50 -60 742 661 ;
+C -1 ; WX 600 ; N Uacute ; B 116 -18 705 784 ;
+C -1 ; WX 600 ; N Atilde ; B 1 0 638 759 ;
+C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N Igrave ; B 87 0 632 784 ;
+C -1 ; WX 600 ; N Iacute ; B 87 0 635 784 ;
+C -1 ; WX 600 ; N Acircumflex ; B 1 0 617 780 ;
+C -1 ; WX 600 ; N Udieresis ; B 116 -18 705 748 ;
+C -1 ; WX 600 ; N Gcaron ; B 85 -18 669 790 ;
+C -1 ; WX 600 ; N Aacute ; B 1 0 665 784 ;
+C -1 ; WX 600 ; N LL ; B -35 0 684 562 ;
+C -1 ; WX 600 ; N twosuperior ; B 202 230 531 616 ;
+C -1 ; WX 600 ; N Scedilla ; B 64 -206 662 582 ;
+C -1 ; WX 600 ; N arrowboth ; B 40 143 688 455 ;
+C -1 ; WX 600 ; N udieresis ; B 84 -15 577 625 ;
+C -1 ; WX 600 ; N odieresis ; B 81 -15 612 625 ;
+C -1 ; WX 600 ; N aring ; B 72 -15 578 678 ;
+C -1 ; WX 600 ; N ij ; B 16 -146 702 648 ;
+C -1 ; WX 600 ; N arrowdown ; B 174 -15 486 608 ;
+C -1 ; WX 600 ; N igrave ; B 87 0 531 661 ;
+C -1 ; WX 600 ; N aacute ; B 72 -15 608 661 ;
+C -1 ; WX 600 ; N stop ; B 19 0 700 562 ;
+C -1 ; WX 600 ; N ocircumflex ; B 81 -15 612 657 ;
+C -1 ; WX 600 ; N gcaron ; B 51 -146 663 667 ;
+C -1 ; WX 600 ; N iacute ; B 87 0 608 661 ;
+C -1 ; WX 600 ; N Ntilde ; B 18 -12 719 759 ;
+C -1 ; WX 600 ; N idieresis ; B 87 0 534 625 ;
+C -1 ; WX 600 ; N Ccedilla ; B 85 -206 664 580 ;
+C -1 ; WX 600 ; N arrowright ; B 32 143 688 455 ;
+C -1 ; WX 600 ; N ucircumflex ; B 84 -15 586 657 ;
+C -1 ; WX 600 ; N Idot ; B 87 0 632 748 ;
+C -1 ; WX 600 ; N agrave ; B 72 -15 578 661 ;
+C -1 ; WX 600 ; N ntilde ; B 28 0 642 636 ;
+C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N return ; B 79 0 700 562 ;
+C -1 ; WX 600 ; N Zcaron ; B 72 0 659 790 ;
+C -1 ; WX 600 ; N uacute ; B 84 -15 608 661 ;
+C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ;
+C -1 ; WX 600 ; N egrave ; B 91 -15 594 661 ;
+C -1 ; WX 600 ; N ugrave ; B 84 -15 577 661 ;
+C -1 ; WX 600 ; N oacute ; B 81 -15 612 661 ;
+C -1 ; WX 600 ; N arrowleft ; B 40 143 695 455 ;
+C -1 ; WX 600 ; N arrowup ; B 243 0 555 623 ;
+EndCharMetrics
+StartComposites 62
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 56 123 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 123 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 6 123 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave -24 123 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 16 123 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde -4 123 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 123 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 123 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 26 123 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 123 ;
+CC Gcaron 2 ; PCC G 0 0 ; PCC caron 36 123 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 123 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 123 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 26 123 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 123 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 26 123 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 123 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 123 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 26 123 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 123 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 26 123 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 26 123 ;
+CC Scedilla 2 ; PCC S 0 0 ; PCC cedilla 20 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 123 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 123 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 26 123 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 123 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 123 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 26 123 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 26 123 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC scedilla 2 ; PCC s 0 0 ; PCC cedilla 0 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Courier-Oblique.afm b/config/psfonts/Courier-Oblique.afm
new file mode 100644 (file)
index 0000000..4dc9419
--- /dev/null
@@ -0,0 +1,348 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1989, 1990 Adobe Systems Incorporated. All rights reserved.
+Comment Creation Date: Thu Jan 18 18:32:01 1990
+Comment UniqueID 27082
+Comment VMusage 6415 46660
+FontName Courier-Oblique
+FullName Courier Oblique
+FamilyName Courier
+Weight Medium
+ItalicAngle -12
+IsFixedPitch true
+FontBBox -30 -157 734 805
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.003
+Notice Copyright (c) 1989, 1990 Adobe Systems Incorporated. All rights reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 426
+Ascender 629
+Descender -157
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 243 -15 457 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ;
+C 35 ; WX 600 ; N numbersign ; B 142 -32 587 639 ;
+C 36 ; WX 600 ; N dollar ; B 115 -126 589 662 ;
+C 37 ; WX 600 ; N percent ; B 147 -15 596 622 ;
+C 38 ; WX 600 ; N ampersand ; B 94 -15 572 543 ;
+C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ;
+C 40 ; WX 600 ; N parenleft ; B 320 -108 565 622 ;
+C 41 ; WX 600 ; N parenright ; B 144 -108 389 622 ;
+C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ;
+C 43 ; WX 600 ; N plus ; B 128 0 562 426 ;
+C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ;
+C 45 ; WX 600 ; N hyphen ; B 161 238 549 278 ;
+C 46 ; WX 600 ; N period ; B 238 -15 382 109 ;
+C 47 ; WX 600 ; N slash ; B 111 -80 606 629 ;
+C 48 ; WX 600 ; N zero ; B 161 -15 568 622 ;
+C 49 ; WX 600 ; N one ; B 105 0 505 622 ;
+C 50 ; WX 600 ; N two ; B 77 0 561 622 ;
+C 51 ; WX 600 ; N three ; B 89 -15 531 622 ;
+C 52 ; WX 600 ; N four ; B 120 0 532 622 ;
+C 53 ; WX 600 ; N five ; B 105 -15 589 607 ;
+C 54 ; WX 600 ; N six ; B 162 -15 629 622 ;
+C 55 ; WX 600 ; N seven ; B 191 0 605 607 ;
+C 56 ; WX 600 ; N eight ; B 139 -15 581 622 ;
+C 57 ; WX 600 ; N nine ; B 100 -15 567 622 ;
+C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ;
+C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ;
+C 60 ; WX 600 ; N less ; B 86 -2 603 428 ;
+C 61 ; WX 600 ; N equal ; B 108 101 582 325 ;
+C 62 ; WX 600 ; N greater ; B 87 -2 604 428 ;
+C 63 ; WX 600 ; N question ; B 224 -15 576 572 ;
+C 64 ; WX 600 ; N at ; B 134 -15 575 622 ;
+C 65 ; WX 600 ; N A ; B 10 0 597 562 ;
+C 66 ; WX 600 ; N B ; B 50 0 609 562 ;
+C 67 ; WX 600 ; N C ; B 100 -18 651 580 ;
+C 68 ; WX 600 ; N D ; B 50 0 638 562 ;
+C 69 ; WX 600 ; N E ; B 60 0 653 562 ;
+C 70 ; WX 600 ; N F ; B 60 0 653 562 ;
+C 71 ; WX 600 ; N G ; B 90 -18 641 580 ;
+C 72 ; WX 600 ; N H ; B 39 0 680 562 ;
+C 73 ; WX 600 ; N I ; B 103 0 616 562 ;
+C 74 ; WX 600 ; N J ; B 59 -18 678 562 ;
+C 75 ; WX 600 ; N K ; B 45 0 664 562 ;
+C 76 ; WX 600 ; N L ; B 54 0 598 562 ;
+C 77 ; WX 600 ; N M ; B 11 0 708 562 ;
+C 78 ; WX 600 ; N N ; B 14 -13 705 562 ;
+C 79 ; WX 600 ; N O ; B 94 -18 625 580 ;
+C 80 ; WX 600 ; N P ; B 86 0 637 562 ;
+C 81 ; WX 600 ; N Q ; B 95 -129 625 580 ;
+C 82 ; WX 600 ; N R ; B 45 0 590 562 ;
+C 83 ; WX 600 ; N S ; B 83 -20 643 580 ;
+C 84 ; WX 600 ; N T ; B 116 0 658 562 ;
+C 85 ; WX 600 ; N U ; B 132 -18 695 562 ;
+C 86 ; WX 600 ; N V ; B 115 -13 716 562 ;
+C 87 ; WX 600 ; N W ; B 115 -13 716 562 ;
+C 88 ; WX 600 ; N X ; B 30 0 668 562 ;
+C 89 ; WX 600 ; N Y ; B 143 0 688 562 ;
+C 90 ; WX 600 ; N Z ; B 86 0 610 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 253 -108 574 622 ;
+C 92 ; WX 600 ; N backslash ; B 256 -80 461 629 ;
+C 93 ; WX 600 ; N bracketright ; B 135 -108 456 622 ;
+C 94 ; WX 600 ; N asciicircum ; B 175 359 587 622 ;
+C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 294 328 506 562 ;
+C 97 ; WX 600 ; N a ; B 83 -15 559 441 ;
+C 98 ; WX 600 ; N b ; B 36 -15 618 629 ;
+C 99 ; WX 600 ; N c ; B 113 -15 607 441 ;
+C 100 ; WX 600 ; N d ; B 92 -15 633 629 ;
+C 101 ; WX 600 ; N e ; B 113 -15 591 441 ;
+C 102 ; WX 600 ; N f ; B 121 0 655 629 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 68 -157 650 441 ;
+C 104 ; WX 600 ; N h ; B 40 0 582 629 ;
+C 105 ; WX 600 ; N i ; B 102 0 505 657 ;
+C 106 ; WX 600 ; N j ; B 59 -157 543 657 ;
+C 107 ; WX 600 ; N k ; B 65 0 626 629 ;
+C 108 ; WX 600 ; N l ; B 102 0 505 629 ;
+C 109 ; WX 600 ; N m ; B 2 0 606 441 ;
+C 110 ; WX 600 ; N n ; B 33 0 575 441 ;
+C 111 ; WX 600 ; N o ; B 102 -15 588 441 ;
+C 112 ; WX 600 ; N p ; B -17 -157 598 441 ;
+C 113 ; WX 600 ; N q ; B 92 -157 675 441 ;
+C 114 ; WX 600 ; N r ; B 67 0 631 441 ;
+C 115 ; WX 600 ; N s ; B 92 -15 570 441 ;
+C 116 ; WX 600 ; N t ; B 157 -15 534 561 ;
+C 117 ; WX 600 ; N u ; B 111 -15 562 426 ;
+C 118 ; WX 600 ; N v ; B 100 -10 674 426 ;
+C 119 ; WX 600 ; N w ; B 82 -10 692 426 ;
+C 120 ; WX 600 ; N x ; B 27 0 648 426 ;
+C 121 ; WX 600 ; N y ; B -30 -157 643 426 ;
+C 122 ; WX 600 ; N z ; B 106 0 586 426 ;
+C 123 ; WX 600 ; N braceleft ; B 240 -108 562 622 ;
+C 124 ; WX 600 ; N bar ; B 265 -80 453 629 ;
+C 125 ; WX 600 ; N braceright ; B 147 -108 470 622 ;
+C 126 ; WX 600 ; N asciitilde ; B 110 160 585 269 ;
+C 161 ; WX 600 ; N exclamdown ; B 232 -157 445 430 ;
+C 162 ; WX 600 ; N cent ; B 158 -49 581 614 ;
+C 163 ; WX 600 ; N sterling ; B 131 -21 614 611 ;
+C 164 ; WX 600 ; N fraction ; B 23 -57 706 665 ;
+C 165 ; WX 600 ; N yen ; B 135 0 693 594 ;
+C 166 ; WX 600 ; N florin ; B -19 -143 664 622 ;
+C 167 ; WX 600 ; N section ; B 111 -78 583 580 ;
+C 168 ; WX 600 ; N currency ; B 99 65 621 499 ;
+C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 213 328 576 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ;
+C 174 ; WX 600 ; N fi ; B 10 0 612 629 ;
+C 175 ; WX 600 ; N fl ; B 10 0 612 629 ;
+C 177 ; WX 600 ; N endash ; B 126 238 584 278 ;
+C 178 ; WX 600 ; N dagger ; B 226 -78 537 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 171 -78 537 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 273 152 418 276 ;
+C 182 ; WX 600 ; N paragraph ; B 107 -78 623 562 ;
+C 183 ; WX 600 ; N bullet ; B 231 137 478 376 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ;
+C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ;
+C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 51 -15 566 97 ;
+C 189 ; WX 600 ; N perthousand ; B 57 -15 627 622 ;
+C 191 ; WX 600 ; N questiondown ; B 112 -157 464 430 ;
+C 193 ; WX 600 ; N grave ; B 294 497 484 672 ;
+C 194 ; WX 600 ; N acute ; B 348 497 612 672 ;
+C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ;
+C 196 ; WX 600 ; N tilde ; B 219 503 617 606 ;
+C 197 ; WX 600 ; N macron ; B 232 525 600 565 ;
+C 198 ; WX 600 ; N breve ; B 279 501 576 609 ;
+C 199 ; WX 600 ; N dotaccent ; B 379 508 452 580 ;
+C 200 ; WX 600 ; N dieresis ; B 313 508 519 580 ;
+C 202 ; WX 600 ; N ring ; B 344 483 492 627 ;
+C 203 ; WX 600 ; N cedilla ; B 221 -151 340 10 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ;
+C 206 ; WX 600 ; N ogonek ; B 207 -151 348 0 ;
+C 207 ; WX 600 ; N caron ; B 262 492 614 669 ;
+C 208 ; WX 600 ; N emdash ; B 51 238 659 278 ;
+C 225 ; WX 600 ; N AE ; B 10 0 648 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 216 259 504 580 ;
+C 232 ; WX 600 ; N Lslash ; B 54 0 598 562 ;
+C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ;
+C 234 ; WX 600 ; N OE ; B 66 0 665 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 217 259 530 580 ;
+C 241 ; WX 600 ; N ae ; B 47 -15 620 441 ;
+C 245 ; WX 600 ; N dotlessi ; B 102 0 505 426 ;
+C 248 ; WX 600 ; N lslash ; B 102 0 559 629 ;
+C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ;
+C 250 ; WX 600 ; N oe ; B 61 -15 609 441 ;
+C 251 ; WX 600 ; N germandbls ; B 55 -15 610 629 ;
+C -1 ; WX 600 ; N scedilla ; B 92 -151 570 441 ;
+C -1 ; WX 600 ; N notegraphic ; B 143 -15 557 572 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 775 ;
+C -1 ; WX 600 ; N ll ; B 40 0 609 629 ;
+C -1 ; WX 600 ; N otilde ; B 102 -15 617 606 ;
+C -1 ; WX 600 ; N scaron ; B 92 -15 614 669 ;
+C -1 ; WX 600 ; N divide ; B 128 1 562 426 ;
+C -1 ; WX 600 ; N Thorn ; B 86 0 599 562 ;
+C -1 ; WX 600 ; N format ; B -28 -157 169 598 ;
+C -1 ; WX 600 ; N largebullet ; B 322 227 388 290 ;
+C -1 ; WX 600 ; N Eth ; B 50 0 638 562 ;
+C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 716 ;
+C -1 ; WX 600 ; N onesuperior ; B 238 249 481 622 ;
+C -1 ; WX 600 ; N dectab ; B 18 0 590 227 ;
+C -1 ; WX 600 ; N Ydieresis ; B 143 0 688 716 ;
+C -1 ; WX 600 ; N merge ; B 192 -15 497 436 ;
+C -1 ; WX 600 ; N IJ ; B 39 -18 681 562 ;
+C -1 ; WX 600 ; N ccedilla ; B 113 -151 607 441 ;
+C -1 ; WX 600 ; N multiply ; B 93 -1 599 426 ;
+C -1 ; WX 600 ; N degree ; B 214 269 576 622 ;
+C -1 ; WX 600 ; N prescription ; B 34 -15 610 562 ;
+C -1 ; WX 600 ; N indent ; B 110 75 574 341 ;
+C -1 ; WX 600 ; N Otilde ; B 94 -18 644 732 ;
+C -1 ; WX 600 ; N thorn ; B -17 -157 598 629 ;
+C -1 ; WX 600 ; N mu ; B 79 -157 562 426 ;
+C -1 ; WX 600 ; N Yacute ; B 143 0 688 793 ;
+C -1 ; WX 600 ; N threesuperior ; B 220 240 494 622 ;
+C -1 ; WX 600 ; N logicalnot ; B 148 64 582 325 ;
+C -1 ; WX 600 ; N Ugrave ; B 132 -18 695 793 ;
+C -1 ; WX 600 ; N eth ; B 102 -15 629 629 ;
+C -1 ; WX 600 ; N left ; B 114 75 578 341 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 60 0 653 775 ;
+C -1 ; WX 600 ; N edieresis ; B 113 -15 591 580 ;
+C -1 ; WX 600 ; N Ograve ; B 94 -18 625 793 ;
+C -1 ; WX 600 ; N down ; B 192 -15 458 422 ;
+C -1 ; WX 600 ; N Agrave ; B 10 0 597 793 ;
+C -1 ; WX 600 ; N atilde ; B 83 -15 617 606 ;
+C -1 ; WX 600 ; N up ; B 232 0 498 437 ;
+C -1 ; WX 600 ; N eacute ; B 113 -15 612 672 ;
+C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ;
+C -1 ; WX 600 ; N lira ; B 125 -21 614 611 ;
+C -1 ; WX 600 ; N Icircumflex ; B 103 0 616 775 ;
+C -1 ; WX 600 ; N Adieresis ; B 10 0 597 716 ;
+C -1 ; WX 600 ; N yacute ; B -30 -157 643 672 ;
+C -1 ; WX 600 ; N icircumflex ; B 102 0 551 654 ;
+C -1 ; WX 600 ; N adieresis ; B 83 -15 559 580 ;
+C -1 ; WX 600 ; N zcaron ; B 106 0 624 669 ;
+C -1 ; WX 600 ; N Scaron ; B 83 -20 673 805 ;
+C -1 ; WX 600 ; N minus ; B 128 195 562 232 ;
+C -1 ; WX 600 ; N Aring ; B 10 0 597 753 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 132 -18 695 775 ;
+C -1 ; WX 600 ; N plusminus ; B 87 0 583 514 ;
+C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ;
+C -1 ; WX 600 ; N Edieresis ; B 60 0 653 716 ;
+C -1 ; WX 600 ; N brokenbar ; B 265 -80 453 629 ;
+C -1 ; WX 600 ; N Idieresis ; B 103 0 616 716 ;
+C -1 ; WX 600 ; N acircumflex ; B 83 -15 581 654 ;
+C -1 ; WX 600 ; N ydieresis ; B -30 -157 643 580 ;
+C -1 ; WX 600 ; N Oacute ; B 94 -18 638 793 ;
+C -1 ; WX 600 ; N Egrave ; B 60 0 653 793 ;
+C -1 ; WX 600 ; N center ; B 103 14 623 580 ;
+C -1 ; WX 600 ; N threequarters ; B 28 -57 711 665 ;
+C -1 ; WX 600 ; N tab ; B 19 0 641 562 ;
+C -1 ; WX 600 ; N ecircumflex ; B 113 -15 591 654 ;
+C -1 ; WX 600 ; N Eacute ; B 60 0 668 793 ;
+C -1 ; WX 600 ; N trademark ; B 108 263 710 562 ;
+C -1 ; WX 600 ; N square ; B 19 0 700 562 ;
+C -1 ; WX 600 ; N onehalf ; B 42 -57 725 665 ;
+C -1 ; WX 600 ; N onequarter ; B 48 -57 731 665 ;
+C -1 ; WX 600 ; N Uacute ; B 132 -18 695 793 ;
+C -1 ; WX 600 ; N Atilde ; B 10 0 644 732 ;
+C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N Igrave ; B 103 0 616 793 ;
+C -1 ; WX 600 ; N Iacute ; B 103 0 638 793 ;
+C -1 ; WX 600 ; N Acircumflex ; B 10 0 597 775 ;
+C -1 ; WX 600 ; N Udieresis ; B 132 -18 695 716 ;
+C -1 ; WX 600 ; N Gcaron ; B 90 -18 643 805 ;
+C -1 ; WX 600 ; N Aacute ; B 10 0 658 793 ;
+C -1 ; WX 600 ; N LL ; B 15 0 640 562 ;
+C -1 ; WX 600 ; N twosuperior ; B 237 249 528 622 ;
+C -1 ; WX 600 ; N Scedilla ; B 83 -151 643 580 ;
+C -1 ; WX 600 ; N arrowboth ; B 36 122 692 476 ;
+C -1 ; WX 600 ; N udieresis ; B 111 -15 562 580 ;
+C -1 ; WX 600 ; N odieresis ; B 102 -15 588 580 ;
+C -1 ; WX 600 ; N aring ; B 83 -15 559 627 ;
+C -1 ; WX 600 ; N ij ; B 44 -157 623 657 ;
+C -1 ; WX 600 ; N arrowdown ; B 157 -15 511 608 ;
+C -1 ; WX 600 ; N igrave ; B 102 0 505 672 ;
+C -1 ; WX 600 ; N aacute ; B 83 -15 612 672 ;
+C -1 ; WX 600 ; N stop ; B 19 0 700 562 ;
+C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ;
+C -1 ; WX 600 ; N gcaron ; B 68 -157 650 669 ;
+C -1 ; WX 600 ; N iacute ; B 102 0 612 672 ;
+C -1 ; WX 600 ; N Ntilde ; B 14 -13 705 732 ;
+C -1 ; WX 600 ; N idieresis ; B 102 0 505 580 ;
+C -1 ; WX 600 ; N Ccedilla ; B 100 -151 651 580 ;
+C -1 ; WX 600 ; N arrowright ; B 35 122 688 476 ;
+C -1 ; WX 600 ; N ucircumflex ; B 111 -15 571 654 ;
+C -1 ; WX 600 ; N Idot ; B 103 0 616 716 ;
+C -1 ; WX 600 ; N agrave ; B 83 -15 559 672 ;
+C -1 ; WX 600 ; N ntilde ; B 33 0 617 606 ;
+C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N return ; B 79 0 700 562 ;
+C -1 ; WX 600 ; N Zcaron ; B 86 0 643 805 ;
+C -1 ; WX 600 ; N uacute ; B 111 -15 602 672 ;
+C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ;
+C -1 ; WX 600 ; N egrave ; B 113 -15 591 672 ;
+C -1 ; WX 600 ; N ugrave ; B 111 -15 562 672 ;
+C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ;
+C -1 ; WX 600 ; N arrowleft ; B 40 122 692 476 ;
+C -1 ; WX 600 ; N arrowup ; B 218 0 572 623 ;
+EndCharMetrics
+StartComposites 62
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 46 121 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 121 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -1 136 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave -4 121 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 12 126 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 27 126 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 121 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 121 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 29 136 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 121 ;
+CC Gcaron 2 ; PCC G 0 0 ; PCC caron 29 136 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 121 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 121 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 29 136 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 121 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 27 126 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 121 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 121 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 29 136 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 121 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 27 126 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 59 136 ;
+CC Scedilla 2 ; PCC S 0 0 ; PCC cedilla 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 121 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 121 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 29 136 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 121 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 121 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 29 136 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 29 136 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC scedilla 2 ; PCC s 0 0 ; PCC cedilla 0 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Courier.afm b/config/psfonts/Courier.afm
new file mode 100644 (file)
index 0000000..3688908
--- /dev/null
@@ -0,0 +1,348 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1989, 1990 Adobe Systems Incorporated. All rights reserved.
+Comment Creation Date: Thu Jan 18 17:48:17 1990
+Comment UniqueID 27077
+Comment VMusage 27874 40242
+FontName Courier
+FullName Courier
+FamilyName Courier
+Weight Medium
+ItalicAngle 0
+IsFixedPitch true
+FontBBox -28 -157 628 805
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.003
+Notice Copyright (c) 1989, 1990 Adobe Systems Incorporated. All rights reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 426
+Ascender 629
+Descender -157
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ;
+C 35 ; WX 600 ; N numbersign ; B 100 -32 500 639 ;
+C 36 ; WX 600 ; N dollar ; B 112 -126 489 662 ;
+C 37 ; WX 600 ; N percent ; B 97 -15 515 622 ;
+C 38 ; WX 600 ; N ampersand ; B 70 -15 531 543 ;
+C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ;
+C 40 ; WX 600 ; N parenleft ; B 276 -108 433 622 ;
+C 41 ; WX 600 ; N parenright ; B 167 -108 324 622 ;
+C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ;
+C 43 ; WX 600 ; N plus ; B 87 0 513 426 ;
+C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ;
+C 45 ; WX 600 ; N hyphen ; B 110 238 490 278 ;
+C 46 ; WX 600 ; N period ; B 229 -15 371 109 ;
+C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ;
+C 48 ; WX 600 ; N zero ; B 113 -15 487 622 ;
+C 49 ; WX 600 ; N one ; B 102 0 498 622 ;
+C 50 ; WX 600 ; N two ; B 77 0 464 622 ;
+C 51 ; WX 600 ; N three ; B 82 -15 459 622 ;
+C 52 ; WX 600 ; N four ; B 88 0 493 622 ;
+C 53 ; WX 600 ; N five ; B 99 -15 490 607 ;
+C 54 ; WX 600 ; N six ; B 118 -15 497 622 ;
+C 55 ; WX 600 ; N seven ; B 89 0 476 607 ;
+C 56 ; WX 600 ; N eight ; B 109 -15 491 622 ;
+C 57 ; WX 600 ; N nine ; B 103 -15 482 622 ;
+C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ;
+C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ;
+C 60 ; WX 600 ; N less ; B 41 -2 519 428 ;
+C 61 ; WX 600 ; N equal ; B 87 101 513 325 ;
+C 62 ; WX 600 ; N greater ; B 81 -2 559 428 ;
+C 63 ; WX 600 ; N question ; B 136 -15 485 572 ;
+C 64 ; WX 600 ; N at ; B 84 -15 526 622 ;
+C 65 ; WX 600 ; N A ; B 10 0 590 562 ;
+C 66 ; WX 600 ; N B ; B 50 0 552 562 ;
+C 67 ; WX 600 ; N C ; B 48 -18 533 580 ;
+C 68 ; WX 600 ; N D ; B 50 0 567 562 ;
+C 69 ; WX 600 ; N E ; B 60 0 543 562 ;
+C 70 ; WX 600 ; N F ; B 60 0 538 562 ;
+C 71 ; WX 600 ; N G ; B 38 -18 568 580 ;
+C 72 ; WX 600 ; N H ; B 39 0 561 562 ;
+C 73 ; WX 600 ; N I ; B 103 0 497 562 ;
+C 74 ; WX 600 ; N J ; B 41 -18 559 562 ;
+C 75 ; WX 600 ; N K ; B 45 0 575 562 ;
+C 76 ; WX 600 ; N L ; B 54 0 547 562 ;
+C 77 ; WX 600 ; N M ; B 11 0 589 562 ;
+C 78 ; WX 600 ; N N ; B 14 -13 586 562 ;
+C 79 ; WX 600 ; N O ; B 43 -18 557 580 ;
+C 80 ; WX 600 ; N P ; B 86 0 551 562 ;
+C 81 ; WX 600 ; N Q ; B 43 -129 557 580 ;
+C 82 ; WX 600 ; N R ; B 45 0 581 562 ;
+C 83 ; WX 600 ; N S ; B 79 -20 522 580 ;
+C 84 ; WX 600 ; N T ; B 45 0 556 562 ;
+C 85 ; WX 600 ; N U ; B 24 -18 576 562 ;
+C 86 ; WX 600 ; N V ; B 3 -13 597 562 ;
+C 87 ; WX 600 ; N W ; B 3 -13 597 562 ;
+C 88 ; WX 600 ; N X ; B 30 0 570 562 ;
+C 89 ; WX 600 ; N Y ; B 31 0 569 562 ;
+C 90 ; WX 600 ; N Z ; B 86 0 514 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 276 -108 442 622 ;
+C 92 ; WX 600 ; N backslash ; B 125 -80 475 629 ;
+C 93 ; WX 600 ; N bracketright ; B 158 -108 324 622 ;
+C 94 ; WX 600 ; N asciicircum ; B 94 359 506 622 ;
+C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ;
+C 97 ; WX 600 ; N a ; B 60 -15 552 441 ;
+C 98 ; WX 600 ; N b ; B 21 -15 568 629 ;
+C 99 ; WX 600 ; N c ; B 73 -15 522 441 ;
+C 100 ; WX 600 ; N d ; B 52 -15 584 629 ;
+C 101 ; WX 600 ; N e ; B 73 -15 541 441 ;
+C 102 ; WX 600 ; N f ; B 121 0 524 629 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 52 -157 559 441 ;
+C 104 ; WX 600 ; N h ; B 25 0 575 629 ;
+C 105 ; WX 600 ; N i ; B 102 0 498 657 ;
+C 106 ; WX 600 ; N j ; B 89 -157 403 657 ;
+C 107 ; WX 600 ; N k ; B 50 0 573 629 ;
+C 108 ; WX 600 ; N l ; B 102 0 498 629 ;
+C 109 ; WX 600 ; N m ; B 2 0 598 441 ;
+C 110 ; WX 600 ; N n ; B 33 0 568 441 ;
+C 111 ; WX 600 ; N o ; B 62 -15 538 441 ;
+C 112 ; WX 600 ; N p ; B 16 -157 548 441 ;
+C 113 ; WX 600 ; N q ; B 52 -157 584 441 ;
+C 114 ; WX 600 ; N r ; B 67 0 552 441 ;
+C 115 ; WX 600 ; N s ; B 94 -15 506 441 ;
+C 116 ; WX 600 ; N t ; B 74 -15 503 561 ;
+C 117 ; WX 600 ; N u ; B 28 -15 555 426 ;
+C 118 ; WX 600 ; N v ; B 17 -10 583 426 ;
+C 119 ; WX 600 ; N w ; B -1 -10 601 426 ;
+C 120 ; WX 600 ; N x ; B 27 0 573 426 ;
+C 121 ; WX 600 ; N y ; B -12 -157 552 426 ;
+C 122 ; WX 600 ; N z ; B 106 0 495 426 ;
+C 123 ; WX 600 ; N braceleft ; B 189 -108 430 622 ;
+C 124 ; WX 600 ; N bar ; B 282 -80 319 629 ;
+C 125 ; WX 600 ; N braceright ; B 170 -108 411 622 ;
+C 126 ; WX 600 ; N asciitilde ; B 67 160 534 269 ;
+C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ;
+C 162 ; WX 600 ; N cent ; B 103 -49 493 614 ;
+C 163 ; WX 600 ; N sterling ; B 91 -21 518 611 ;
+C 164 ; WX 600 ; N fraction ; B 31 -57 569 665 ;
+C 165 ; WX 600 ; N yen ; B 33 0 567 594 ;
+C 166 ; WX 600 ; N florin ; B 11 -143 532 622 ;
+C 167 ; WX 600 ; N section ; B 120 -78 481 580 ;
+C 168 ; WX 600 ; N currency ; B 80 65 520 499 ;
+C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 143 328 457 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ;
+C 174 ; WX 600 ; N fi ; B 10 0 590 629 ;
+C 175 ; WX 600 ; N fl ; B 10 0 590 629 ;
+C 177 ; WX 600 ; N endash ; B 75 238 525 278 ;
+C 178 ; WX 600 ; N dagger ; B 148 -78 452 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 148 -78 452 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 229 152 371 276 ;
+C 182 ; WX 600 ; N paragraph ; B 57 -78 504 562 ;
+C 183 ; WX 600 ; N bullet ; B 179 137 421 376 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ;
+C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ;
+C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 44 -15 556 97 ;
+C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ;
+C 191 ; WX 600 ; N questiondown ; B 115 -157 464 430 ;
+C 193 ; WX 600 ; N grave ; B 151 497 378 672 ;
+C 194 ; WX 600 ; N acute ; B 242 497 469 672 ;
+C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ;
+C 196 ; WX 600 ; N tilde ; B 109 503 491 606 ;
+C 197 ; WX 600 ; N macron ; B 120 525 480 565 ;
+C 198 ; WX 600 ; N breve ; B 153 501 447 609 ;
+C 199 ; WX 600 ; N dotaccent ; B 264 508 336 580 ;
+C 200 ; WX 600 ; N dieresis ; B 198 508 402 580 ;
+C 202 ; WX 600 ; N ring ; B 228 483 372 627 ;
+C 203 ; WX 600 ; N cedilla ; B 249 -151 358 10 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ;
+C 206 ; WX 600 ; N ogonek ; B 227 -151 370 0 ;
+C 207 ; WX 600 ; N caron ; B 124 492 476 669 ;
+C 208 ; WX 600 ; N emdash ; B 0 238 600 278 ;
+C 225 ; WX 600 ; N AE ; B 10 0 543 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 161 259 437 580 ;
+C 232 ; WX 600 ; N Lslash ; B 54 0 547 562 ;
+C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ;
+C 234 ; WX 600 ; N OE ; B 14 0 560 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 162 259 438 580 ;
+C 241 ; WX 600 ; N ae ; B 26 -15 563 441 ;
+C 245 ; WX 600 ; N dotlessi ; B 102 0 498 426 ;
+C 248 ; WX 600 ; N lslash ; B 102 0 498 629 ;
+C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ;
+C 250 ; WX 600 ; N oe ; B 26 -15 552 441 ;
+C 251 ; WX 600 ; N germandbls ; B 55 -15 581 629 ;
+C -1 ; WX 600 ; N scedilla ; B 94 -151 506 441 ;
+C -1 ; WX 600 ; N notegraphic ; B 136 -15 464 572 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 775 ;
+C -1 ; WX 600 ; N ll ; B 25 0 560 629 ;
+C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ;
+C -1 ; WX 600 ; N scaron ; B 94 -15 506 669 ;
+C -1 ; WX 600 ; N divide ; B 87 1 513 426 ;
+C -1 ; WX 600 ; N Thorn ; B 86 0 531 562 ;
+C -1 ; WX 600 ; N format ; B 5 -157 42 598 ;
+C -1 ; WX 600 ; N largebullet ; B 268 227 332 290 ;
+C -1 ; WX 600 ; N Eth ; B 30 0 567 562 ;
+C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 716 ;
+C -1 ; WX 600 ; N onesuperior ; B 179 249 421 622 ;
+C -1 ; WX 600 ; N dectab ; B 18 0 582 227 ;
+C -1 ; WX 600 ; N Ydieresis ; B 31 0 569 716 ;
+C -1 ; WX 600 ; N merge ; B 167 -15 433 436 ;
+C -1 ; WX 600 ; N IJ ; B 39 -18 562 562 ;
+C -1 ; WX 600 ; N ccedilla ; B 73 -151 522 441 ;
+C -1 ; WX 600 ; N multiply ; B 87 -1 514 426 ;
+C -1 ; WX 600 ; N degree ; B 123 269 477 622 ;
+C -1 ; WX 600 ; N prescription ; B 34 -15 570 562 ;
+C -1 ; WX 600 ; N indent ; B 70 75 530 341 ;
+C -1 ; WX 600 ; N Otilde ; B 43 -18 557 732 ;
+C -1 ; WX 600 ; N thorn ; B 1 -157 548 629 ;
+C -1 ; WX 600 ; N mu ; B 28 -157 555 426 ;
+C -1 ; WX 600 ; N Yacute ; B 31 0 569 793 ;
+C -1 ; WX 600 ; N threesuperior ; B 162 240 399 622 ;
+C -1 ; WX 600 ; N logicalnot ; B 87 64 513 325 ;
+C -1 ; WX 600 ; N Ugrave ; B 24 -18 576 793 ;
+C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ;
+C -1 ; WX 600 ; N left ; B 70 75 530 341 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 60 0 543 775 ;
+C -1 ; WX 600 ; N edieresis ; B 73 -15 541 580 ;
+C -1 ; WX 600 ; N Ograve ; B 43 -18 557 793 ;
+C -1 ; WX 600 ; N down ; B 167 -15 433 422 ;
+C -1 ; WX 600 ; N Agrave ; B 10 0 590 793 ;
+C -1 ; WX 600 ; N atilde ; B 60 -15 552 606 ;
+C -1 ; WX 600 ; N up ; B 167 0 433 437 ;
+C -1 ; WX 600 ; N eacute ; B 73 -15 541 672 ;
+C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ;
+C -1 ; WX 600 ; N lira ; B 80 -21 518 611 ;
+C -1 ; WX 600 ; N Icircumflex ; B 103 0 497 775 ;
+C -1 ; WX 600 ; N Adieresis ; B 10 0 590 716 ;
+C -1 ; WX 600 ; N yacute ; B -12 -157 552 672 ;
+C -1 ; WX 600 ; N icircumflex ; B 94 0 498 654 ;
+C -1 ; WX 600 ; N adieresis ; B 60 -15 552 580 ;
+C -1 ; WX 600 ; N zcaron ; B 106 0 495 669 ;
+C -1 ; WX 600 ; N Scaron ; B 79 -20 522 805 ;
+C -1 ; WX 600 ; N minus ; B 87 195 513 232 ;
+C -1 ; WX 600 ; N Aring ; B 10 0 590 753 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 24 -18 576 775 ;
+C -1 ; WX 600 ; N plusminus ; B 87 0 513 514 ;
+C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ;
+C -1 ; WX 600 ; N Edieresis ; B 60 0 543 716 ;
+C -1 ; WX 600 ; N brokenbar ; B 282 -80 319 629 ;
+C -1 ; WX 600 ; N Idieresis ; B 103 0 497 716 ;
+C -1 ; WX 600 ; N acircumflex ; B 60 -15 552 654 ;
+C -1 ; WX 600 ; N ydieresis ; B -12 -157 552 580 ;
+C -1 ; WX 600 ; N Oacute ; B 43 -18 557 793 ;
+C -1 ; WX 600 ; N Egrave ; B 60 0 543 793 ;
+C -1 ; WX 600 ; N center ; B 40 14 560 580 ;
+C -1 ; WX 600 ; N threequarters ; B 22 -57 574 665 ;
+C -1 ; WX 600 ; N tab ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N ecircumflex ; B 73 -15 541 654 ;
+C -1 ; WX 600 ; N Eacute ; B 60 0 543 793 ;
+C -1 ; WX 600 ; N trademark ; B 10 263 591 562 ;
+C -1 ; WX 600 ; N square ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ;
+C -1 ; WX 600 ; N onequarter ; B 6 -57 594 665 ;
+C -1 ; WX 600 ; N Uacute ; B 24 -18 576 793 ;
+C -1 ; WX 600 ; N Atilde ; B 10 0 590 732 ;
+C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N Igrave ; B 103 0 497 793 ;
+C -1 ; WX 600 ; N Iacute ; B 103 0 497 793 ;
+C -1 ; WX 600 ; N Acircumflex ; B 10 0 590 775 ;
+C -1 ; WX 600 ; N Udieresis ; B 24 -18 576 716 ;
+C -1 ; WX 600 ; N Gcaron ; B 38 -18 568 805 ;
+C -1 ; WX 600 ; N Aacute ; B 10 0 590 793 ;
+C -1 ; WX 600 ; N LL ; B 15 0 585 562 ;
+C -1 ; WX 600 ; N twosuperior ; B 184 249 417 622 ;
+C -1 ; WX 600 ; N Scedilla ; B 79 -151 522 580 ;
+C -1 ; WX 600 ; N arrowboth ; B -28 122 628 476 ;
+C -1 ; WX 600 ; N udieresis ; B 28 -15 555 580 ;
+C -1 ; WX 600 ; N odieresis ; B 62 -15 538 580 ;
+C -1 ; WX 600 ; N aring ; B 60 -15 552 627 ;
+C -1 ; WX 600 ; N ij ; B 44 -157 483 657 ;
+C -1 ; WX 600 ; N arrowdown ; B 123 -15 477 608 ;
+C -1 ; WX 600 ; N igrave ; B 102 0 498 672 ;
+C -1 ; WX 600 ; N aacute ; B 60 -15 552 672 ;
+C -1 ; WX 600 ; N stop ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ;
+C -1 ; WX 600 ; N gcaron ; B 52 -157 559 669 ;
+C -1 ; WX 600 ; N iacute ; B 102 0 498 672 ;
+C -1 ; WX 600 ; N Ntilde ; B 14 -13 586 732 ;
+C -1 ; WX 600 ; N idieresis ; B 102 0 498 580 ;
+C -1 ; WX 600 ; N Ccedilla ; B 48 -151 533 580 ;
+C -1 ; WX 600 ; N arrowright ; B -24 122 624 476 ;
+C -1 ; WX 600 ; N ucircumflex ; B 28 -15 555 654 ;
+C -1 ; WX 600 ; N Idot ; B 103 0 497 716 ;
+C -1 ; WX 600 ; N agrave ; B 60 -15 552 672 ;
+C -1 ; WX 600 ; N ntilde ; B 33 0 568 606 ;
+C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N return ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N Zcaron ; B 86 0 514 805 ;
+C -1 ; WX 600 ; N uacute ; B 28 -15 555 672 ;
+C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ;
+C -1 ; WX 600 ; N egrave ; B 73 -15 541 672 ;
+C -1 ; WX 600 ; N ugrave ; B 28 -15 555 672 ;
+C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ;
+C -1 ; WX 600 ; N arrowleft ; B -24 122 624 476 ;
+C -1 ; WX 600 ; N arrowup ; B 123 0 477 623 ;
+EndCharMetrics
+StartComposites 62
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 20 121 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 121 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -30 136 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave -30 121 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring -15 126 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 126 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 121 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 121 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 136 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 121 ;
+CC Gcaron 2 ; PCC G 0 0 ; PCC caron 0 136 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 121 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 121 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 136 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 121 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 126 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 121 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 121 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 136 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 121 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 126 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 30 136 ;
+CC Scedilla 2 ; PCC S 0 0 ; PCC cedilla 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 121 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 121 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 136 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 121 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 121 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 136 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 136 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC scedilla 2 ; PCC s 0 0 ; PCC cedilla 0 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Helvetica-Bold.afm b/config/psfonts/Helvetica-Bold.afm
new file mode 100644 (file)
index 0000000..a1e1b33
--- /dev/null
@@ -0,0 +1,570 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Thu Mar 15 09:43:00 1990
+Comment UniqueID 28357
+Comment VMusage 26878 33770
+FontName Helvetica-Bold
+FullName Helvetica Bold
+FamilyName Helvetica
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -170 -228 1003 962
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 532
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ;
+C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ;
+C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ;
+C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ;
+C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ;
+C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ;
+C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ;
+C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ;
+C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ;
+C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ;
+C 43 ; WX 584 ; N plus ; B 40 0 544 506 ;
+C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ;
+C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ;
+C 46 ; WX 278 ; N period ; B 64 0 214 146 ;
+C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ;
+C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ;
+C 49 ; WX 556 ; N one ; B 69 0 378 710 ;
+C 50 ; WX 556 ; N two ; B 26 0 511 710 ;
+C 51 ; WX 556 ; N three ; B 27 -19 516 710 ;
+C 52 ; WX 556 ; N four ; B 27 0 526 710 ;
+C 53 ; WX 556 ; N five ; B 27 -19 516 698 ;
+C 54 ; WX 556 ; N six ; B 31 -19 520 710 ;
+C 55 ; WX 556 ; N seven ; B 25 0 528 698 ;
+C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ;
+C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ;
+C 58 ; WX 333 ; N colon ; B 92 0 242 512 ;
+C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ;
+C 60 ; WX 584 ; N less ; B 38 -8 546 514 ;
+C 61 ; WX 584 ; N equal ; B 40 87 544 419 ;
+C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ;
+C 63 ; WX 611 ; N question ; B 60 0 556 727 ;
+C 64 ; WX 975 ; N at ; B 118 -19 856 737 ;
+C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
+C 66 ; WX 722 ; N B ; B 76 0 669 718 ;
+C 67 ; WX 722 ; N C ; B 44 -19 684 737 ;
+C 68 ; WX 722 ; N D ; B 76 0 685 718 ;
+C 69 ; WX 667 ; N E ; B 76 0 621 718 ;
+C 70 ; WX 611 ; N F ; B 76 0 587 718 ;
+C 71 ; WX 778 ; N G ; B 44 -19 713 737 ;
+C 72 ; WX 722 ; N H ; B 71 0 651 718 ;
+C 73 ; WX 278 ; N I ; B 64 0 214 718 ;
+C 74 ; WX 556 ; N J ; B 22 -18 484 718 ;
+C 75 ; WX 722 ; N K ; B 87 0 722 718 ;
+C 76 ; WX 611 ; N L ; B 76 0 583 718 ;
+C 77 ; WX 833 ; N M ; B 69 0 765 718 ;
+C 78 ; WX 722 ; N N ; B 69 0 654 718 ;
+C 79 ; WX 778 ; N O ; B 44 -19 734 737 ;
+C 80 ; WX 667 ; N P ; B 76 0 627 718 ;
+C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ;
+C 82 ; WX 722 ; N R ; B 76 0 677 718 ;
+C 83 ; WX 667 ; N S ; B 39 -19 629 737 ;
+C 84 ; WX 611 ; N T ; B 14 0 598 718 ;
+C 85 ; WX 722 ; N U ; B 72 -19 651 718 ;
+C 86 ; WX 667 ; N V ; B 19 0 648 718 ;
+C 87 ; WX 944 ; N W ; B 16 0 929 718 ;
+C 88 ; WX 667 ; N X ; B 14 0 653 718 ;
+C 89 ; WX 667 ; N Y ; B 15 0 653 718 ;
+C 90 ; WX 611 ; N Z ; B 25 0 586 718 ;
+C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ;
+C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ;
+C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ;
+C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ;
+C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ;
+C 97 ; WX 556 ; N a ; B 29 -14 527 546 ;
+C 98 ; WX 611 ; N b ; B 61 -14 578 718 ;
+C 99 ; WX 556 ; N c ; B 34 -14 524 546 ;
+C 100 ; WX 611 ; N d ; B 34 -14 551 718 ;
+C 101 ; WX 556 ; N e ; B 23 -14 528 546 ;
+C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 40 -217 553 546 ;
+C 104 ; WX 611 ; N h ; B 65 0 546 718 ;
+C 105 ; WX 278 ; N i ; B 69 0 209 725 ;
+C 106 ; WX 278 ; N j ; B 3 -214 209 725 ;
+C 107 ; WX 556 ; N k ; B 69 0 562 718 ;
+C 108 ; WX 278 ; N l ; B 69 0 209 718 ;
+C 109 ; WX 889 ; N m ; B 64 0 826 546 ;
+C 110 ; WX 611 ; N n ; B 65 0 546 546 ;
+C 111 ; WX 611 ; N o ; B 34 -14 578 546 ;
+C 112 ; WX 611 ; N p ; B 62 -207 578 546 ;
+C 113 ; WX 611 ; N q ; B 34 -207 552 546 ;
+C 114 ; WX 389 ; N r ; B 64 0 373 546 ;
+C 115 ; WX 556 ; N s ; B 30 -14 519 546 ;
+C 116 ; WX 333 ; N t ; B 10 -6 309 676 ;
+C 117 ; WX 611 ; N u ; B 66 -14 545 532 ;
+C 118 ; WX 556 ; N v ; B 13 0 543 532 ;
+C 119 ; WX 778 ; N w ; B 10 0 769 532 ;
+C 120 ; WX 556 ; N x ; B 15 0 541 532 ;
+C 121 ; WX 556 ; N y ; B 10 -214 539 532 ;
+C 122 ; WX 500 ; N z ; B 20 0 480 532 ;
+C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ;
+C 124 ; WX 280 ; N bar ; B 84 -19 196 737 ;
+C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ;
+C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ;
+C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ;
+C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ;
+C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ;
+C 165 ; WX 556 ; N yen ; B -9 0 565 698 ;
+C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ;
+C 167 ; WX 556 ; N section ; B 34 -184 522 727 ;
+C 168 ; WX 556 ; N currency ; B -3 76 559 636 ;
+C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ;
+C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ;
+C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ;
+C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ;
+C 174 ; WX 611 ; N fi ; B 10 0 542 727 ;
+C 175 ; WX 611 ; N fl ; B 10 0 542 727 ;
+C 177 ; WX 556 ; N endash ; B 0 227 556 333 ;
+C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ;
+C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ;
+C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ;
+C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ;
+C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ;
+C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ;
+C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ;
+C 193 ; WX 333 ; N grave ; B -23 604 225 750 ;
+C 194 ; WX 333 ; N acute ; B 108 604 356 750 ;
+C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ;
+C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ;
+C 197 ; WX 333 ; N macron ; B -6 604 339 678 ;
+C 198 ; WX 333 ; N breve ; B -2 604 335 750 ;
+C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ;
+C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ;
+C 202 ; WX 333 ; N ring ; B 59 568 275 776 ;
+C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ;
+C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ;
+C 207 ; WX 333 ; N caron ; B -10 604 343 750 ;
+C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ;
+C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 22 276 347 737 ;
+C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ;
+C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ;
+C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 6 276 360 737 ;
+C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ;
+C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ;
+C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ;
+C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ;
+C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ;
+C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ;
+C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ;
+C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ;
+C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ;
+C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ;
+C -1 ; WX 333 ; N threesuperior ; B 8 271 326 710 ;
+C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ;
+C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ;
+C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ;
+C -1 ; WX 333 ; N twosuperior ; B 9 283 324 710 ;
+C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ;
+C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ;
+C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ;
+C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ;
+C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ;
+C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ;
+C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ;
+C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ;
+C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ;
+C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ;
+C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ;
+C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ;
+C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ;
+C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ;
+C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ;
+C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ;
+C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ;
+C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ;
+C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ;
+C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ;
+C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ;
+C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ;
+C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ;
+C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ;
+C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ;
+C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ;
+C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ;
+C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ;
+C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ;
+C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ;
+C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ;
+C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ;
+C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ;
+C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ;
+C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ;
+C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ;
+C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ;
+C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ;
+C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ;
+C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ;
+C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ;
+C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
+C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ;
+C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ;
+C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ;
+C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ;
+C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ;
+C -1 ; WX 584 ; N minus ; B 40 197 544 309 ;
+C -1 ; WX 333 ; N onesuperior ; B 26 283 237 710 ;
+C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ;
+C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ;
+C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
+C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ;
+C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ;
+C -1 ; WX 400 ; N degree ; B 57 426 343 712 ;
+C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ;
+C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ;
+C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ;
+C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ;
+C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ;
+C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ;
+C -1 ; WX 280 ; N brokenbar ; B 84 -19 196 737 ;
+C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 209
+
+KPX A y -30
+KPX A w -30
+KPX A v -40
+KPX A u -30
+KPX A Y -110
+KPX A W -60
+KPX A V -80
+KPX A U -50
+KPX A T -90
+KPX A Q -40
+KPX A O -40
+KPX A G -50
+KPX A C -40
+
+KPX B U -10
+KPX B A -30
+
+KPX D period -30
+KPX D comma -30
+KPX D Y -70
+KPX D W -40
+KPX D V -40
+KPX D A -40
+
+KPX F period -100
+KPX F comma -100
+KPX F a -20
+KPX F A -80
+
+KPX J u -20
+KPX J period -20
+KPX J comma -20
+KPX J A -20
+
+KPX K y -40
+KPX K u -30
+KPX K o -35
+KPX K e -15
+KPX K O -30
+
+KPX L y -30
+KPX L quoteright -140
+KPX L quotedblright -140
+KPX L Y -120
+KPX L W -80
+KPX L V -110
+KPX L T -90
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -50
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -50
+
+KPX P period -120
+KPX P o -40
+KPX P e -30
+KPX P comma -120
+KPX P a -30
+KPX P A -100
+
+KPX Q period 20
+KPX Q comma 20
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -40
+KPX R V -50
+KPX R U -20
+KPX R T -20
+KPX R O -20
+
+KPX T y -60
+KPX T w -60
+KPX T u -90
+KPX T semicolon -40
+KPX T r -80
+KPX T period -80
+KPX T o -80
+KPX T hyphen -120
+KPX T e -60
+KPX T comma -80
+KPX T colon -40
+KPX T a -80
+KPX T O -40
+KPX T A -90
+
+KPX U period -30
+KPX U comma -30
+KPX U A -50
+
+KPX V u -60
+KPX V semicolon -40
+KPX V period -120
+KPX V o -90
+KPX V hyphen -80
+KPX V e -50
+KPX V comma -120
+KPX V colon -40
+KPX V a -60
+KPX V O -50
+KPX V G -50
+KPX V A -80
+
+KPX W y -20
+KPX W u -45
+KPX W semicolon -10
+KPX W period -80
+KPX W o -60
+KPX W hyphen -40
+KPX W e -35
+KPX W comma -80
+KPX W colon -10
+KPX W a -40
+KPX W O -20
+KPX W A -60
+
+KPX Y u -100
+KPX Y semicolon -50
+KPX Y period -100
+KPX Y o -100
+KPX Y e -80
+KPX Y comma -100
+KPX Y colon -50
+KPX Y a -90
+KPX Y O -70
+KPX Y A -110
+
+KPX a y -20
+KPX a w -15
+KPX a v -15
+KPX a g -10
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b l -10
+
+KPX c y -10
+KPX c l -20
+KPX c k -20
+KPX c h -10
+
+KPX colon space -40
+
+KPX comma space -40
+KPX comma quoteright -120
+KPX comma quotedblright -120
+
+KPX d y -15
+KPX d w -15
+KPX d v -15
+KPX d d -10
+
+KPX e y -15
+KPX e x -15
+KPX e w -15
+KPX e v -15
+KPX e period 20
+KPX e comma 10
+
+KPX f quoteright 30
+KPX f quotedblright 30
+KPX f period -10
+KPX f o -20
+KPX f e -10
+KPX f comma -10
+
+KPX g g -10
+KPX g e 10
+
+KPX h y -20
+
+KPX k o -15
+
+KPX l y -15
+KPX l w -15
+
+KPX m y -30
+KPX m u -20
+
+KPX n y -20
+KPX n v -40
+KPX n u -10
+
+KPX o y -20
+KPX o x -30
+KPX o w -15
+KPX o v -20
+
+KPX p y -15
+
+KPX period space -40
+KPX period quoteright -120
+KPX period quotedblright -120
+
+KPX quotedblright space -80
+
+KPX quoteleft quoteleft -46
+
+KPX quoteright v -20
+KPX quoteright space -80
+KPX quoteright s -60
+KPX quoteright r -40
+KPX quoteright quoteright -46
+KPX quoteright l -20
+KPX quoteright d -80
+
+KPX r y 10
+KPX r v 10
+KPX r t 20
+KPX r s -15
+KPX r q -20
+KPX r period -60
+KPX r o -20
+KPX r hyphen -20
+KPX r g -15
+KPX r d -20
+KPX r comma -60
+KPX r c -20
+
+KPX s w -15
+
+KPX semicolon space -40
+
+KPX space quoteleft -60
+KPX space quotedblleft -80
+KPX space Y -120
+KPX space W -80
+KPX space V -80
+KPX space T -100
+
+KPX v period -80
+KPX v o -30
+KPX v comma -80
+KPX v a -20
+
+KPX w period -40
+KPX w o -20
+KPX w comma -40
+
+KPX x e -10
+
+KPX y period -80
+KPX y o -25
+KPX y e -10
+KPX y comma -80
+KPX y a -30
+
+KPX z e 10
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 186 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 186 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 186 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 186 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 195 186 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 186 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 186 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 186 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 186 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 186 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 186 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 186 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 186 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 186 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 186 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 186 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 186 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 186 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 186 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 186 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 186 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 186 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 186 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 186 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 186 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 186 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 186 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 186 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Helvetica-BoldOblique.afm b/config/psfonts/Helvetica-BoldOblique.afm
new file mode 100644 (file)
index 0000000..b6cff41
--- /dev/null
@@ -0,0 +1,570 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Thu Mar 15 10:44:33 1990
+Comment UniqueID 28371
+Comment VMusage 7614 43068
+FontName Helvetica-BoldOblique
+FullName Helvetica Bold Oblique
+FamilyName Helvetica
+Weight Bold
+ItalicAngle -12
+IsFixedPitch false
+FontBBox -174 -228 1114 962
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 532
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ;
+C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ;
+C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ;
+C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ;
+C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ;
+C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ;
+C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ;
+C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ;
+C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ;
+C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ;
+C 43 ; WX 584 ; N plus ; B 82 0 610 506 ;
+C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ;
+C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ;
+C 46 ; WX 278 ; N period ; B 64 0 245 146 ;
+C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ;
+C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ;
+C 49 ; WX 556 ; N one ; B 173 0 529 710 ;
+C 50 ; WX 556 ; N two ; B 26 0 619 710 ;
+C 51 ; WX 556 ; N three ; B 65 -19 608 710 ;
+C 52 ; WX 556 ; N four ; B 60 0 598 710 ;
+C 53 ; WX 556 ; N five ; B 64 -19 636 698 ;
+C 54 ; WX 556 ; N six ; B 85 -19 619 710 ;
+C 55 ; WX 556 ; N seven ; B 125 0 676 698 ;
+C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ;
+C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ;
+C 58 ; WX 333 ; N colon ; B 92 0 351 512 ;
+C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ;
+C 60 ; WX 584 ; N less ; B 82 -8 655 514 ;
+C 61 ; WX 584 ; N equal ; B 58 87 633 419 ;
+C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ;
+C 63 ; WX 611 ; N question ; B 165 0 671 727 ;
+C 64 ; WX 975 ; N at ; B 186 -19 954 737 ;
+C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
+C 66 ; WX 722 ; N B ; B 76 0 764 718 ;
+C 67 ; WX 722 ; N C ; B 107 -19 789 737 ;
+C 68 ; WX 722 ; N D ; B 76 0 777 718 ;
+C 69 ; WX 667 ; N E ; B 76 0 757 718 ;
+C 70 ; WX 611 ; N F ; B 76 0 740 718 ;
+C 71 ; WX 778 ; N G ; B 108 -19 817 737 ;
+C 72 ; WX 722 ; N H ; B 71 0 804 718 ;
+C 73 ; WX 278 ; N I ; B 64 0 367 718 ;
+C 74 ; WX 556 ; N J ; B 60 -18 637 718 ;
+C 75 ; WX 722 ; N K ; B 87 0 858 718 ;
+C 76 ; WX 611 ; N L ; B 76 0 611 718 ;
+C 77 ; WX 833 ; N M ; B 69 0 918 718 ;
+C 78 ; WX 722 ; N N ; B 69 0 807 718 ;
+C 79 ; WX 778 ; N O ; B 107 -19 823 737 ;
+C 80 ; WX 667 ; N P ; B 76 0 738 718 ;
+C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ;
+C 82 ; WX 722 ; N R ; B 76 0 778 718 ;
+C 83 ; WX 667 ; N S ; B 81 -19 718 737 ;
+C 84 ; WX 611 ; N T ; B 140 0 751 718 ;
+C 85 ; WX 722 ; N U ; B 116 -19 804 718 ;
+C 86 ; WX 667 ; N V ; B 172 0 801 718 ;
+C 87 ; WX 944 ; N W ; B 169 0 1082 718 ;
+C 88 ; WX 667 ; N X ; B 14 0 791 718 ;
+C 89 ; WX 667 ; N Y ; B 168 0 806 718 ;
+C 90 ; WX 611 ; N Z ; B 25 0 737 718 ;
+C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ;
+C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ;
+C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ;
+C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ;
+C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ;
+C 97 ; WX 556 ; N a ; B 55 -14 583 546 ;
+C 98 ; WX 611 ; N b ; B 61 -14 645 718 ;
+C 99 ; WX 556 ; N c ; B 79 -14 599 546 ;
+C 100 ; WX 611 ; N d ; B 82 -14 704 718 ;
+C 101 ; WX 556 ; N e ; B 70 -14 593 546 ;
+C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 38 -217 666 546 ;
+C 104 ; WX 611 ; N h ; B 65 0 629 718 ;
+C 105 ; WX 278 ; N i ; B 69 0 363 725 ;
+C 106 ; WX 278 ; N j ; B -42 -214 363 725 ;
+C 107 ; WX 556 ; N k ; B 69 0 670 718 ;
+C 108 ; WX 278 ; N l ; B 69 0 362 718 ;
+C 109 ; WX 889 ; N m ; B 64 0 909 546 ;
+C 110 ; WX 611 ; N n ; B 65 0 629 546 ;
+C 111 ; WX 611 ; N o ; B 82 -14 643 546 ;
+C 112 ; WX 611 ; N p ; B 18 -207 645 546 ;
+C 113 ; WX 611 ; N q ; B 80 -207 665 546 ;
+C 114 ; WX 389 ; N r ; B 64 0 489 546 ;
+C 115 ; WX 556 ; N s ; B 63 -14 584 546 ;
+C 116 ; WX 333 ; N t ; B 100 -6 422 676 ;
+C 117 ; WX 611 ; N u ; B 98 -14 658 532 ;
+C 118 ; WX 556 ; N v ; B 126 0 656 532 ;
+C 119 ; WX 778 ; N w ; B 123 0 882 532 ;
+C 120 ; WX 556 ; N x ; B 15 0 648 532 ;
+C 121 ; WX 556 ; N y ; B 42 -214 652 532 ;
+C 122 ; WX 500 ; N z ; B 20 0 583 532 ;
+C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ;
+C 124 ; WX 280 ; N bar ; B 80 -19 353 737 ;
+C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ;
+C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ;
+C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ;
+C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ;
+C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ;
+C 165 ; WX 556 ; N yen ; B 60 0 713 698 ;
+C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ;
+C 167 ; WX 556 ; N section ; B 61 -184 598 727 ;
+C 168 ; WX 556 ; N currency ; B 27 76 680 636 ;
+C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ;
+C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ;
+C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ;
+C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ;
+C 174 ; WX 611 ; N fi ; B 87 0 696 727 ;
+C 175 ; WX 611 ; N fl ; B 87 0 695 727 ;
+C 177 ; WX 556 ; N endash ; B 48 227 627 333 ;
+C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ;
+C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ;
+C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ;
+C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ;
+C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ;
+C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ;
+C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ;
+C 193 ; WX 333 ; N grave ; B 136 604 353 750 ;
+C 194 ; WX 333 ; N acute ; B 236 604 515 750 ;
+C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ;
+C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ;
+C 197 ; WX 333 ; N macron ; B 122 604 483 678 ;
+C 198 ; WX 333 ; N breve ; B 156 604 494 750 ;
+C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ;
+C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ;
+C 202 ; WX 333 ; N ring ; B 200 568 420 776 ;
+C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ;
+C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ;
+C 207 ; WX 333 ; N caron ; B 149 604 502 750 ;
+C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ;
+C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 92 276 465 737 ;
+C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ;
+C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ;
+C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 92 276 485 737 ;
+C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ;
+C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ;
+C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ;
+C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ;
+C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ;
+C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ;
+C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ;
+C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ;
+C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ;
+C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ;
+C -1 ; WX 333 ; N threesuperior ; B 91 271 441 710 ;
+C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ;
+C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ;
+C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ;
+C -1 ; WX 333 ; N twosuperior ; B 69 283 449 710 ;
+C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ;
+C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ;
+C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ;
+C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ;
+C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ;
+C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ;
+C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ;
+C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ;
+C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ;
+C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ;
+C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ;
+C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ;
+C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ;
+C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ;
+C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ;
+C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ;
+C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ;
+C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ;
+C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ;
+C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ;
+C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ;
+C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ;
+C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ;
+C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ;
+C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ;
+C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ;
+C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ;
+C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ;
+C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ;
+C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ;
+C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ;
+C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ;
+C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ;
+C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ;
+C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ;
+C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ;
+C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ;
+C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ;
+C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ;
+C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ;
+C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ;
+C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
+C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ;
+C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ;
+C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ;
+C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ;
+C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ;
+C -1 ; WX 584 ; N minus ; B 82 197 610 309 ;
+C -1 ; WX 333 ; N onesuperior ; B 148 283 388 710 ;
+C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ;
+C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ;
+C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
+C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ;
+C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ;
+C -1 ; WX 400 ; N degree ; B 175 426 467 712 ;
+C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ;
+C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ;
+C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ;
+C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ;
+C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ;
+C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ;
+C -1 ; WX 280 ; N brokenbar ; B 80 -19 353 737 ;
+C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 209
+
+KPX A y -30
+KPX A w -30
+KPX A v -40
+KPX A u -30
+KPX A Y -110
+KPX A W -60
+KPX A V -80
+KPX A U -50
+KPX A T -90
+KPX A Q -40
+KPX A O -40
+KPX A G -50
+KPX A C -40
+
+KPX B U -10
+KPX B A -30
+
+KPX D period -30
+KPX D comma -30
+KPX D Y -70
+KPX D W -40
+KPX D V -40
+KPX D A -40
+
+KPX F period -100
+KPX F comma -100
+KPX F a -20
+KPX F A -80
+
+KPX J u -20
+KPX J period -20
+KPX J comma -20
+KPX J A -20
+
+KPX K y -40
+KPX K u -30
+KPX K o -35
+KPX K e -15
+KPX K O -30
+
+KPX L y -30
+KPX L quoteright -140
+KPX L quotedblright -140
+KPX L Y -120
+KPX L W -80
+KPX L V -110
+KPX L T -90
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -50
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -50
+
+KPX P period -120
+KPX P o -40
+KPX P e -30
+KPX P comma -120
+KPX P a -30
+KPX P A -100
+
+KPX Q period 20
+KPX Q comma 20
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -40
+KPX R V -50
+KPX R U -20
+KPX R T -20
+KPX R O -20
+
+KPX T y -60
+KPX T w -60
+KPX T u -90
+KPX T semicolon -40
+KPX T r -80
+KPX T period -80
+KPX T o -80
+KPX T hyphen -120
+KPX T e -60
+KPX T comma -80
+KPX T colon -40
+KPX T a -80
+KPX T O -40
+KPX T A -90
+
+KPX U period -30
+KPX U comma -30
+KPX U A -50
+
+KPX V u -60
+KPX V semicolon -40
+KPX V period -120
+KPX V o -90
+KPX V hyphen -80
+KPX V e -50
+KPX V comma -120
+KPX V colon -40
+KPX V a -60
+KPX V O -50
+KPX V G -50
+KPX V A -80
+
+KPX W y -20
+KPX W u -45
+KPX W semicolon -10
+KPX W period -80
+KPX W o -60
+KPX W hyphen -40
+KPX W e -35
+KPX W comma -80
+KPX W colon -10
+KPX W a -40
+KPX W O -20
+KPX W A -60
+
+KPX Y u -100
+KPX Y semicolon -50
+KPX Y period -100
+KPX Y o -100
+KPX Y e -80
+KPX Y comma -100
+KPX Y colon -50
+KPX Y a -90
+KPX Y O -70
+KPX Y A -110
+
+KPX a y -20
+KPX a w -15
+KPX a v -15
+KPX a g -10
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b l -10
+
+KPX c y -10
+KPX c l -20
+KPX c k -20
+KPX c h -10
+
+KPX colon space -40
+
+KPX comma space -40
+KPX comma quoteright -120
+KPX comma quotedblright -120
+
+KPX d y -15
+KPX d w -15
+KPX d v -15
+KPX d d -10
+
+KPX e y -15
+KPX e x -15
+KPX e w -15
+KPX e v -15
+KPX e period 20
+KPX e comma 10
+
+KPX f quoteright 30
+KPX f quotedblright 30
+KPX f period -10
+KPX f o -20
+KPX f e -10
+KPX f comma -10
+
+KPX g g -10
+KPX g e 10
+
+KPX h y -20
+
+KPX k o -15
+
+KPX l y -15
+KPX l w -15
+
+KPX m y -30
+KPX m u -20
+
+KPX n y -20
+KPX n v -40
+KPX n u -10
+
+KPX o y -20
+KPX o x -30
+KPX o w -15
+KPX o v -20
+
+KPX p y -15
+
+KPX period space -40
+KPX period quoteright -120
+KPX period quotedblright -120
+
+KPX quotedblright space -80
+
+KPX quoteleft quoteleft -46
+
+KPX quoteright v -20
+KPX quoteright space -80
+KPX quoteright s -60
+KPX quoteright r -40
+KPX quoteright quoteright -46
+KPX quoteright l -20
+KPX quoteright d -80
+
+KPX r y 10
+KPX r v 10
+KPX r t 20
+KPX r s -15
+KPX r q -20
+KPX r period -60
+KPX r o -20
+KPX r hyphen -20
+KPX r g -15
+KPX r d -20
+KPX r comma -60
+KPX r c -20
+
+KPX s w -15
+
+KPX semicolon space -40
+
+KPX space quoteleft -60
+KPX space quotedblleft -80
+KPX space Y -120
+KPX space W -80
+KPX space V -80
+KPX space T -100
+
+KPX v period -80
+KPX v o -30
+KPX v comma -80
+KPX v a -20
+
+KPX w period -40
+KPX w o -20
+KPX w comma -40
+
+KPX x e -10
+
+KPX y period -80
+KPX y o -25
+KPX y e -10
+KPX y comma -80
+KPX y a -30
+
+KPX z e 10
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 235 186 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 235 186 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 235 186 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 235 186 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 235 186 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 235 186 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 207 186 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 207 186 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 207 186 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 207 186 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 13 186 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 13 186 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 13 186 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 13 186 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 235 186 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 263 186 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 263 186 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 263 186 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 263 186 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 263 186 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 207 186 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 235 186 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 235 186 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 186 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 235 186 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 207 186 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 207 186 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 186 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Helvetica-Oblique.afm b/config/psfonts/Helvetica-Oblique.afm
new file mode 100644 (file)
index 0000000..3d69eb7
--- /dev/null
@@ -0,0 +1,612 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.
+Comment Creation Date: Thu Mar 15 10:24:18 1990
+Comment UniqueID 28362
+Comment VMusage 7572 42473
+FontName Helvetica-Oblique
+FullName Helvetica Oblique
+FamilyName Helvetica
+Weight Medium
+ItalicAngle -12
+IsFixedPitch false
+FontBBox -170 -225 1116 931
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.006
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 523
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ;
+C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ;
+C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ;
+C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ;
+C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ;
+C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ;
+C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ;
+C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ;
+C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ;
+C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ;
+C 43 ; WX 584 ; N plus ; B 85 0 606 505 ;
+C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ;
+C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ;
+C 46 ; WX 278 ; N period ; B 87 0 214 106 ;
+C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ;
+C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ;
+C 49 ; WX 556 ; N one ; B 207 0 508 703 ;
+C 50 ; WX 556 ; N two ; B 26 0 617 703 ;
+C 51 ; WX 556 ; N three ; B 75 -19 610 703 ;
+C 52 ; WX 556 ; N four ; B 61 0 576 703 ;
+C 53 ; WX 556 ; N five ; B 68 -19 621 688 ;
+C 54 ; WX 556 ; N six ; B 91 -19 615 703 ;
+C 55 ; WX 556 ; N seven ; B 137 0 669 688 ;
+C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ;
+C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ;
+C 58 ; WX 278 ; N colon ; B 87 0 301 516 ;
+C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ;
+C 60 ; WX 584 ; N less ; B 94 11 641 495 ;
+C 61 ; WX 584 ; N equal ; B 63 115 628 390 ;
+C 62 ; WX 584 ; N greater ; B 50 11 597 495 ;
+C 63 ; WX 556 ; N question ; B 161 0 610 727 ;
+C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ;
+C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
+C 66 ; WX 667 ; N B ; B 74 0 712 718 ;
+C 67 ; WX 722 ; N C ; B 108 -19 782 737 ;
+C 68 ; WX 722 ; N D ; B 81 0 764 718 ;
+C 69 ; WX 667 ; N E ; B 86 0 762 718 ;
+C 70 ; WX 611 ; N F ; B 86 0 736 718 ;
+C 71 ; WX 778 ; N G ; B 111 -19 799 737 ;
+C 72 ; WX 722 ; N H ; B 77 0 799 718 ;
+C 73 ; WX 278 ; N I ; B 91 0 341 718 ;
+C 74 ; WX 500 ; N J ; B 47 -19 581 718 ;
+C 75 ; WX 667 ; N K ; B 76 0 808 718 ;
+C 76 ; WX 556 ; N L ; B 76 0 555 718 ;
+C 77 ; WX 833 ; N M ; B 73 0 914 718 ;
+C 78 ; WX 722 ; N N ; B 76 0 799 718 ;
+C 79 ; WX 778 ; N O ; B 105 -19 826 737 ;
+C 80 ; WX 667 ; N P ; B 86 0 737 718 ;
+C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ;
+C 82 ; WX 722 ; N R ; B 88 0 773 718 ;
+C 83 ; WX 667 ; N S ; B 90 -19 713 737 ;
+C 84 ; WX 611 ; N T ; B 148 0 750 718 ;
+C 85 ; WX 722 ; N U ; B 123 -19 797 718 ;
+C 86 ; WX 667 ; N V ; B 173 0 800 718 ;
+C 87 ; WX 944 ; N W ; B 169 0 1081 718 ;
+C 88 ; WX 667 ; N X ; B 19 0 790 718 ;
+C 89 ; WX 667 ; N Y ; B 167 0 806 718 ;
+C 90 ; WX 611 ; N Z ; B 23 0 741 718 ;
+C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ;
+C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ;
+C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ;
+C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ;
+C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
+C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ;
+C 97 ; WX 556 ; N a ; B 61 -15 559 538 ;
+C 98 ; WX 556 ; N b ; B 58 -15 584 718 ;
+C 99 ; WX 500 ; N c ; B 74 -15 553 538 ;
+C 100 ; WX 556 ; N d ; B 84 -15 652 718 ;
+C 101 ; WX 556 ; N e ; B 84 -15 578 538 ;
+C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 42 -220 610 538 ;
+C 104 ; WX 556 ; N h ; B 65 0 573 718 ;
+C 105 ; WX 222 ; N i ; B 67 0 308 718 ;
+C 106 ; WX 222 ; N j ; B -60 -210 308 718 ;
+C 107 ; WX 500 ; N k ; B 67 0 600 718 ;
+C 108 ; WX 222 ; N l ; B 67 0 308 718 ;
+C 109 ; WX 833 ; N m ; B 65 0 852 538 ;
+C 110 ; WX 556 ; N n ; B 65 0 573 538 ;
+C 111 ; WX 556 ; N o ; B 83 -14 585 538 ;
+C 112 ; WX 556 ; N p ; B 14 -207 584 538 ;
+C 113 ; WX 556 ; N q ; B 84 -207 605 538 ;
+C 114 ; WX 333 ; N r ; B 77 0 446 538 ;
+C 115 ; WX 500 ; N s ; B 63 -15 529 538 ;
+C 116 ; WX 278 ; N t ; B 102 -7 368 669 ;
+C 117 ; WX 556 ; N u ; B 94 -15 600 523 ;
+C 118 ; WX 500 ; N v ; B 119 0 603 523 ;
+C 119 ; WX 722 ; N w ; B 125 0 820 523 ;
+C 120 ; WX 500 ; N x ; B 11 0 594 523 ;
+C 121 ; WX 500 ; N y ; B 15 -214 600 523 ;
+C 122 ; WX 500 ; N z ; B 31 0 571 523 ;
+C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ;
+C 124 ; WX 260 ; N bar ; B 90 -19 324 737 ;
+C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ;
+C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ;
+C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ;
+C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ;
+C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ;
+C 165 ; WX 556 ; N yen ; B 81 0 699 688 ;
+C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ;
+C 167 ; WX 556 ; N section ; B 76 -191 584 737 ;
+C 168 ; WX 556 ; N currency ; B 60 99 646 603 ;
+C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ;
+C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ;
+C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ;
+C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ;
+C 174 ; WX 500 ; N fi ; B 86 0 587 728 ;
+C 175 ; WX 500 ; N fl ; B 86 0 585 728 ;
+C 177 ; WX 556 ; N endash ; B 51 240 623 313 ;
+C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ;
+C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ;
+C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ;
+C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ;
+C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ;
+C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ;
+C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ;
+C 193 ; WX 333 ; N grave ; B 170 593 337 734 ;
+C 194 ; WX 333 ; N acute ; B 248 593 475 734 ;
+C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ;
+C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ;
+C 197 ; WX 333 ; N macron ; B 143 627 468 684 ;
+C 198 ; WX 333 ; N breve ; B 167 595 476 731 ;
+C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ;
+C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ;
+C 202 ; WX 333 ; N ring ; B 214 572 402 756 ;
+C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ;
+C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ;
+C 207 ; WX 333 ; N caron ; B 177 593 468 734 ;
+C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ;
+C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 100 304 449 737 ;
+C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ;
+C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ;
+C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 100 304 468 737 ;
+C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ;
+C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ;
+C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ;
+C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ;
+C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ;
+C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ;
+C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ;
+C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ;
+C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ;
+C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ;
+C -1 ; WX 333 ; N threesuperior ; B 90 270 436 703 ;
+C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ;
+C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ;
+C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ;
+C -1 ; WX 333 ; N twosuperior ; B 64 281 449 703 ;
+C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ;
+C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ;
+C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ;
+C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ;
+C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ;
+C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ;
+C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ;
+C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ;
+C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ;
+C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ;
+C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ;
+C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ;
+C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ;
+C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ;
+C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ;
+C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ;
+C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ;
+C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ;
+C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ;
+C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ;
+C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ;
+C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ;
+C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ;
+C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ;
+C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ;
+C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ;
+C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ;
+C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ;
+C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ;
+C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ;
+C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ;
+C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ;
+C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ;
+C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ;
+C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ;
+C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ;
+C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ;
+C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ;
+C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ;
+C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ;
+C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
+C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ;
+C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ;
+C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ;
+C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ;
+C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ;
+C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ;
+C -1 ; WX 584 ; N minus ; B 85 216 606 289 ;
+C -1 ; WX 333 ; N onesuperior ; B 166 281 371 703 ;
+C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ;
+C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
+C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ;
+C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
+C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ;
+C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ;
+C -1 ; WX 400 ; N degree ; B 169 411 468 703 ;
+C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ;
+C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ;
+C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ;
+C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ;
+C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
+C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ;
+C -1 ; WX 260 ; N brokenbar ; B 90 -19 324 737 ;
+C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 250
+
+KPX A y -40
+KPX A w -40
+KPX A v -40
+KPX A u -30
+KPX A Y -100
+KPX A W -50
+KPX A V -70
+KPX A U -50
+KPX A T -120
+KPX A Q -30
+KPX A O -30
+KPX A G -30
+KPX A C -30
+
+KPX B period -20
+KPX B comma -20
+KPX B U -10
+
+KPX C period -30
+KPX C comma -30
+
+KPX D period -70
+KPX D comma -70
+KPX D Y -90
+KPX D W -40
+KPX D V -70
+KPX D A -40
+
+KPX F r -45
+KPX F period -150
+KPX F o -30
+KPX F e -30
+KPX F comma -150
+KPX F a -50
+KPX F A -80
+
+KPX J u -20
+KPX J period -30
+KPX J comma -30
+KPX J a -20
+KPX J A -20
+
+KPX K y -50
+KPX K u -30
+KPX K o -40
+KPX K e -40
+KPX K O -50
+
+KPX L y -30
+KPX L quoteright -160
+KPX L quotedblright -140
+KPX L Y -140
+KPX L W -70
+KPX L V -110
+KPX L T -110
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -60
+KPX O W -30
+KPX O V -50
+KPX O T -40
+KPX O A -20
+
+KPX P period -180
+KPX P o -50
+KPX P e -50
+KPX P comma -180
+KPX P a -40
+KPX P A -120
+
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -30
+KPX R V -50
+KPX R U -40
+KPX R T -30
+KPX R O -20
+
+KPX S period -20
+KPX S comma -20
+
+KPX T y -120
+KPX T w -120
+KPX T u -120
+KPX T semicolon -20
+KPX T r -120
+KPX T period -120
+KPX T o -120
+KPX T hyphen -140
+KPX T e -120
+KPX T comma -120
+KPX T colon -20
+KPX T a -120
+KPX T O -40
+KPX T A -120
+
+KPX U period -40
+KPX U comma -40
+KPX U A -40
+
+KPX V u -70
+KPX V semicolon -40
+KPX V period -125
+KPX V o -80
+KPX V hyphen -80
+KPX V e -80
+KPX V comma -125
+KPX V colon -40
+KPX V a -70
+KPX V O -40
+KPX V G -40
+KPX V A -80
+
+KPX W y -20
+KPX W u -30
+KPX W period -80
+KPX W o -30
+KPX W hyphen -40
+KPX W e -30
+KPX W comma -80
+KPX W a -40
+KPX W O -20
+KPX W A -50
+
+KPX Y u -110
+KPX Y semicolon -60
+KPX Y period -140
+KPX Y o -140
+KPX Y i -20
+KPX Y hyphen -140
+KPX Y e -140
+KPX Y comma -140
+KPX Y colon -60
+KPX Y a -140
+KPX Y O -85
+KPX Y A -110
+
+KPX a y -30
+KPX a w -20
+KPX a v -20
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b period -40
+KPX b l -20
+KPX b comma -40
+KPX b b -10
+
+KPX c k -20
+KPX c comma -15
+
+KPX colon space -50
+
+KPX comma quoteright -100
+KPX comma quotedblright -100
+
+KPX e y -20
+KPX e x -30
+KPX e w -20
+KPX e v -30
+KPX e period -15
+KPX e comma -15
+
+KPX f quoteright 50
+KPX f quotedblright 60
+KPX f period -30
+KPX f o -30
+KPX f e -30
+KPX f dotlessi -28
+KPX f comma -30
+KPX f a -30
+
+KPX g r -10
+
+KPX h y -30
+
+KPX k o -20
+KPX k e -20
+
+KPX m y -15
+KPX m u -10
+
+KPX n y -15
+KPX n v -20
+KPX n u -10
+
+KPX o y -30
+KPX o x -30
+KPX o w -15
+KPX o v -15
+KPX o period -40
+KPX o comma -40
+
+KPX oslash z -55
+KPX oslash y -70
+KPX oslash x -85
+KPX oslash w -70
+KPX oslash v -70
+KPX oslash u -55
+KPX oslash t -55
+KPX oslash s -55
+KPX oslash r -55
+KPX oslash q -55
+KPX oslash period -95
+KPX oslash p -55
+KPX oslash o -55
+KPX oslash n -55
+KPX oslash m -55
+KPX oslash l -55
+KPX oslash k -55
+KPX oslash j -55
+KPX oslash i -55
+KPX oslash h -55
+KPX oslash g -55
+KPX oslash f -55
+KPX oslash e -55
+KPX oslash d -55
+KPX oslash comma -95
+KPX oslash c -55
+KPX oslash b -55
+KPX oslash a -55
+
+KPX p y -30
+KPX p period -35
+KPX p comma -35
+
+KPX period space -60
+KPX period quoteright -100
+KPX period quotedblright -100
+
+KPX quotedblright space -40
+
+KPX quoteleft quoteleft -57
+
+KPX quoteright space -70
+KPX quoteright s -50
+KPX quoteright r -50
+KPX quoteright quoteright -57
+KPX quoteright d -50
+
+KPX r y 30
+KPX r v 30
+KPX r u 15
+KPX r t 40
+KPX r semicolon 30
+KPX r period -50
+KPX r p 30
+KPX r n 25
+KPX r m 25
+KPX r l 15
+KPX r k 15
+KPX r i 15
+KPX r comma -50
+KPX r colon 30
+KPX r a -10
+
+KPX s w -30
+KPX s period -15
+KPX s comma -15
+
+KPX semicolon space -50
+
+KPX space quoteleft -60
+KPX space quotedblleft -30
+KPX space Y -90
+KPX space W -40
+KPX space V -50
+KPX space T -50
+
+KPX v period -80
+KPX v o -25
+KPX v e -25
+KPX v comma -80
+KPX v a -25
+
+KPX w period -60
+KPX w o -10
+KPX w e -10
+KPX w comma -60
+KPX w a -15
+
+KPX x e -30
+
+KPX y period -100
+KPX y o -20
+KPX y e -20
+KPX y comma -100
+KPX y a -20
+
+KPX z o -15
+KPX z e -15
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 208 195 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 208 195 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 208 195 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 208 195 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 204 175 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 208 195 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 208 195 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 208 195 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 208 195 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 208 195 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 14 195 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 14 195 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 14 195 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 14 195 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 246 195 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 264 195 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 264 195 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 264 195 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 264 195 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 264 195 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 208 195 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 236 195 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 236 195 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 236 195 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 236 195 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 208 195 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 208 195 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 180 195 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Helvetica.afm b/config/psfonts/Helvetica.afm
new file mode 100644 (file)
index 0000000..1eb3b44
--- /dev/null
@@ -0,0 +1,612 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.
+Comment Creation Date: Thu Mar 15 08:58:00 1990
+Comment UniqueID 28352
+Comment VMusage 26389 33281
+FontName Helvetica
+FullName Helvetica
+FamilyName Helvetica
+Weight Medium
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -166 -225 1000 931
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.006
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 523
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ;
+C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ;
+C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ;
+C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ;
+C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ;
+C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ;
+C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ;
+C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ;
+C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ;
+C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ;
+C 43 ; WX 584 ; N plus ; B 39 0 545 505 ;
+C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ;
+C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ;
+C 46 ; WX 278 ; N period ; B 87 0 191 106 ;
+C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ;
+C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ;
+C 49 ; WX 556 ; N one ; B 101 0 359 703 ;
+C 50 ; WX 556 ; N two ; B 26 0 507 703 ;
+C 51 ; WX 556 ; N three ; B 34 -19 522 703 ;
+C 52 ; WX 556 ; N four ; B 25 0 523 703 ;
+C 53 ; WX 556 ; N five ; B 32 -19 514 688 ;
+C 54 ; WX 556 ; N six ; B 38 -19 518 703 ;
+C 55 ; WX 556 ; N seven ; B 37 0 523 688 ;
+C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ;
+C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ;
+C 58 ; WX 278 ; N colon ; B 87 0 191 516 ;
+C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ;
+C 60 ; WX 584 ; N less ; B 48 11 536 495 ;
+C 61 ; WX 584 ; N equal ; B 39 115 545 390 ;
+C 62 ; WX 584 ; N greater ; B 48 11 536 495 ;
+C 63 ; WX 556 ; N question ; B 56 0 492 727 ;
+C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ;
+C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
+C 66 ; WX 667 ; N B ; B 74 0 627 718 ;
+C 67 ; WX 722 ; N C ; B 44 -19 681 737 ;
+C 68 ; WX 722 ; N D ; B 81 0 674 718 ;
+C 69 ; WX 667 ; N E ; B 86 0 616 718 ;
+C 70 ; WX 611 ; N F ; B 86 0 583 718 ;
+C 71 ; WX 778 ; N G ; B 48 -19 704 737 ;
+C 72 ; WX 722 ; N H ; B 77 0 646 718 ;
+C 73 ; WX 278 ; N I ; B 91 0 188 718 ;
+C 74 ; WX 500 ; N J ; B 17 -19 428 718 ;
+C 75 ; WX 667 ; N K ; B 76 0 663 718 ;
+C 76 ; WX 556 ; N L ; B 76 0 537 718 ;
+C 77 ; WX 833 ; N M ; B 73 0 761 718 ;
+C 78 ; WX 722 ; N N ; B 76 0 646 718 ;
+C 79 ; WX 778 ; N O ; B 39 -19 739 737 ;
+C 80 ; WX 667 ; N P ; B 86 0 622 718 ;
+C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ;
+C 82 ; WX 722 ; N R ; B 88 0 684 718 ;
+C 83 ; WX 667 ; N S ; B 49 -19 620 737 ;
+C 84 ; WX 611 ; N T ; B 14 0 597 718 ;
+C 85 ; WX 722 ; N U ; B 79 -19 644 718 ;
+C 86 ; WX 667 ; N V ; B 20 0 647 718 ;
+C 87 ; WX 944 ; N W ; B 16 0 928 718 ;
+C 88 ; WX 667 ; N X ; B 19 0 648 718 ;
+C 89 ; WX 667 ; N Y ; B 14 0 653 718 ;
+C 90 ; WX 611 ; N Z ; B 23 0 588 718 ;
+C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ;
+C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ;
+C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ;
+C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ;
+C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
+C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ;
+C 97 ; WX 556 ; N a ; B 36 -15 530 538 ;
+C 98 ; WX 556 ; N b ; B 58 -15 517 718 ;
+C 99 ; WX 500 ; N c ; B 30 -15 477 538 ;
+C 100 ; WX 556 ; N d ; B 35 -15 499 718 ;
+C 101 ; WX 556 ; N e ; B 40 -15 516 538 ;
+C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 40 -220 499 538 ;
+C 104 ; WX 556 ; N h ; B 65 0 491 718 ;
+C 105 ; WX 222 ; N i ; B 67 0 155 718 ;
+C 106 ; WX 222 ; N j ; B -16 -210 155 718 ;
+C 107 ; WX 500 ; N k ; B 67 0 501 718 ;
+C 108 ; WX 222 ; N l ; B 67 0 155 718 ;
+C 109 ; WX 833 ; N m ; B 65 0 769 538 ;
+C 110 ; WX 556 ; N n ; B 65 0 491 538 ;
+C 111 ; WX 556 ; N o ; B 35 -14 521 538 ;
+C 112 ; WX 556 ; N p ; B 58 -207 517 538 ;
+C 113 ; WX 556 ; N q ; B 35 -207 494 538 ;
+C 114 ; WX 333 ; N r ; B 77 0 332 538 ;
+C 115 ; WX 500 ; N s ; B 32 -15 464 538 ;
+C 116 ; WX 278 ; N t ; B 14 -7 257 669 ;
+C 117 ; WX 556 ; N u ; B 68 -15 489 523 ;
+C 118 ; WX 500 ; N v ; B 8 0 492 523 ;
+C 119 ; WX 722 ; N w ; B 14 0 709 523 ;
+C 120 ; WX 500 ; N x ; B 11 0 490 523 ;
+C 121 ; WX 500 ; N y ; B 11 -214 489 523 ;
+C 122 ; WX 500 ; N z ; B 31 0 469 523 ;
+C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ;
+C 124 ; WX 260 ; N bar ; B 94 -19 167 737 ;
+C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ;
+C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ;
+C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ;
+C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ;
+C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ;
+C 165 ; WX 556 ; N yen ; B 3 0 553 688 ;
+C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ;
+C 167 ; WX 556 ; N section ; B 43 -191 512 737 ;
+C 168 ; WX 556 ; N currency ; B 28 99 528 603 ;
+C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ;
+C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ;
+C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ;
+C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ;
+C 174 ; WX 500 ; N fi ; B 14 0 434 728 ;
+C 175 ; WX 500 ; N fl ; B 14 0 432 728 ;
+C 177 ; WX 556 ; N endash ; B 0 240 556 313 ;
+C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ;
+C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ;
+C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ;
+C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ;
+C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ;
+C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ;
+C 193 ; WX 333 ; N grave ; B 14 593 211 734 ;
+C 194 ; WX 333 ; N acute ; B 122 593 319 734 ;
+C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ;
+C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ;
+C 197 ; WX 333 ; N macron ; B 10 627 323 684 ;
+C 198 ; WX 333 ; N breve ; B 13 595 321 731 ;
+C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ;
+C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ;
+C 202 ; WX 333 ; N ring ; B 75 572 259 756 ;
+C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ;
+C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ;
+C 207 ; WX 333 ; N caron ; B 21 593 312 734 ;
+C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ;
+C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 24 304 346 737 ;
+C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ;
+C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ;
+C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 25 304 341 737 ;
+C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ;
+C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ;
+C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ;
+C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ;
+C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ;
+C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ;
+C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ;
+C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ;
+C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ;
+C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ;
+C -1 ; WX 333 ; N threesuperior ; B 5 270 325 703 ;
+C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ;
+C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ;
+C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ;
+C -1 ; WX 333 ; N twosuperior ; B 4 281 323 703 ;
+C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ;
+C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ;
+C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ;
+C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ;
+C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ;
+C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ;
+C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ;
+C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ;
+C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ;
+C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ;
+C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ;
+C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ;
+C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ;
+C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ;
+C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ;
+C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ;
+C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ;
+C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ;
+C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ;
+C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ;
+C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ;
+C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ;
+C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ;
+C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ;
+C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ;
+C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ;
+C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ;
+C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ;
+C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ;
+C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ;
+C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ;
+C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ;
+C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ;
+C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ;
+C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ;
+C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ;
+C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ;
+C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ;
+C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ;
+C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ;
+C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
+C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ;
+C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ;
+C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ;
+C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ;
+C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ;
+C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ;
+C -1 ; WX 584 ; N minus ; B 39 216 545 289 ;
+C -1 ; WX 333 ; N onesuperior ; B 43 281 222 703 ;
+C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ;
+C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
+C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ;
+C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
+C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ;
+C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ;
+C -1 ; WX 400 ; N degree ; B 54 411 346 703 ;
+C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ;
+C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ;
+C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ;
+C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ;
+C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
+C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ;
+C -1 ; WX 260 ; N brokenbar ; B 94 -19 167 737 ;
+C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 250
+
+KPX A y -40
+KPX A w -40
+KPX A v -40
+KPX A u -30
+KPX A Y -100
+KPX A W -50
+KPX A V -70
+KPX A U -50
+KPX A T -120
+KPX A Q -30
+KPX A O -30
+KPX A G -30
+KPX A C -30
+
+KPX B period -20
+KPX B comma -20
+KPX B U -10
+
+KPX C period -30
+KPX C comma -30
+
+KPX D period -70
+KPX D comma -70
+KPX D Y -90
+KPX D W -40
+KPX D V -70
+KPX D A -40
+
+KPX F r -45
+KPX F period -150
+KPX F o -30
+KPX F e -30
+KPX F comma -150
+KPX F a -50
+KPX F A -80
+
+KPX J u -20
+KPX J period -30
+KPX J comma -30
+KPX J a -20
+KPX J A -20
+
+KPX K y -50
+KPX K u -30
+KPX K o -40
+KPX K e -40
+KPX K O -50
+
+KPX L y -30
+KPX L quoteright -160
+KPX L quotedblright -140
+KPX L Y -140
+KPX L W -70
+KPX L V -110
+KPX L T -110
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -60
+KPX O W -30
+KPX O V -50
+KPX O T -40
+KPX O A -20
+
+KPX P period -180
+KPX P o -50
+KPX P e -50
+KPX P comma -180
+KPX P a -40
+KPX P A -120
+
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -30
+KPX R V -50
+KPX R U -40
+KPX R T -30
+KPX R O -20
+
+KPX S period -20
+KPX S comma -20
+
+KPX T y -120
+KPX T w -120
+KPX T u -120
+KPX T semicolon -20
+KPX T r -120
+KPX T period -120
+KPX T o -120
+KPX T hyphen -140
+KPX T e -120
+KPX T comma -120
+KPX T colon -20
+KPX T a -120
+KPX T O -40
+KPX T A -120
+
+KPX U period -40
+KPX U comma -40
+KPX U A -40
+
+KPX V u -70
+KPX V semicolon -40
+KPX V period -125
+KPX V o -80
+KPX V hyphen -80
+KPX V e -80
+KPX V comma -125
+KPX V colon -40
+KPX V a -70
+KPX V O -40
+KPX V G -40
+KPX V A -80
+
+KPX W y -20
+KPX W u -30
+KPX W period -80
+KPX W o -30
+KPX W hyphen -40
+KPX W e -30
+KPX W comma -80
+KPX W a -40
+KPX W O -20
+KPX W A -50
+
+KPX Y u -110
+KPX Y semicolon -60
+KPX Y period -140
+KPX Y o -140
+KPX Y i -20
+KPX Y hyphen -140
+KPX Y e -140
+KPX Y comma -140
+KPX Y colon -60
+KPX Y a -140
+KPX Y O -85
+KPX Y A -110
+
+KPX a y -30
+KPX a w -20
+KPX a v -20
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b period -40
+KPX b l -20
+KPX b comma -40
+KPX b b -10
+
+KPX c k -20
+KPX c comma -15
+
+KPX colon space -50
+
+KPX comma quoteright -100
+KPX comma quotedblright -100
+
+KPX e y -20
+KPX e x -30
+KPX e w -20
+KPX e v -30
+KPX e period -15
+KPX e comma -15
+
+KPX f quoteright 50
+KPX f quotedblright 60
+KPX f period -30
+KPX f o -30
+KPX f e -30
+KPX f dotlessi -28
+KPX f comma -30
+KPX f a -30
+
+KPX g r -10
+
+KPX h y -30
+
+KPX k o -20
+KPX k e -20
+
+KPX m y -15
+KPX m u -10
+
+KPX n y -15
+KPX n v -20
+KPX n u -10
+
+KPX o y -30
+KPX o x -30
+KPX o w -15
+KPX o v -15
+KPX o period -40
+KPX o comma -40
+
+KPX oslash z -55
+KPX oslash y -70
+KPX oslash x -85
+KPX oslash w -70
+KPX oslash v -70
+KPX oslash u -55
+KPX oslash t -55
+KPX oslash s -55
+KPX oslash r -55
+KPX oslash q -55
+KPX oslash period -95
+KPX oslash p -55
+KPX oslash o -55
+KPX oslash n -55
+KPX oslash m -55
+KPX oslash l -55
+KPX oslash k -55
+KPX oslash j -55
+KPX oslash i -55
+KPX oslash h -55
+KPX oslash g -55
+KPX oslash f -55
+KPX oslash e -55
+KPX oslash d -55
+KPX oslash comma -95
+KPX oslash c -55
+KPX oslash b -55
+KPX oslash a -55
+
+KPX p y -30
+KPX p period -35
+KPX p comma -35
+
+KPX period space -60
+KPX period quoteright -100
+KPX period quotedblright -100
+
+KPX quotedblright space -40
+
+KPX quoteleft quoteleft -57
+
+KPX quoteright space -70
+KPX quoteright s -50
+KPX quoteright r -50
+KPX quoteright quoteright -57
+KPX quoteright d -50
+
+KPX r y 30
+KPX r v 30
+KPX r u 15
+KPX r t 40
+KPX r semicolon 30
+KPX r period -50
+KPX r p 30
+KPX r n 25
+KPX r m 25
+KPX r l 15
+KPX r k 15
+KPX r i 15
+KPX r comma -50
+KPX r colon 30
+KPX r a -10
+
+KPX s w -30
+KPX s period -15
+KPX s comma -15
+
+KPX semicolon space -50
+
+KPX space quoteleft -60
+KPX space quotedblleft -30
+KPX space Y -90
+KPX space W -40
+KPX space V -50
+KPX space T -50
+
+KPX v period -80
+KPX v o -25
+KPX v e -25
+KPX v comma -80
+KPX v a -25
+
+KPX w period -60
+KPX w o -10
+KPX w e -10
+KPX w comma -60
+KPX w a -15
+
+KPX x e -30
+
+KPX y period -100
+KPX y o -20
+KPX y e -20
+KPX y comma -100
+KPX y a -20
+
+KPX z o -15
+KPX z e -15
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 195 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 195 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 195 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 195 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 167 175 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 195 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 195 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 195 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 195 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 195 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 195 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 195 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 195 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 195 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 205 195 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 195 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 195 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 195 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 195 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 195 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 195 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 195 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 195 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 195 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 195 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 195 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 195 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 195 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Times-Bold.afm b/config/psfonts/Times-Bold.afm
new file mode 100644 (file)
index 0000000..55207f9
--- /dev/null
@@ -0,0 +1,648 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Mar 20 12:17:14 1990
+Comment UniqueID 28417
+Comment VMusage 30458 37350
+FontName Times-Bold
+FullName Times Bold
+FamilyName Times
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -168 -218 1000 935
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 676
+XHeight 461
+Ascender 676
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ;
+C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ;
+C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ;
+C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ;
+C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ;
+C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ;
+C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ;
+C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ;
+C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
+C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ;
+C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ;
+C 46 ; WX 250 ; N period ; B 41 -13 210 156 ;
+C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ;
+C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ;
+C 49 ; WX 500 ; N one ; B 65 0 442 688 ;
+C 50 ; WX 500 ; N two ; B 17 0 478 688 ;
+C 51 ; WX 500 ; N three ; B 16 -14 468 688 ;
+C 52 ; WX 500 ; N four ; B 19 0 475 688 ;
+C 53 ; WX 500 ; N five ; B 22 -8 470 676 ;
+C 54 ; WX 500 ; N six ; B 28 -13 475 688 ;
+C 55 ; WX 500 ; N seven ; B 17 0 477 676 ;
+C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ;
+C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ;
+C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ;
+C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ;
+C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
+C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
+C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
+C 63 ; WX 500 ; N question ; B 57 -13 445 689 ;
+C 64 ; WX 930 ; N at ; B 108 -19 822 691 ;
+C 65 ; WX 722 ; N A ; B 9 0 689 690 ;
+C 66 ; WX 667 ; N B ; B 16 0 619 676 ;
+C 67 ; WX 722 ; N C ; B 49 -19 687 691 ;
+C 68 ; WX 722 ; N D ; B 14 0 690 676 ;
+C 69 ; WX 667 ; N E ; B 16 0 641 676 ;
+C 70 ; WX 611 ; N F ; B 16 0 583 676 ;
+C 71 ; WX 778 ; N G ; B 37 -19 755 691 ;
+C 72 ; WX 778 ; N H ; B 21 0 759 676 ;
+C 73 ; WX 389 ; N I ; B 20 0 370 676 ;
+C 74 ; WX 500 ; N J ; B 3 -96 479 676 ;
+C 75 ; WX 778 ; N K ; B 30 0 769 676 ;
+C 76 ; WX 667 ; N L ; B 19 0 638 676 ;
+C 77 ; WX 944 ; N M ; B 14 0 921 676 ;
+C 78 ; WX 722 ; N N ; B 16 -18 701 676 ;
+C 79 ; WX 778 ; N O ; B 35 -19 743 691 ;
+C 80 ; WX 611 ; N P ; B 16 0 600 676 ;
+C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ;
+C 82 ; WX 722 ; N R ; B 26 0 715 676 ;
+C 83 ; WX 556 ; N S ; B 35 -19 513 692 ;
+C 84 ; WX 667 ; N T ; B 31 0 636 676 ;
+C 85 ; WX 722 ; N U ; B 16 -19 701 676 ;
+C 86 ; WX 722 ; N V ; B 16 -18 701 676 ;
+C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ;
+C 88 ; WX 722 ; N X ; B 16 0 699 676 ;
+C 89 ; WX 722 ; N Y ; B 15 0 699 676 ;
+C 90 ; WX 667 ; N Z ; B 28 0 634 676 ;
+C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ;
+C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ;
+C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ;
+C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ;
+C 97 ; WX 500 ; N a ; B 25 -14 488 473 ;
+C 98 ; WX 556 ; N b ; B 17 -14 521 676 ;
+C 99 ; WX 444 ; N c ; B 25 -14 430 473 ;
+C 100 ; WX 556 ; N d ; B 25 -14 534 676 ;
+C 101 ; WX 444 ; N e ; B 25 -14 426 473 ;
+C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 28 -206 483 473 ;
+C 104 ; WX 556 ; N h ; B 16 0 534 676 ;
+C 105 ; WX 278 ; N i ; B 16 0 255 691 ;
+C 106 ; WX 333 ; N j ; B -57 -203 263 691 ;
+C 107 ; WX 556 ; N k ; B 22 0 543 676 ;
+C 108 ; WX 278 ; N l ; B 16 0 255 676 ;
+C 109 ; WX 833 ; N m ; B 16 0 814 473 ;
+C 110 ; WX 556 ; N n ; B 21 0 539 473 ;
+C 111 ; WX 500 ; N o ; B 25 -14 476 473 ;
+C 112 ; WX 556 ; N p ; B 19 -205 524 473 ;
+C 113 ; WX 556 ; N q ; B 34 -205 536 473 ;
+C 114 ; WX 444 ; N r ; B 29 0 434 473 ;
+C 115 ; WX 389 ; N s ; B 25 -14 361 473 ;
+C 116 ; WX 333 ; N t ; B 20 -12 332 630 ;
+C 117 ; WX 556 ; N u ; B 16 -14 537 461 ;
+C 118 ; WX 500 ; N v ; B 21 -14 485 461 ;
+C 119 ; WX 722 ; N w ; B 23 -14 707 461 ;
+C 120 ; WX 500 ; N x ; B 12 0 484 461 ;
+C 121 ; WX 500 ; N y ; B 16 -205 480 461 ;
+C 122 ; WX 444 ; N z ; B 21 0 420 461 ;
+C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ;
+C 124 ; WX 220 ; N bar ; B 66 -19 154 691 ;
+C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ;
+C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ;
+C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ;
+C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ;
+C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ;
+C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ;
+C 165 ; WX 500 ; N yen ; B -64 0 547 676 ;
+C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ;
+C 167 ; WX 500 ; N section ; B 57 -132 443 691 ;
+C 168 ; WX 500 ; N currency ; B -26 61 526 613 ;
+C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ;
+C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ;
+C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ;
+C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ;
+C 174 ; WX 556 ; N fi ; B 14 0 536 691 ;
+C 175 ; WX 556 ; N fl ; B 14 0 536 691 ;
+C 177 ; WX 500 ; N endash ; B 0 181 500 271 ;
+C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ;
+C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ;
+C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ;
+C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ;
+C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ;
+C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ;
+C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ;
+C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ;
+C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ;
+C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ;
+C 193 ; WX 333 ; N grave ; B 8 528 246 713 ;
+C 194 ; WX 333 ; N acute ; B 86 528 324 713 ;
+C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ;
+C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ;
+C 197 ; WX 333 ; N macron ; B 1 565 331 637 ;
+C 198 ; WX 333 ; N breve ; B 15 528 318 691 ;
+C 199 ; WX 333 ; N dotaccent ; B 103 537 230 667 ;
+C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ;
+C 202 ; WX 333 ; N ring ; B 60 527 273 740 ;
+C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ;
+C 206 ; WX 333 ; N ogonek ; B 90 -173 319 44 ;
+C 207 ; WX 333 ; N caron ; B -2 528 335 704 ;
+C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ;
+C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ;
+C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ;
+C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ;
+C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ;
+C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ;
+C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ;
+C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ;
+C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ;
+C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ;
+C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ;
+C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ;
+C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ;
+C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ;
+C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ;
+C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ;
+C -1 ; WX 278 ; N icircumflex ; B -36 0 301 704 ;
+C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ;
+C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ;
+C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ;
+C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ;
+C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ;
+C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ;
+C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ;
+C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ;
+C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ;
+C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ;
+C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ;
+C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ;
+C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ;
+C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ;
+C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ;
+C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ;
+C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ;
+C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ;
+C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ;
+C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ;
+C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ;
+C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ;
+C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ;
+C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ;
+C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ;
+C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ;
+C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ;
+C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ;
+C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ;
+C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ;
+C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ;
+C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ;
+C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ;
+C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ;
+C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ;
+C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ;
+C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ;
+C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ;
+C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ;
+C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ;
+C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ;
+C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ;
+C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ;
+C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ;
+C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ;
+C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ;
+C -1 ; WX 278 ; N idieresis ; B -36 0 301 667 ;
+C -1 ; WX 278 ; N iacute ; B 16 0 290 713 ;
+C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
+C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
+C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ;
+C -1 ; WX 570 ; N minus ; B 33 209 537 297 ;
+C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ;
+C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ;
+C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ;
+C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ;
+C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ;
+C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ;
+C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ;
+C -1 ; WX 400 ; N degree ; B 57 402 343 688 ;
+C -1 ; WX 278 ; N igrave ; B -26 0 255 713 ;
+C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ;
+C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ;
+C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ;
+C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ;
+C -1 ; WX 722 ; N Yacute ; B 15 0 699 928 ;
+C -1 ; WX 220 ; N brokenbar ; B 66 -19 154 691 ;
+C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 283
+
+KPX A y -74
+KPX A w -90
+KPX A v -100
+KPX A u -50
+KPX A quoteright -74
+KPX A quotedblright 0
+KPX A p -25
+KPX A Y -100
+KPX A W -130
+KPX A V -145
+KPX A U -50
+KPX A T -95
+KPX A Q -45
+KPX A O -45
+KPX A G -55
+KPX A C -55
+
+KPX B period 0
+KPX B comma 0
+KPX B U -10
+KPX B A -30
+
+KPX D period -20
+KPX D comma 0
+KPX D Y -40
+KPX D W -40
+KPX D V -40
+KPX D A -35
+
+KPX F r 0
+KPX F period -110
+KPX F o -25
+KPX F i 0
+KPX F e -25
+KPX F comma -92
+KPX F a -25
+KPX F A -90
+
+KPX G period 0
+KPX G comma 0
+
+KPX J u -15
+KPX J period -20
+KPX J o -15
+KPX J e -15
+KPX J comma 0
+KPX J a -15
+KPX J A -30
+
+KPX K y -45
+KPX K u -15
+KPX K o -25
+KPX K e -25
+KPX K O -30
+
+KPX L y -55
+KPX L quoteright -110
+KPX L quotedblright -20
+KPX L Y -92
+KPX L W -92
+KPX L V -92
+KPX L T -92
+
+KPX N period 0
+KPX N comma 0
+KPX N A -20
+
+KPX O period 0
+KPX O comma 0
+KPX O Y -50
+KPX O X -40
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -40
+
+KPX P period -110
+KPX P o -20
+KPX P e -20
+KPX P comma -92
+KPX P a -10
+KPX P A -74
+
+KPX Q period -20
+KPX Q comma 0
+KPX Q U -10
+
+KPX R Y -35
+KPX R W -35
+KPX R V -55
+KPX R U -30
+KPX R T -40
+KPX R O -30
+
+KPX S period 0
+KPX S comma 0
+
+KPX T y -74
+KPX T w -74
+KPX T u -92
+KPX T semicolon -74
+KPX T r -74
+KPX T period -90
+KPX T o -92
+KPX T i -18
+KPX T hyphen -92
+KPX T h 0
+KPX T e -92
+KPX T comma -74
+KPX T colon -74
+KPX T a -92
+KPX T O -18
+KPX T A -90
+
+KPX U period -50
+KPX U comma -50
+KPX U A -60
+
+KPX V u -92
+KPX V semicolon -92
+KPX V period -145
+KPX V o -100
+KPX V i -37
+KPX V hyphen -74
+KPX V e -100
+KPX V comma -129
+KPX V colon -92
+KPX V a -92
+KPX V O -45
+KPX V G -30
+KPX V A -135
+
+KPX W y -60
+KPX W u -50
+KPX W semicolon -55
+KPX W period -92
+KPX W o -75
+KPX W i -18
+KPX W hyphen -37
+KPX W h 0
+KPX W e -65
+KPX W comma -92
+KPX W colon -55
+KPX W a -65
+KPX W O -10
+KPX W A -120
+
+KPX Y u -92
+KPX Y semicolon -92
+KPX Y period -92
+KPX Y o -111
+KPX Y i -37
+KPX Y hyphen -92
+KPX Y e -111
+KPX Y comma -92
+KPX Y colon -92
+KPX Y a -85
+KPX Y O -35
+KPX Y A -110
+
+KPX a y 0
+KPX a w 0
+KPX a v -25
+KPX a t 0
+KPX a p 0
+KPX a g 0
+KPX a b 0
+
+KPX b y 0
+KPX b v -15
+KPX b u -20
+KPX b period -40
+KPX b l 0
+KPX b comma 0
+KPX b b -10
+
+KPX c y 0
+KPX c period 0
+KPX c l 0
+KPX c k 0
+KPX c h 0
+KPX c comma 0
+
+KPX colon space 0
+
+KPX comma space 0
+KPX comma quoteright -55
+KPX comma quotedblright -45
+
+KPX d y 0
+KPX d w -15
+KPX d v 0
+KPX d period 0
+KPX d d 0
+KPX d comma 0
+
+KPX e y 0
+KPX e x 0
+KPX e w 0
+KPX e v -15
+KPX e period 0
+KPX e p 0
+KPX e g 0
+KPX e comma 0
+KPX e b 0
+
+KPX f quoteright 55
+KPX f quotedblright 50
+KPX f period -15
+KPX f o -25
+KPX f l 0
+KPX f i -25
+KPX f f 0
+KPX f e 0
+KPX f dotlessi -35
+KPX f comma -15
+KPX f a 0
+
+KPX g y 0
+KPX g r 0
+KPX g period -15
+KPX g o 0
+KPX g i 0
+KPX g g 0
+KPX g e 0
+KPX g comma 0
+KPX g a 0
+
+KPX h y -15
+
+KPX i v -10
+
+KPX k y -15
+KPX k o -15
+KPX k e -10
+
+KPX l y 0
+KPX l w 0
+
+KPX m y 0
+KPX m u 0
+
+KPX n y 0
+KPX n v -40
+KPX n u 0
+
+KPX o y 0
+KPX o x 0
+KPX o w -10
+KPX o v -10
+KPX o g 0
+
+KPX p y 0
+
+KPX period quoteright -55
+KPX period quotedblright -55
+
+KPX quotedblleft quoteleft 0
+KPX quotedblleft A -10
+
+KPX quotedblright space 0
+
+KPX quoteleft quoteleft -63
+KPX quoteleft A -10
+
+KPX quoteright v -20
+KPX quoteright t 0
+KPX quoteright space -74
+KPX quoteright s -37
+KPX quoteright r -20
+KPX quoteright quoteright -63
+KPX quoteright quotedblright 0
+KPX quoteright l 0
+KPX quoteright d -20
+
+KPX r y 0
+KPX r v -10
+KPX r u 0
+KPX r t 0
+KPX r s 0
+KPX r r 0
+KPX r q -18
+KPX r period -100
+KPX r p -10
+KPX r o -18
+KPX r n -15
+KPX r m 0
+KPX r l 0
+KPX r k 0
+KPX r i 0
+KPX r hyphen -37
+KPX r g -10
+KPX r e -18
+KPX r d 0
+KPX r comma -92
+KPX r c -18
+KPX r a 0
+
+KPX s w 0
+
+KPX space quoteleft 0
+KPX space quotedblleft 0
+KPX space Y -55
+KPX space W -30
+KPX space V -45
+KPX space T -30
+KPX space A -55
+
+KPX v period -70
+KPX v o -10
+KPX v e -10
+KPX v comma -55
+KPX v a -10
+
+KPX w period -70
+KPX w o -10
+KPX w h 0
+KPX w e 0
+KPX w comma -55
+KPX w a 0
+
+KPX x e 0
+
+KPX y period -70
+KPX y o -25
+KPX y e -10
+KPX y comma -55
+KPX y a 0
+
+KPX z o 0
+KPX z e 0
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 188 210 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 188 210 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 188 210 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 188 210 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 180 195 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 188 210 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 208 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 174 210 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 174 210 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 174 210 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 174 210 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 210 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 210 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 210 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 210 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 210 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 210 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 210 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 210 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 210 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 210 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 210 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 222 210 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 222 210 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 222 210 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 222 210 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 210 215 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 215 210 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 210 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 77 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 77 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 77 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 77 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 77 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 77 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 62 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 62 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 62 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 62 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -34 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -34 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -34 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -34 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 105 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 105 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 105 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 105 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Times-BoldItalic.afm b/config/psfonts/Times-BoldItalic.afm
new file mode 100644 (file)
index 0000000..25ab54e
--- /dev/null
@@ -0,0 +1,648 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Mar 20 13:14:55 1990
+Comment UniqueID 28425
+Comment VMusage 32721 39613
+FontName Times-BoldItalic
+FullName Times Bold Italic
+FamilyName Times
+Weight Bold
+ItalicAngle -15
+IsFixedPitch false
+FontBBox -200 -218 996 921
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.009
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 669
+XHeight 462
+Ascender 699
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ;
+C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ;
+C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ;
+C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ;
+C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ;
+C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ;
+C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ;
+C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ;
+C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ;
+C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
+C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ;
+C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ;
+C 46 ; WX 250 ; N period ; B -9 -13 139 135 ;
+C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ;
+C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ;
+C 49 ; WX 500 ; N one ; B 5 0 419 683 ;
+C 50 ; WX 500 ; N two ; B -27 0 446 683 ;
+C 51 ; WX 500 ; N three ; B -15 -13 450 683 ;
+C 52 ; WX 500 ; N four ; B -15 0 503 683 ;
+C 53 ; WX 500 ; N five ; B -11 -13 487 669 ;
+C 54 ; WX 500 ; N six ; B 23 -15 509 679 ;
+C 55 ; WX 500 ; N seven ; B 52 0 525 669 ;
+C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ;
+C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ;
+C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ;
+C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ;
+C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
+C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
+C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
+C 63 ; WX 500 ; N question ; B 79 -13 470 684 ;
+C 64 ; WX 832 ; N at ; B 63 -18 770 685 ;
+C 65 ; WX 667 ; N A ; B -67 0 593 683 ;
+C 66 ; WX 667 ; N B ; B -24 0 624 669 ;
+C 67 ; WX 667 ; N C ; B 32 -18 677 685 ;
+C 68 ; WX 722 ; N D ; B -46 0 685 669 ;
+C 69 ; WX 667 ; N E ; B -27 0 653 669 ;
+C 70 ; WX 667 ; N F ; B -13 0 660 669 ;
+C 71 ; WX 722 ; N G ; B 21 -18 706 685 ;
+C 72 ; WX 778 ; N H ; B -24 0 799 669 ;
+C 73 ; WX 389 ; N I ; B -32 0 406 669 ;
+C 74 ; WX 500 ; N J ; B -46 -99 524 669 ;
+C 75 ; WX 667 ; N K ; B -21 0 702 669 ;
+C 76 ; WX 611 ; N L ; B -22 0 590 669 ;
+C 77 ; WX 889 ; N M ; B -29 -12 917 669 ;
+C 78 ; WX 722 ; N N ; B -27 -15 748 669 ;
+C 79 ; WX 722 ; N O ; B 27 -18 691 685 ;
+C 80 ; WX 611 ; N P ; B -27 0 613 669 ;
+C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ;
+C 82 ; WX 667 ; N R ; B -29 0 623 669 ;
+C 83 ; WX 556 ; N S ; B 2 -18 526 685 ;
+C 84 ; WX 611 ; N T ; B 50 0 650 669 ;
+C 85 ; WX 722 ; N U ; B 67 -18 744 669 ;
+C 86 ; WX 667 ; N V ; B 65 -18 715 669 ;
+C 87 ; WX 889 ; N W ; B 65 -18 940 669 ;
+C 88 ; WX 667 ; N X ; B -24 0 694 669 ;
+C 89 ; WX 611 ; N Y ; B 73 0 659 669 ;
+C 90 ; WX 611 ; N Z ; B -11 0 590 669 ;
+C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ;
+C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ;
+C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ;
+C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ;
+C 97 ; WX 500 ; N a ; B -21 -14 455 462 ;
+C 98 ; WX 500 ; N b ; B -14 -13 444 699 ;
+C 99 ; WX 444 ; N c ; B -5 -13 392 462 ;
+C 100 ; WX 500 ; N d ; B -21 -13 517 699 ;
+C 101 ; WX 444 ; N e ; B 5 -13 398 462 ;
+C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B -52 -203 478 462 ;
+C 104 ; WX 556 ; N h ; B -13 -9 498 699 ;
+C 105 ; WX 278 ; N i ; B 2 -9 263 684 ;
+C 106 ; WX 278 ; N j ; B -189 -207 279 684 ;
+C 107 ; WX 500 ; N k ; B -23 -8 483 699 ;
+C 108 ; WX 278 ; N l ; B 2 -9 290 699 ;
+C 109 ; WX 778 ; N m ; B -14 -9 722 462 ;
+C 110 ; WX 556 ; N n ; B -6 -9 493 462 ;
+C 111 ; WX 500 ; N o ; B -3 -13 441 462 ;
+C 112 ; WX 500 ; N p ; B -120 -205 446 462 ;
+C 113 ; WX 500 ; N q ; B 1 -205 471 462 ;
+C 114 ; WX 389 ; N r ; B -21 0 389 462 ;
+C 115 ; WX 389 ; N s ; B -19 -13 333 462 ;
+C 116 ; WX 278 ; N t ; B -11 -9 281 594 ;
+C 117 ; WX 556 ; N u ; B 15 -9 492 462 ;
+C 118 ; WX 444 ; N v ; B 16 -13 401 462 ;
+C 119 ; WX 667 ; N w ; B 16 -13 614 462 ;
+C 120 ; WX 500 ; N x ; B -46 -13 469 462 ;
+C 121 ; WX 444 ; N y ; B -94 -205 392 462 ;
+C 122 ; WX 389 ; N z ; B -43 -78 368 449 ;
+C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ;
+C 124 ; WX 220 ; N bar ; B 66 -18 154 685 ;
+C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ;
+C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ;
+C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ;
+C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ;
+C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ;
+C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ;
+C 165 ; WX 500 ; N yen ; B 33 0 628 669 ;
+C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ;
+C 167 ; WX 500 ; N section ; B 36 -143 459 685 ;
+C 168 ; WX 500 ; N currency ; B -26 34 526 586 ;
+C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ;
+C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ;
+C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ;
+C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ;
+C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ;
+C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ;
+C 177 ; WX 500 ; N endash ; B -40 178 477 269 ;
+C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ;
+C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ;
+C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ;
+C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ;
+C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ;
+C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ;
+C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ;
+C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ;
+C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ;
+C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ;
+C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ;
+C 193 ; WX 333 ; N grave ; B 85 516 297 697 ;
+C 194 ; WX 333 ; N acute ; B 139 516 379 697 ;
+C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ;
+C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ;
+C 197 ; WX 333 ; N macron ; B 51 553 393 623 ;
+C 198 ; WX 333 ; N breve ; B 71 516 387 678 ;
+C 199 ; WX 333 ; N dotaccent ; B 163 525 293 655 ;
+C 200 ; WX 333 ; N dieresis ; B 55 525 397 655 ;
+C 202 ; WX 333 ; N ring ; B 127 516 340 729 ;
+C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ;
+C 206 ; WX 333 ; N ogonek ; B -40 -173 189 44 ;
+C 207 ; WX 333 ; N caron ; B 79 516 411 690 ;
+C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ;
+C 225 ; WX 944 ; N AE ; B -64 0 918 669 ;
+C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ;
+C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ;
+C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ;
+C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ;
+C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ;
+C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ;
+C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ;
+C 248 ; WX 278 ; N lslash ; B -13 -9 301 699 ;
+C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ;
+C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ;
+C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ;
+C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ;
+C -1 ; WX 444 ; N ccedilla ; B -24 -218 392 462 ;
+C -1 ; WX 444 ; N ydieresis ; B -94 -205 438 655 ;
+C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ;
+C -1 ; WX 278 ; N icircumflex ; B -2 -9 325 690 ;
+C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ;
+C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ;
+C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ;
+C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ;
+C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ;
+C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ;
+C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ;
+C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ;
+C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ;
+C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ;
+C -1 ; WX 556 ; N udieresis ; B 15 -9 494 655 ;
+C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ;
+C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ;
+C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ;
+C -1 ; WX 444 ; N edieresis ; B 5 -13 443 655 ;
+C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ;
+C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ;
+C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ;
+C -1 ; WX 389 ; N scaron ; B -19 -13 439 690 ;
+C -1 ; WX 389 ; N Idieresis ; B -32 0 445 862 ;
+C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ;
+C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ;
+C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ;
+C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ;
+C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ;
+C -1 ; WX 389 ; N Icircumflex ; B -32 0 420 897 ;
+C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ;
+C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ;
+C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ;
+C -1 ; WX 389 ; N Iacute ; B -32 0 412 904 ;
+C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ;
+C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ;
+C -1 ; WX 556 ; N Scaron ; B 2 -18 526 897 ;
+C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ;
+C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ;
+C -1 ; WX 500 ; N adieresis ; B -21 -14 471 655 ;
+C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ;
+C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ;
+C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ;
+C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ;
+C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ;
+C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ;
+C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ;
+C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ;
+C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ;
+C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ;
+C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ;
+C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ;
+C -1 ; WX 278 ; N idieresis ; B 2 -9 360 655 ;
+C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ;
+C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
+C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
+C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ;
+C -1 ; WX 606 ; N minus ; B 51 209 555 297 ;
+C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ;
+C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ;
+C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ;
+C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ;
+C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ;
+C -1 ; WX 500 ; N odieresis ; B -3 -13 466 655 ;
+C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ;
+C -1 ; WX 400 ; N degree ; B 83 397 369 683 ;
+C -1 ; WX 278 ; N igrave ; B 2 -9 260 697 ;
+C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ;
+C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ;
+C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ;
+C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ;
+C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ;
+C -1 ; WX 220 ; N brokenbar ; B 66 -18 154 685 ;
+C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 283
+
+KPX A y -74
+KPX A w -74
+KPX A v -74
+KPX A u -30
+KPX A quoteright -74
+KPX A quotedblright 0
+KPX A p 0
+KPX A Y -70
+KPX A W -100
+KPX A V -95
+KPX A U -50
+KPX A T -55
+KPX A Q -55
+KPX A O -50
+KPX A G -60
+KPX A C -65
+
+KPX B period 0
+KPX B comma 0
+KPX B U -10
+KPX B A -25
+
+KPX D period 0
+KPX D comma 0
+KPX D Y -50
+KPX D W -40
+KPX D V -50
+KPX D A -25
+
+KPX F r -50
+KPX F period -129
+KPX F o -70
+KPX F i -40
+KPX F e -100
+KPX F comma -129
+KPX F a -95
+KPX F A -100
+
+KPX G period 0
+KPX G comma 0
+
+KPX J u -40
+KPX J period -10
+KPX J o -40
+KPX J e -40
+KPX J comma -10
+KPX J a -40
+KPX J A -25
+
+KPX K y -20
+KPX K u -20
+KPX K o -25
+KPX K e -25
+KPX K O -30
+
+KPX L y -37
+KPX L quoteright -55
+KPX L quotedblright 0
+KPX L Y -37
+KPX L W -37
+KPX L V -37
+KPX L T -18
+
+KPX N period 0
+KPX N comma 0
+KPX N A -30
+
+KPX O period 0
+KPX O comma 0
+KPX O Y -50
+KPX O X -40
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -40
+
+KPX P period -129
+KPX P o -55
+KPX P e -50
+KPX P comma -129
+KPX P a -40
+KPX P A -85
+
+KPX Q period 0
+KPX Q comma 0
+KPX Q U -10
+
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+KPX R U -40
+KPX R T -30
+KPX R O -40
+
+KPX S period 0
+KPX S comma 0
+
+KPX T y -37
+KPX T w -37
+KPX T u -37
+KPX T semicolon -74
+KPX T r -37
+KPX T period -92
+KPX T o -95
+KPX T i -37
+KPX T hyphen -92
+KPX T h 0
+KPX T e -92
+KPX T comma -92
+KPX T colon -74
+KPX T a -92
+KPX T O -18
+KPX T A -55
+
+KPX U period 0
+KPX U comma 0
+KPX U A -45
+
+KPX V u -55
+KPX V semicolon -74
+KPX V period -129
+KPX V o -111
+KPX V i -55
+KPX V hyphen -70
+KPX V e -111
+KPX V comma -129
+KPX V colon -74
+KPX V a -111
+KPX V O -30
+KPX V G -10
+KPX V A -85
+
+KPX W y -55
+KPX W u -55
+KPX W semicolon -55
+KPX W period -74
+KPX W o -80
+KPX W i -37
+KPX W hyphen -50
+KPX W h 0
+KPX W e -90
+KPX W comma -74
+KPX W colon -55
+KPX W a -85
+KPX W O -15
+KPX W A -74
+
+KPX Y u -92
+KPX Y semicolon -92
+KPX Y period -74
+KPX Y o -111
+KPX Y i -55
+KPX Y hyphen -92
+KPX Y e -111
+KPX Y comma -92
+KPX Y colon -92
+KPX Y a -92
+KPX Y O -25
+KPX Y A -74
+
+KPX a y 0
+KPX a w 0
+KPX a v 0
+KPX a t 0
+KPX a p 0
+KPX a g 0
+KPX a b 0
+
+KPX b y 0
+KPX b v 0
+KPX b u -20
+KPX b period -40
+KPX b l 0
+KPX b comma 0
+KPX b b -10
+
+KPX c y 0
+KPX c period 0
+KPX c l 0
+KPX c k -10
+KPX c h -10
+KPX c comma 0
+
+KPX colon space 0
+
+KPX comma space 0
+KPX comma quoteright -95
+KPX comma quotedblright -95
+
+KPX d y 0
+KPX d w 0
+KPX d v 0
+KPX d period 0
+KPX d d 0
+KPX d comma 0
+
+KPX e y 0
+KPX e x 0
+KPX e w 0
+KPX e v 0
+KPX e period 0
+KPX e p 0
+KPX e g 0
+KPX e comma 0
+KPX e b -10
+
+KPX f quoteright 55
+KPX f quotedblright 0
+KPX f period -10
+KPX f o -10
+KPX f l 0
+KPX f i 0
+KPX f f -18
+KPX f e -10
+KPX f dotlessi -30
+KPX f comma -10
+KPX f a 0
+
+KPX g y 0
+KPX g r 0
+KPX g period 0
+KPX g o 0
+KPX g i 0
+KPX g g 0
+KPX g e 0
+KPX g comma 0
+KPX g a 0
+
+KPX h y 0
+
+KPX i v 0
+
+KPX k y 0
+KPX k o -10
+KPX k e -30
+
+KPX l y 0
+KPX l w 0
+
+KPX m y 0
+KPX m u 0
+
+KPX n y 0
+KPX n v -40
+KPX n u 0
+
+KPX o y -10
+KPX o x -10
+KPX o w -25
+KPX o v -15
+KPX o g 0
+
+KPX p y 0
+
+KPX period quoteright -95
+KPX period quotedblright -95
+
+KPX quotedblleft quoteleft 0
+KPX quotedblleft A 0
+
+KPX quotedblright space 0
+
+KPX quoteleft quoteleft -74
+KPX quoteleft A 0
+
+KPX quoteright v -15
+KPX quoteright t -37
+KPX quoteright space -74
+KPX quoteright s -74
+KPX quoteright r -15
+KPX quoteright quoteright -74
+KPX quoteright quotedblright 0
+KPX quoteright l 0
+KPX quoteright d -15
+
+KPX r y 0
+KPX r v 0
+KPX r u 0
+KPX r t 0
+KPX r s 0
+KPX r r 0
+KPX r q 0
+KPX r period -65
+KPX r p 0
+KPX r o 0
+KPX r n 0
+KPX r m 0
+KPX r l 0
+KPX r k 0
+KPX r i 0
+KPX r hyphen 0
+KPX r g 0
+KPX r e 0
+KPX r d 0
+KPX r comma -65
+KPX r c 0
+KPX r a 0
+
+KPX s w 0
+
+KPX space quoteleft 0
+KPX space quotedblleft 0
+KPX space Y -70
+KPX space W -70
+KPX space V -70
+KPX space T 0
+KPX space A -37
+
+KPX v period -37
+KPX v o -15
+KPX v e -15
+KPX v comma -37
+KPX v a 0
+
+KPX w period -37
+KPX w o -15
+KPX w h 0
+KPX w e -10
+KPX w comma -37
+KPX w a -10
+
+KPX x e -10
+
+KPX y period -37
+KPX y o 0
+KPX y e 0
+KPX y comma -37
+KPX y a 0
+
+KPX z o 0
+KPX z e 0
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 172 207 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 187 207 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 207 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 172 207 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 157 192 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 207 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 172 207 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 187 207 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 187 207 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 172 207 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 33 207 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 53 207 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 48 207 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 33 207 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 210 207 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 200 207 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 207 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 215 207 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 207 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 207 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 207 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 210 207 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 230 207 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 230 207 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 200 207 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 154 207 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 169 207 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 207 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 74 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 74 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 46 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -42 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -37 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -37 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 97 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 69 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 74 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 97 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 102 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 41 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 13 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Times-Italic.afm b/config/psfonts/Times-Italic.afm
new file mode 100644 (file)
index 0000000..6d7a003
--- /dev/null
@@ -0,0 +1,648 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Mar 20 13:14:56 1990
+Comment UniqueID 28427
+Comment VMusage 32912 39804
+FontName Times-Italic
+FullName Times Italic
+FamilyName Times
+Weight Medium
+ItalicAngle -15.5
+IsFixedPitch false
+FontBBox -169 -217 1010 883
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 653
+XHeight 441
+Ascender 683
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ;
+C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ;
+C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ;
+C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ;
+C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ;
+C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ;
+C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ;
+C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ;
+C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ;
+C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ;
+C 43 ; WX 675 ; N plus ; B 86 0 590 506 ;
+C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ;
+C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ;
+C 46 ; WX 250 ; N period ; B 27 -11 138 100 ;
+C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ;
+C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ;
+C 49 ; WX 500 ; N one ; B 49 0 409 676 ;
+C 50 ; WX 500 ; N two ; B 12 0 452 676 ;
+C 51 ; WX 500 ; N three ; B 15 -7 465 676 ;
+C 52 ; WX 500 ; N four ; B 1 0 479 676 ;
+C 53 ; WX 500 ; N five ; B 15 -7 491 666 ;
+C 54 ; WX 500 ; N six ; B 30 -7 521 686 ;
+C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ;
+C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ;
+C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ;
+C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ;
+C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ;
+C 60 ; WX 675 ; N less ; B 84 -8 592 514 ;
+C 61 ; WX 675 ; N equal ; B 86 120 590 386 ;
+C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ;
+C 63 ; WX 500 ; N question ; B 132 -12 472 664 ;
+C 64 ; WX 920 ; N at ; B 118 -18 806 666 ;
+C 65 ; WX 611 ; N A ; B -51 0 564 668 ;
+C 66 ; WX 611 ; N B ; B -8 0 588 653 ;
+C 67 ; WX 667 ; N C ; B 66 -18 689 666 ;
+C 68 ; WX 722 ; N D ; B -8 0 700 653 ;
+C 69 ; WX 611 ; N E ; B -1 0 634 653 ;
+C 70 ; WX 611 ; N F ; B 8 0 645 653 ;
+C 71 ; WX 722 ; N G ; B 52 -18 722 666 ;
+C 72 ; WX 722 ; N H ; B -8 0 767 653 ;
+C 73 ; WX 333 ; N I ; B -8 0 384 653 ;
+C 74 ; WX 444 ; N J ; B -6 -18 491 653 ;
+C 75 ; WX 667 ; N K ; B 7 0 722 653 ;
+C 76 ; WX 556 ; N L ; B -8 0 559 653 ;
+C 77 ; WX 833 ; N M ; B -18 0 873 653 ;
+C 78 ; WX 667 ; N N ; B -20 -15 727 653 ;
+C 79 ; WX 722 ; N O ; B 60 -18 699 666 ;
+C 80 ; WX 611 ; N P ; B 0 0 605 653 ;
+C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ;
+C 82 ; WX 611 ; N R ; B -13 0 588 653 ;
+C 83 ; WX 500 ; N S ; B 17 -18 508 667 ;
+C 84 ; WX 556 ; N T ; B 59 0 633 653 ;
+C 85 ; WX 722 ; N U ; B 102 -18 765 653 ;
+C 86 ; WX 611 ; N V ; B 76 -18 688 653 ;
+C 87 ; WX 833 ; N W ; B 71 -18 906 653 ;
+C 88 ; WX 611 ; N X ; B -29 0 655 653 ;
+C 89 ; WX 556 ; N Y ; B 78 0 633 653 ;
+C 90 ; WX 556 ; N Z ; B -6 0 606 653 ;
+C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ;
+C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ;
+C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ;
+C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ;
+C 97 ; WX 500 ; N a ; B 17 -11 476 441 ;
+C 98 ; WX 500 ; N b ; B 23 -11 473 683 ;
+C 99 ; WX 444 ; N c ; B 30 -11 425 441 ;
+C 100 ; WX 500 ; N d ; B 15 -13 527 683 ;
+C 101 ; WX 444 ; N e ; B 31 -11 412 441 ;
+C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 8 -206 472 441 ;
+C 104 ; WX 500 ; N h ; B 19 -9 478 683 ;
+C 105 ; WX 278 ; N i ; B 49 -11 264 654 ;
+C 106 ; WX 278 ; N j ; B -124 -207 276 654 ;
+C 107 ; WX 444 ; N k ; B 14 -11 461 683 ;
+C 108 ; WX 278 ; N l ; B 41 -11 279 683 ;
+C 109 ; WX 722 ; N m ; B 12 -9 704 441 ;
+C 110 ; WX 500 ; N n ; B 14 -9 474 441 ;
+C 111 ; WX 500 ; N o ; B 27 -11 468 441 ;
+C 112 ; WX 500 ; N p ; B -75 -205 469 441 ;
+C 113 ; WX 500 ; N q ; B 25 -209 483 441 ;
+C 114 ; WX 389 ; N r ; B 45 0 412 441 ;
+C 115 ; WX 389 ; N s ; B 16 -13 366 442 ;
+C 116 ; WX 278 ; N t ; B 37 -11 296 546 ;
+C 117 ; WX 500 ; N u ; B 42 -11 475 441 ;
+C 118 ; WX 444 ; N v ; B 21 -18 426 441 ;
+C 119 ; WX 667 ; N w ; B 16 -18 648 441 ;
+C 120 ; WX 444 ; N x ; B -27 -11 447 441 ;
+C 121 ; WX 444 ; N y ; B -24 -206 426 441 ;
+C 122 ; WX 389 ; N z ; B -2 -81 380 428 ;
+C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ;
+C 124 ; WX 275 ; N bar ; B 105 -18 171 666 ;
+C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ;
+C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
+C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ;
+C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ;
+C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ;
+C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ;
+C 165 ; WX 500 ; N yen ; B 27 0 603 653 ;
+C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ;
+C 167 ; WX 500 ; N section ; B 53 -162 461 666 ;
+C 168 ; WX 500 ; N currency ; B -22 53 522 597 ;
+C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ;
+C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ;
+C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ;
+C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ;
+C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ;
+C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ;
+C 177 ; WX 500 ; N endash ; B -6 197 505 243 ;
+C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ;
+C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ;
+C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
+C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ;
+C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ;
+C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ;
+C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ;
+C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ;
+C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ;
+C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ;
+C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ;
+C 193 ; WX 333 ; N grave ; B 121 492 311 664 ;
+C 194 ; WX 333 ; N acute ; B 180 494 403 664 ;
+C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ;
+C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ;
+C 197 ; WX 333 ; N macron ; B 99 532 411 583 ;
+C 198 ; WX 333 ; N breve ; B 117 492 418 650 ;
+C 199 ; WX 333 ; N dotaccent ; B 207 508 305 606 ;
+C 200 ; WX 333 ; N dieresis ; B 107 508 405 606 ;
+C 202 ; WX 333 ; N ring ; B 155 492 355 691 ;
+C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ;
+C 206 ; WX 333 ; N ogonek ; B -20 -169 200 40 ;
+C 207 ; WX 333 ; N caron ; B 121 492 426 661 ;
+C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ;
+C 225 ; WX 889 ; N AE ; B -27 0 911 653 ;
+C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ;
+C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ;
+C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ;
+C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ;
+C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ;
+C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ;
+C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ;
+C 248 ; WX 278 ; N lslash ; B 37 -11 307 683 ;
+C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ;
+C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ;
+C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ;
+C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ;
+C -1 ; WX 444 ; N ccedilla ; B 26 -217 425 441 ;
+C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ;
+C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ;
+C -1 ; WX 278 ; N icircumflex ; B 34 -11 328 661 ;
+C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ;
+C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ;
+C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ;
+C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ;
+C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ;
+C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ;
+C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ;
+C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ;
+C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ;
+C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ;
+C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ;
+C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ;
+C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ;
+C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ;
+C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ;
+C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ;
+C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ;
+C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ;
+C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ;
+C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ;
+C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ;
+C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ;
+C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ;
+C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ;
+C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ;
+C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ;
+C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ;
+C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ;
+C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ;
+C -1 ; WX 333 ; N Iacute ; B -8 0 413 876 ;
+C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ;
+C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ;
+C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ;
+C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ;
+C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ;
+C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ;
+C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ;
+C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ;
+C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ;
+C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ;
+C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ;
+C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ;
+C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ;
+C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ;
+C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ;
+C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ;
+C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ;
+C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ;
+C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ;
+C -1 ; WX 278 ; N idieresis ; B 49 -11 353 606 ;
+C -1 ; WX 278 ; N iacute ; B 49 -11 356 664 ;
+C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ;
+C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ;
+C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ;
+C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ;
+C -1 ; WX 675 ; N minus ; B 86 220 590 286 ;
+C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ;
+C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ;
+C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ;
+C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ;
+C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ;
+C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ;
+C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ;
+C -1 ; WX 400 ; N degree ; B 101 390 387 676 ;
+C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ;
+C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ;
+C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ;
+C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ;
+C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ;
+C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ;
+C -1 ; WX 275 ; N brokenbar ; B 105 -18 171 666 ;
+C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 283
+
+KPX A y -55
+KPX A w -55
+KPX A v -55
+KPX A u -20
+KPX A quoteright -37
+KPX A quotedblright 0
+KPX A p 0
+KPX A Y -55
+KPX A W -95
+KPX A V -105
+KPX A U -50
+KPX A T -37
+KPX A Q -40
+KPX A O -40
+KPX A G -35
+KPX A C -30
+
+KPX B period 0
+KPX B comma 0
+KPX B U -10
+KPX B A -25
+
+KPX D period 0
+KPX D comma 0
+KPX D Y -40
+KPX D W -40
+KPX D V -40
+KPX D A -35
+
+KPX F r -55
+KPX F period -135
+KPX F o -105
+KPX F i -45
+KPX F e -75
+KPX F comma -135
+KPX F a -75
+KPX F A -115
+
+KPX G period 0
+KPX G comma 0
+
+KPX J u -35
+KPX J period -25
+KPX J o -25
+KPX J e -25
+KPX J comma -25
+KPX J a -35
+KPX J A -40
+
+KPX K y -40
+KPX K u -40
+KPX K o -40
+KPX K e -35
+KPX K O -50
+
+KPX L y -30
+KPX L quoteright -37
+KPX L quotedblright 0
+KPX L Y -20
+KPX L W -55
+KPX L V -55
+KPX L T -20
+
+KPX N period 0
+KPX N comma 0
+KPX N A -27
+
+KPX O period 0
+KPX O comma 0
+KPX O Y -50
+KPX O X -40
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -55
+
+KPX P period -135
+KPX P o -80
+KPX P e -80
+KPX P comma -135
+KPX P a -80
+KPX P A -90
+
+KPX Q period 0
+KPX Q comma 0
+KPX Q U -10
+
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+KPX R U -40
+KPX R T 0
+KPX R O -40
+
+KPX S period 0
+KPX S comma 0
+
+KPX T y -74
+KPX T w -74
+KPX T u -55
+KPX T semicolon -65
+KPX T r -55
+KPX T period -74
+KPX T o -92
+KPX T i -55
+KPX T hyphen -74
+KPX T h 0
+KPX T e -92
+KPX T comma -74
+KPX T colon -55
+KPX T a -92
+KPX T O -18
+KPX T A -50
+
+KPX U period -25
+KPX U comma -25
+KPX U A -40
+
+KPX V u -74
+KPX V semicolon -74
+KPX V period -129
+KPX V o -111
+KPX V i -74
+KPX V hyphen -55
+KPX V e -111
+KPX V comma -129
+KPX V colon -65
+KPX V a -111
+KPX V O -30
+KPX V G 0
+KPX V A -60
+
+KPX W y -70
+KPX W u -55
+KPX W semicolon -65
+KPX W period -92
+KPX W o -92
+KPX W i -55
+KPX W hyphen -37
+KPX W h 0
+KPX W e -92
+KPX W comma -92
+KPX W colon -65
+KPX W a -92
+KPX W O -25
+KPX W A -60
+
+KPX Y u -92
+KPX Y semicolon -65
+KPX Y period -92
+KPX Y o -92
+KPX Y i -74
+KPX Y hyphen -74
+KPX Y e -92
+KPX Y comma -92
+KPX Y colon -65
+KPX Y a -92
+KPX Y O -15
+KPX Y A -50
+
+KPX a y 0
+KPX a w 0
+KPX a v 0
+KPX a t 0
+KPX a p 0
+KPX a g -10
+KPX a b 0
+
+KPX b y 0
+KPX b v 0
+KPX b u -20
+KPX b period -40
+KPX b l 0
+KPX b comma 0
+KPX b b 0
+
+KPX c y 0
+KPX c period 0
+KPX c l 0
+KPX c k -20
+KPX c h -15
+KPX c comma 0
+
+KPX colon space 0
+
+KPX comma space 0
+KPX comma quoteright -140
+KPX comma quotedblright -140
+
+KPX d y 0
+KPX d w 0
+KPX d v 0
+KPX d period 0
+KPX d d 0
+KPX d comma 0
+
+KPX e y -30
+KPX e x -20
+KPX e w -15
+KPX e v -15
+KPX e period -15
+KPX e p 0
+KPX e g -40
+KPX e comma -10
+KPX e b 0
+
+KPX f quoteright 92
+KPX f quotedblright 0
+KPX f period -15
+KPX f o 0
+KPX f l 0
+KPX f i -20
+KPX f f -18
+KPX f e 0
+KPX f dotlessi -60
+KPX f comma -10
+KPX f a 0
+
+KPX g y 0
+KPX g r 0
+KPX g period -15
+KPX g o 0
+KPX g i 0
+KPX g g -10
+KPX g e -10
+KPX g comma -10
+KPX g a 0
+
+KPX h y 0
+
+KPX i v 0
+
+KPX k y -10
+KPX k o -10
+KPX k e -10
+
+KPX l y 0
+KPX l w 0
+
+KPX m y 0
+KPX m u 0
+
+KPX n y 0
+KPX n v -40
+KPX n u 0
+
+KPX o y 0
+KPX o x 0
+KPX o w 0
+KPX o v -10
+KPX o g -10
+
+KPX p y 0
+
+KPX period quoteright -140
+KPX period quotedblright -140
+
+KPX quotedblleft quoteleft 0
+KPX quotedblleft A 0
+
+KPX quotedblright space 0
+
+KPX quoteleft quoteleft -111
+KPX quoteleft A 0
+
+KPX quoteright v -10
+KPX quoteright t -30
+KPX quoteright space -111
+KPX quoteright s -40
+KPX quoteright r -25
+KPX quoteright quoteright -111
+KPX quoteright quotedblright 0
+KPX quoteright l 0
+KPX quoteright d -25
+
+KPX r y 0
+KPX r v 0
+KPX r u 0
+KPX r t 0
+KPX r s -10
+KPX r r 0
+KPX r q -37
+KPX r period -111
+KPX r p 0
+KPX r o -45
+KPX r n 0
+KPX r m 0
+KPX r l 0
+KPX r k 0
+KPX r i 0
+KPX r hyphen -20
+KPX r g -37
+KPX r e -37
+KPX r d -37
+KPX r comma -111
+KPX r c -37
+KPX r a -15
+
+KPX s w 0
+
+KPX space quoteleft 0
+KPX space quotedblleft 0
+KPX space Y -75
+KPX space W -40
+KPX space V -35
+KPX space T -18
+KPX space A -18
+
+KPX v period -74
+KPX v o 0
+KPX v e 0
+KPX v comma -74
+KPX v a 0
+
+KPX w period -74
+KPX w o 0
+KPX w h 0
+KPX w e 0
+KPX w comma -74
+KPX w a 0
+
+KPX x e 0
+
+KPX y period -55
+KPX y o 0
+KPX y e 0
+KPX y comma -55
+KPX y a 0
+
+KPX z o 0
+KPX z e 0
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 139 212 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 144 212 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 139 212 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 149 212 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 129 192 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 139 212 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 149 212 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 169 212 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 159 212 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 149 212 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 10 212 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 40 212 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 30 212 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 10 212 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 177 212 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 212 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 230 212 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 205 212 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 212 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 94 212 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 215 212 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 225 212 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 215 212 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 132 212 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 142 212 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 112 212 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 84 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -57 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -52 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 49 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 74 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 69 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 74 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 74 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 74 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 36 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 8 0 ;
+EndComposites
+EndFontMetrics
diff --git a/config/psfonts/Times-Roman.afm b/config/psfonts/Times-Roman.afm
new file mode 100644 (file)
index 0000000..e5092b5
--- /dev/null
@@ -0,0 +1,648 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Mar 20 12:15:44 1990
+Comment UniqueID 28416
+Comment VMusage 30487 37379
+FontName Times-Roman
+FullName Times Roman
+FamilyName Times
+Weight Roman
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -168 -218 1000 898
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 662
+XHeight 450
+Ascender 683
+Descender -217
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ;
+C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ;
+C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ;
+C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ;
+C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ;
+C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ;
+C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ;
+C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ;
+C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ;
+C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ;
+C 43 ; WX 564 ; N plus ; B 30 0 534 506 ;
+C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ;
+C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ;
+C 46 ; WX 250 ; N period ; B 70 -11 181 100 ;
+C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ;
+C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ;
+C 49 ; WX 500 ; N one ; B 111 0 394 676 ;
+C 50 ; WX 500 ; N two ; B 30 0 475 676 ;
+C 51 ; WX 500 ; N three ; B 43 -14 431 676 ;
+C 52 ; WX 500 ; N four ; B 12 0 472 676 ;
+C 53 ; WX 500 ; N five ; B 32 -14 438 688 ;
+C 54 ; WX 500 ; N six ; B 34 -14 468 684 ;
+C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ;
+C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ;
+C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ;
+C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ;
+C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ;
+C 60 ; WX 564 ; N less ; B 28 -8 536 514 ;
+C 61 ; WX 564 ; N equal ; B 30 120 534 386 ;
+C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ;
+C 63 ; WX 444 ; N question ; B 68 -8 414 676 ;
+C 64 ; WX 921 ; N at ; B 116 -14 809 676 ;
+C 65 ; WX 722 ; N A ; B 15 0 706 674 ;
+C 66 ; WX 667 ; N B ; B 17 0 593 662 ;
+C 67 ; WX 667 ; N C ; B 28 -14 633 676 ;
+C 68 ; WX 722 ; N D ; B 16 0 685 662 ;
+C 69 ; WX 611 ; N E ; B 12 0 597 662 ;
+C 70 ; WX 556 ; N F ; B 12 0 546 662 ;
+C 71 ; WX 722 ; N G ; B 32 -14 709 676 ;
+C 72 ; WX 722 ; N H ; B 19 0 702 662 ;
+C 73 ; WX 333 ; N I ; B 18 0 315 662 ;
+C 74 ; WX 389 ; N J ; B 10 -14 370 662 ;
+C 75 ; WX 722 ; N K ; B 34 0 723 662 ;
+C 76 ; WX 611 ; N L ; B 12 0 598 662 ;
+C 77 ; WX 889 ; N M ; B 12 0 863 662 ;
+C 78 ; WX 722 ; N N ; B 12 -11 707 662 ;
+C 79 ; WX 722 ; N O ; B 34 -14 688 676 ;
+C 80 ; WX 556 ; N P ; B 16 0 542 662 ;
+C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ;
+C 82 ; WX 667 ; N R ; B 17 0 659 662 ;
+C 83 ; WX 556 ; N S ; B 42 -14 491 676 ;
+C 84 ; WX 611 ; N T ; B 17 0 593 662 ;
+C 85 ; WX 722 ; N U ; B 14 -14 705 662 ;
+C 86 ; WX 722 ; N V ; B 16 -11 697 662 ;
+C 87 ; WX 944 ; N W ; B 5 -11 932 662 ;
+C 88 ; WX 722 ; N X ; B 10 0 704 662 ;
+C 89 ; WX 722 ; N Y ; B 22 0 703 662 ;
+C 90 ; WX 611 ; N Z ; B 9 0 597 662 ;
+C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ;
+C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ;
+C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ;
+C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ;
+C 97 ; WX 444 ; N a ; B 37 -10 442 460 ;
+C 98 ; WX 500 ; N b ; B 3 -10 468 683 ;
+C 99 ; WX 444 ; N c ; B 25 -10 412 460 ;
+C 100 ; WX 500 ; N d ; B 27 -10 491 683 ;
+C 101 ; WX 444 ; N e ; B 25 -10 424 460 ;
+C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 28 -218 470 460 ;
+C 104 ; WX 500 ; N h ; B 9 0 487 683 ;
+C 105 ; WX 278 ; N i ; B 16 0 253 683 ;
+C 106 ; WX 278 ; N j ; B -70 -218 194 683 ;
+C 107 ; WX 500 ; N k ; B 7 0 505 683 ;
+C 108 ; WX 278 ; N l ; B 19 0 257 683 ;
+C 109 ; WX 778 ; N m ; B 16 0 775 460 ;
+C 110 ; WX 500 ; N n ; B 16 0 485 460 ;
+C 111 ; WX 500 ; N o ; B 29 -10 470 460 ;
+C 112 ; WX 500 ; N p ; B 5 -217 470 460 ;
+C 113 ; WX 500 ; N q ; B 24 -217 488 460 ;
+C 114 ; WX 333 ; N r ; B 5 0 335 460 ;
+C 115 ; WX 389 ; N s ; B 51 -10 348 460 ;
+C 116 ; WX 278 ; N t ; B 13 -10 279 579 ;
+C 117 ; WX 500 ; N u ; B 9 -10 479 450 ;
+C 118 ; WX 500 ; N v ; B 19 -14 477 450 ;
+C 119 ; WX 722 ; N w ; B 21 -14 694 450 ;
+C 120 ; WX 500 ; N x ; B 17 0 479 450 ;
+C 121 ; WX 500 ; N y ; B 14 -218 475 450 ;
+C 122 ; WX 444 ; N z ; B 27 0 418 450 ;
+C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ;
+C 124 ; WX 200 ; N bar ; B 67 -14 133 676 ;
+C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ;
+C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
+C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ;
+C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ;
+C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ;
+C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ;
+C 165 ; WX 500 ; N yen ; B -53 0 512 662 ;
+C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ;
+C 167 ; WX 500 ; N section ; B 70 -148 426 676 ;
+C 168 ; WX 500 ; N currency ; B -22 58 522 602 ;
+C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ;
+C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ;
+C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ;
+C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ;
+C 174 ; WX 556 ; N fi ; B 31 0 521 683 ;
+C 175 ; WX 556 ; N fl ; B 32 0 521 683 ;
+C 177 ; WX 500 ; N endash ; B 0 201 500 250 ;
+C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ;
+C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ;
+C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
+C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ;
+C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ;
+C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ;
+C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ;
+C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ;
+C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ;
+C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ;
+C 193 ; WX 333 ; N grave ; B 19 507 242 678 ;
+C 194 ; WX 333 ; N acute ; B 93 507 317 678 ;
+C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ;
+C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ;
+C 197 ; WX 333 ; N macron ; B 11 547 322 601 ;
+C 198 ; WX 333 ; N breve ; B 26 507 307 664 ;
+C 199 ; WX 333 ; N dotaccent ; B 118 523 216 623 ;
+C 200 ; WX 333 ; N dieresis ; B 18 523 315 623 ;
+C 202 ; WX 333 ; N ring ; B 67 512 266 711 ;
+C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ;
+C 206 ; WX 333 ; N ogonek ; B 64 -165 249 0 ;
+C 207 ; WX 333 ; N caron ; B 11 507 322 674 ;
+C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ;
+C 225 ; WX 889 ; N AE ; B 0 0 863 662 ;
+C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ;
+C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ;
+C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ;
+C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ;
+C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ;
+C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ;
+C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ;
+C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ;
+C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ;
+C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ;
+C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ;
+C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ;
+C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ;
+C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ;
+C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ;
+C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ;
+C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ;
+C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ;
+C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ;
+C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ;
+C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ;
+C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ;
+C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ;
+C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ;
+C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ;
+C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ;
+C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ;
+C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ;
+C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ;
+C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ;
+C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ;
+C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ;
+C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ;
+C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ;
+C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ;
+C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ;
+C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ;
+C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ;
+C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ;
+C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ;
+C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ;
+C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ;
+C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ;
+C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ;
+C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ;
+C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ;
+C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ;
+C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ;
+C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ;
+C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ;
+C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ;
+C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ;
+C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ;
+C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ;
+C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ;
+C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ;
+C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ;
+C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ;
+C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ;
+C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ;
+C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ;
+C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ;
+C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ;
+C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ;
+C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ;
+C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ;
+C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ;
+C -1 ; WX 564 ; N minus ; B 30 220 534 286 ;
+C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ;
+C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ;
+C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ;
+C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ;
+C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ;
+C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ;
+C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ;
+C -1 ; WX 400 ; N degree ; B 57 390 343 676 ;
+C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ;
+C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ;
+C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ;
+C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ;
+C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ;
+C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ;
+C -1 ; WX 200 ; N brokenbar ; B 67 -14 133 676 ;
+C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 283
+
+KPX A y -92
+KPX A w -92
+KPX A v -74
+KPX A u 0
+KPX A quoteright -111
+KPX A quotedblright 0
+KPX A p 0
+KPX A Y -105
+KPX A W -90
+KPX A V -135
+KPX A U -55
+KPX A T -111
+KPX A Q -55
+KPX A O -55
+KPX A G -40
+KPX A C -40
+
+KPX B period 0
+KPX B comma 0
+KPX B U -10
+KPX B A -35
+
+KPX D period 0
+KPX D comma 0
+KPX D Y -55
+KPX D W -30
+KPX D V -40
+KPX D A -40
+
+KPX F r 0
+KPX F period -80
+KPX F o -15
+KPX F i 0
+KPX F e 0
+KPX F comma -80
+KPX F a -15
+KPX F A -74
+
+KPX G period 0
+KPX G comma 0
+
+KPX J u 0
+KPX J period 0
+KPX J o 0
+KPX J e 0
+KPX J comma 0
+KPX J a 0
+KPX J A -60
+
+KPX K y -25
+KPX K u -15
+KPX K o -35
+KPX K e -25
+KPX K O -30
+
+KPX L y -55
+KPX L quoteright -92
+KPX L quotedblright 0
+KPX L Y -100
+KPX L W -74
+KPX L V -100
+KPX L T -92
+
+KPX N period 0
+KPX N comma 0
+KPX N A -35
+
+KPX O period 0
+KPX O comma 0
+KPX O Y -50
+KPX O X -40
+KPX O W -35
+KPX O V -50
+KPX O T -40
+KPX O A -35
+
+KPX P period -111
+KPX P o 0
+KPX P e 0
+KPX P comma -111
+KPX P a -15
+KPX P A -92
+
+KPX Q period 0
+KPX Q comma 0
+KPX Q U -10
+
+KPX R Y -65
+KPX R W -55
+KPX R V -80
+KPX R U -40
+KPX R T -60
+KPX R O -40
+
+KPX S period 0
+KPX S comma 0
+
+KPX T y -80
+KPX T w -80
+KPX T u -45
+KPX T semicolon -55
+KPX T r -35
+KPX T period -74
+KPX T o -80
+KPX T i -35
+KPX T hyphen -92
+KPX T h 0
+KPX T e -70
+KPX T comma -74
+KPX T colon -50
+KPX T a -80
+KPX T O -18
+KPX T A -93
+
+KPX U period 0
+KPX U comma 0
+KPX U A -40
+
+KPX V u -75
+KPX V semicolon -74
+KPX V period -129
+KPX V o -129
+KPX V i -60
+KPX V hyphen -100
+KPX V e -111
+KPX V comma -129
+KPX V colon -74
+KPX V a -111
+KPX V O -40
+KPX V G -15
+KPX V A -135
+
+KPX W y -73
+KPX W u -50
+KPX W semicolon -37
+KPX W period -92
+KPX W o -80
+KPX W i -40
+KPX W hyphen -65
+KPX W h 0
+KPX W e -80
+KPX W comma -92
+KPX W colon -37
+KPX W a -80
+KPX W O -10
+KPX W A -120
+
+KPX Y u -111
+KPX Y semicolon -92
+KPX Y period -129
+KPX Y o -110
+KPX Y i -55
+KPX Y hyphen -111
+KPX Y e -100
+KPX Y comma -129
+KPX Y colon -92
+KPX Y a -100
+KPX Y O -30
+KPX Y A -120
+
+KPX a y 0
+KPX a w -15
+KPX a v -20
+KPX a t 0
+KPX a p 0
+KPX a g 0
+KPX a b 0
+
+KPX b y 0
+KPX b v -15
+KPX b u -20
+KPX b period -40
+KPX b l 0
+KPX b comma 0
+KPX b b 0
+
+KPX c y -15
+KPX c period 0
+KPX c l 0
+KPX c k 0
+KPX c h 0
+KPX c comma 0
+
+KPX colon space 0
+
+KPX comma space 0
+KPX comma quoteright -70
+KPX comma quotedblright -70
+
+KPX d y 0
+KPX d w 0
+KPX d v 0
+KPX d period 0
+KPX d d 0
+KPX d comma 0
+
+KPX e y -15
+KPX e x -15
+KPX e w -25
+KPX e v -25
+KPX e period 0
+KPX e p 0
+KPX e g -15
+KPX e comma 0
+KPX e b 0
+
+KPX f quoteright 55
+KPX f quotedblright 0
+KPX f period 0
+KPX f o 0
+KPX f l 0
+KPX f i -20
+KPX f f -25
+KPX f e 0
+KPX f dotlessi -50
+KPX f comma 0
+KPX f a -10
+
+KPX g y 0
+KPX g r 0
+KPX g period 0
+KPX g o 0
+KPX g i 0
+KPX g g 0
+KPX g e 0
+KPX g comma 0
+KPX g a -5
+
+KPX h y -5
+
+KPX i v -25
+
+KPX k y -15
+KPX k o -10
+KPX k e -10
+
+KPX l y 0
+KPX l w -10
+
+KPX m y 0
+KPX m u 0
+
+KPX n y -15
+KPX n v -40
+KPX n u 0
+
+KPX o y -10
+KPX o x 0
+KPX o w -25
+KPX o v -15
+KPX o g 0
+
+KPX p y -10
+
+KPX period quoteright -70
+KPX period quotedblright -70
+
+KPX quotedblleft quoteleft 0
+KPX quotedblleft A -80
+
+KPX quotedblright space 0
+
+KPX quoteleft quoteleft -74
+KPX quoteleft A -80
+
+KPX quoteright v -50
+KPX quoteright t -18
+KPX quoteright space -74
+KPX quoteright s -55
+KPX quoteright r -50
+KPX quoteright quoteright -74
+KPX quoteright quotedblright 0
+KPX quoteright l -10
+KPX quoteright d -50
+
+KPX r y 0
+KPX r v 0
+KPX r u 0
+KPX r t 0
+KPX r s 0
+KPX r r 0
+KPX r q 0
+KPX r period -55
+KPX r p 0
+KPX r o 0
+KPX r n 0
+KPX r m 0
+KPX r l 0
+KPX r k 0
+KPX r i 0
+KPX r hyphen -20
+KPX r g -18
+KPX r e 0
+KPX r d 0
+KPX r comma -40
+KPX r c 0
+KPX r a 0
+
+KPX s w 0
+
+KPX space quoteleft 0
+KPX space quotedblleft 0
+KPX space Y -90
+KPX space W -30
+KPX space V -50
+KPX space T -18
+KPX space A -55
+
+KPX v period -65
+KPX v o -20
+KPX v e -15
+KPX v comma -65
+KPX v a -25
+
+KPX w period -65
+KPX w o -10
+KPX w h 0
+KPX w e 0
+KPX w comma -65
+KPX w a -10
+
+KPX x e -15
+
+KPX y period -65
+KPX y o 0
+KPX y e 0
+KPX y comma -65
+KPX y a 0
+
+KPX z o 0
+KPX z e 0
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 212 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 212 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 212 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 212 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 185 187 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 212 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 212 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 212 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 212 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 212 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 212 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 212 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 212 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 212 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 212 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 195 212 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 195 212 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 195 212 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 195 212 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 212 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 212 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 212 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 212 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 195 212 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 195 212 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 212 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 56 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 56 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 56 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ;
+EndComposites
+EndFontMetrics
index 06dfc78efd612b2720e8c085e4d6907d65f6b4f7..efc2f9dad480b710500b3d54018153500137480d 100644 (file)
@@ -1,4 +1,4 @@
-@node Concept Index, Installation, Command Index, Top
+@node Concept Index, Configuration, Command Index, Top
 @chapter Concept Index
 @printindex cp
 @setfilename ignored
 @chapter Concept Index
 @printindex cp
 @setfilename ignored
index 3c1a4adcc1d01c853e53807ab97a279ffa755591..386f6dd547334075399c90c98c2445a890f50431 100644 (file)
@@ -1,18 +1,13 @@
-@node Configuration, Portable File Format, Installation, Top
+@node Configuration, Portable File Format, Concept Index, Top
 @appendix Configuring PSPP
 @cindex configuration
 @cindex PSPP, configuring
 
 @appendix Configuring PSPP
 @cindex configuration
 @cindex PSPP, configuring
 
-PSPP has dozens of configuration possibilities and hundreds of
-settings.  This is both a bane and a blessing.  On one hand, it's
-possible to easily accommodate diverse ranges of setups.  But, on the
-other, the multitude of possibilities can overwhelm the casual user.
-Fortunately, the configuration mechanisms are profusely described in the
-sections below@enddots{}
+This chapter describe how to configure PSPP for your system.
 
 @menu
 * File locations::              How PSPP finds config files.
 
 @menu
 * File locations::              How PSPP finds config files.
-* Configuration techniques::    Many different methods of configuration@enddots{}
+* Configuration techniques::    Many different methods of configuration...
 * Configuration files::         How configuration files are read.
 * Environment variables::       All about environment variables.
 * Output devices::              Describing your terminal(s) and printer(s).
 * Configuration files::         How configuration files are read.
 * Environment variables::       All about environment variables.
 * Output devices::              Describing your terminal(s) and printer(s).
@@ -20,123 +15,19 @@ sections below@enddots{}
 * ASCII driver class::          Configuration of character-code devices.
 * HTML driver class::           Configuration for HTML output.
 * Miscellaneous configuring::   Even more configuration variables.
 * ASCII driver class::          Configuration of character-code devices.
 * HTML driver class::           Configuration for HTML output.
 * Miscellaneous configuring::   Even more configuration variables.
-* Improving output quality::    Hints for producing ever-more-lovely output.
 @end menu
 
 @node File locations, Configuration techniques, Configuration, Configuration
 @section Locating configuration files
 
 @end menu
 
 @node File locations, Configuration techniques, Configuration, Configuration
 @section Locating configuration files
 
-PSPP uses the same method to find most of its configuration files:
-
-@enumerate
-@item
-The @dfn{base name} of the file being sought is determined.
-
-@item
-The path to search is determined.  
-
-@item
-Each directory in the search path, from left to right, is searched for a
-file with the name of the base name.  The first occurrence is read
-as the configuration file.
-@end enumerate
-
-The first two steps are elaborated below for the sake of our pedantic
-friends.
-
-@enumerate
-@item
-A @dfn{base name} is a file name lacking an absolute directory
-reference.  Some examples of base names are: @file{ps-encodings},
-@file{devices}, @file{devps/DESC} (under UNIX), @file{devps\DESC} (under
-M$ environments).
-
-Determining the base name is a two-step process:
-
-@enumerate a
-@item
-If the appropriate environment variable is defined, the value of that
-variable is used (@pxref{Environment variables}).  For instance, when
-searching for the output driver initialization file, the variable
-examined is @code{STAT_OUTPUT_INIT_FILE}.
-
-@item
-Otherwise, the compiled-in default is used.  For example, when searching
-for the output driver initialization file, the default base name is
-@file{devices}.
-@end enumerate
-
-@strong{Please note:} If a user-specified base name does contain an
-absolute directory reference, as in a file name like
-@file{/home/pfaff/fonts/TR}, no path is searched---the file name is used
-exactly as given---and the algorithm terminates.
-
-@item
-The path is the first of the following that is defined:
-
-@itemize @bullet
-@item
-A variable definition for the path given in the user environment.  This
-is a PSPP-specific environment variable name; for instance,
-@code{STAT_OUTPUT_INIT_PATH}.
-
-@item 
-In some cases, another, less-specific environment variable is checked.
-For instance, when searching for font files, the PostScript driver first
-checks for a variable with name @code{STAT_GROFF_FONT_PATH}, then for
-one with name @code{GROFF_FONT_PATH}.  (However, font searching has its
-own list of esoteric search rules.)
-
-@item
-The configuration file path, which is itself determined by the
-following rules:
-
-@enumerate a
-@item
-If the command line contains an option of the form @samp{-B @var{path}}
-or @samp{--config-dir=@var{path}}, then the value given on the
-rightmost occurrence of such an option is used.
-
-@item
-Otherwise, if the environment variable @code{STAT_CONFIG_PATH} is
-defined, the value of that variable is used.
-
-@item
-Otherwise, the compiled-in fallback default is used.  On UNIX machines,
-the default fallback path is
-
-@enumerate 1
-@item
-@file{~/.pspp}
-
-@item
-@file{/usr/local/lib/pspp}
-
-@item
-@file{/usr/lib/pspp}
-@end enumerate
-
-On DOS machines, the default fallback path is:
-
-@enumerate 1
-@item
-All the paths from the DOS search path in the @samp{PATH} environment
-variable, in left-to-right order.
-
-@item
-@file{C:\PSPP}, as a last resort.
-@end enumerate
-
-Note that the installer of PSPP can easily change this default
-fallback path; thus the above should not be taken as gospel.
-@end enumerate
-@end itemize
-@end enumerate
-
-As a final note: Under DOS, directories given in paths are delimited by
-semicolons (@samp{;}); under UNIX, directories are delimited by colons
-(@samp{:}).  This corresponds with the standard path delimiter under
-these OSes.
+PSPP searches each directory in the configuration file path for most
+configuration files.  The default configuration file path searches first
+@file{~/.pspp}, then the package system configuration directory (usually
+@file{/usr/local/etc/pspp} or @file{/etc/pspp}).  The value of
+environment variable @env{PSPP_CONFIG_PATH}, if defined, overrides this
+default path.  Finally, @samp{-B @var{path}} or
+@samp{--config-dir=@var{path}} specified on the command line has highest
+priority.
 
 @node Configuration techniques, Configuration files, File locations, Configuration
 @section Configuration techniques
 
 @node Configuration techniques, Configuration files, File locations, Configuration
 @section Configuration techniques
@@ -231,55 +122,11 @@ even something so simple.  Environment variables are further described
 in the sections below:
 
 @menu
 in the sections below:
 
 @menu
-* Variable values::             Values of variables are determined this way.
 * Environment substitutions::   How environment substitutions are made.
 * Predefined variables::        A few variables are automatically defined.
 @end menu
 
 * Environment substitutions::   How environment substitutions are made.
 * Predefined variables::        A few variables are automatically defined.
 @end menu
 
-@node Variable values, Environment substitutions, Environment variables, Environment variables
-@subsection Values of environment variables
-
-Values for environment variables are obtained by the following means,
-which are arranged in order of decreasing precedence:
-
-@enumerate
-@item
-Command-line options.  @xref{Invocation}.
-
-@item
-The @file{environment} configuration file---more on this below.
-
-@item
-Actual environment variables (defined in the shell or other parent
-process).
-@end enumerate
-
-The @file{environment} configuration file is located through application
-of the usual algorithm for configuration files (@pxref{File locations}),
-except that its contents do not affect the search path used to find
-@file{environment} itself.  Use of @file{environment} is discouraged on
-systems that allow an arbitrarily large environment; it is supported for
-use on systems like MS-DOS that limit environment size.
-
-@file{environment} is composed of lines having the form
-@samp{@var{key}=@var{value}}, where @var{key} and the equals sign
-(@samp{=}) are required, and @var{value} is optional.  If @var{value} is
-given, variable @var{key} is given that value; if @var{value} is absent,
-variable @var{key} is undefined (deleted).  Variables may not be defined
-with a null value.
-
-Environment substitutions are performed on each line in the file
-(@pxref{Environment substitutions}).
-
-See @ref{Configuration files}, for more details on formatting of the
-environment configuration file.
-
-@quotation
-@strong{Please note:} Support for @file{environment} is not yet
-implemented.
-@end quotation
-
-@node Environment substitutions, Predefined variables, Variable values, Environment variables
+@node Environment substitutions, Predefined variables, Environment variables, Environment variables
 @subsection Environment substitutions
 
 Much of the power of environment variables lies in the way that they may
 @subsection Environment substitutions
 
 Much of the power of environment variables lies in the way that they may
@@ -287,24 +134,15 @@ be substituted into configuration files.  Variable substitutions are
 described below.
 
 The line is scanned from left to right.  In this scan, all characters
 described below.
 
 The line is scanned from left to right.  In this scan, all characters
-other than dollar signs (@samp{$}) are retained unmolested.  Dollar
-signs, however, introduce an environment variable reference.  References
+other than dollar signs (@samp{$}) are retained without change.  Dollar
+signs introduce environment variable references.  References
 take three forms:
 
 @table @code
 @item $@var{var}
 take three forms:
 
 @table @code
 @item $@var{var}
-Replaced by the value of environment variable @var{var}, determined as
-specified in @ref{Variable values}.  @var{var} must be one of the
-following:
-
-@itemize @bullet
-@item
-One or more letters.
-
-@item
-Exactly one nonalphabetic character.  This may not be a left brace
-(@samp{@{}).
-@end itemize
+Replaced by the value of environment variable @var{var}.  @var{var} must
+consist of either one or more letters, or exactly one non-alphabetic
+character other than a left brace (@samp{@{}).
 
 @item $@{@var{var}@}
 Same as above, but @var{var} may contain any character (except
 
 @item $@{@var{var}@}
 Same as above, but @var{var} may contain any character (except
@@ -737,34 +575,9 @@ signs.
 @section The PostScript driver class
 
 The @code{postscript} driver class is used to produce output that is
 @section The PostScript driver class
 
 The @code{postscript} driver class is used to produce output that is
-acceptable to PostScript printers and to PC-based PostScript
-interpreters such as Ghostscript.  Continuing a long tradition,
-PSPP's PostScript driver is configurable to the point of
-absurdity.
-
-There are actually two PostScript drivers.  The first one,
-@samp{postscript}, produces ordinary DSC-compliant PostScript output.
-The second one @samp{epsf}, produces an Encapsulated PostScript file.
-The two drivers are otherwise identical in configuration and in
-operation.
-
-The PostScript driver is described in further detail below.
-
-@menu
-* PS output options::           Output file options.
-* PS page options::             Paper, margins, scaling & rotation, more!
-* PS file options::             Configuration files.
-* PS font options::             Default fonts, font options.
-* PS line options::             Line widths, options.
-* Prologue::                    Details on the PostScript prologue.
-* Encodings::                   Details on PostScript font encodings.
-@end menu
-
-@node PS output options, PS page options, PostScript driver class, PostScript driver class
-@subsection PostScript output options
+acceptable to PostScript printers and other interpreters.
 
 
-These options deal with the form of the output and the output file
-itself:
+The available options are listed below.
 
 @table @code
 @item output-file=@var{filename}
 
 @table @code
 @item output-file=@var{filename}
@@ -773,57 +586,6 @@ File to which output should be sent.  This can be an ordinary filename
 (i.e., @code{"pspp.ps"}), a pipe filename (i.e., @code{"|lpr"}), or
 stdout (@code{"-"}).  Default: @code{"pspp.ps"}.
 
 (i.e., @code{"pspp.ps"}), a pipe filename (i.e., @code{"|lpr"}), or
 stdout (@code{"-"}).  Default: @code{"pspp.ps"}.
 
-@item color=@var{boolean}
-
-Most of the time black-and-white PostScript devices are smart enough to
-map colors to shades themselves.  However, you can cause the PSPP
-output driver to do an ugly simulation of this in its own driver by
-turning @code{color} off.  Default: @code{on}.
-
-This is a boolean setting, as are many settings in the PostScript
-driver.  Valid positive boolean values are @samp{on}, @samp{true},
-@samp{yes}, and nonzero integers.  Negative boolean values are
-@samp{off}, @samp{false}, @samp{no}, and zero.
-
-@item data=@var{data-type}
-
-One of @code{clean7bit}, @code{clean8bit}, or @code{binary}.  This
-controls what characters will be written to the output file.  PostScript
-produced with @code{clean7bit} can be transmitted over 7-bit
-transmission channels that use ASCII control characters for line
-control.  @code{clean8bit} is similar but allows characters above 127 to
-be written to the output file.  @code{binary} allows any character in
-the output file.  Default: @code{clean7bit}.
-
-@item line-ends=@var{line-end-type}
-
-One of @code{cr}, @code{lf}, or @code{crlf}.  This controls what is used
-for new-line in the output file.  Default: @code{cr}.
-
-@item optimize-line-size=@var{level}
-
-Either @code{0} or @code{1}.  If @var{level} is @code{1}, then short
-line segments will be collected and merged into longer ones.  This
-reduces output file size but requires more time and memory.  A
-@var{level} of @code{0} has the advantage of being better for
-interactive environments.  @code{1} is the default unless the
-@code{screen} flag is set; in that case, the default is @code{0}.
-
-@item optimize-text-size=@var{level}
-
-One of @code{0}, @code{1}, or @code{2}, each higher level representing
-correspondingly more aggressive space savings for text in the output
-file and requiring correspondingly more time and memory.  Unfortunately
-the levels presently are all the same.  @code{1} is the default unless
-the @code{screen} flag is set; in that case, the default is @code{0}.
-@end table
-
-@node PS page options, PS file options, PS output options, PostScript driver class
-@subsection PostScript page options
-
-These options affect page setup:
-
-@table @code
 @item headers=@var{boolean}
 
 Controls whether the standard headers showing the time and date and
 @item headers=@var{boolean}
 
 Controls whether the standard headers showing the time and date and
@@ -849,355 +611,58 @@ Sets the margins around the page.  The headers, if enabled, are not
 included in the margins; they are in addition to the margins.  For a
 description of dimensions, see @ref{Dimensions}.  Default: @code{0.5in}.
 
 included in the margins; they are in addition to the margins.  For a
 description of dimensions, see @ref{Dimensions}.  Default: @code{0.5in}.
 
-@end table
-
-@node PS file options, PS font options, PS page options, PostScript driver class
-@subsection PostScript file options
-
-Oh, my.  You don't really want to know about the way that the PostScript
-driver deals with files, do you?  Well I suppose you're entitled, but I
-warn you right now: it's not pretty.  Here goes@enddots{}
-
-First let's look at the options that are available:
-
-@table @code
-
-@item font-dir=@var{font-directory}
-
-Sets the font directory.  Default: @code{devps}.
-
-@item prologue-file=@var{prologue-file-name}
+@item prop-font=@var{afm-file}[,@var{font-file}[,@var{encoding-file}]]
+@itemx emph-font=@var{afm-file}[,@var{font-file}[,@var{encoding-file}]]
+@itemx fixed-font=@var{afm-file}[,@var{font-file}[,@var{encoding-file}]]
 
 
-Sets the name of the PostScript prologue file.  You can write your own
-prologue, though I have no idea why you'd want to: see @ref{Prologue}.
-Default: @code{ps-prologue}.
+Sets the font used for proportional, emphasized, or fixed-pitch text.
+The only required value is @var{afm-file}, the AFM file for the font.
 
 
-@item device-file=@var{device-file-name}
+If specified, @var{font-file} will be downloaded to the printer at the
+beginning of the print job.  The font file may be in PFA or PFB format.
 
 
-Sets the name of the Groff-format device description file.  The
-PostScript driver reads this to know about the scaling of fonts
-and so on.  The format of such files is described in the groff_font man page,
-included with Groff.  Default: @code{DESC}.
+The font is reencoded as specified in @var{encoding-file}, if specified.
+Each line in @var{encoding-file} should consist of a PostScript
+character name and a decimal encoding value (between 0 and 255),
+separated by white space.  Blank lines and comments introduced by
+@samp{#} are also allowed.
 
 
-@item encoding-file=@var{encoding-file-name}
+The files specified on these options are located as follows.  If
+the file name begins with @samp{/}, then it is taken as an absolute
+path.  Otherwise, PSPP searches its configuration path for the specified
+name prefixed by @code{psfonts/} (@pxref{File locations}).
 
 
-Sets the name of the encoding file.  This file contains a list of all
-font encodings that will be needed so that the driver can put all of
-them at the top of the prologue.  @xref{Encodings}.  Default:
-@code{ps-encodings}.
-
-If the specified encoding file cannot be found, this error will be
-silently ignored, since most people do not need any encodings besides
-the ones that can be found using @code{auto-encodings}, described below.
-
-@item auto-encode=@var{boolean}
-
-When enabled, the font encodings needed by the default proportional- and
-fixed-pitch fonts will automatically be dumped to the PostScript
-output.  Otherwise, it is assumed that the user has an encoding file
-and knows how to use it (@pxref{Encodings}).  There is probably no good
-reason to turn off this convenient feature.  Default: @code{on}.
-
-@end table
-
-Next I suppose it's time to describe the search algorithm.  When the
-PostScript driver needs a file, whether that file be a font, a
-PostScript prologue, or what you will, it searches in this manner:
-
-@enumerate
-
-@item
-Constructs a path by taking the first of the following that is defined:
-
-@enumerate a
-
-@item
-Environment variable @code{STAT_GROFF_FONT_PATH}.  @xref{Environment
-variables}.
-
-@item
-Environment variable @code{GROFF_FONT_PATH}.
-
-@item
-The compiled-in fallback default.
-@end enumerate
-
-@item
-Constructs a base name from concatenating, in order, the font directory,
-a path separator (@samp{/} or @samp{\}), and the file to be found.  A
-typical base name would be something like @code{devps/ps-encodings}.
-
-@item
-Searches for the base name in the path constructed above.  If the file
-is found, the algorithm terminates.
-
-@item
-Searches for the base name in the standard configuration path.  See
-@ref{File locations}, for more details.  If the file is found, the
-algorithm terminates.
-
-@item
-At this point we remove the font directory and path separator from the
-base name.  Now the base name is simply the file to be found, i.e.,
-@code{ps-encodings}.
-
-@item
-Searches for the base name in the path constructed in the first step.
-If the file is found, the algorithm terminates.
-
-@item
-Searches for the base name in the standard configuration path.  If the
-file is found, the algorithm terminates.
-
-@item
-The algorithm terminates unsuccessfully.
-@end enumerate
-
-So, as you see, there are several ways to configure the PostScript
-drivers.  Careful selection of techniques can make the configuration
-very flexible indeed.
-
-@node PS font options, PS line options, PS file options, PostScript driver class
-@subsection PostScript font options
-
-The list of available font options is short and sweet:
-
-@table @code
-@item prop-font=@var{font-name}
-
-Sets the default proportional font.  The name should be that of a
-PostScript font.  Default: @code{"Helvetica"}.
-
-@item fixed-font=@var{font-name}
-
-Sets the default fixed-pitch font.  The name should be that of a
-PostScript font.  Default: @code{"Courier"}.
+Default: proportional font @code{Times-Roman.afm}, emphasis font
+@code{Times-Italic.afm}, fixed-pitch font @code{Courier.afm}.
 
 @item font-size=@var{font-size}
 
 Sets the size of the default fonts, in thousandths of a point.  Default:
 
 @item font-size=@var{font-size}
 
 Sets the size of the default fonts, in thousandths of a point.  Default:
-@code{10000}.
-
-@end table
-
-@node PS line options, Prologue, PS font options, PostScript driver class
-@subsection PostScript line options
-
-Most tables contain lines, or rules, between cells.  Some features of
-the way that lines are drawn in PostScript tables are user-definable:
-
-@table @code
-
-@item line-style=@var{style}
-
-Sets the style used for lines used to divide tables into sections.
-@var{style} must be either @code{thick}, in which case thick lines are
-used, or @var{double}, in which case double lines are used.  Default:
-@code{thick}.
+10000 (10 point).
 
 @item line-gutter=@var{dimension}
 
 
 @item line-gutter=@var{dimension}
 
-Sets the line gutter, which is the amount of white space on either side
-of lines that border text or graphics objects.  @xref{Dimensions}.
-Default: @code{0.5pt}.
+Sets the width of white space on either side of lines that border text
+or graphics objects.  @xref{Dimensions}.  Default: @code{1pt}.
 
 @item line-spacing=@var{dimension}
 
 
 @item line-spacing=@var{dimension}
 
-Sets the line spacing, which is the amount of white space that separates
-lines that are side by side, as in a double line.  Default:
-@code{0.5pt}.
+Sets the spacing between the lines in a double line in a table.
+Default: @code{1pt}.
 
 @item line-width=@var{dimension}
 
 
 @item line-width=@var{dimension}
 
-Sets the width of a typical line used in tables.  Default: @code{0.5pt}.
-
-@item line-width-thick=@var{dimension}
-
-Sets the width of a thick line used in tables.  Not used if
-@code{line-style} is set to @code{thick}.  Default: @code{1.5pt}.
-
+Sets the width of the lines used in tables.  Default: @code{0.5pt}.
 @end table
 
 @end table
 
-@node Prologue, Encodings, PS line options, PostScript driver class
-@subsection The PostScript prologue
-
-Most PostScript files that are generated mechanically by programs
-consist of two parts: a prologue and a body.  The prologue is generally
-a collection of boilerplate.  Only the body differs greatly between
-two outputs from the same program.
-This is also the strategy used in the PSPP PostScript driver.  In
-general, the prologue supplied with PSPP will be more than sufficient.
-In this case, you will not need to read the rest of this section.
-However, hackers might want to know more.  Read on, if you fall into
-this category.
-
-The prologue is dumped into the output stream essentially unmodified.
-However, two actions are performed on its lines.  First, certain lines
-may be omitted as specified in the prologue file itself.  Second,
-variables are substituted.
-
-The following lines are omitted:
-
-@enumerate
-@item
-All lines that contain three bangs in a row (@code{!!!}).
-
-@item
-Lines that contain @code{!eps}, if the PostScript driver is producing
-ordinary PostScript output.  Otherwise an EPS file is being produced,
-and the line is included in the output, although everything following
-@code{!eps} is deleted.
-
-@item
-Lines that contain @code{!ps}, if the PostScript driver is producing EPS
-output.  Otherwise, ordinary PostScript is being produced, and the line
-is included in the output, although everything following @code{!ps} is
-deleted.
-@end enumerate
-
-The following are the variables that are substituted.  Only the
-variables listed are substituted; environment variables are not.
-@xref{Environment substitutions}.
-
-@table @code
-@item bounding-box
-
-The page bounding box, in points, as four space-separated numbers.  For
-U.S. letter size paper, this is @samp{0 0 612 792}.
-
-@item creator
-
-PSPP version as a string: @samp{GNU PSPP 0.1b}, for example.
-
-@item date
-
-Date the file was created.  Example: @samp{Tue May 21 13:46:22 1991}.
-
-@item data
-
-Value of the @code{data} PostScript driver option, as one of the strings
-@samp{Clean7Bit}, @samp{Clean8Bit}, or @samp{Binary}.
-
-@item orientation
-
-Page orientation, as one of the strings @code{Portrait} or
-@code{Landscape}.
-
-@item user
-
-Under multiuser OSes, the user's login name, taken either from the
-environment variable @code{LOGNAME} or, if that fails, the result of the
-C library function @code{getlogin()}.  Defaults to @samp{nobody}.
-
-@item host
-
-System hostname as reported by @code{gethostname()}.  Defaults to
-@samp{nowhere}.
-
-@item prop-font
-
-Name of the default proportional font, prefixed by the word
-@samp{font} and a space.  Example: @samp{font Times-Roman}.
-
-@item fixed-font
-
-Name of the default fixed-pitch font, prefixed by the word @samp{font}
-and a space.
-
-@item scale-factor
-
-The page scaling factor as a floating-point number.  Example:
-@code{1.0}.  Note that this is also passed as an argument to the BP
-macro.
-
-@item paper-length
-@item paper-width
-
-The paper length and paper width, respectively, in thousandths of a
-point.  Note that these are also passed as arguments to the BP macro.
-
-@item left-margin
-@item top-margin
-
-The left margin and top margin, respectively, in thousandths of a
-point.  Note that these are also passed as arguments to the BP macro.
-
-@item title
-
-Document title as a string.  This is not the title specified in the
-PSPP syntax file.  A typical title is the word @samp{PSPP} followed
-by the syntax file name in parentheses.  Example: @samp{PSPP
-(<stdin>)}.
-
-@item source-file
-
-PSPP syntax file name.  Example: @samp{mary96/first.stat}.
-
-@end table
-
-Any other questions about the PostScript prologue can best be answered
-by examining the default prologue or the PSPP source.
-
-@node Encodings,  , Prologue, PostScript driver class
-@subsection PostScript encodings
-
-PostScript fonts often contain many more than 256 characters, in order
-to accommodate foreign language characters and special symbols.
-PostScript uses @dfn{encodings} to map these onto single-byte symbol
-sets.  Each font can have many different encodings applied to it.
-
-PSPP's PostScript driver needs to know which encoding to apply to each
-font.  It can determine this from the information encapsulated in the
-Groff font description that it reads.  However, there is an additional
-problem---for efficiency, the PostScript driver needs to have a complete
-list of all encodings that will be used in the entire session @emph{when
-it opens the output file}.  For this reason, it can't use the
-information built into the fonts because it doesn't know which fonts
-will be used.
-
-As a stopgap solution, there are two mechanisms for specifying which
-encodings will be used.  The first mechanism is automatic and it is the
-only one that most PSPP users will ever need.  The second mechanism is
-manual, but it is more flexible.  Either mechanism or both may be used
-at one time.
-
-The first mechanism is activated by the @samp{auto-encode} driver option
-(@pxref{PS file options}).  When enabled, @samp{auto-encode} causes the
-PostScript driver to include the encodings used by the default
-proportional and fixed-pitch fonts (@pxref{PS font options}).  Many
-PSPP output files will only need these encodings.
-
-The second mechanism is the file specified by the @samp{encoding-file}
-option (@pxref{PS file options}).  If it exists, this file must consist
-of lines in PSPP configuration-file format (@pxref{Configuration
-files}).  Each line that is not a comment should name a PostScript
-encoding to include in the output.
-
-It is not an error if an encoding is included more than once, by either
-mechanism.  It will appear only once in the output.  It is also not an
-error if an encoding is included in the output but never used.  It
-@emph{is} an error if an encoding is used but not included by one of
-these mechanisms.  In this case, the built-in PostScript encoding
-@samp{ISOLatin1Encoding} is substituted.
-
 @node ASCII driver class, HTML driver class, PostScript driver class, Configuration
 @section The ASCII driver class
 
 The ASCII driver class produces output that can be displayed on a
 @node ASCII driver class, HTML driver class, PostScript driver class, Configuration
 @section The ASCII driver class
 
 The ASCII driver class produces output that can be displayed on a
-terminal or output to printers.  All of its options are highly
-configurable.  The ASCII driver has class name @samp{ascii}.
-
-The ASCII driver is described in further detail below.
+terminal or output to printers.  The ASCII driver has class name
+@samp{ascii}.
 
 
-@menu
-* ASCII output options::        Output file options.
-* ASCII page options::          Page size, margins, more.
-* ASCII font options::          Box character, bold & italics.
-@end menu
-
-@node ASCII output options, ASCII page options, ASCII driver class, ASCII driver class
-@subsection ASCII output options
+The available options are listed below.
 
 @table @code
 @item output-file=@var{filename}
 
 @table @code
 @item output-file=@var{filename}
@@ -1206,55 +671,16 @@ File to which output should be sent.  This can be an ordinary filename
 (e.g., @code{"pspp.txt"}), a pipe filename (e.g., @code{"|lpr"}), or
 stdout (@code{"-"}).  Default: @code{"pspp.list"}.
 
 (e.g., @code{"pspp.txt"}), a pipe filename (e.g., @code{"|lpr"}), or
 stdout (@code{"-"}).  Default: @code{"pspp.list"}.
 
-@item char-set=@var{char-set-type}
-
-One of @samp{ascii} or @samp{latin1}.  This has no effect on output at
-the present time.  Default: @code{ascii}.
-
-@item form-feed-string=@var{form-feed-value}
-
-The string written to the output to cause a formfeed.  See also
-@code{paginate}, described below, for a related setting.  Default:
-@code{"\f"}.
-
-@item newline-string=@var{new-line-value}
-
-The string written to the output to cause a new-line (carriage return
-plus linefeed).  The default, which can be specified explicitly with
-@code{newline-string=default}, is to use the system-dependent new-line
-sequence by opening the output file in text mode.  This is usually the
-right choice.
-
-However, @code{newline-string} can be set to any string.  When this is
-done, the output file is opened in binary mode.
-
 @item paginate=@var{boolean}
 
 @item paginate=@var{boolean}
 
-If set, a formfeed (as set in @code{form-feed-string}, described above)
-will be written to the device after every page.  Default: @code{on}.
+If set, a formfeed will be written at the end of every page.  Default:
+@code{on}.
 
 @item tab-width=@var{tab-width-value}
 
 The distance between tab stops for this device.  If set to 0, tabs will
 not be used in the output.  Default: @code{8}.
 
 
 @item tab-width=@var{tab-width-value}
 
 The distance between tab stops for this device.  If set to 0, tabs will
 not be used in the output.  Default: @code{8}.
 
-@item init=@var{initialization-string}.
-
-String written to the device before anything else, at the beginning of
-the output.  Default: @code{""} (the empty string).
-
-@item done=@var{finalization-string}.
-
-String written to the device after everything else, at the end of the
-output.  Default: @code{""} (the empty string).
-@end table
-
-@node ASCII page options, ASCII font options, ASCII output options, ASCII driver class
-@subsection ASCII page options
-
-These options affect page setup:
-
-@table @code
 @item headers=@var{boolean}
 
 If enabled, two lines of header information giving title and subtitle,
 @item headers=@var{boolean}
 
 If enabled, two lines of header information giving title and subtitle,
@@ -1272,25 +698,6 @@ from this value.  Default: @code{66}.
 Physical width of a page, in characters.  Margins are subtracted from
 this value.  Default: @code{130}.
 
 Physical width of a page, in characters.  Margins are subtracted from
 this value.  Default: @code{130}.
 
-@item lpi=@var{lines-per-inch}
-
-Number of lines per vertical inch.  Not currently used.  Default: @code{6}.
-
-@item cpi=@var{characters-per-inch}
-
-Number of characters per horizontal inch.  Not currently used.  Default:
-@code{10}.
-
-@item left-margin=@var{left-margin-width}
-
-Width of the left margin, in characters.  PSPP subtracts this value
-from the page width.  Default: @code{0}.
-
-@item right-margin=@var{right-margin-width}
-
-Width of the right margin, in characters.  PSPP subtracts this value
-from the page width.  Default: @code{0}.
-
 @item top-margin=@var{top-margin-lines}
 
 Length of the top margin, in lines.  PSPP subtracts this value from
 @item top-margin=@var{top-margin-lines}
 
 Length of the top margin, in lines.  PSPP subtracts this value from
@@ -1301,14 +708,6 @@ the page length.  Default: @code{2}.
 Length of the bottom margin, in lines.  PSPP subtracts this value from
 the page length.  Default: @code{2}.
 
 Length of the bottom margin, in lines.  PSPP subtracts this value from
 the page length.  Default: @code{2}.
 
-@end table
-
-@node ASCII font options,  , ASCII page options, ASCII driver class
-@subsection ASCII font options
-
-These are the ASCII font options:
-
-@table @code
 @item box[@var{line-type}]=@var{box-chars}
 
 The characters used for lines in tables produced by the ASCII driver can
 @item box[@var{line-type}]=@var{box-chars}
 
 The characters used for lines in tables produced by the ASCII driver can
@@ -1316,9 +715,8 @@ be changed using this option.  @var{line-type} is used to indicate which
 type of line to change; @var{box-chars} is the character or string of
 characters to use for this type of line.
 
 type of line to change; @var{box-chars} is the character or string of
 characters to use for this type of line.
 
-@var{line-type} must be a 4-digit number in base 4.  The digits are in
-the order `right', `bottom', `left', `top'.  The four possibilities for
-each digit are:
+@var{line-type} must be a 4-digit number.  The digits are in the order
+`right', `bottom', `left', `top'.  The possibilities for each digit are:
 
 @table @asis
 @item 0
 
 @table @asis
 @item 0
@@ -1329,10 +727,6 @@ Single line.
 
 @item 2
 Double line.
 
 @item 2
 Double line.
-
-@item 3
-Special device-defined line, if one is available; otherwise, a double
-line.
 @end table
 
 Examples:
 @end table
 
 Examples:
@@ -1377,113 +771,22 @@ Defaults:
 @*@code{box[0020]="="}
 @*@code{box[2020]="="}
 
 @*@code{box[0020]="="}
 @*@code{box[2020]="="}
 
-@item
-@code{box[0200]="#"}
-@*@code{box[0002]="#"}
-@*@code{box[0202]="#"}
-
 @item
 @code{box[3000]="="}
 @*@code{box[0030]="="}
 @*@code{box[3030]="="}
 
 @item
 @code{box[3000]="="}
 @*@code{box[0030]="="}
 @*@code{box[3030]="="}
 
-@item
-@code{box[0300]="#"}
-@*@code{box[0003]="#"}
-@*@code{box[0303]="#"}
-
 @item
 For all others, @samp{+} is used unless there are double lines or
 special lines, in which case @samp{#} is used.
 @end itemize
 
 @item
 For all others, @samp{+} is used unless there are double lines or
 special lines, in which case @samp{#} is used.
 @end itemize
 
-@item italic-on=@var{italic-on-string}
-
-Character sequence written to turn on italics or underline printing.  If
-this is set to @code{overstrike}, then the driver will simulate
-underlining by overstriking with underscore characters (@samp{_}) in the
-manner described by @code{overstrike-style} and
-@code{carriage-return-style}.  Default: @code{overstrike}.
-
-@item italic-off=@var{italic-off-string}
-
-Character sequence to turn off italics or underline printing.  Default:
-@code{""} (the empty string).
-
-@item bold-on=@var{bold-on-string}
-
-Character sequence written to turn on bold or emphasized printing.  If
-set to @code{overstrike}, then the driver will simulated bold printing
-by overstriking characters in the manner described by
-@code{overstrike-style} and @code{carriage-return-style}.  Default:
-@code{overstrike}.
-
-@item bold-off=@var{bold-off-string}
-
-Character sequence to turn off bold or emphasized printing.  Default:
-@code{""} (the empty string).
-
-@item bold-italic-on=@var{bold-italic-on-string}
-
-Character sequence written to turn on bold-italic printing.  If set to
-@code{overstrike}, then the driver will simulate bold-italics by
-overstriking twice, once with the character, a second time with an
-underscore (@samp{_}) character, in the manner described by
-@code{overstrike-style} and @code{carriage-return-style}.  Default:
-@code{overstrike}.
+@item emphasis=@var{emphasis-style}
 
 
-@item bold-italic-off=@var{bold-italic-off-string}
-
-Character sequence to turn off bold-italic printing.  Default: @code{""}
-(the empty string).
-
-@item overstrike-style=@var{overstrike-option}
-
-Either @code{single} or @code{line}:
-
-@itemize @bullet
-@item
-If @code{single} is selected, then, to overstrike a line of text, the
-output driver will output a character, backspace, overstrike, output a
-character, backspace, overstrike, and so on along a line.
-
-@item
-If @code{line} is selected then the output driver will output an entire
-line, then backspace or emit a carriage return (as indicated by
-@code{carriage-return-style}), then overstrike the entire line at once.
-@end itemize
-
-@code{single} is recommended for use with ttys and programs that
-understand overstriking in text files, such as the pager @code{less}.
-@code{single} will also work with printer devices but results in rapid
-back-and-forth motions of the printhead that can cause the printer to
-physically overheat!
-
-@code{line} is recommended for use with printer devices.  Most programs
-that understand overstriking in text files will not properly deal with
-@code{line} mode.  
-
-Default: @code{single}.
-
-@item carriage-return-style=@var{carriage-return-type}
-
-Either @code{bs} or @code{cr}.  This option applies only when one or
-more of the font commands is set to @code{overstrike} and, at the same
-time, @code{overstrike-style} is set to @code{line}.
-
-@itemize @bullet
-@item
-If @code{bs} is selected then the driver will return to the beginning of
-a line by emitting a sequence of backspace characters (ASCII 8).
-
-@item
-If @code{cr} is selected then the driver will return to the beginning of
-a line by emitting a single carriage-return character (ASCII 13).
-@end itemize
-
-Although @code{cr} is preferred as being more compact, @code{bs} is more
-general since some devices do not interpret carriage returns in the
-desired manner.  Default: @code{bs}.
+How to emphasize text.  Your choices are @code{bold}, @code{underline},
+or @code{none}.  Bold and underline emphasis are achieved with
+overstriking, which may not be supported by all the software to which
+you might pass the output.
 @end table
 
 @node HTML driver class, Miscellaneous configuring, ASCII driver class, Configuration
 @end table
 
 @node HTML driver class, Miscellaneous configuring, ASCII driver class, Configuration
@@ -1494,7 +797,7 @@ tables-capable web browsers such as Emacs' w3-mode.  Its configuration
 is very simple.  Currently, the output has a very plain format.  In the
 future, further work may be done on improving the output appearance.
 
 is very simple.  Currently, the output has a very plain format.  In the
 future, further work may be done on improving the output appearance.
 
-There are few options for use with the @code{html} driver class:
+There are is only one option:
 
 @table @code
 @item output-file=@var{filename}
 
 @table @code
 @item output-file=@var{filename}
@@ -1502,87 +805,9 @@ There are few options for use with the @code{html} driver class:
 File to which output should be sent.  This can be an ordinary filename
 (i.e., @code{"pspp.ps"}), a pipe filename (i.e., @code{"|lpr"}), or
 stdout (@code{"-"}).  Default: @code{"pspp.html"}.
 File to which output should be sent.  This can be an ordinary filename
 (i.e., @code{"pspp.ps"}), a pipe filename (i.e., @code{"|lpr"}), or
 stdout (@code{"-"}).  Default: @code{"pspp.html"}.
-
-@item prologue-file=@var{prologue-file-name}
-
-Sets the name of the PostScript prologue file.  You can write your own
-prologue if you want to customize colors or other settings: see
-@ref{HTML Prologue}.  Default: @code{html-prologue}.
-@end table
-
-@menu
-* HTML Prologue::               Format of the HTML prologue file.
-@end menu
-
-@node HTML Prologue,  , HTML driver class, HTML driver class
-@subsection The HTML prologue
-
-HTML files that are generated by PSPP consist of two parts: a prologue
-and a body.  The prologue is a collection of boilerplate.  Only the body
-differs greatly between two outputs.  You can tune the colors and other
-attributes of the output by editing the prologue.
-The prologue is dumped into the output stream essentially unmodified.
-However, two actions are performed on its lines.  First, certain lines
-may be omitted as specified in the prologue file itself.  Second,
-variables are substituted.
-
-The following lines are omitted:
-
-@enumerate
-@item
-All lines that contain three bangs in a row (@code{!!!}).
-
-@item
-Lines that contain @code{!title}, if no title is set for the output.  If
-a title is set, then the characters @code{!title} are removed before the
-line is output.
-
-@item
-Lines that contain @code{!subtitle}, if no subtitle is set for the
-output.  If a subtitle is set, then the characters @code{!subtitle} are
-removed before the line is output.
-@end enumerate
-
-The following are the variables that are substituted.  Only the
-variables listed are substituted; environment variables are not.
-@xref{Environment substitutions}.
-
-@table @code
-@item generator
-
-PSPP version as a string: @samp{GNU PSPP 0.1b}, for example.
-
-@item date
-
-Date the file was created.  Example: @samp{Tue May 21 13:46:22 1991}.
-
-@item user
-
-Under multiuser OSes, the user's login name, taken either from the
-environment variable @code{LOGNAME} or, if that fails, the result of the
-C library function @code{getlogin()}.  Defaults to @samp{nobody}.
-
-@item host
-
-System hostname as reported by @code{gethostname()}.  Defaults to
-@samp{nowhere}.
-
-@item title
-
-Document title as a string.  This is the title specified in the PSPP
-syntax file.
-
-@item subtitle
-
-Document subtitle as a string.  
-
-@item source-file
-
-PSPP syntax file name.  Example: @samp{mary96/first.stat}.
 @end table
 
 @end table
 
-@node Miscellaneous configuring, Improving output quality, HTML driver class, Configuration
+@node Miscellaneous configuring,, HTML driver class, Configuration
 @section Miscellaneous configuration
 
 The following environment variables can be used to further configure
 @section Miscellaneous configuration
 
 The following environment variables can be used to further configure
@@ -1670,66 +895,3 @@ Default: (UNIX) @file{/tmp}, (MS-DOS) @file{\}, (other OSes) empty string.
 Under MS-DOS only, these variables are consulted after TMPDIR, in this
 order.
 @end table
 Under MS-DOS only, these variables are consulted after TMPDIR, in this
 order.
 @end table
-
-@node Improving output quality,  , Miscellaneous configuring, Configuration
-@section Improving output quality
-
-When its drivers are set up properly, PSPP can produce output that
-looks very good indeed.  The PostScript driver, suitably configured, can
-produce presentation-quality output.  Here are a few guidelines for
-producing better-looking output, regardless of output driver.  Your
-mileage may vary, of course, and everyone has different esthetic
-preferences.
-
-@itemize @bullet
-@item
-Width is important in PSPP output.  Greater output width leads to more
-readable output, to a point.  Try the following to increase the output
-width:
-
-@itemize @minus
-@item
-If you're using the ASCII driver with a dot-matrix printer, figure out
-what you need to do to put the printer into compressed mode.  Put that
-string into the @code{init-string} setting.  Try to get 132 columns; 160
-might be better, but you might find that print that tiny is difficult to
-read.
-
-@item
-With the PostScript driver, try these ideas:
-
-@itemize +
-@item
-Landscape mode.
-
-@item
-Legal-size (8.5" x 14") paper in landscape mode.
-
-@item
-Reducing font sizes.  If you're using 12-point fonts, try 10 point; if
-you're using 10-point fonts, try 8 point.  Some fonts are more readable
-than others at small sizes.
-@end itemize
-@end itemize
-
-Try to strike a balance between character size and page width.
-
-@item
-Use high-quality fonts.  Many public domain fonts are poor in quality.
-Recently, URW made some high-quality fonts available under the GPL.
-These are probably suitable.
-
-@item
-Be sure you're using the proper font metrics.  The font metrics provided
-with PSPP may not correspond to the fonts actually being printed.
-This can cause bizarre-looking output.
-
-@item
-Make sure that you're using good ink/ribbon/toner.  Darker print is
-easier to read.
-
-@item
-Use plain fonts with serifs, such as Times-Roman or Palatino.  Avoid
-choosing italic or bold fonts as document base fonts.
-@end itemize
-@setfilename ignored
index 97f82ec515c9cdb9e3f02e629e3b937c4becab1a..86296c7f8a92a946aef1bf7ce7425350a84c8025 100644 (file)
@@ -7,44 +7,9 @@
 @cindex gcc
 @cindex compiler, recommended
 @cindex compiler, gcc
 @cindex gcc
 @cindex compiler, recommended
 @cindex compiler, gcc
-PSPP conforms to the GNU Coding Standards.  PSPP is written in, and
-requires for proper operation, ANSI/ISO C.  You might want to
-additionally note the following points:
-
-@itemize @bullet
-@item
-The compiler and linker must allow for significance of several
-characters in external identifiers.  The exact number is unknown but at
-least 31 is recommended.
-
-@item
-The @code{int} type must be 32 bits or wider.
-
-@item
-The recommended compiler is gcc 2.7.2.1 or later, but any ANSI compiler
-will do if it fits the above criteria.
-@end itemize
-
-Many UNIX variants should work out-of-the-box, as PSPP uses GNU
-autoconf to detect differences between environments.  Please report any
-problems with compilation of PSPP under UNIX and UNIX-like operating
-systems---portability is a major concern of the author.
-
-The pages below give specific instructions for installing PSPP
-on each type of system mentioned above.
-
-@menu
-* UNIX installation::           Installing on UNIX-like environments.
-@end menu
-
-@node UNIX installation,  , Installation, Installation
-@section UNIX installation
-@cindex UNIX, installing PSPP under
-@cindex installation, under UNIX
-@noindent
-To install PSPP under a UNIX-like operating system, follow the steps
-below in order.  Some of the text below was taken directly from various
-Free Software Foundation sources.
+PSPP is written in ISO C and primarily targeted at UNIX-like
+environments.  To install PSPP under a UNIX-like operating system,
+follow the steps below.
 
 @enumerate
 @item
 
 @enumerate
 @item
@@ -60,23 +25,7 @@ for.
 
 You can optionally supply some options to @code{configure} to
 give it hints about how to do its job.  Type @code{./configure --help}
 
 You can optionally supply some options to @code{configure} to
 give it hints about how to do its job.  Type @code{./configure --help}
-to see a list of options.  One of the most useful options is
-@samp{--with-checker}, which enables the use of the Checker memory
-debugger under supported operating systems.  Checker must already be
-installed to use this option.  Do not use @samp{--with-checker} if you
-are not debugging PSPP itself.
-
-@cindex @file{Makefile}
-@cindex @file{config.h}
-@cindex @file{pref.h}
-@cindex makefile
-@item
-(optional) Edit @file{Makefile}, @file{config.h}, and @file{pref.h}.
-These files are produced by @code{configure}.  Note that most PSPP
-settings can be changed at runtime.
-
-@file{pref.h} is only generated by @code{configure} if it does not
-already exist.  (It's copied from @file{prefh.orig}.)
+to see a list of options.
 
 @cindex compiling
 @item
 
 @cindex compiling
 @item
index a87ca2b41399d51814df9fa3d29f096d78afde33..f4d1dc7c3070a80b414adb5d117fe268c66960a0 100644 (file)
@@ -86,7 +86,6 @@ Software Foundation raise funds for GNU development.''
 * Command Index::               Index of PSPP procedures.
 * Concept Index::               Index of concepts.
 
 * Command Index::               Index of PSPP procedures.
 * Concept Index::               Index of concepts.
 
-* Installation::                How to compile and install PSPP.
 * Configuration::               Configuring PSPP.
 
 * Portable File Format::        Format of PSPP portable files.
 * Configuration::               Configuring PSPP.
 
 * Portable File Format::        Format of PSPP portable files.
@@ -117,7 +116,6 @@ Software Foundation raise funds for GNU development.''
 @include command-index.texi
 @include concept-index.texi
 
 @include command-index.texi
 @include concept-index.texi
 
-@include installing.texi
 @include configuring.texi
 
 @include portable-file-format.texi
 @include configuring.texi
 
 @include portable-file-format.texi
index 82b0f4d4ecd5efcc1ee759e785dd6a77cfe40c8c..38619d68ef0cd1443fa323646757ab74de27512e 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PSPP 0.3.1\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
 msgstr ""
 "Project-Id-Version: PSPP 0.3.1\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2006-03-28 13:51+0800\n"
+"POT-Creation-Date: 2006-04-03 11:09-0700\n"
 "PO-Revision-Date: 2004-01-23 13:04+0800\n"
 "Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
 "Language-Team: John Darrington <john@darrington.wattle.id.au>\n"
 "PO-Revision-Date: 2004-01-23 13:04+0800\n"
 "Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
 "Language-Team: John Darrington <john@darrington.wattle.id.au>\n"
@@ -1038,7 +1038,7 @@ msgstr ""
 
 #: src/language/command.c:758 src/language/data-io/matrix-data.c:534
 #: src/language/data-io/print.c:336 src/language/data-io/print.c:1051
 
 #: src/language/command.c:758 src/language/data-io/matrix-data.c:534
 #: src/language/data-io/print.c:336 src/language/data-io/print.c:1051
-#: src/language/dictionary/vector.c:197 src/language/lexer/lexer.c:451
+#: src/language/dictionary/vector.c:197 src/language/lexer/lexer.c:453
 #: src/language/stats/autorecode.c:144 src/language/xforms/select-if.c:57
 #: src/language/xforms/select-if.c:137
 msgid "expecting end of command"
 #: src/language/stats/autorecode.c:144 src/language/xforms/select-if.c:57
 #: src/language/xforms/select-if.c:137
 msgid "expecting end of command"
@@ -1729,44 +1729,39 @@ msgid ""
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
 
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
 
-#: src/language/data-io/list.q:149 src/language/stats/descriptives.c:356
+#: src/language/data-io/list.q:151 src/language/stats/descriptives.c:356
 msgid "No variables specified."
 msgstr ""
 
 msgid "No variables specified."
 msgstr ""
 
-#: src/language/data-io/list.q:157
+#: src/language/data-io/list.q:159
 #, c-format
 msgid ""
 "The first case (%ld) specified precedes the last case (%ld) specified.  The "
 "values will be swapped."
 msgstr ""
 
 #, c-format
 msgid ""
 "The first case (%ld) specified precedes the last case (%ld) specified.  The "
 "values will be swapped."
 msgstr ""
 
-#: src/language/data-io/list.q:165
+#: src/language/data-io/list.q:167
 #, c-format
 msgid ""
 "The first case (%ld) to list is less than 1.  The value is being reset to 1."
 msgstr ""
 
 #, c-format
 msgid ""
 "The first case (%ld) to list is less than 1.  The value is being reset to 1."
 msgstr ""
 
-#: src/language/data-io/list.q:171
+#: src/language/data-io/list.q:173
 #, c-format
 msgid ""
 "The last case (%ld) to list is less than 1.  The value is being reset to 1."
 msgstr ""
 
 #, c-format
 msgid ""
 "The last case (%ld) to list is less than 1.  The value is being reset to 1."
 msgstr ""
 
-#: src/language/data-io/list.q:177
+#: src/language/data-io/list.q:179
 #, c-format
 msgid "The step value %ld is less than 1.  The value is being reset to 1."
 msgstr ""
 
 #, c-format
 msgid "The step value %ld is less than 1.  The value is being reset to 1."
 msgstr ""
 
-#: src/language/data-io/list.q:203
+#: src/language/data-io/list.q:205
 msgid "`/FORMAT WEIGHT' specified, but weighting is not on."
 msgstr ""
 
 msgid "`/FORMAT WEIGHT' specified, but weighting is not on."
 msgstr ""
 
-#: src/language/data-io/list.q:258 src/output/html.c:413
-#, c-format
-msgid "Cannot open first page on HTML device %s."
-msgstr ""
-
-#: src/language/data-io/list.q:438
+#: src/language/data-io/list.q:432
 msgid "Line"
 msgstr ""
 
 msgid "Line"
 msgstr ""
 
@@ -2339,11 +2334,11 @@ msgid ""
 "s."
 msgstr ""
 
 "s."
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:157 src/language/lexer/lexer.c:588
+#: src/language/dictionary/value-labels.c:157 src/language/lexer/lexer.c:590
 msgid "expecting string"
 msgstr ""
 
 msgid "expecting string"
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:166 src/language/lexer/lexer.c:602
+#: src/language/dictionary/value-labels.c:166 src/language/lexer/lexer.c:604
 msgid "expecting integer"
 msgstr ""
 
 msgid "expecting integer"
 msgstr ""
 
@@ -2576,98 +2571,98 @@ msgstr ""
 msgid "Data format %s is not valid."
 msgstr ""
 
 msgid "Data format %s is not valid."
 msgstr ""
 
-#: src/language/lexer/lexer.c:262
+#: src/language/lexer/lexer.c:264
 #, c-format
 msgid "%s does not form a valid number."
 msgstr ""
 
 #, c-format
 msgid "%s does not form a valid number."
 msgstr ""
 
-#: src/language/lexer/lexer.c:366
+#: src/language/lexer/lexer.c:368
 #, c-format
 msgid "Bad character in input: `%c'."
 msgstr ""
 
 #, c-format
 msgid "Bad character in input: `%c'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:368
+#: src/language/lexer/lexer.c:370
 #, c-format
 msgid "Bad character in input: `\\%o'."
 msgstr ""
 
 #, c-format
 msgid "Bad character in input: `\\%o'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:399
+#: src/language/lexer/lexer.c:401
 #, c-format
 msgid "Subcommand %s may only be specified once."
 msgstr ""
 
 #, c-format
 msgid "Subcommand %s may only be specified once."
 msgstr ""
 
-#: src/language/lexer/lexer.c:407
+#: src/language/lexer/lexer.c:409
 #, c-format
 msgid "missing required subcommand %s"
 msgstr ""
 
 #, c-format
 msgid "missing required subcommand %s"
 msgstr ""
 
-#: src/language/lexer/lexer.c:436
+#: src/language/lexer/lexer.c:438
 #, c-format
 msgid "Syntax error %s at %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error %s at %s."
 msgstr ""
 
-#: src/language/lexer/lexer.c:439
+#: src/language/lexer/lexer.c:441
 #, c-format
 msgid "Syntax error at %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error at %s."
 msgstr ""
 
-#: src/language/lexer/lexer.c:557 src/language/lexer/lexer.c:574
+#: src/language/lexer/lexer.c:559 src/language/lexer/lexer.c:576
 #, c-format
 msgid "expecting `%s'"
 msgstr ""
 
 #, c-format
 msgid "expecting `%s'"
 msgstr ""
 
-#: src/language/lexer/lexer.c:616
+#: src/language/lexer/lexer.c:618
 msgid "expecting number"
 msgstr ""
 
 msgid "expecting number"
 msgstr ""
 
-#: src/language/lexer/lexer.c:630
+#: src/language/lexer/lexer.c:632
 msgid "expecting identifier"
 msgstr ""
 
 msgid "expecting identifier"
 msgstr ""
 
-#: src/language/lexer/lexer.c:840
+#: src/language/lexer/lexer.c:842
 msgid "<ERROR>"
 msgstr ""
 
 msgid "<ERROR>"
 msgstr ""
 
-#: src/language/lexer/lexer.c:986
+#: src/language/lexer/lexer.c:988
 msgid "binary"
 msgstr ""
 
 msgid "binary"
 msgstr ""
 
-#: src/language/lexer/lexer.c:991
+#: src/language/lexer/lexer.c:993
 msgid "octal"
 msgstr ""
 
 msgid "octal"
 msgstr ""
 
-#: src/language/lexer/lexer.c:996
+#: src/language/lexer/lexer.c:998
 msgid "hex"
 msgstr ""
 
 msgid "hex"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1006
+#: src/language/lexer/lexer.c:1008
 #, c-format
 msgid "String of %s digits has %d characters, which is not a multiple of %d."
 msgstr ""
 
 #, c-format
 msgid "String of %s digits has %d characters, which is not a multiple of %d."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1035
+#: src/language/lexer/lexer.c:1037
 #, c-format
 msgid "`%c' is not a valid %s digit."
 msgstr ""
 
 #, c-format
 msgid "`%c' is not a valid %s digit."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1066
+#: src/language/lexer/lexer.c:1068
 msgid "Unterminated string constant."
 msgstr ""
 
 msgid "Unterminated string constant."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1120
+#: src/language/lexer/lexer.c:1122
 msgid "Unexpected end of file in string concatenation."
 msgstr ""
 
 msgid "Unexpected end of file in string concatenation."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1128
+#: src/language/lexer/lexer.c:1130
 msgid "String expected following `+'."
 msgstr ""
 
 msgid "String expected following `+'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1141
+#: src/language/lexer/lexer.c:1143
 #, c-format
 msgid "String exceeds 255 characters in length (%d characters)."
 msgstr ""
 
 #, c-format
 msgid "String exceeds 255 characters in length (%d characters)."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1156
+#: src/language/lexer/lexer.c:1158
 msgid ""
 "Sorry, literal strings may not contain null characters.  Replacing with "
 "spaces."
 msgid ""
 "Sorry, literal strings may not contain null characters.  Replacing with "
 "spaces."
@@ -2784,8 +2779,7 @@ msgstr ""
 msgid "Opening `%s': %s."
 msgstr ""
 
 msgid "Opening `%s': %s."
 msgstr ""
 
-#: src/language/line-buffer.c:459 src/output/html.c:341
-#: src/output/postscript.c:1452
+#: src/language/line-buffer.c:459
 #, c-format
 msgid "Reading `%s': %s."
 msgstr ""
 #, c-format
 msgid "Reading `%s': %s."
 msgstr ""
@@ -2905,7 +2899,7 @@ msgid "Missing"
 msgstr ""
 
 #: src/language/stats/crosstabs.q:817 src/language/stats/crosstabs.q:1020
 msgstr ""
 
 #: src/language/stats/crosstabs.q:817 src/language/stats/crosstabs.q:1020
-#: src/language/stats/crosstabs.q:1734 src/language/stats/examine.q:859
+#: src/language/stats/crosstabs.q:1740 src/language/stats/examine.q:859
 #: src/language/stats/frequencies.q:1221 src/language/stats/oneway.q:312
 #: src/language/stats/oneway.q:475 src/language/stats/regression.q:294
 msgid "Total"
 #: src/language/stats/frequencies.q:1221 src/language/stats/oneway.q:312
 #: src/language/stats/oneway.q:475 src/language/stats/regression.q:294
 msgid "Total"
@@ -2956,6 +2950,10 @@ msgstr ""
 msgid "adj. resid."
 msgstr ""
 
 msgid "adj. resid."
 msgstr ""
 
+#: src/language/stats/crosstabs.q:1107
+msgid "Chi-square tests."
+msgstr ""
+
 #: src/language/stats/crosstabs.q:1110 src/language/stats/crosstabs.q:1137
 #: src/language/stats/crosstabs.q:1157 src/language/stats/crosstabs.q:1178
 #: src/language/stats/examine.q:1369
 #: src/language/stats/crosstabs.q:1110 src/language/stats/crosstabs.q:1137
 #: src/language/stats/crosstabs.q:1157 src/language/stats/crosstabs.q:1178
 #: src/language/stats/examine.q:1369
@@ -2981,6 +2979,10 @@ msgstr ""
 msgid "Exact. Sig. (1-sided)"
 msgstr ""
 
 msgid "Exact. Sig. (1-sided)"
 msgstr ""
 
+#: src/language/stats/crosstabs.q:1133
+msgid "Symmetric measures."
+msgstr ""
+
 #: src/language/stats/crosstabs.q:1136 src/language/stats/crosstabs.q:1177
 msgid "Category"
 msgstr ""
 #: src/language/stats/crosstabs.q:1136 src/language/stats/crosstabs.q:1177
 msgid "Category"
 msgstr ""
@@ -2997,6 +2999,10 @@ msgstr ""
 msgid "Approx. Sig."
 msgstr ""
 
 msgid "Approx. Sig."
 msgstr ""
 
+#: src/language/stats/crosstabs.q:1152
+msgid "Risk estimate."
+msgstr ""
+
 #: src/language/stats/crosstabs.q:1156
 #, c-format
 msgid "95%% Confidence Interval"
 #: src/language/stats/crosstabs.q:1156
 #, c-format
 msgid "95%% Confidence Interval"
@@ -3012,136 +3018,140 @@ msgstr ""
 msgid "Upper"
 msgstr ""
 
 msgid "Upper"
 msgstr ""
 
+#: src/language/stats/crosstabs.q:1174
+msgid "Directional measures."
+msgstr ""
+
 #: src/language/stats/crosstabs.q:1179 src/ui/gui/var-sheet.c:68
 msgid "Type"
 msgstr ""
 
 #: src/language/stats/crosstabs.q:1179 src/ui/gui/var-sheet.c:68
 msgid "Type"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1929
+#: src/language/stats/crosstabs.q:1935
 msgid "Pearson Chi-Square"
 msgstr ""
 
 msgid "Pearson Chi-Square"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1930
+#: src/language/stats/crosstabs.q:1936
 msgid "Likelihood Ratio"
 msgstr ""
 
 msgid "Likelihood Ratio"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1931
+#: src/language/stats/crosstabs.q:1937
 msgid "Fisher's Exact Test"
 msgstr ""
 
 msgid "Fisher's Exact Test"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1932
+#: src/language/stats/crosstabs.q:1938
 msgid "Continuity Correction"
 msgstr ""
 
 msgid "Continuity Correction"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1933
+#: src/language/stats/crosstabs.q:1939
 msgid "Linear-by-Linear Association"
 msgstr ""
 
 msgid "Linear-by-Linear Association"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1970 src/language/stats/crosstabs.q:2040
-#: src/language/stats/crosstabs.q:2099
+#: src/language/stats/crosstabs.q:1976 src/language/stats/crosstabs.q:2046
+#: src/language/stats/crosstabs.q:2105
 msgid "N of Valid Cases"
 msgstr ""
 
 msgid "N of Valid Cases"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1986 src/language/stats/crosstabs.q:2115
+#: src/language/stats/crosstabs.q:1992 src/language/stats/crosstabs.q:2121
 msgid "Nominal by Nominal"
 msgstr ""
 
 msgid "Nominal by Nominal"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1987 src/language/stats/crosstabs.q:2116
+#: src/language/stats/crosstabs.q:1993 src/language/stats/crosstabs.q:2122
 msgid "Ordinal by Ordinal"
 msgstr ""
 
 msgid "Ordinal by Ordinal"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1988
+#: src/language/stats/crosstabs.q:1994
 msgid "Interval by Interval"
 msgstr ""
 
 msgid "Interval by Interval"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1989
+#: src/language/stats/crosstabs.q:1995
 msgid "Measure of Agreement"
 msgstr ""
 
 msgid "Measure of Agreement"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1994
+#: src/language/stats/crosstabs.q:2000
 msgid "Phi"
 msgstr ""
 
 msgid "Phi"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1995
+#: src/language/stats/crosstabs.q:2001
 msgid "Cramer's V"
 msgstr ""
 
 msgid "Cramer's V"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1996
+#: src/language/stats/crosstabs.q:2002
 msgid "Contingency Coefficient"
 msgstr ""
 
 msgid "Contingency Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1997
+#: src/language/stats/crosstabs.q:2003
 msgid "Kendall's tau-b"
 msgstr ""
 
 msgid "Kendall's tau-b"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1998
+#: src/language/stats/crosstabs.q:2004
 msgid "Kendall's tau-c"
 msgstr ""
 
 msgid "Kendall's tau-c"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1999
+#: src/language/stats/crosstabs.q:2005
 msgid "Gamma"
 msgstr ""
 
 msgid "Gamma"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2000
+#: src/language/stats/crosstabs.q:2006
 msgid "Spearman Correlation"
 msgstr ""
 
 msgid "Spearman Correlation"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2001
+#: src/language/stats/crosstabs.q:2007
 msgid "Pearson's R"
 msgstr ""
 
 msgid "Pearson's R"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2002
+#: src/language/stats/crosstabs.q:2008
 msgid "Kappa"
 msgstr ""
 
 msgid "Kappa"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2072
+#: src/language/stats/crosstabs.q:2078
 #, c-format
 msgid "Odds Ratio for %s (%g / %g)"
 msgstr ""
 
 #, c-format
 msgid "Odds Ratio for %s (%g / %g)"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2075
+#: src/language/stats/crosstabs.q:2081
 #, c-format
 msgid "Odds Ratio for %s (%.*s / %.*s)"
 msgstr ""
 
 #, c-format
 msgid "Odds Ratio for %s (%.*s / %.*s)"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2083
+#: src/language/stats/crosstabs.q:2089
 #, c-format
 msgid "For cohort %s = %g"
 msgstr ""
 
 #, c-format
 msgid "For cohort %s = %g"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2086
+#: src/language/stats/crosstabs.q:2092
 #, c-format
 msgid "For cohort %s = %.*s"
 msgstr ""
 
 #, c-format
 msgid "For cohort %s = %.*s"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2117
+#: src/language/stats/crosstabs.q:2123
 msgid "Nominal by Interval"
 msgstr ""
 
 msgid "Nominal by Interval"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2122
+#: src/language/stats/crosstabs.q:2128
 msgid "Lambda"
 msgstr ""
 
 msgid "Lambda"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2123
+#: src/language/stats/crosstabs.q:2129
 msgid "Goodman and Kruskal tau"
 msgstr ""
 
 msgid "Goodman and Kruskal tau"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2124
+#: src/language/stats/crosstabs.q:2130
 msgid "Uncertainty Coefficient"
 msgstr ""
 
 msgid "Uncertainty Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2125
+#: src/language/stats/crosstabs.q:2131
 msgid "Somers' d"
 msgstr ""
 
 msgid "Somers' d"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2126
+#: src/language/stats/crosstabs.q:2132
 msgid "Eta"
 msgstr ""
 
 msgid "Eta"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2131
+#: src/language/stats/crosstabs.q:2137
 msgid "Symmetric"
 msgstr ""
 
 msgid "Symmetric"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2132 src/language/stats/crosstabs.q:2133
+#: src/language/stats/crosstabs.q:2138 src/language/stats/crosstabs.q:2139
 #, c-format
 msgid "%s Dependent"
 msgstr ""
 #, c-format
 msgid "%s Dependent"
 msgstr ""
@@ -3725,7 +3735,7 @@ msgstr ""
 msgid "SE. Mean"
 msgstr ""
 
 msgid "SE. Mean"
 msgstr ""
 
-#: src/language/stats/t-test.q:702
+#: src/language/stats/t-test.q:703
 msgid "Group Statistics"
 msgstr ""
 
 msgid "Group Statistics"
 msgstr ""
 
@@ -4132,630 +4142,376 @@ msgstr ""
 msgid "installation error"
 msgstr ""
 
 msgid "installation error"
 msgstr ""
 
-#: src/output/ascii.c:235
+#: src/output/afm.c:150
 #, c-format
 #, c-format
-msgid "ASCII driver initializing as `%s'..."
+msgid "opening font metrics file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:290
-#, c-format
-msgid ""
-"ascii driver: Area of page excluding margins and headers must be at least 59 "
-"characters wide by 15 lines long.  Page as configured is only %d characters "
-"by %d lines."
+#: src/output/afm.c:240
+msgid "first line must be StartFontMetrics"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:395 src/output/html.c:103 src/output/postscript.c:454
+#: src/output/afm.c:267
 #, c-format
 #, c-format
-msgid "%s: Initialization complete."
+msgid "unsupported MappingScheme %d"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:407 src/output/html.c:115 src/output/postscript.c:467
-#, c-format
-msgid "%s: Beginning closing..."
+#: src/output/afm.c:288
+msgid "required FontName is missing"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:429 src/output/html.c:120 src/output/postscript.c:486
-#, c-format
-msgid "%s: Finished closing."
+#: src/output/afm.c:395
+msgid "CharMetrics line must start with C or CH"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:490
+#: src/output/afm.c:536
 #, c-format
 #, c-format
-msgid ""
-"Bad index value for `box' key: syntax is box[INDEX], 0 <= INDEX < %d "
-"decimal, with INDEX expressed in base 4."
+msgid "reference to unknown character \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:496
-#, c-format
-msgid "Duplicate value for key `%s'."
+#: src/output/afm.c:594
+msgid "expected end of file"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:505
-#, c-format
-msgid "Unknown configuration parameter `%s' for ascii device driver."
+#: src/output/afm.c:606
+msgid "syntax error expecting end of line"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:518
-#, c-format
-msgid ""
-"Unknown character set `%s'.  Valid character sets are `ascii' and `latin1'."
+#: src/output/afm.c:624 src/output/afm.c:661
+msgid "number out of valid range"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:527
-#, c-format
-msgid ""
-"Unknown overstrike style `%s'.  Valid overstrike styles are `single' and "
-"`line'."
+#: src/output/afm.c:626 src/output/afm.c:663
+msgid "invalid numeric syntax"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:536
-#, c-format
-msgid ""
-"Unknown carriage return style `%s'.  Valid carriage return styles are `cr' "
-"and `bs'."
+#: src/output/afm.c:642
+msgid "syntax error expecting integer"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:548 src/output/postscript.c:677
-#, c-format
-msgid "Positive integer required as value for `%s'."
+#: src/output/afm.c:680
+msgid "syntax error expecting number"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:579
-#, c-format
-msgid "Zero or positive integer required as value for `%s'."
+#: src/output/afm.c:693
+msgid "syntax error in hex constant"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:650 src/output/postscript.c:635
-#, c-format
-msgid "Boolean value expected for %s."
+#: src/output/afm.c:708
+msgid "syntax error expecting hex constant"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:682 src/output/ascii.c:697 src/output/ascii.c:714
-#, c-format
-msgid "ASCII output driver: %s: %s"
+#: src/output/afm.c:746
+msgid "unexpected end of line"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:790
-#, c-format
-msgid "ascii_line_horz: bad hline (%d,%d),%d out of (%d,%d)\n"
+#: src/output/afm.c:797
+msgid "unexpected end of line expecting string"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:824
+#: src/output/ascii.c:161
 #, c-format
 #, c-format
-msgid "ascii_line_vert: bad vline %d,(%d,%d) out of (%d,%d)\n"
+msgid "ascii: opening output file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:854
+#: src/output/ascii.c:172
 #, c-format
 #, c-format
-msgid "ascii_line_intersection: bad intsct (%d,%d) out of (%d,%d)\n"
-msgstr ""
-
-#: src/output/ascii.c:1002
-#, c-format
-msgid "%s: horiz=%d, vert=%d\n"
-msgstr ""
-
-#: src/output/ascii.c:1174
-#, c-format
-msgid "Writing `%s': %s"
-msgstr ""
-
-#: src/output/ascii.c:1584 src/output/postscript.c:2099
-#, c-format
-msgid "%s - Page %d"
-msgstr ""
-
-#: src/output/ascii.c:1641
-msgid "Charts are unsupported with ascii drivers."
-msgstr ""
-
-#: src/output/charts/plot-hist.c:127
-msgid "HISTOGRAM"
-msgstr ""
-
-#: src/output/groff-font.c:107
-#, c-format
-msgid "%s: Opening Groff font file..."
-msgstr ""
-
-#: src/output/groff-font.c:161
-msgid "Missing font name."
-msgstr ""
-
-#: src/output/groff-font.c:171
-msgid "Missing encoding filename."
-msgstr ""
-
-#: src/output/groff-font.c:184
-msgid "Bad spacewidth value."
-msgstr ""
-
-#: src/output/groff-font.c:196
-msgid "Bad slant value."
-msgstr ""
-
-#: src/output/groff-font.c:221
-#, c-format
-msgid "Unknown ligature `%s'."
-msgstr ""
-
-#: src/output/groff-font.c:256
-msgid "Unexpected end of line reading character set."
-msgstr ""
-
-#: src/output/groff-font.c:264
-msgid "Can't use ditto mark for first character."
-msgstr ""
-
-#: src/output/groff-font.c:269
-msgid "Can't ditto into an unnamed character."
-msgstr ""
-
-#: src/output/groff-font.c:286
-#, c-format
-msgid "Missing metrics for character `%s'."
+msgid ""
+"ascii: page excluding margins and headers must be at least 59 characters "
+"wide by 15 lines long, but as configured is only %d characters by %d lines"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:295
+#: src/output/ascii.c:233
 #, c-format
 #, c-format
-msgid "Missing type for character `%s'."
+msgid "ascii: closing output file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:304
+#: src/output/ascii.c:285
 #, c-format
 #, c-format
-msgid "Missing code for character `%s'."
-msgstr ""
-
-#: src/output/groff-font.c:323
-msgid "Malformed kernpair."
-msgstr ""
-
-#: src/output/groff-font.c:330
-msgid "Unexpected end of line reading kernpairs."
-msgstr ""
-
-#: src/output/groff-font.c:336
-msgid "Bad kern value."
-msgstr ""
-
-#: src/output/groff-font.c:368
-#, c-format
-msgid "Font read successfully with internal name %s."
-msgstr ""
-
-#: src/output/groff-font.c:389
-msgid "Error reading font."
-msgstr ""
-
-#: src/output/groff-font.c:402
-msgid "installation error: Groff font error: "
+msgid ""
+"ascii: bad index value for `box' key: syntax is box[INDEX], 0 <= INDEX < %d "
+"decimal, with INDEX expressed in base 4"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:432
+#: src/output/ascii.c:292
 #, c-format
 #, c-format
-msgid "Bad character \\%3o."
+msgid "ascii: multiple values for %s"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:687
+#: src/output/ascii.c:300
 #, c-format
 #, c-format
-msgid "Groff font error: Cannot find \"%s\"."
+msgid "ascii: unknown parameter `%s'"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:752
+#: src/output/ascii.c:314
 #, c-format
 #, c-format
-msgid "%s: Opening Groff description file..."
-msgstr ""
-
-#: src/output/groff-font.c:768
-msgid "Multiple `sizes' declarations."
-msgstr ""
-
-#: src/output/groff-font.c:785
-msgid "Unexpected end of file.  Missing 0 terminator to `sizes' command?"
+msgid "ascii: positive integer required as `%s' value"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:797 src/output/groff-font.c:804
-#: src/output/groff-font.c:817
-msgid "Bad argument to `sizes'."
+#: src/output/ascii.c:340
+msgid "ascii: `emphasis' value must be `bold', `underline', or `none'"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:809
-msgid "Bad range in argument to `sizes'."
-msgstr ""
-
-#: src/output/groff-font.c:838
-msgid "Family name expected."
-msgstr ""
-
-#: src/output/groff-font.c:843
-msgid "This command already specified."
-msgstr ""
-
-#: src/output/groff-font.c:863
+#: src/output/ascii.c:353
 #, c-format
 #, c-format
-msgid "%s: Device characteristic already defined."
+msgid "ascii: zero or positive integer required as `%s' value"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:869
+#: src/output/ascii.c:384
 #, c-format
 #, c-format
-msgid "%s: Invalid numeric format."
+msgid "ascii: boolean value expected for `%s'"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:899
-msgid "Missing `res', `unitwidth', and/or `sizes' line(s)."
-msgstr ""
-
-#: src/output/groff-font.c:925
-msgid "Description file read successfully."
-msgstr ""
-
-#: src/output/groff-font.c:957
-msgid "Error reading description file."
-msgstr ""
-
-#: src/output/groff-font.c:1014
-msgid "<<fallback>>"
-msgstr ""
-
-#: src/output/html.c:67
+#: src/output/ascii.c:473
 #, c-format
 #, c-format
-msgid "HTML driver initializing as `%s'..."
+msgid "ascii: bad line (%d,%d)-(%d,%d) out of (%d,%d)\n"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:171
+#: src/output/ascii.c:683 src/output/postscript.c:832
 #, c-format
 #, c-format
-msgid "Unknown configuration parameter `%s' for HTML device driver."
-msgstr ""
-
-#: src/output/html.c:251
-msgid ""
-"Cannot find HTML prologue.  The use of `-vv' on the command line is "
-"suggested as a debugging aid."
-msgstr ""
-
-#: src/output/html.c:256
-#, c-format
-msgid "%s: %s: Opening HTML prologue..."
+msgid "%s - Page %d"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:280 src/output/postscript.c:1350
-#: src/output/postscript.c:1361
-msgid "nobody"
+#: src/output/ascii.c:727
+msgid "ascii: charts are unsupported by this driver"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:289 src/output/html.c:292 src/output/postscript.c:1357
-#: src/output/postscript.c:1362
-msgid "nowhere"
+#: src/output/charts/plot-hist.c:127
+msgid "HISTOGRAM"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:350
+#: src/output/html.c:68
 #, c-format
 #, c-format
-msgid "%s: HTML prologue read successfully."
+msgid "opening HTML output file: %s"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:354
-#, c-format
-msgid "%s: Error reading HTML prologue."
+#: src/output/html.c:79
+msgid "PSPP Output"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:382
+#: src/output/html.c:165
 #, c-format
 #, c-format
-msgid "HTML output driver: %s: %s"
+msgid "unknown configuration parameter `%s' for HTML device driver"
 msgstr ""
 
 msgstr ""
 
-#: src/output/output.c:160
+#: src/output/output.c:159
 #, c-format
 msgid "Unknown output driver `%s'."
 msgstr ""
 
 #, c-format
 msgid "Unknown output driver `%s'."
 msgstr ""
 
-#: src/output/output.c:162
+#: src/output/output.c:161
 #, c-format
 msgid "Output driver `%s' referenced but never defined."
 msgstr ""
 
 #, c-format
 msgid "Output driver `%s' referenced but never defined."
 msgstr ""
 
-#: src/output/output.c:255
+#: src/output/output.c:254
 msgid "Using default output driver configuration."
 msgstr ""
 
 msgid "Using default output driver configuration."
 msgstr ""
 
-#: src/output/output.c:288
+#: src/output/output.c:289
 msgid ""
 "Cannot find output initialization file.  Use `-vvvvv' to view search path."
 msgstr ""
 
 msgid ""
 "Cannot find output initialization file.  Use `-vvvvv' to view search path."
 msgstr ""
 
-#: src/output/output.c:293
-#, c-format
-msgid "%s: Opening device description file..."
-msgstr ""
-
-#: src/output/output.c:297 src/output/output.c:1205
-#: src/output/postscript.c:1095
+#: src/output/output.c:297 src/output/output.c:1060
 #, c-format
 msgid "Opening %s: %s."
 msgstr ""
 
 #, c-format
 msgid "Opening %s: %s."
 msgstr ""
 
-#: src/output/output.c:308 src/output/output.c:1216
-#: src/output/postscript.c:1110
+#: src/output/output.c:308 src/output/output.c:1071
 #, c-format
 msgid "Reading %s: %s."
 msgstr ""
 
 #, c-format
 msgid "Reading %s: %s."
 msgstr ""
 
-#: src/output/output.c:330 src/output/output.c:497
+#: src/output/output.c:330 src/output/output.c:496
 msgid "Syntax error."
 msgstr ""
 
 msgid "Syntax error."
 msgstr ""
 
-#: src/output/output.c:340 src/output/postscript.c:1121
+#: src/output/output.c:340
 #, c-format
 msgid "Closing %s: %s."
 msgstr ""
 
 #, c-format
 msgid "Closing %s: %s."
 msgstr ""
 
-#: src/output/output.c:347
-msgid "Device definition file read successfully."
-msgstr ""
-
-#: src/output/output.c:349
+#: src/output/output.c:348
 msgid "No output drivers are active."
 msgstr ""
 
 msgid "No output drivers are active."
 msgstr ""
 
-#: src/output/output.c:352
+#: src/output/output.c:351
 msgid "Error reading device definition file."
 msgstr ""
 
 msgid "Error reading device definition file."
 msgstr ""
 
-#: src/output/output.c:469
+#: src/output/output.c:468
 #, c-format
 msgid ""
 "Driver classes:\n"
 "\t"
 msgstr ""
 
 #, c-format
 msgid ""
 "Driver classes:\n"
 "\t"
 msgstr ""
 
-#: src/output/output.c:598
+#: src/output/output.c:597
 msgid "Syntax error in string constant."
 msgstr ""
 
 msgid "Syntax error in string constant."
 msgstr ""
 
-#: src/output/output.c:630
+#: src/output/output.c:632
 msgid "Syntax error in options."
 msgstr ""
 
 msgid "Syntax error in options."
 msgstr ""
 
-#: src/output/output.c:640
+#: src/output/output.c:642
 msgid "Syntax error in options (`=' expected)."
 msgstr ""
 
 msgid "Syntax error in options (`=' expected)."
 msgstr ""
 
-#: src/output/output.c:647
+#: src/output/output.c:649
 msgid "Syntax error in options (value expected after `=')."
 msgstr ""
 
 msgid "Syntax error in options (value expected after `=')."
 msgstr ""
 
-#: src/output/output.c:744
+#: src/output/output.c:691
 #, c-format
 msgid "Unknown output driver class `%s'."
 msgstr ""
 
 #, c-format
 msgid "Unknown output driver class `%s'."
 msgstr ""
 
-#: src/output/output.c:751
-#, c-format
-msgid "Can't initialize output driver class `%s'."
-msgstr ""
-
-#: src/output/output.c:758
-#, c-format
-msgid "Can't initialize output driver `%s' of class `%s'."
-msgstr ""
-
-#: src/output/output.c:780
+#: src/output/output.c:712
 #, c-format
 msgid "Unknown device type `%s'."
 msgstr ""
 
 #, c-format
 msgid "Unknown device type `%s'."
 msgstr ""
 
-#: src/output/output.c:793
-#, c-format
-msgid "Can't complete initialization of output driver `%s' of class `%s'."
-msgstr ""
-
-#: src/output/output.c:839
-msgid "Driver definition line contains fewer fields than expected"
-msgstr ""
-
-#: src/output/output.c:876
+#: src/output/output.c:731
 #, c-format
 #, c-format
-msgid "Can't deinitialize output driver class `%s'."
+msgid "Can't initialize output driver `%s' of class `%s'."
 msgstr ""
 
 msgstr ""
 
-#: src/output/output.c:949
-#, c-format
-msgid "Trying to find keyword `%s'...\n"
+#: src/output/output.c:776
+msgid "Driver definition line missing driver name or class name"
 msgstr ""
 
 msgstr ""
 
-#: src/output/output.c:1066
+#: src/output/output.c:922
 #, c-format
 msgid "Unit \"%s\" is unknown in dimension \"%s\"."
 msgstr ""
 
 #, c-format
 msgid "Unit \"%s\" is unknown in dimension \"%s\"."
 msgstr ""
 
-#: src/output/output.c:1081
+#: src/output/output.c:937
 #, c-format
 msgid "Bad dimension \"%s\"."
 msgstr ""
 
 #, c-format
 msgid "Bad dimension \"%s\"."
 msgstr ""
 
-#: src/output/output.c:1107
+#: src/output/output.c:963
 #, c-format
 msgid "`x' expected in paper size `%s'."
 msgstr ""
 
 #, c-format
 msgid "`x' expected in paper size `%s'."
 msgstr ""
 
-#: src/output/output.c:1117
+#: src/output/output.c:973
 #, c-format
 msgid "Trailing garbage `%s' on paper size `%s'."
 msgstr ""
 
 #, c-format
 msgid "Trailing garbage `%s' on paper size `%s'."
 msgstr ""
 
-#: src/output/output.c:1166
+#: src/output/output.c:1022
 msgid "Paper size name must not be empty."
 msgstr ""
 
 msgid "Paper size name must not be empty."
 msgstr ""
 
-#: src/output/output.c:1197
+#: src/output/output.c:1053
 msgid "Cannot find `papersize' configuration file."
 msgstr ""
 
 msgid "Cannot find `papersize' configuration file."
 msgstr ""
 
-#: src/output/output.c:1201
-#, c-format
-msgid "%s: Opening paper size definition file..."
-msgstr ""
-
-#: src/output/output.c:1243
+#: src/output/output.c:1098
 msgid "Syntax error in paper size definition."
 msgstr ""
 
 msgid "Syntax error in paper size definition."
 msgstr ""
 
-#: src/output/output.c:1272
-msgid "Paper size definition file read successfully."
-msgstr ""
-
-#: src/output/output.c:1274
+#: src/output/output.c:1127
 msgid "Error reading paper size definition file."
 msgstr ""
 
 msgid "Error reading paper size definition file."
 msgstr ""
 
-#: src/output/output.c:1330
-#, c-format
-msgid "Error closing page on %s device of %s class."
-msgstr ""
-
-#: src/output/output.c:1334
+#: src/output/postscript.c:164
 #, c-format
 #, c-format
-msgid "Error opening page on %s device of %s class."
+msgid "opening PostScript output file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:319
-#, c-format
-msgid "PostScript driver initializing as `%s'..."
-msgstr ""
-
-#: src/output/postscript.c:443
+#: src/output/postscript.c:202
 #, c-format
 msgid ""
 #, c-format
 msgid ""
-"PostScript driver: The defined page is not long enough to hold margins and "
-"headers, plus least 15 lines of the default fonts.  In fact, there's only "
-"room for %d lines of each font at the default size of %d.%03d points."
+"The defined PostScript page is not long enough to hold margins and headers, "
+"plus least 15 lines of the default fonts.  In fact, there's only room for %d "
+"lines of each font at the default size of %d.%03d points."
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:573
+#: src/output/postscript.c:250
 #, c-format
 #, c-format
-msgid "Unknown configuration parameter `%s' for PostScript device driver."
+msgid "closing PostScript output file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:589
+#: src/output/postscript.c:310
 #, c-format
 #, c-format
-msgid ""
-"Unknown orientation `%s'.  Valid orientations are `portrait' and `landscape'."
+msgid "unknown configuration parameter `%s' for PostScript device driver"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:601
-msgid ""
-"Unknown value for `data'.  Valid values are `clean7bit', `clean8bit', and "
-"`binary'."
-msgstr ""
-
-#: src/output/postscript.c:610
-msgid "Unknown value for `line-ends'.  Valid values are `lf' and `crlf'."
-msgstr ""
-
-#: src/output/postscript.c:619
-msgid "Unknown value for `line-style'.  Valid values are `thick' and `double'."
-msgstr ""
-
-#: src/output/postscript.c:682
+#: src/output/postscript.c:326
 #, c-format
 msgid ""
 #, c-format
 msgid ""
-"Default font size must be at least 1 point (value of 1000 for key `%s')."
-msgstr ""
-
-#: src/output/postscript.c:714
-#, c-format
-msgid "Value for `%s' must be a dimension of positive length (i.e., `1in')."
-msgstr ""
-
-#: src/output/postscript.c:778
-#, c-format
-msgid "Nonnegative integer required as value for `%s'."
+"unknown orientation `%s' (valid orientations are `portrait' and `landscape')"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:904
+#: src/output/postscript.c:338
 #, c-format
 #, c-format
-msgid "%s: %s: Opening PostScript font encoding..."
+msgid "boolean value expected for %s"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:910
+#: src/output/postscript.c:351
 #, c-format
 #, c-format
-msgid ""
-"PostScript driver: Cannot open encoding file `%s': %s.  Substituting "
-"ISOLatin1Encoding for missing encoding."
-msgstr ""
-
-#: src/output/postscript.c:952
-msgid "PostScript driver: Invalid numeric format."
+msgid "positive integer value required for `%s'"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:957
+#: src/output/postscript.c:356
 #, c-format
 #, c-format
-msgid ""
-"PostScript driver: Codes must be between 0 and 255.  (%d is not allowed.)"
+msgid "default font size must be at least 1 point (value of 1000 for key `%s')"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:993
+#: src/output/postscript.c:388
 #, c-format
 #, c-format
-msgid "PostScript driver: Error closing encoding file `%s'."
+msgid "value for `%s' must be a dimension of positive length (i.e., `1in')"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:996
+#: src/output/postscript.c:1182
 #, c-format
 #, c-format
-msgid "%s: PostScript font encoding read successfully."
+msgid "\"%s\": bad font specification"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1090
+#: src/output/postscript.c:1190
 #, c-format
 #, c-format
-msgid "%s: %s: Opening PostScript encoding list file."
+msgid "could not find AFM file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1123
+#: src/output/postscript.c:1204
 #, c-format
 #, c-format
-msgid "%s: PostScript encoding list file read successfully."
+msgid "could not find font \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1137
-msgid "<<default encoding>>"
-msgstr ""
-
-#: src/output/postscript.c:1294
-msgid ""
-"Cannot find PostScript prologue.  The use of `-vv' on the command line is "
-"suggested as a debugging aid."
-msgstr ""
-
-#: src/output/postscript.c:1299
+#: src/output/postscript.c:1213
 #, c-format
 #, c-format
-msgid "%s: %s: Opening PostScript prologue..."
+msgid "could not find encoding \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1465
+#: src/output/postscript.c:1313
 #, c-format
 #, c-format
-msgid "%s: PostScript prologue read successfully."
+msgid "cannot open font file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1469
+#: src/output/postscript.c:1354
 #, c-format
 #, c-format
-msgid "%s: Error reading PostScript prologue."
+msgid "reading font file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1639
+#: src/output/postscript.c:1376
 #, c-format
 #, c-format
-msgid "PostScript output driver: %s: %s"
+msgid "cannot open font encoding file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:2338
-#, c-format
-msgid "PostScript driver: Cannot find encoding `%s' for PostScript font `%s'."
+#: src/output/postscript.c:1405
+msgid "invalid numeric format"
 msgstr ""
 
 msgstr ""
 
-#: src/output/table.c:259
+#: src/output/table.c:239
 #, c-format
 msgid "bad vline: x=%d+%d=%d y=(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
 msgstr ""
 
 #, c-format
 msgid "bad vline: x=%d+%d=%d y=(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
 msgstr ""
 
-#: src/output/table.c:334
+#: src/output/table.c:310
 #, c-format
 msgid ""
 "bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
 #, c-format
 msgid ""
 "bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
@@ -4918,8 +4674,6 @@ msgid ""
 "  -B, --config-dir=DIR      set configuration directory to DIR\n"
 "  -o, --device=DEVICE       select output driver DEVICE and disable "
 "defaults\n"
 "  -B, --config-dir=DIR      set configuration directory to DIR\n"
 "  -o, --device=DEVICE       select output driver DEVICE and disable "
 "defaults\n"
-"  -d, --define=VAR[=VALUE]  set environment variable VAR to VALUE, or empty\n"
-"  -u, --undef=VAR           undefine environment variable VAR\n"
 "\n"
 "Input and output:\n"
 "  -f, --out-file=FILE       send output to FILE (overwritten)\n"
 "\n"
 "Input and output:\n"
 "  -f, --out-file=FILE       send output to FILE (overwritten)\n"
@@ -4948,7 +4702,7 @@ msgid ""
 "\n"
 msgstr ""
 
 "\n"
 msgstr ""
 
-#: src/ui/terminal/command-line.c:249
+#: src/ui/terminal/command-line.c:247
 #, c-format
 msgid ""
 "\n"
 #, c-format
 msgid ""
 "\n"
index 450ace185fdc7da9821c0b09911bd7eae92419bb..24e9770c99e6ef5b72bede4c923fe2b5ef499453 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2006-03-28 13:51+0800\n"
+"POT-Creation-Date: 2006-04-03 11:09-0700\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1039,7 +1039,7 @@ msgstr ""
 
 #: src/language/command.c:758 src/language/data-io/matrix-data.c:534
 #: src/language/data-io/print.c:336 src/language/data-io/print.c:1051
 
 #: src/language/command.c:758 src/language/data-io/matrix-data.c:534
 #: src/language/data-io/print.c:336 src/language/data-io/print.c:1051
-#: src/language/dictionary/vector.c:197 src/language/lexer/lexer.c:451
+#: src/language/dictionary/vector.c:197 src/language/lexer/lexer.c:453
 #: src/language/stats/autorecode.c:144 src/language/xforms/select-if.c:57
 #: src/language/xforms/select-if.c:137
 msgid "expecting end of command"
 #: src/language/stats/autorecode.c:144 src/language/xforms/select-if.c:57
 #: src/language/xforms/select-if.c:137
 msgid "expecting end of command"
@@ -1730,44 +1730,39 @@ msgid ""
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
 
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
 
-#: src/language/data-io/list.q:149 src/language/stats/descriptives.c:356
+#: src/language/data-io/list.q:151 src/language/stats/descriptives.c:356
 msgid "No variables specified."
 msgstr ""
 
 msgid "No variables specified."
 msgstr ""
 
-#: src/language/data-io/list.q:157
+#: src/language/data-io/list.q:159
 #, c-format
 msgid ""
 "The first case (%ld) specified precedes the last case (%ld) specified.  The "
 "values will be swapped."
 msgstr ""
 
 #, c-format
 msgid ""
 "The first case (%ld) specified precedes the last case (%ld) specified.  The "
 "values will be swapped."
 msgstr ""
 
-#: src/language/data-io/list.q:165
+#: src/language/data-io/list.q:167
 #, c-format
 msgid ""
 "The first case (%ld) to list is less than 1.  The value is being reset to 1."
 msgstr ""
 
 #, c-format
 msgid ""
 "The first case (%ld) to list is less than 1.  The value is being reset to 1."
 msgstr ""
 
-#: src/language/data-io/list.q:171
+#: src/language/data-io/list.q:173
 #, c-format
 msgid ""
 "The last case (%ld) to list is less than 1.  The value is being reset to 1."
 msgstr ""
 
 #, c-format
 msgid ""
 "The last case (%ld) to list is less than 1.  The value is being reset to 1."
 msgstr ""
 
-#: src/language/data-io/list.q:177
+#: src/language/data-io/list.q:179
 #, c-format
 msgid "The step value %ld is less than 1.  The value is being reset to 1."
 msgstr ""
 
 #, c-format
 msgid "The step value %ld is less than 1.  The value is being reset to 1."
 msgstr ""
 
-#: src/language/data-io/list.q:203
+#: src/language/data-io/list.q:205
 msgid "`/FORMAT WEIGHT' specified, but weighting is not on."
 msgstr ""
 
 msgid "`/FORMAT WEIGHT' specified, but weighting is not on."
 msgstr ""
 
-#: src/language/data-io/list.q:258 src/output/html.c:413
-#, c-format
-msgid "Cannot open first page on HTML device %s."
-msgstr ""
-
-#: src/language/data-io/list.q:438
+#: src/language/data-io/list.q:432
 msgid "Line"
 msgstr ""
 
 msgid "Line"
 msgstr ""
 
@@ -2340,11 +2335,11 @@ msgid ""
 "s."
 msgstr ""
 
 "s."
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:157 src/language/lexer/lexer.c:588
+#: src/language/dictionary/value-labels.c:157 src/language/lexer/lexer.c:590
 msgid "expecting string"
 msgstr ""
 
 msgid "expecting string"
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:166 src/language/lexer/lexer.c:602
+#: src/language/dictionary/value-labels.c:166 src/language/lexer/lexer.c:604
 msgid "expecting integer"
 msgstr ""
 
 msgid "expecting integer"
 msgstr ""
 
@@ -2577,98 +2572,98 @@ msgstr ""
 msgid "Data format %s is not valid."
 msgstr ""
 
 msgid "Data format %s is not valid."
 msgstr ""
 
-#: src/language/lexer/lexer.c:262
+#: src/language/lexer/lexer.c:264
 #, c-format
 msgid "%s does not form a valid number."
 msgstr ""
 
 #, c-format
 msgid "%s does not form a valid number."
 msgstr ""
 
-#: src/language/lexer/lexer.c:366
+#: src/language/lexer/lexer.c:368
 #, c-format
 msgid "Bad character in input: `%c'."
 msgstr ""
 
 #, c-format
 msgid "Bad character in input: `%c'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:368
+#: src/language/lexer/lexer.c:370
 #, c-format
 msgid "Bad character in input: `\\%o'."
 msgstr ""
 
 #, c-format
 msgid "Bad character in input: `\\%o'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:399
+#: src/language/lexer/lexer.c:401
 #, c-format
 msgid "Subcommand %s may only be specified once."
 msgstr ""
 
 #, c-format
 msgid "Subcommand %s may only be specified once."
 msgstr ""
 
-#: src/language/lexer/lexer.c:407
+#: src/language/lexer/lexer.c:409
 #, c-format
 msgid "missing required subcommand %s"
 msgstr ""
 
 #, c-format
 msgid "missing required subcommand %s"
 msgstr ""
 
-#: src/language/lexer/lexer.c:436
+#: src/language/lexer/lexer.c:438
 #, c-format
 msgid "Syntax error %s at %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error %s at %s."
 msgstr ""
 
-#: src/language/lexer/lexer.c:439
+#: src/language/lexer/lexer.c:441
 #, c-format
 msgid "Syntax error at %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error at %s."
 msgstr ""
 
-#: src/language/lexer/lexer.c:557 src/language/lexer/lexer.c:574
+#: src/language/lexer/lexer.c:559 src/language/lexer/lexer.c:576
 #, c-format
 msgid "expecting `%s'"
 msgstr ""
 
 #, c-format
 msgid "expecting `%s'"
 msgstr ""
 
-#: src/language/lexer/lexer.c:616
+#: src/language/lexer/lexer.c:618
 msgid "expecting number"
 msgstr ""
 
 msgid "expecting number"
 msgstr ""
 
-#: src/language/lexer/lexer.c:630
+#: src/language/lexer/lexer.c:632
 msgid "expecting identifier"
 msgstr ""
 
 msgid "expecting identifier"
 msgstr ""
 
-#: src/language/lexer/lexer.c:840
+#: src/language/lexer/lexer.c:842
 msgid "<ERROR>"
 msgstr ""
 
 msgid "<ERROR>"
 msgstr ""
 
-#: src/language/lexer/lexer.c:986
+#: src/language/lexer/lexer.c:988
 msgid "binary"
 msgstr ""
 
 msgid "binary"
 msgstr ""
 
-#: src/language/lexer/lexer.c:991
+#: src/language/lexer/lexer.c:993
 msgid "octal"
 msgstr ""
 
 msgid "octal"
 msgstr ""
 
-#: src/language/lexer/lexer.c:996
+#: src/language/lexer/lexer.c:998
 msgid "hex"
 msgstr ""
 
 msgid "hex"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1006
+#: src/language/lexer/lexer.c:1008
 #, c-format
 msgid "String of %s digits has %d characters, which is not a multiple of %d."
 msgstr ""
 
 #, c-format
 msgid "String of %s digits has %d characters, which is not a multiple of %d."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1035
+#: src/language/lexer/lexer.c:1037
 #, c-format
 msgid "`%c' is not a valid %s digit."
 msgstr ""
 
 #, c-format
 msgid "`%c' is not a valid %s digit."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1066
+#: src/language/lexer/lexer.c:1068
 msgid "Unterminated string constant."
 msgstr ""
 
 msgid "Unterminated string constant."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1120
+#: src/language/lexer/lexer.c:1122
 msgid "Unexpected end of file in string concatenation."
 msgstr ""
 
 msgid "Unexpected end of file in string concatenation."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1128
+#: src/language/lexer/lexer.c:1130
 msgid "String expected following `+'."
 msgstr ""
 
 msgid "String expected following `+'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1141
+#: src/language/lexer/lexer.c:1143
 #, c-format
 msgid "String exceeds 255 characters in length (%d characters)."
 msgstr ""
 
 #, c-format
 msgid "String exceeds 255 characters in length (%d characters)."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1156
+#: src/language/lexer/lexer.c:1158
 msgid ""
 "Sorry, literal strings may not contain null characters.  Replacing with "
 "spaces."
 msgid ""
 "Sorry, literal strings may not contain null characters.  Replacing with "
 "spaces."
@@ -2785,8 +2780,7 @@ msgstr ""
 msgid "Opening `%s': %s."
 msgstr ""
 
 msgid "Opening `%s': %s."
 msgstr ""
 
-#: src/language/line-buffer.c:459 src/output/html.c:341
-#: src/output/postscript.c:1452
+#: src/language/line-buffer.c:459
 #, c-format
 msgid "Reading `%s': %s."
 msgstr ""
 #, c-format
 msgid "Reading `%s': %s."
 msgstr ""
@@ -2906,7 +2900,7 @@ msgid "Missing"
 msgstr ""
 
 #: src/language/stats/crosstabs.q:817 src/language/stats/crosstabs.q:1020
 msgstr ""
 
 #: src/language/stats/crosstabs.q:817 src/language/stats/crosstabs.q:1020
-#: src/language/stats/crosstabs.q:1734 src/language/stats/examine.q:859
+#: src/language/stats/crosstabs.q:1740 src/language/stats/examine.q:859
 #: src/language/stats/frequencies.q:1221 src/language/stats/oneway.q:312
 #: src/language/stats/oneway.q:475 src/language/stats/regression.q:294
 msgid "Total"
 #: src/language/stats/frequencies.q:1221 src/language/stats/oneway.q:312
 #: src/language/stats/oneway.q:475 src/language/stats/regression.q:294
 msgid "Total"
@@ -2957,6 +2951,10 @@ msgstr ""
 msgid "adj. resid."
 msgstr ""
 
 msgid "adj. resid."
 msgstr ""
 
+#: src/language/stats/crosstabs.q:1107
+msgid "Chi-square tests."
+msgstr ""
+
 #: src/language/stats/crosstabs.q:1110 src/language/stats/crosstabs.q:1137
 #: src/language/stats/crosstabs.q:1157 src/language/stats/crosstabs.q:1178
 #: src/language/stats/examine.q:1369
 #: src/language/stats/crosstabs.q:1110 src/language/stats/crosstabs.q:1137
 #: src/language/stats/crosstabs.q:1157 src/language/stats/crosstabs.q:1178
 #: src/language/stats/examine.q:1369
@@ -2982,6 +2980,10 @@ msgstr ""
 msgid "Exact. Sig. (1-sided)"
 msgstr ""
 
 msgid "Exact. Sig. (1-sided)"
 msgstr ""
 
+#: src/language/stats/crosstabs.q:1133
+msgid "Symmetric measures."
+msgstr ""
+
 #: src/language/stats/crosstabs.q:1136 src/language/stats/crosstabs.q:1177
 msgid "Category"
 msgstr ""
 #: src/language/stats/crosstabs.q:1136 src/language/stats/crosstabs.q:1177
 msgid "Category"
 msgstr ""
@@ -2998,6 +3000,10 @@ msgstr ""
 msgid "Approx. Sig."
 msgstr ""
 
 msgid "Approx. Sig."
 msgstr ""
 
+#: src/language/stats/crosstabs.q:1152
+msgid "Risk estimate."
+msgstr ""
+
 #: src/language/stats/crosstabs.q:1156
 #, c-format
 msgid "95%% Confidence Interval"
 #: src/language/stats/crosstabs.q:1156
 #, c-format
 msgid "95%% Confidence Interval"
@@ -3013,136 +3019,140 @@ msgstr ""
 msgid "Upper"
 msgstr ""
 
 msgid "Upper"
 msgstr ""
 
+#: src/language/stats/crosstabs.q:1174
+msgid "Directional measures."
+msgstr ""
+
 #: src/language/stats/crosstabs.q:1179 src/ui/gui/var-sheet.c:68
 msgid "Type"
 msgstr ""
 
 #: src/language/stats/crosstabs.q:1179 src/ui/gui/var-sheet.c:68
 msgid "Type"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1929
+#: src/language/stats/crosstabs.q:1935
 msgid "Pearson Chi-Square"
 msgstr ""
 
 msgid "Pearson Chi-Square"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1930
+#: src/language/stats/crosstabs.q:1936
 msgid "Likelihood Ratio"
 msgstr ""
 
 msgid "Likelihood Ratio"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1931
+#: src/language/stats/crosstabs.q:1937
 msgid "Fisher's Exact Test"
 msgstr ""
 
 msgid "Fisher's Exact Test"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1932
+#: src/language/stats/crosstabs.q:1938
 msgid "Continuity Correction"
 msgstr ""
 
 msgid "Continuity Correction"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1933
+#: src/language/stats/crosstabs.q:1939
 msgid "Linear-by-Linear Association"
 msgstr ""
 
 msgid "Linear-by-Linear Association"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1970 src/language/stats/crosstabs.q:2040
-#: src/language/stats/crosstabs.q:2099
+#: src/language/stats/crosstabs.q:1976 src/language/stats/crosstabs.q:2046
+#: src/language/stats/crosstabs.q:2105
 msgid "N of Valid Cases"
 msgstr ""
 
 msgid "N of Valid Cases"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1986 src/language/stats/crosstabs.q:2115
+#: src/language/stats/crosstabs.q:1992 src/language/stats/crosstabs.q:2121
 msgid "Nominal by Nominal"
 msgstr ""
 
 msgid "Nominal by Nominal"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1987 src/language/stats/crosstabs.q:2116
+#: src/language/stats/crosstabs.q:1993 src/language/stats/crosstabs.q:2122
 msgid "Ordinal by Ordinal"
 msgstr ""
 
 msgid "Ordinal by Ordinal"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1988
+#: src/language/stats/crosstabs.q:1994
 msgid "Interval by Interval"
 msgstr ""
 
 msgid "Interval by Interval"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1989
+#: src/language/stats/crosstabs.q:1995
 msgid "Measure of Agreement"
 msgstr ""
 
 msgid "Measure of Agreement"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1994
+#: src/language/stats/crosstabs.q:2000
 msgid "Phi"
 msgstr ""
 
 msgid "Phi"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1995
+#: src/language/stats/crosstabs.q:2001
 msgid "Cramer's V"
 msgstr ""
 
 msgid "Cramer's V"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1996
+#: src/language/stats/crosstabs.q:2002
 msgid "Contingency Coefficient"
 msgstr ""
 
 msgid "Contingency Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1997
+#: src/language/stats/crosstabs.q:2003
 msgid "Kendall's tau-b"
 msgstr ""
 
 msgid "Kendall's tau-b"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1998
+#: src/language/stats/crosstabs.q:2004
 msgid "Kendall's tau-c"
 msgstr ""
 
 msgid "Kendall's tau-c"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1999
+#: src/language/stats/crosstabs.q:2005
 msgid "Gamma"
 msgstr ""
 
 msgid "Gamma"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2000
+#: src/language/stats/crosstabs.q:2006
 msgid "Spearman Correlation"
 msgstr ""
 
 msgid "Spearman Correlation"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2001
+#: src/language/stats/crosstabs.q:2007
 msgid "Pearson's R"
 msgstr ""
 
 msgid "Pearson's R"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2002
+#: src/language/stats/crosstabs.q:2008
 msgid "Kappa"
 msgstr ""
 
 msgid "Kappa"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2072
+#: src/language/stats/crosstabs.q:2078
 #, c-format
 msgid "Odds Ratio for %s (%g / %g)"
 msgstr ""
 
 #, c-format
 msgid "Odds Ratio for %s (%g / %g)"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2075
+#: src/language/stats/crosstabs.q:2081
 #, c-format
 msgid "Odds Ratio for %s (%.*s / %.*s)"
 msgstr ""
 
 #, c-format
 msgid "Odds Ratio for %s (%.*s / %.*s)"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2083
+#: src/language/stats/crosstabs.q:2089
 #, c-format
 msgid "For cohort %s = %g"
 msgstr ""
 
 #, c-format
 msgid "For cohort %s = %g"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2086
+#: src/language/stats/crosstabs.q:2092
 #, c-format
 msgid "For cohort %s = %.*s"
 msgstr ""
 
 #, c-format
 msgid "For cohort %s = %.*s"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2117
+#: src/language/stats/crosstabs.q:2123
 msgid "Nominal by Interval"
 msgstr ""
 
 msgid "Nominal by Interval"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2122
+#: src/language/stats/crosstabs.q:2128
 msgid "Lambda"
 msgstr ""
 
 msgid "Lambda"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2123
+#: src/language/stats/crosstabs.q:2129
 msgid "Goodman and Kruskal tau"
 msgstr ""
 
 msgid "Goodman and Kruskal tau"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2124
+#: src/language/stats/crosstabs.q:2130
 msgid "Uncertainty Coefficient"
 msgstr ""
 
 msgid "Uncertainty Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2125
+#: src/language/stats/crosstabs.q:2131
 msgid "Somers' d"
 msgstr ""
 
 msgid "Somers' d"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2126
+#: src/language/stats/crosstabs.q:2132
 msgid "Eta"
 msgstr ""
 
 msgid "Eta"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2131
+#: src/language/stats/crosstabs.q:2137
 msgid "Symmetric"
 msgstr ""
 
 msgid "Symmetric"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2132 src/language/stats/crosstabs.q:2133
+#: src/language/stats/crosstabs.q:2138 src/language/stats/crosstabs.q:2139
 #, c-format
 msgid "%s Dependent"
 msgstr ""
 #, c-format
 msgid "%s Dependent"
 msgstr ""
@@ -3726,7 +3736,7 @@ msgstr ""
 msgid "SE. Mean"
 msgstr ""
 
 msgid "SE. Mean"
 msgstr ""
 
-#: src/language/stats/t-test.q:702
+#: src/language/stats/t-test.q:703
 msgid "Group Statistics"
 msgstr ""
 
 msgid "Group Statistics"
 msgstr ""
 
@@ -4133,630 +4143,376 @@ msgstr ""
 msgid "installation error"
 msgstr ""
 
 msgid "installation error"
 msgstr ""
 
-#: src/output/ascii.c:235
+#: src/output/afm.c:150
 #, c-format
 #, c-format
-msgid "ASCII driver initializing as `%s'..."
+msgid "opening font metrics file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:290
-#, c-format
-msgid ""
-"ascii driver: Area of page excluding margins and headers must be at least 59 "
-"characters wide by 15 lines long.  Page as configured is only %d characters "
-"by %d lines."
+#: src/output/afm.c:240
+msgid "first line must be StartFontMetrics"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:395 src/output/html.c:103 src/output/postscript.c:454
+#: src/output/afm.c:267
 #, c-format
 #, c-format
-msgid "%s: Initialization complete."
+msgid "unsupported MappingScheme %d"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:407 src/output/html.c:115 src/output/postscript.c:467
-#, c-format
-msgid "%s: Beginning closing..."
+#: src/output/afm.c:288
+msgid "required FontName is missing"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:429 src/output/html.c:120 src/output/postscript.c:486
-#, c-format
-msgid "%s: Finished closing."
+#: src/output/afm.c:395
+msgid "CharMetrics line must start with C or CH"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:490
+#: src/output/afm.c:536
 #, c-format
 #, c-format
-msgid ""
-"Bad index value for `box' key: syntax is box[INDEX], 0 <= INDEX < %d "
-"decimal, with INDEX expressed in base 4."
+msgid "reference to unknown character \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:496
-#, c-format
-msgid "Duplicate value for key `%s'."
+#: src/output/afm.c:594
+msgid "expected end of file"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:505
-#, c-format
-msgid "Unknown configuration parameter `%s' for ascii device driver."
+#: src/output/afm.c:606
+msgid "syntax error expecting end of line"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:518
-#, c-format
-msgid ""
-"Unknown character set `%s'.  Valid character sets are `ascii' and `latin1'."
+#: src/output/afm.c:624 src/output/afm.c:661
+msgid "number out of valid range"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:527
-#, c-format
-msgid ""
-"Unknown overstrike style `%s'.  Valid overstrike styles are `single' and "
-"`line'."
+#: src/output/afm.c:626 src/output/afm.c:663
+msgid "invalid numeric syntax"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:536
-#, c-format
-msgid ""
-"Unknown carriage return style `%s'.  Valid carriage return styles are `cr' "
-"and `bs'."
+#: src/output/afm.c:642
+msgid "syntax error expecting integer"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:548 src/output/postscript.c:677
-#, c-format
-msgid "Positive integer required as value for `%s'."
+#: src/output/afm.c:680
+msgid "syntax error expecting number"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:579
-#, c-format
-msgid "Zero or positive integer required as value for `%s'."
+#: src/output/afm.c:693
+msgid "syntax error in hex constant"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:650 src/output/postscript.c:635
-#, c-format
-msgid "Boolean value expected for %s."
+#: src/output/afm.c:708
+msgid "syntax error expecting hex constant"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:682 src/output/ascii.c:697 src/output/ascii.c:714
-#, c-format
-msgid "ASCII output driver: %s: %s"
+#: src/output/afm.c:746
+msgid "unexpected end of line"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:790
-#, c-format
-msgid "ascii_line_horz: bad hline (%d,%d),%d out of (%d,%d)\n"
+#: src/output/afm.c:797
+msgid "unexpected end of line expecting string"
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:824
+#: src/output/ascii.c:161
 #, c-format
 #, c-format
-msgid "ascii_line_vert: bad vline %d,(%d,%d) out of (%d,%d)\n"
+msgid "ascii: opening output file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/ascii.c:854
+#: src/output/ascii.c:172
 #, c-format
 #, c-format
-msgid "ascii_line_intersection: bad intsct (%d,%d) out of (%d,%d)\n"
-msgstr ""
-
-#: src/output/ascii.c:1002
-#, c-format
-msgid "%s: horiz=%d, vert=%d\n"
-msgstr ""
-
-#: src/output/ascii.c:1174
-#, c-format
-msgid "Writing `%s': %s"
-msgstr ""
-
-#: src/output/ascii.c:1584 src/output/postscript.c:2099
-#, c-format
-msgid "%s - Page %d"
-msgstr ""
-
-#: src/output/ascii.c:1641
-msgid "Charts are unsupported with ascii drivers."
-msgstr ""
-
-#: src/output/charts/plot-hist.c:127
-msgid "HISTOGRAM"
-msgstr ""
-
-#: src/output/groff-font.c:107
-#, c-format
-msgid "%s: Opening Groff font file..."
-msgstr ""
-
-#: src/output/groff-font.c:161
-msgid "Missing font name."
-msgstr ""
-
-#: src/output/groff-font.c:171
-msgid "Missing encoding filename."
-msgstr ""
-
-#: src/output/groff-font.c:184
-msgid "Bad spacewidth value."
-msgstr ""
-
-#: src/output/groff-font.c:196
-msgid "Bad slant value."
-msgstr ""
-
-#: src/output/groff-font.c:221
-#, c-format
-msgid "Unknown ligature `%s'."
-msgstr ""
-
-#: src/output/groff-font.c:256
-msgid "Unexpected end of line reading character set."
-msgstr ""
-
-#: src/output/groff-font.c:264
-msgid "Can't use ditto mark for first character."
-msgstr ""
-
-#: src/output/groff-font.c:269
-msgid "Can't ditto into an unnamed character."
-msgstr ""
-
-#: src/output/groff-font.c:286
-#, c-format
-msgid "Missing metrics for character `%s'."
+msgid ""
+"ascii: page excluding margins and headers must be at least 59 characters "
+"wide by 15 lines long, but as configured is only %d characters by %d lines"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:295
+#: src/output/ascii.c:233
 #, c-format
 #, c-format
-msgid "Missing type for character `%s'."
+msgid "ascii: closing output file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:304
+#: src/output/ascii.c:285
 #, c-format
 #, c-format
-msgid "Missing code for character `%s'."
-msgstr ""
-
-#: src/output/groff-font.c:323
-msgid "Malformed kernpair."
-msgstr ""
-
-#: src/output/groff-font.c:330
-msgid "Unexpected end of line reading kernpairs."
-msgstr ""
-
-#: src/output/groff-font.c:336
-msgid "Bad kern value."
-msgstr ""
-
-#: src/output/groff-font.c:368
-#, c-format
-msgid "Font read successfully with internal name %s."
-msgstr ""
-
-#: src/output/groff-font.c:389
-msgid "Error reading font."
-msgstr ""
-
-#: src/output/groff-font.c:402
-msgid "installation error: Groff font error: "
+msgid ""
+"ascii: bad index value for `box' key: syntax is box[INDEX], 0 <= INDEX < %d "
+"decimal, with INDEX expressed in base 4"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:432
+#: src/output/ascii.c:292
 #, c-format
 #, c-format
-msgid "Bad character \\%3o."
+msgid "ascii: multiple values for %s"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:687
+#: src/output/ascii.c:300
 #, c-format
 #, c-format
-msgid "Groff font error: Cannot find \"%s\"."
+msgid "ascii: unknown parameter `%s'"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:752
+#: src/output/ascii.c:314
 #, c-format
 #, c-format
-msgid "%s: Opening Groff description file..."
-msgstr ""
-
-#: src/output/groff-font.c:768
-msgid "Multiple `sizes' declarations."
-msgstr ""
-
-#: src/output/groff-font.c:785
-msgid "Unexpected end of file.  Missing 0 terminator to `sizes' command?"
+msgid "ascii: positive integer required as `%s' value"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:797 src/output/groff-font.c:804
-#: src/output/groff-font.c:817
-msgid "Bad argument to `sizes'."
+#: src/output/ascii.c:340
+msgid "ascii: `emphasis' value must be `bold', `underline', or `none'"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:809
-msgid "Bad range in argument to `sizes'."
-msgstr ""
-
-#: src/output/groff-font.c:838
-msgid "Family name expected."
-msgstr ""
-
-#: src/output/groff-font.c:843
-msgid "This command already specified."
-msgstr ""
-
-#: src/output/groff-font.c:863
+#: src/output/ascii.c:353
 #, c-format
 #, c-format
-msgid "%s: Device characteristic already defined."
+msgid "ascii: zero or positive integer required as `%s' value"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:869
+#: src/output/ascii.c:384
 #, c-format
 #, c-format
-msgid "%s: Invalid numeric format."
+msgid "ascii: boolean value expected for `%s'"
 msgstr ""
 
 msgstr ""
 
-#: src/output/groff-font.c:899
-msgid "Missing `res', `unitwidth', and/or `sizes' line(s)."
-msgstr ""
-
-#: src/output/groff-font.c:925
-msgid "Description file read successfully."
-msgstr ""
-
-#: src/output/groff-font.c:957
-msgid "Error reading description file."
-msgstr ""
-
-#: src/output/groff-font.c:1014
-msgid "<<fallback>>"
-msgstr ""
-
-#: src/output/html.c:67
+#: src/output/ascii.c:473
 #, c-format
 #, c-format
-msgid "HTML driver initializing as `%s'..."
+msgid "ascii: bad line (%d,%d)-(%d,%d) out of (%d,%d)\n"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:171
+#: src/output/ascii.c:683 src/output/postscript.c:832
 #, c-format
 #, c-format
-msgid "Unknown configuration parameter `%s' for HTML device driver."
-msgstr ""
-
-#: src/output/html.c:251
-msgid ""
-"Cannot find HTML prologue.  The use of `-vv' on the command line is "
-"suggested as a debugging aid."
-msgstr ""
-
-#: src/output/html.c:256
-#, c-format
-msgid "%s: %s: Opening HTML prologue..."
+msgid "%s - Page %d"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:280 src/output/postscript.c:1350
-#: src/output/postscript.c:1361
-msgid "nobody"
+#: src/output/ascii.c:727
+msgid "ascii: charts are unsupported by this driver"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:289 src/output/html.c:292 src/output/postscript.c:1357
-#: src/output/postscript.c:1362
-msgid "nowhere"
+#: src/output/charts/plot-hist.c:127
+msgid "HISTOGRAM"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:350
+#: src/output/html.c:68
 #, c-format
 #, c-format
-msgid "%s: HTML prologue read successfully."
+msgid "opening HTML output file: %s"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:354
-#, c-format
-msgid "%s: Error reading HTML prologue."
+#: src/output/html.c:79
+msgid "PSPP Output"
 msgstr ""
 
 msgstr ""
 
-#: src/output/html.c:382
+#: src/output/html.c:165
 #, c-format
 #, c-format
-msgid "HTML output driver: %s: %s"
+msgid "unknown configuration parameter `%s' for HTML device driver"
 msgstr ""
 
 msgstr ""
 
-#: src/output/output.c:160
+#: src/output/output.c:159
 #, c-format
 msgid "Unknown output driver `%s'."
 msgstr ""
 
 #, c-format
 msgid "Unknown output driver `%s'."
 msgstr ""
 
-#: src/output/output.c:162
+#: src/output/output.c:161
 #, c-format
 msgid "Output driver `%s' referenced but never defined."
 msgstr ""
 
 #, c-format
 msgid "Output driver `%s' referenced but never defined."
 msgstr ""
 
-#: src/output/output.c:255
+#: src/output/output.c:254
 msgid "Using default output driver configuration."
 msgstr ""
 
 msgid "Using default output driver configuration."
 msgstr ""
 
-#: src/output/output.c:288
+#: src/output/output.c:289
 msgid ""
 "Cannot find output initialization file.  Use `-vvvvv' to view search path."
 msgstr ""
 
 msgid ""
 "Cannot find output initialization file.  Use `-vvvvv' to view search path."
 msgstr ""
 
-#: src/output/output.c:293
-#, c-format
-msgid "%s: Opening device description file..."
-msgstr ""
-
-#: src/output/output.c:297 src/output/output.c:1205
-#: src/output/postscript.c:1095
+#: src/output/output.c:297 src/output/output.c:1060
 #, c-format
 msgid "Opening %s: %s."
 msgstr ""
 
 #, c-format
 msgid "Opening %s: %s."
 msgstr ""
 
-#: src/output/output.c:308 src/output/output.c:1216
-#: src/output/postscript.c:1110
+#: src/output/output.c:308 src/output/output.c:1071
 #, c-format
 msgid "Reading %s: %s."
 msgstr ""
 
 #, c-format
 msgid "Reading %s: %s."
 msgstr ""
 
-#: src/output/output.c:330 src/output/output.c:497
+#: src/output/output.c:330 src/output/output.c:496
 msgid "Syntax error."
 msgstr ""
 
 msgid "Syntax error."
 msgstr ""
 
-#: src/output/output.c:340 src/output/postscript.c:1121
+#: src/output/output.c:340
 #, c-format
 msgid "Closing %s: %s."
 msgstr ""
 
 #, c-format
 msgid "Closing %s: %s."
 msgstr ""
 
-#: src/output/output.c:347
-msgid "Device definition file read successfully."
-msgstr ""
-
-#: src/output/output.c:349
+#: src/output/output.c:348
 msgid "No output drivers are active."
 msgstr ""
 
 msgid "No output drivers are active."
 msgstr ""
 
-#: src/output/output.c:352
+#: src/output/output.c:351
 msgid "Error reading device definition file."
 msgstr ""
 
 msgid "Error reading device definition file."
 msgstr ""
 
-#: src/output/output.c:469
+#: src/output/output.c:468
 #, c-format
 msgid ""
 "Driver classes:\n"
 "\t"
 msgstr ""
 
 #, c-format
 msgid ""
 "Driver classes:\n"
 "\t"
 msgstr ""
 
-#: src/output/output.c:598
+#: src/output/output.c:597
 msgid "Syntax error in string constant."
 msgstr ""
 
 msgid "Syntax error in string constant."
 msgstr ""
 
-#: src/output/output.c:630
+#: src/output/output.c:632
 msgid "Syntax error in options."
 msgstr ""
 
 msgid "Syntax error in options."
 msgstr ""
 
-#: src/output/output.c:640
+#: src/output/output.c:642
 msgid "Syntax error in options (`=' expected)."
 msgstr ""
 
 msgid "Syntax error in options (`=' expected)."
 msgstr ""
 
-#: src/output/output.c:647
+#: src/output/output.c:649
 msgid "Syntax error in options (value expected after `=')."
 msgstr ""
 
 msgid "Syntax error in options (value expected after `=')."
 msgstr ""
 
-#: src/output/output.c:744
+#: src/output/output.c:691
 #, c-format
 msgid "Unknown output driver class `%s'."
 msgstr ""
 
 #, c-format
 msgid "Unknown output driver class `%s'."
 msgstr ""
 
-#: src/output/output.c:751
-#, c-format
-msgid "Can't initialize output driver class `%s'."
-msgstr ""
-
-#: src/output/output.c:758
-#, c-format
-msgid "Can't initialize output driver `%s' of class `%s'."
-msgstr ""
-
-#: src/output/output.c:780
+#: src/output/output.c:712
 #, c-format
 msgid "Unknown device type `%s'."
 msgstr ""
 
 #, c-format
 msgid "Unknown device type `%s'."
 msgstr ""
 
-#: src/output/output.c:793
-#, c-format
-msgid "Can't complete initialization of output driver `%s' of class `%s'."
-msgstr ""
-
-#: src/output/output.c:839
-msgid "Driver definition line contains fewer fields than expected"
-msgstr ""
-
-#: src/output/output.c:876
+#: src/output/output.c:731
 #, c-format
 #, c-format
-msgid "Can't deinitialize output driver class `%s'."
+msgid "Can't initialize output driver `%s' of class `%s'."
 msgstr ""
 
 msgstr ""
 
-#: src/output/output.c:949
-#, c-format
-msgid "Trying to find keyword `%s'...\n"
+#: src/output/output.c:776
+msgid "Driver definition line missing driver name or class name"
 msgstr ""
 
 msgstr ""
 
-#: src/output/output.c:1066
+#: src/output/output.c:922
 #, c-format
 msgid "Unit \"%s\" is unknown in dimension \"%s\"."
 msgstr ""
 
 #, c-format
 msgid "Unit \"%s\" is unknown in dimension \"%s\"."
 msgstr ""
 
-#: src/output/output.c:1081
+#: src/output/output.c:937
 #, c-format
 msgid "Bad dimension \"%s\"."
 msgstr ""
 
 #, c-format
 msgid "Bad dimension \"%s\"."
 msgstr ""
 
-#: src/output/output.c:1107
+#: src/output/output.c:963
 #, c-format
 msgid "`x' expected in paper size `%s'."
 msgstr ""
 
 #, c-format
 msgid "`x' expected in paper size `%s'."
 msgstr ""
 
-#: src/output/output.c:1117
+#: src/output/output.c:973
 #, c-format
 msgid "Trailing garbage `%s' on paper size `%s'."
 msgstr ""
 
 #, c-format
 msgid "Trailing garbage `%s' on paper size `%s'."
 msgstr ""
 
-#: src/output/output.c:1166
+#: src/output/output.c:1022
 msgid "Paper size name must not be empty."
 msgstr ""
 
 msgid "Paper size name must not be empty."
 msgstr ""
 
-#: src/output/output.c:1197
+#: src/output/output.c:1053
 msgid "Cannot find `papersize' configuration file."
 msgstr ""
 
 msgid "Cannot find `papersize' configuration file."
 msgstr ""
 
-#: src/output/output.c:1201
-#, c-format
-msgid "%s: Opening paper size definition file..."
-msgstr ""
-
-#: src/output/output.c:1243
+#: src/output/output.c:1098
 msgid "Syntax error in paper size definition."
 msgstr ""
 
 msgid "Syntax error in paper size definition."
 msgstr ""
 
-#: src/output/output.c:1272
-msgid "Paper size definition file read successfully."
-msgstr ""
-
-#: src/output/output.c:1274
+#: src/output/output.c:1127
 msgid "Error reading paper size definition file."
 msgstr ""
 
 msgid "Error reading paper size definition file."
 msgstr ""
 
-#: src/output/output.c:1330
-#, c-format
-msgid "Error closing page on %s device of %s class."
-msgstr ""
-
-#: src/output/output.c:1334
+#: src/output/postscript.c:164
 #, c-format
 #, c-format
-msgid "Error opening page on %s device of %s class."
+msgid "opening PostScript output file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:319
-#, c-format
-msgid "PostScript driver initializing as `%s'..."
-msgstr ""
-
-#: src/output/postscript.c:443
+#: src/output/postscript.c:202
 #, c-format
 msgid ""
 #, c-format
 msgid ""
-"PostScript driver: The defined page is not long enough to hold margins and "
-"headers, plus least 15 lines of the default fonts.  In fact, there's only "
-"room for %d lines of each font at the default size of %d.%03d points."
+"The defined PostScript page is not long enough to hold margins and headers, "
+"plus least 15 lines of the default fonts.  In fact, there's only room for %d "
+"lines of each font at the default size of %d.%03d points."
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:573
+#: src/output/postscript.c:250
 #, c-format
 #, c-format
-msgid "Unknown configuration parameter `%s' for PostScript device driver."
+msgid "closing PostScript output file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:589
+#: src/output/postscript.c:310
 #, c-format
 #, c-format
-msgid ""
-"Unknown orientation `%s'.  Valid orientations are `portrait' and `landscape'."
+msgid "unknown configuration parameter `%s' for PostScript device driver"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:601
-msgid ""
-"Unknown value for `data'.  Valid values are `clean7bit', `clean8bit', and "
-"`binary'."
-msgstr ""
-
-#: src/output/postscript.c:610
-msgid "Unknown value for `line-ends'.  Valid values are `lf' and `crlf'."
-msgstr ""
-
-#: src/output/postscript.c:619
-msgid "Unknown value for `line-style'.  Valid values are `thick' and `double'."
-msgstr ""
-
-#: src/output/postscript.c:682
+#: src/output/postscript.c:326
 #, c-format
 msgid ""
 #, c-format
 msgid ""
-"Default font size must be at least 1 point (value of 1000 for key `%s')."
-msgstr ""
-
-#: src/output/postscript.c:714
-#, c-format
-msgid "Value for `%s' must be a dimension of positive length (i.e., `1in')."
-msgstr ""
-
-#: src/output/postscript.c:778
-#, c-format
-msgid "Nonnegative integer required as value for `%s'."
+"unknown orientation `%s' (valid orientations are `portrait' and `landscape')"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:904
+#: src/output/postscript.c:338
 #, c-format
 #, c-format
-msgid "%s: %s: Opening PostScript font encoding..."
+msgid "boolean value expected for %s"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:910
+#: src/output/postscript.c:351
 #, c-format
 #, c-format
-msgid ""
-"PostScript driver: Cannot open encoding file `%s': %s.  Substituting "
-"ISOLatin1Encoding for missing encoding."
-msgstr ""
-
-#: src/output/postscript.c:952
-msgid "PostScript driver: Invalid numeric format."
+msgid "positive integer value required for `%s'"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:957
+#: src/output/postscript.c:356
 #, c-format
 #, c-format
-msgid ""
-"PostScript driver: Codes must be between 0 and 255.  (%d is not allowed.)"
+msgid "default font size must be at least 1 point (value of 1000 for key `%s')"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:993
+#: src/output/postscript.c:388
 #, c-format
 #, c-format
-msgid "PostScript driver: Error closing encoding file `%s'."
+msgid "value for `%s' must be a dimension of positive length (i.e., `1in')"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:996
+#: src/output/postscript.c:1182
 #, c-format
 #, c-format
-msgid "%s: PostScript font encoding read successfully."
+msgid "\"%s\": bad font specification"
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1090
+#: src/output/postscript.c:1190
 #, c-format
 #, c-format
-msgid "%s: %s: Opening PostScript encoding list file."
+msgid "could not find AFM file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1123
+#: src/output/postscript.c:1204
 #, c-format
 #, c-format
-msgid "%s: PostScript encoding list file read successfully."
+msgid "could not find font \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1137
-msgid "<<default encoding>>"
-msgstr ""
-
-#: src/output/postscript.c:1294
-msgid ""
-"Cannot find PostScript prologue.  The use of `-vv' on the command line is "
-"suggested as a debugging aid."
-msgstr ""
-
-#: src/output/postscript.c:1299
+#: src/output/postscript.c:1213
 #, c-format
 #, c-format
-msgid "%s: %s: Opening PostScript prologue..."
+msgid "could not find encoding \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1465
+#: src/output/postscript.c:1313
 #, c-format
 #, c-format
-msgid "%s: PostScript prologue read successfully."
+msgid "cannot open font file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1469
+#: src/output/postscript.c:1354
 #, c-format
 #, c-format
-msgid "%s: Error reading PostScript prologue."
+msgid "reading font file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:1639
+#: src/output/postscript.c:1376
 #, c-format
 #, c-format
-msgid "PostScript output driver: %s: %s"
+msgid "cannot open font encoding file \"%s\""
 msgstr ""
 
 msgstr ""
 
-#: src/output/postscript.c:2338
-#, c-format
-msgid "PostScript driver: Cannot find encoding `%s' for PostScript font `%s'."
+#: src/output/postscript.c:1405
+msgid "invalid numeric format"
 msgstr ""
 
 msgstr ""
 
-#: src/output/table.c:259
+#: src/output/table.c:239
 #, c-format
 msgid "bad vline: x=%d+%d=%d y=(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
 msgstr ""
 
 #, c-format
 msgid "bad vline: x=%d+%d=%d y=(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
 msgstr ""
 
-#: src/output/table.c:334
+#: src/output/table.c:310
 #, c-format
 msgid ""
 "bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
 #, c-format
 msgid ""
 "bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
@@ -4919,8 +4675,6 @@ msgid ""
 "  -B, --config-dir=DIR      set configuration directory to DIR\n"
 "  -o, --device=DEVICE       select output driver DEVICE and disable "
 "defaults\n"
 "  -B, --config-dir=DIR      set configuration directory to DIR\n"
 "  -o, --device=DEVICE       select output driver DEVICE and disable "
 "defaults\n"
-"  -d, --define=VAR[=VALUE]  set environment variable VAR to VALUE, or empty\n"
-"  -u, --undef=VAR           undefine environment variable VAR\n"
 "\n"
 "Input and output:\n"
 "  -f, --out-file=FILE       send output to FILE (overwritten)\n"
 "\n"
 "Input and output:\n"
 "  -f, --out-file=FILE       send output to FILE (overwritten)\n"
@@ -4949,7 +4703,7 @@ msgid ""
 "\n"
 msgstr ""
 
 "\n"
 msgstr ""
 
-#: src/ui/terminal/command-line.c:249
+#: src/ui/terminal/command-line.c:247
 #, c-format
 msgid ""
 "\n"
 #, c-format
 msgid ""
 "\n"
index 4a96aeb941a9479876c7386203e97d30fc102f8b..ce8805cd38ae9b14a0a9103dbdf292989c570350 100644 (file)
@@ -1,3 +1,14 @@
+Mon Apr  3 11:03:36 2006  Ben Pfaff  <blp@gnu.org>
+
+       * list.q: (write_all_headers) Adapt to new html and output
+       internals.
+       (clean_up) Ditto.
+       (write_varname) Ditto.
+       (write_fallback_headers) Ditto.
+       (determine_layout) Ditto.
+       (list_cases) Ditto.
+       
+
 Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
        
        * Moved files from src directory
 Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
        
        * Moved files from src directory
index 3b5066255eaf3f2c33f89ca286c975b3c95d6c57..e3324cf20f354f575315da1fbfa25b9b2d11082b 100644 (file)
@@ -792,12 +792,12 @@ dump_fixed_table (const struct dls_var_spec *specs,
       tab_text (t, 1, i, TAT_PRINTF, "%d", spec->rec);
       tab_text (t, 2, i, TAT_PRINTF, "%3d-%3d",
                    spec->fc, spec->lc);
       tab_text (t, 1, i, TAT_PRINTF, "%d", spec->rec);
       tab_text (t, 2, i, TAT_PRINTF, "%3d-%3d",
                    spec->fc, spec->lc);
-      tab_text (t, 3, i, TAB_LEFT | TAT_FIX,
+      tab_text (t, 3, i, TAB_LEFT | TAB_FIX,
                    fmt_to_string (&spec->input));
     }
 
                    fmt_to_string (&spec->input));
     }
 
-  tab_title (t, 1, ngettext ("Reading %d record from %s.",
-                             "Reading %d records from %s.", rec_cnt),
+  tab_title (t, ngettext ("Reading %d record from %s.",
+                          "Reading %d records from %s.", rec_cnt),
              rec_cnt, fh_get_name (fh));
   tab_submit (t);
 }
              rec_cnt, fh_get_name (fh));
   tab_submit (t);
 }
@@ -908,11 +908,11 @@ dump_free_table (const struct data_list_pgm *dls,
     for (i = 1, spec = dls->first; spec; spec = spec->next, i++)
       {
        tab_text (t, 0, i, TAB_LEFT, spec->v->name);
     for (i = 1, spec = dls->first; spec; spec = spec->next, i++)
       {
        tab_text (t, 0, i, TAB_LEFT, spec->v->name);
-       tab_text (t, 1, i, TAB_LEFT | TAT_FIX, fmt_to_string (&spec->input));
+       tab_text (t, 1, i, TAB_LEFT | TAB_FIX, fmt_to_string (&spec->input));
       }
   }
 
       }
   }
 
-  tab_title (t, 1, _("Reading free-form data from %s."), fh_get_name (fh));
+  tab_title (t, _("Reading free-form data from %s."), fh_get_name (fh));
   
   tab_submit (t);
 }
   
   tab_submit (t);
 }
index 8980bdde253a2af0e402a0a1b502e8cbc876c54b..b212efeb308ae63ee86b6577220ccf365e0ba32d 100644 (file)
@@ -115,10 +115,12 @@ write_line (struct outp_driver *d, char *s)
   struct outp_text text;
   
   assert (d->cp_y + d->font_height <= d->length);
   struct outp_text text;
   
   assert (d->cp_y + d->font_height <= d->length);
-  text.options = OUTP_T_JUST_LEFT;
-  ls_init (&text.s, s, strlen (s));
+  text.font = OUTP_FIXED;
+  text.justification = OUTP_LEFT;
+  ls_init (&text.string, s, strlen (s));
   text.x = d->cp_x;
   text.y = d->cp_y;
   text.x = d->cp_x;
   text.y = d->cp_y;
+  text.h = text.v = INT_MAX;
   d->class->text_draw (d, &text);
   d->cp_x = 0;
   d->cp_y += d->font_height;
   d->class->text_draw (d, &text);
   d->cp_x = 0;
   d->cp_y += d->font_height;
@@ -252,25 +254,17 @@ write_all_headers (void *aux UNUSED)
        {
          struct html_driver_ext *x = d->ext;
   
        {
          struct html_driver_ext *x = d->ext;
   
-         assert (d->driver_open);
-         if (x->sequence_no == 0 && !d->class->open_page (d))
-           {
-             msg (ME, _("Cannot open first page on HTML device %s."),
-                  d->name);
-             return;
-           }
-
-         fputs ("<TABLE BORDER=1>\n  <TR>\n", x->file.file);
+         fputs ("<TABLE BORDER=1>\n  <TR>\n", x->file);
          
          {
            size_t i;
 
            for (i = 0; i < cmd.n_variables; i++)
          
          {
            size_t i;
 
            for (i = 0; i < cmd.n_variables; i++)
-             fprintf (x->file.file, "    <TH><I><B>%s</B></I></TH>\n",
+             fprintf (x->file, "    <TH><EM>%s</EM></TH>\n",
                       cmd.v_variables[i]->name);
          }
 
                       cmd.v_variables[i]->name);
          }
 
-         fputs ("  <TR>\n", x->file.file);
+         fputs ("  </TR>\n", x->file);
        }
       else
        assert (0);
        }
       else
        assert (0);
@@ -380,16 +374,14 @@ clean_up (void)
            free (prc->header);
          }
        free (prc);
            free (prc->header);
          }
        free (prc);
-      
-       d->class->text_set_font_by_name (d, "PROP");
       }
     else if (d->class == &html_class)
       {
       }
     else if (d->class == &html_class)
       {
-       if (d->driver_open && d->page_open)
+       if (d->page_open)
          {
            struct html_driver_ext *x = d->ext;
 
          {
            struct html_driver_ext *x = d->ext;
 
-           fputs ("</TABLE>\n", x->file.file);
+           fputs ("</TABLE>\n", x->file);
          }
       }
     else
          }
       }
     else
@@ -405,12 +397,9 @@ static void
 write_varname (struct outp_driver *d, char *string, int indent)
 {
   struct outp_text text;
 write_varname (struct outp_driver *d, char *string, int indent)
 {
   struct outp_text text;
-
-  text.options = OUTP_T_JUST_LEFT;
-  ls_init (&text.s, string, strlen (string));
-  d->class->text_metrics (d, &text);
+  int width;
   
   
-  if (d->cp_x + text.h > d->width)
+  if (d->cp_x + outp_string_width (d, string, OUTP_FIXED) > d->width)
     {
       d->cp_y += d->font_height;
       if (d->cp_y + d->font_height > d->length)
     {
       d->cp_y += d->font_height;
       if (d->cp_y + d->font_height > d->length)
@@ -418,10 +407,15 @@ write_varname (struct outp_driver *d, char *string, int indent)
       d->cp_x = indent;
     }
 
       d->cp_x = indent;
     }
 
+  text.font = OUTP_FIXED;
+  text.justification = OUTP_LEFT;
+  ls_init (&text.string, string, strlen (string));
   text.x = d->cp_x;
   text.y = d->cp_y;
   text.x = d->cp_x;
   text.y = d->cp_y;
+  text.h = text.v = INT_MAX;
   d->class->text_draw (d, &text);
   d->class->text_draw (d, &text);
-  d->cp_x += text.h;
+  d->class->text_metrics (d, &text, &width, NULL);
+  d->cp_x += width;
 }
 
 /* When we can't fit all the values across the page, we write out all
 }
 
 /* When we can't fit all the values across the page, we write out all
@@ -448,13 +442,15 @@ write_fallback_headers (struct outp_driver *d)
        outp_eject_page (d);
       
       /* The leader is a string like `Line 1: '.  Write the leader. */
        outp_eject_page (d);
       
       /* The leader is a string like `Line 1: '.  Write the leader. */
-      sprintf(leader, "%s %d:", Line, ++line_number);
-      text.options = OUTP_T_JUST_LEFT;
-      ls_init (&text.s, leader, strlen (leader));
+      sprintf (leader, "%s %d:", Line, ++line_number);
+      text.font = OUTP_FIXED;
+      text.justification = OUTP_LEFT;
+      ls_init (&text.string, leader, strlen (leader));
       text.x = 0;
       text.y = d->cp_y;
       text.x = 0;
       text.y = d->cp_y;
+      text.h = text.v = INT_MAX;
       d->class->text_draw (d, &text);
       d->class->text_draw (d, &text);
-      d->cp_x = text.h;
+      d->class->text_metrics (d, &text, &d->cp_x, NULL);
 
       goto entry;
       do
 
       goto entry;
       do
@@ -528,8 +524,7 @@ determine_layout (void)
       
       assert (d->class->special == 0);
 
       
       assert (d->class->special == 0);
 
-      if (!d->page_open)
-       d->class->open_page (d);
+      outp_open_page (d);
       
       max_width = n_chars_width (d);
       largest_page_width = max (largest_page_width, max_width);
       
       max_width = n_chars_width (d);
       largest_page_width = max (largest_page_width, max_width);
@@ -548,7 +543,6 @@ determine_layout (void)
       if (width <= max_width)
        {
          prc->header_rows = 2;
       if (width <= max_width)
        {
          prc->header_rows = 2;
-         d->class->text_set_font_by_name (d, "FIXED");
          continue;
        }
 
          continue;
        }
 
@@ -593,8 +587,6 @@ determine_layout (void)
            prc->header_rows = max (prc->header_rows,
                                    strlen (cmd.v_variables[column]->name));
          prc->header_rows++;
            prc->header_rows = max (prc->header_rows,
                                    strlen (cmd.v_variables[column]->name));
          prc->header_rows++;
-
-         d->class->text_set_font_by_name (d, "FIXED");
          continue;
        }
 
          continue;
        }
 
@@ -605,7 +597,6 @@ determine_layout (void)
       d->cp_y += d->font_height;
       write_fallback_headers (d);
       d->cp_y += d->font_height;
       d->cp_y += d->font_height;
       write_fallback_headers (d);
       d->cp_y += d->font_height;
-      d->class->text_set_font_by_name (d, "FIXED");
     }
 
   line_buf = xmalloc (max (1022, largest_page_width) + 2);
     }
 
   line_buf = xmalloc (max (1022, largest_page_width) + 2);
@@ -692,12 +683,13 @@ list_cases (struct ccase *c, void *aux UNUSED)
        struct html_driver_ext *x = d->ext;
        int column;
 
        struct html_driver_ext *x = d->ext;
        int column;
 
-       fputs ("  <TR>\n", x->file.file);
+       fputs ("  <TR>\n", x->file);
        
        for (column = 0; column < cmd.n_variables; column++)
          {
            struct variable *v = cmd.v_variables[column];
        
        for (column = 0; column < cmd.n_variables; column++)
          {
            struct variable *v = cmd.v_variables[column];
-           char buf[41];
+           char buf[256];
+            struct fixed_string s;
            
             if ((formats[v->print.type].cat & FCAT_STRING) || v->fv != -1)
              data_out (buf, &v->print, case_data (c, v->fv));
            
             if ((formats[v->print.type].cat & FCAT_STRING) || v->fv != -1)
              data_out (buf, &v->print, case_data (c, v->fv));
@@ -707,13 +699,14 @@ list_cases (struct ccase *c, void *aux UNUSED)
                 case_idx_value.f = case_idx;
                 data_out (buf, &v->print, &case_idx_value); 
               }
                 case_idx_value.f = case_idx;
                 data_out (buf, &v->print, &case_idx_value); 
               }
-           buf[v->print.w] = 0;
 
 
-           fprintf (x->file.file, "    <TD ALIGN=RIGHT>%s</TD>\n",
-                    &buf[strspn (buf, " ")]);
+            ls_init (&s, buf, v->print.w);
+            fputs ("    <TD>", x->file);
+            html_put_cell_contents (d, TAB_FIX, &s);
+            fputs ("</TD>\n", x->file);
          }
          
          }
          
-       fputs ("  </TR>\n", x->file.file);
+       fputs ("  </TR>\n", x->file);
       }
     else
       assert (0);
       }
     else
       assert (0);
index 9d835abe5204f439fbe97b18b7a091a9b8b8e1bd..52828400f9382194b4e3c25f0e3f95f06612b7d2 100644 (file)
@@ -810,12 +810,12 @@ dump_table (const struct file_handle *fh)
        {
          int len = strlen (spec->u.c);
          nspec++;
        {
          int len = strlen (spec->u.c);
          nspec++;
-         tab_text (t, 0, nspec, TAB_LEFT | TAT_FIX | TAT_PRINTF,
+         tab_text (t, 0, nspec, TAB_LEFT | TAB_FIX | TAT_PRINTF,
                        "\"%s\"", spec->u.c);
          tab_text (t, 1, nspec, TAT_PRINTF, "%d", recno + 1);
          tab_text (t, 2, nspec, TAT_PRINTF, "%3d-%3d",
                        spec->fc + 1, spec->fc + len);
                        "\"%s\"", spec->u.c);
          tab_text (t, 1, nspec, TAT_PRINTF, "%d", recno + 1);
          tab_text (t, 2, nspec, TAT_PRINTF, "%3d-%3d",
                        spec->fc + 1, spec->fc + len);
-         tab_text (t, 3, nspec, TAB_LEFT | TAT_FIX | TAT_PRINTF,
+         tab_text (t, 3, nspec, TAB_LEFT | TAB_FIX | TAT_PRINTF,
                        "A%d", len);
          break;
        }
                        "A%d", len);
          break;
        }
@@ -826,7 +826,7 @@ dump_table (const struct file_handle *fh)
          tab_text (t, 1, nspec, TAT_PRINTF, "%d", recno + 1);
          tab_text (t, 2, nspec, TAT_PRINTF, "%3d-%3d",
                        spec->fc + 1, spec->fc + spec->u.v.f.w);
          tab_text (t, 1, nspec, TAT_PRINTF, "%d", recno + 1);
          tab_text (t, 2, nspec, TAT_PRINTF, "%3d-%3d",
                        spec->fc + 1, spec->fc + spec->u.v.f.w);
-         tab_text (t, 3, nspec, TAB_LEFT | TAT_FIX,
+         tab_text (t, 3, nspec, TAB_LEFT | TAB_FIX,
                        fmt_to_string (&spec->u.v.f));
          break;
        }
                        fmt_to_string (&spec->u.v.f));
          break;
        }
@@ -837,12 +837,12 @@ dump_table (const struct file_handle *fh)
       }
 
   if (fh != NULL)
       }
 
   if (fh != NULL)
-    tab_title (t, 1, ngettext ("Writing %d record to %s.",
-                               "Writing %d records to %s.", recno),
+    tab_title (t, ngettext ("Writing %d record to %s.",
+                            "Writing %d records to %s.", recno),
                recno, fh_get_name (fh));
   else
                recno, fh_get_name (fh));
   else
-    tab_title (t, 1, ngettext ("Writing %d record.",
-                               "Writing %d records.", recno), recno);
+    tab_title (t, ngettext ("Writing %d record.",
+                            "Writing %d records.", recno), recno);
   tab_submit (t);
 }
 
   tab_submit (t);
 }
 
@@ -927,7 +927,7 @@ print_trns_proc (void *trns_, struct ccase *c, int case_num UNUSED)
        if (t->writer == NULL)
          {
            buf[len] = 0;
        if (t->writer == NULL)
          {
            buf[len] = 0;
-           tab_output_text (TAT_FIX | TAT_NOWRAP, buf);
+           tab_output_text (TAB_FIX | TAT_NOWRAP, buf);
          }
        else
          {
          }
        else
          {
index 98cc90ddfb9e600114de1b8712ff97b65c08c729..1f9bc7e49d7b7830cd4f9e2db6997cd4c97ce821 100644 (file)
@@ -96,7 +96,7 @@ cmd_sysfile_info (void)
   sfm_close_reader (reader);
 
   t = tab_create (2, 9, 0);
   sfm_close_reader (reader);
 
   t = tab_create (2, 9, 0);
-  tab_vline (t, TAL_1 | TAL_SPACING, 1, 0, 8);
+  tab_vline (t, TAL_GAP, 1, 0, 8);
   tab_text (t, 0, 0, TAB_LEFT, _("File:"));
   tab_text (t, 1, 0, TAB_LEFT, fh_get_filename (h));
   tab_text (t, 0, 1, TAB_LEFT, _("Label:"));
   tab_text (t, 0, 0, TAB_LEFT, _("File:"));
   tab_text (t, 1, 0, TAB_LEFT, fh_get_filename (h));
   tab_text (t, 0, 1, TAB_LEFT, _("Label:"));
@@ -200,7 +200,7 @@ cmd_display (void)
       else
        {
          tab_output_text (TAB_LEFT | TAT_TITLE, _("File label:"));
       else
        {
          tab_output_text (TAB_LEFT | TAT_TITLE, _("File label:"));
-         tab_output_text (TAB_LEFT | TAT_FIX, dict_get_label (default_dict));
+         tab_output_text (TAB_LEFT | TAB_FIX, dict_get_label (default_dict));
        }
     }
   else
        }
     }
   else
@@ -311,7 +311,7 @@ display_documents (void)
                 && len > 0)
            len--;
          buf[len + 1] = 0;
                 && len > 0)
            len--;
          buf[len + 1] = 0;
-         tab_output_text (TAB_LEFT | TAT_FIX | TAT_NOWRAP, buf);
+         tab_output_text (TAB_LEFT | TAB_FIX | TAT_NOWRAP, buf);
        }
     }
 }
        }
     }
 }
index 0803f0825ed712e2be08b27f19263adc28fb0d9c..45d265ddcac1681fa9d33a972b560668ea6c434c 100644 (file)
@@ -465,7 +465,7 @@ read_syntax_file (struct string *line, struct getl_source *s)
 
   /* Echo to listing file, if configured to do so. */
   if (get_echo ())
 
   /* Echo to listing file, if configured to do so. */
   if (get_echo ())
-    tab_output_text (TAB_LEFT | TAT_FIX, ds_c_str (line));
+    tab_output_text (TAB_LEFT | TAB_FIX, ds_c_str (line));
 
   return true;
 }
 
   return true;
 }
index d11d2d8d79d658e9b201e723d9d989523e17a44a..d6de30528a246881a75f02356d1fdaf1697154eb 100644 (file)
@@ -809,7 +809,7 @@ make_summary_table (void)
   int cur_tab = 0;
 
   summary = tab_create (7, 3 + nxtab, 1);
   int cur_tab = 0;
 
   summary = tab_create (7, 3 + nxtab, 1);
-  tab_title (summary, 0, _("Summary."));
+  tab_title (summary, _("Summary."));
   tab_headers (summary, 1, 0, 3, 0);
   tab_joint_text (summary, 1, 0, 6, 0, TAB_CENTER, _("Cases"));
   tab_joint_text (summary, 1, 1, 2, 1, TAB_CENTER, _("Valid"));
   tab_headers (summary, 1, 0, 3, 0);
   tab_joint_text (summary, 1, 0, 6, 0, TAB_CENTER, _("Cases"));
   tab_joint_text (summary, 1, 1, 2, 1, TAB_CENTER, _("Valid"));
@@ -1088,7 +1088,7 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
          }
        strcpy (cp, "].");
 
          }
        strcpy (cp, "].");
 
-       tab_title (table, 0, title);
+       tab_title (table, "%s", title);
        local_free (title);
       }
       
        local_free (title);
       }
       
@@ -1104,7 +1104,7 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
                          (pe - pb) / n_cols * 3 / 2 * N_CHISQ + 10, 1);
       tab_headers (chisq, 1 + (nvar - 2), 0, 1, 0);
 
                          (pe - pb) / n_cols * 3 / 2 * N_CHISQ + 10, 1);
       tab_headers (chisq, 1 + (nvar - 2), 0, 1, 0);
 
-      tab_title (chisq, 0, "Chi-square tests.");
+      tab_title (chisq, _("Chi-square tests."));
       
       tab_offset (chisq, nvar - 2, 0);
       tab_text (chisq, 0, 0, TAB_LEFT | TAT_TITLE, _("Statistic"));
       
       tab_offset (chisq, nvar - 2, 0);
       tab_text (chisq, 0, 0, TAB_LEFT | TAT_TITLE, _("Statistic"));
@@ -1130,7 +1130,7 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
     {
       sym = tab_create (6 + (nvar - 2), (pe - pb) / n_cols * 7 + 10, 1);
       tab_headers (sym, 2 + (nvar - 2), 0, 1, 0);
     {
       sym = tab_create (6 + (nvar - 2), (pe - pb) / n_cols * 7 + 10, 1);
       tab_headers (sym, 2 + (nvar - 2), 0, 1, 0);
-      tab_title (sym, 0, "Symmetric measures.");
+      tab_title (sym, _("Symmetric measures."));
 
       tab_offset (sym, nvar - 2, 0);
       tab_text (sym, 0, 0, TAB_LEFT | TAT_TITLE, _("Category"));
 
       tab_offset (sym, nvar - 2, 0);
       tab_text (sym, 0, 0, TAB_LEFT | TAT_TITLE, _("Category"));
@@ -1149,7 +1149,7 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
     {
       risk = tab_create (4 + (nvar - 2), (pe - pb) / n_cols * 4 + 10, 1);
       tab_headers (risk, 1 + nvar - 2, 0, 2, 0);
     {
       risk = tab_create (4 + (nvar - 2), (pe - pb) / n_cols * 4 + 10, 1);
       tab_headers (risk, 1 + nvar - 2, 0, 2, 0);
-      tab_title (risk, 0, "Risk estimate.");
+      tab_title (risk, _("Risk estimate."));
 
       tab_offset (risk, nvar - 2, 0);
       tab_joint_text (risk, 2, 0, 3, 0, TAB_CENTER | TAT_TITLE | TAT_PRINTF,
 
       tab_offset (risk, nvar - 2, 0);
       tab_joint_text (risk, 2, 0, 3, 0, TAB_CENTER | TAT_TITLE | TAT_PRINTF,
@@ -1171,7 +1171,7 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
     {
       direct = tab_create (7 + (nvar - 2), (pe - pb) / n_cols * 7 + 10, 1);
       tab_headers (direct, 3 + (nvar - 2), 0, 1, 0);
     {
       direct = tab_create (7 + (nvar - 2), (pe - pb) / n_cols * 7 + 10, 1);
       tab_headers (direct, 3 + (nvar - 2), 0, 1, 0);
-      tab_title (direct, 0, "Directional measures.");
+      tab_title (direct, _("Directional measures."));
 
       tab_offset (direct, nvar - 2, 0);
       tab_text (direct, 0, 0, TAB_LEFT | TAT_TITLE, _("Category"));
 
       tab_offset (direct, nvar - 2, 0);
       tab_text (direct, 0, 0, TAB_LEFT | TAT_TITLE, _("Category"));
@@ -1466,7 +1466,7 @@ submit (struct tab_table *t)
   tab_box (t, TAL_2, TAL_2, -1, -1, 0, 0, tab_nc (t) - 1, tab_nr (t) - 1);
   tab_box (t, -1, -1, -1, TAL_1, tab_l (t), tab_t (t) - 1, tab_nc (t) - 1,
           tab_nr (t) - 1);
   tab_box (t, TAL_2, TAL_2, -1, -1, 0, 0, tab_nc (t) - 1, tab_nr (t) - 1);
   tab_box (t, -1, -1, -1, TAL_1, tab_l (t), tab_t (t) - 1, tab_nc (t) - 1,
           tab_nr (t) - 1);
-  tab_box (t, -1, -1, -1, TAL_1 | TAL_SPACING, 0, tab_t (t), tab_l (t) - 1,
+  tab_box (t, -1, -1, -1, TAL_GAP, 0, tab_t (t), tab_l (t) - 1,
           tab_nr (t) - 1);
   tab_vline (t, TAL_2, tab_l (t), 0, tab_nr (t) - 1);
   tab_dim (t, crosstabs_dim);
           tab_nr (t) - 1);
   tab_vline (t, TAL_2, tab_l (t), 0, tab_nr (t) - 1);
   tab_dim (t, crosstabs_dim);
@@ -1481,14 +1481,20 @@ crosstabs_dim (struct tab_table *t, struct outp_driver *d)
   int i;
   
   /* Width of a numerical column. */
   int i;
   
   /* Width of a numerical column. */
-  int c = outp_string_width (d, "0.000000");
+  int c = outp_string_width (d, "0.000000", OUTP_PROPORTIONAL);
   if (cmd.miss == CRS_REPORT)
   if (cmd.miss == CRS_REPORT)
-    c += outp_string_width (d, "M");
+    c += outp_string_width (d, "M", OUTP_PROPORTIONAL);
 
   /* Set width for header columns. */
   if (t->l != 0)
     {
 
   /* Set width for header columns. */
   if (t->l != 0)
     {
-      int w = (d->width - t->vr_tot - c * (t->nc - t->l)) / t->l;
+      size_t i;
+      int w;
+
+      w = d->width - c * (t->nc - t->l);
+      for (i = 0; i <= t->nc; i++)
+        w -= t->wrv[i];
+      w /= t->l;
       
       if (w < d->prop_em_width * 8)
        w = d->prop_em_width * 8;
       
       if (w < d->prop_em_width * 8)
        w = d->prop_em_width * 8;
index b305deea0f1aa022add52c4b0199daeb5a33c0c6..9a90cc9f119951a26e2e6af57ca7f604e55d86c2 100644 (file)
@@ -540,7 +540,7 @@ dump_z_table (struct dsc_proc *dsc)
   }
   
   t = tab_create (2, cnt + 1, 0);
   }
   
   t = tab_create (2, cnt + 1, 0);
-  tab_title (t, 0, _("Mapping of variables to corresponding Z-scores."));
+  tab_title (t, _("Mapping of variables to corresponding Z-scores."));
   tab_columns (t, SOM_COL_DOWN, 1);
   tab_headers (t, 0, 0, 1, 0);
   tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 1, cnt);
   tab_columns (t, SOM_COL_DOWN, 1);
   tab_headers (t, 0, 0, 1, 0);
   tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 1, cnt);
@@ -915,7 +915,7 @@ display (struct dsc_proc *dsc)
          tab_float (t, nc++, i + 1, TAB_NONE, dv->stats[j], 10, 3);
     }
 
          tab_float (t, nc++, i + 1, TAB_NONE, dv->stats[j], 10, 3);
     }
 
-  tab_title (t, 1, _("Valid cases = %g; cases with missing value(s) = %g."),
+  tab_title (t, _("Valid cases = %g; cases with missing value(s) = %g."),
             dsc->valid, dsc->missing_listwise);
 
   tab_submit (t);
             dsc->valid, dsc->missing_listwise);
 
   tab_submit (t);
index 8248ff18c9c5d5cb1f17fe389da28fa270e79def..aad3baa10fd4380e68b0faddede7d834480b6966 100644 (file)
@@ -914,7 +914,7 @@ show_summary(struct variable **dependent_var, int n_dep_var,
   tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
 
 
   tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
 
 
-  tab_title (tbl, 0, _("Case Processing Summary"));
+  tab_title (tbl, _("Case Processing Summary"));
   
 
   tab_joint_text(tbl, heading_columns, 0, 
   
 
   tab_joint_text(tbl, heading_columns, 0, 
@@ -1120,7 +1120,7 @@ show_extremes(struct variable **dependent_var, int n_dep_var,
 
   tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows );
 
 
   tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows );
 
-  tab_title (tbl, 0, _("Extreme Values"));
+  tab_title (tbl, _("Extreme Values"));
 
   tab_vline (tbl, TAL_2, n_cols - 2, 0, n_rows -1);
   tab_vline (tbl, TAL_1, n_cols - 1, 0, n_rows -1);
 
   tab_vline (tbl, TAL_2, n_cols - 2, 0, n_rows -1);
   tab_vline (tbl, TAL_1, n_cols - 1, 0, n_rows -1);
@@ -1369,7 +1369,7 @@ show_descriptives(struct variable **dependent_var,
   tab_text (tbl, n_cols - 2, 0, TAB_CENTER | TAT_TITLE, _("Statistic"));
   tab_text (tbl, n_cols - 1, 0, TAB_CENTER | TAT_TITLE, _("Std. Error"));
 
   tab_text (tbl, n_cols - 2, 0, TAB_CENTER | TAT_TITLE, _("Statistic"));
   tab_text (tbl, n_cols - 1, 0, TAB_CENTER | TAT_TITLE, _("Std. Error"));
 
-  tab_title (tbl, 0, _("Descriptives"));
+  tab_title (tbl, _("Descriptives"));
 
 
   for ( i = 0 ; i < n_dep_var ; ++i ) 
 
 
   for ( i = 0 ; i < n_dep_var ; ++i ) 
@@ -1957,7 +1957,7 @@ show_percentiles(struct variable **dependent_var,
   tab_vline (tbl, TAL_2, n_heading_columns, 0, n_rows - 1);
 
 
   tab_vline (tbl, TAL_2, n_heading_columns, 0, n_rows - 1);
 
 
-  tab_title (tbl, 0, _("Percentiles"));
+  tab_title (tbl, _("Percentiles"));
 
 
   tab_hline (tbl, TAL_1, n_heading_columns, n_cols - 1, 1 );
 
 
   tab_hline (tbl, TAL_1, n_heading_columns, n_cols - 1, 1 );
index 9b338a83535de77aa11863706114efd0b6fa8943..b34299322db347a58940144109afc5e971beb053 100644 (file)
@@ -1214,7 +1214,7 @@ dump_full (struct variable *v)
     }
 
   tab_box (t, TAL_1, TAL_1,
     }
 
   tab_box (t, TAL_1, TAL_1,
-          cmd.spaces == FRQ_SINGLE ? -1 : (TAL_1 | TAL_SPACING), TAL_1,
+          cmd.spaces == FRQ_SINGLE ? -1 : TAL_GAP, TAL_1,
           0, 0, 4 + lab, r);
   tab_hline (t, TAL_2, 0, 4 + lab, 2);
   tab_hline (t, TAL_2, 0, 4 + lab, r);
           0, 0, 4 + lab, r);
   tab_hline (t, TAL_2, 0, 4 + lab, 2);
   tab_hline (t, TAL_2, 0, 4 + lab, r);
@@ -1224,7 +1224,7 @@ dump_full (struct variable *v)
   tab_float (t, 2 + lab, r, TAB_NONE, 100.0, 5, 1);
   tab_float (t, 3 + lab, r, TAB_NONE, 100.0, 5, 1);
 
   tab_float (t, 2 + lab, r, TAB_NONE, 100.0, 5, 1);
   tab_float (t, 3 + lab, r, TAB_NONE, 100.0, 5, 1);
 
-  tab_title (t, 1, "%s: %s", v->name, v->label ? v->label : "");
+  tab_title (t, "%s: %s", v->name, v->label ? v->label : "");
   tab_submit (t);
 
 }
   tab_submit (t);
 
 }
@@ -1234,9 +1234,9 @@ dump_full (struct variable *v)
 static void
 condensed_dim (struct tab_table *t, struct outp_driver *d)
 {
 static void
 condensed_dim (struct tab_table *t, struct outp_driver *d)
 {
-  int cum_w = max (outp_string_width (d, _("Cum")),
-                  max (outp_string_width (d, _("Cum")),
-                       outp_string_width (d, "000")));
+  int cum_w = max (outp_string_width (d, _("Cum"), OUTP_PROPORTIONAL),
+                  max (outp_string_width (d, _("Cum"), OUTP_PROPORTIONAL),
+                       outp_string_width (d, "000", OUTP_PROPORTIONAL)));
 
   int i;
 
 
   int i;
 
@@ -1295,10 +1295,10 @@ dump_condensed (struct variable *v)
     }
 
   tab_box (t, TAL_1, TAL_1,
     }
 
   tab_box (t, TAL_1, TAL_1,
-          cmd.spaces == FRQ_SINGLE ? -1 : (TAL_1 | TAL_SPACING), TAL_1,
+          cmd.spaces == FRQ_SINGLE ? -1 : TAL_GAP, TAL_1,
           0, 0, 3, r - 1);
   tab_hline (t, TAL_2, 0, 3, 2);
           0, 0, 3, r - 1);
   tab_hline (t, TAL_2, 0, 3, 2);
-  tab_title (t, 1, "%s: %s", v->name, v->label ? v->label : "");
+  tab_title (t, "%s: %s", v->name, v->label ? v->label : "");
   tab_columns (t, SOM_COL_DOWN, 1);
   tab_submit (t);
 }
   tab_columns (t, SOM_COL_DOWN, 1);
   tab_submit (t);
 }
@@ -1500,7 +1500,7 @@ dump_statistics (struct variable *v, int show_varname)
 
 
   tab_vline (t, TAL_1 , 2, 0, tab_nr(t) - 1);
 
 
   tab_vline (t, TAL_1 , 2, 0, tab_nr(t) - 1);
-  tab_vline (t, TAL_1 | TAL_SPACING , 1, 0, tab_nr(t) - 1 ) ;
+  tab_vline (t, TAL_GAP , 1, 0, tab_nr(t) - 1 ) ;
   
   r=2; /* N missing and N valid are always dumped */
 
   
   r=2; /* N missing and N valid are always dumped */
 
@@ -1537,9 +1537,9 @@ dump_statistics (struct variable *v, int show_varname)
   if (show_varname)
     {
       if (v->label)
   if (show_varname)
     {
       if (v->label)
-       tab_title (t, 1, "%s: %s", v->name, v->label);
+       tab_title (t, "%s: %s", v->name, v->label);
       else
       else
-       tab_title (t, 0, v->name);
+       tab_title (t, "%s", v->name);
     }
   else
     tab_flags (t, SOMF_NO_TITLE);
     }
   else
     tab_flags (t, SOMF_NO_TITLE);
index a2d6ab9cb0bde3a4daf336674b97bce338bf9029..9837d4ceb7ad6c5ec06c82014c8051829d034f37 100644 (file)
@@ -355,7 +355,7 @@ show_anova_table(void)
     }
 
 
     }
 
 
-  tab_title (t, 0, _("ANOVA"));
+  tab_title (t, _("ANOVA"));
   tab_submit (t);
 
 
   tab_submit (t);
 
 
@@ -412,7 +412,7 @@ show_descriptives(void)
   tab_text (t, 9, 1, TAB_CENTER | TAT_TITLE, _("Maximum"));
 
 
   tab_text (t, 9, 1, TAB_CENTER | TAT_TITLE, _("Maximum"));
 
 
-  tab_title (t, 0, _("Descriptives"));
+  tab_title (t, _("Descriptives"));
 
 
   row = 2;
 
 
   row = 2;
@@ -541,7 +541,7 @@ show_homogeneity(void)
   tab_text (t,  4, 0, TAB_CENTER | TAT_TITLE, _("Significance"));
   
 
   tab_text (t,  4, 0, TAB_CENTER | TAT_TITLE, _("Significance"));
   
 
-  tab_title (t, 0, _("Test of Homogeneity of Variances"));
+  tab_title (t, _("Test of Homogeneity of Variances"));
 
   for ( v=0 ; v < n_vars ; ++v ) 
     {
 
   for ( v=0 ; v < n_vars ; ++v ) 
     {
@@ -611,7 +611,7 @@ show_contrast_coeffs(short *bad_contrast)
 
   tab_vline(t, TAL_2, 2, 0, n_rows - 1);
 
 
   tab_vline(t, TAL_2, 2, 0, n_rows - 1);
 
-  tab_title (t, 0, _("Contrast Coefficients"));
+  tab_title (t, _("Contrast Coefficients"));
 
   tab_text (t,  0, 2, TAB_LEFT | TAT_TITLE, _("Contrast"));
 
 
   tab_text (t,  0, 2, TAB_LEFT | TAT_TITLE, _("Contrast"));
 
@@ -678,7 +678,7 @@ show_contrast_tests(short *bad_contrast)
   tab_vline(t, TAL_2, 3, 0, n_rows - 1);
 
 
   tab_vline(t, TAL_2, 3, 0, n_rows - 1);
 
 
-  tab_title (t, 0, _("Contrast Tests"));
+  tab_title (t, _("Contrast Tests"));
 
   tab_text (t,  2, 0, TAB_CENTER | TAT_TITLE, _("Contrast"));
   tab_text (t,  3, 0, TAB_CENTER | TAT_TITLE, _("Value of Contrast"));
 
   tab_text (t,  2, 0, TAB_CENTER | TAT_TITLE, _("Contrast"));
   tab_text (t,  3, 0, TAB_CENTER | TAT_TITLE, _("Value of Contrast"));
index 757ebf1a76c4eca4c7c5b07e23bb19fe403763c8..c30f6898700188964589f8fee0de78e49cc889b8 100644 (file)
@@ -150,7 +150,7 @@ reg_stats_r (pspp_linreg_cache * c)
   tab_float (t, 2, 1, TAB_RIGHT, rsq, 10, 2);
   tab_float (t, 3, 1, TAB_RIGHT, adjrsq, 10, 2);
   tab_float (t, 4, 1, TAB_RIGHT, std_error, 10, 2);
   tab_float (t, 2, 1, TAB_RIGHT, rsq, 10, 2);
   tab_float (t, 3, 1, TAB_RIGHT, adjrsq, 10, 2);
   tab_float (t, 4, 1, TAB_RIGHT, std_error, 10, 2);
-  tab_title (t, 0, _("Model Summary"));
+  tab_title (t, _("Model Summary"));
   tab_submit (t);
 }
 
   tab_submit (t);
 }
 
@@ -252,7 +252,7 @@ reg_stats_coeff (pspp_linreg_cache * c)
       pval = 2 * gsl_cdf_tdist_Q (fabs (t_stat), 1.0);
       tab_float (t, 6, j + 1, 0, pval, 10, 2);
     }
       pval = 2 * gsl_cdf_tdist_Q (fabs (t_stat), 1.0);
       tab_float (t, 6, j + 1, 0, pval, 10, 2);
     }
-  tab_title (t, 0, _("Coefficients"));
+  tab_title (t, _("Coefficients"));
   tab_submit (t);
   free (tmp);
 }
   tab_submit (t);
   free (tmp);
 }
@@ -313,7 +313,7 @@ reg_stats_anova (pspp_linreg_cache * c)
 
   tab_float (t, 6, 1, 0, pval, 8, 3);
 
 
   tab_float (t, 6, 1, 0, pval, 8, 3);
 
-  tab_title (t, 0, _("ANOVA"));
+  tab_title (t, _("ANOVA"));
   tab_submit (t);
 }
 static void
   tab_submit (t);
 }
 static void
@@ -384,7 +384,7 @@ reg_stats_bcov (pspp_linreg_cache * c)
                     gsl_matrix_get (c->cov, row, col), 8, 3);
        }
     }
                     gsl_matrix_get (c->cov, row, col), 8, 3);
        }
     }
-  tab_title (t, 0, _("Coefficient Correlations"));
+  tab_title (t, _("Coefficient Correlations"));
   tab_submit (t);
 }
 static void
   tab_submit (t);
 }
 static void
index c558d60acc1be8ad1d08ce94b156260148b8e28c..4754b211297bf4182ef2be42994d47595f9bb920 100644 (file)
@@ -677,7 +677,7 @@ ssbox_one_sample_init(struct ssbox *this,
   this->populate = ssbox_one_sample_populate;
 
   ssbox_base_init(this, hsize,vsize);
   this->populate = ssbox_one_sample_populate;
 
   ssbox_base_init(this, hsize,vsize);
-  tab_title (this->t, 0, _("One-Sample Statistics"));
+  tab_title (this->t, _("One-Sample Statistics"));
   tab_vline(this->t, TAL_2, 1,0,vsize - 1);
   tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, _("N"));
   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
   tab_vline(this->t, TAL_2, 1,0,vsize - 1);
   tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, _("N"));
   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
@@ -699,8 +699,8 @@ ssbox_independent_samples_init(struct ssbox *this,
   this->populate = ssbox_independent_samples_populate;
 
   ssbox_base_init(this, hsize,vsize);
   this->populate = ssbox_independent_samples_populate;
 
   ssbox_base_init(this, hsize,vsize);
-  tab_title (this->t, 0, _("Group Statistics"));
-  tab_vline(this->t,0,1,0,vsize - 1);
+  tab_vline (this->t, TAL_GAP, 1, 0,vsize - 1);
+  tab_title (this->t, _("Group Statistics"));
   tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, indep_var->name);
   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("N"));
   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
   tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, indep_var->name);
   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("N"));
   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
@@ -823,8 +823,8 @@ ssbox_paired_init(struct ssbox *this, struct cmd_t_test *cmd UNUSED)
   this->populate = ssbox_paired_populate;
 
   ssbox_base_init(this, hsize,vsize);
   this->populate = ssbox_paired_populate;
 
   ssbox_base_init(this, hsize,vsize);
-  tab_title (this->t, 0, _("Paired Sample Statistics"));
-  tab_vline(this->t,TAL_0,1,0,vsize-1);
+  tab_title (this->t, _("Paired Sample Statistics"));
+  tab_vline(this->t,TAL_GAP,1,0,vsize-1);
   tab_vline(this->t,TAL_2,2,0,vsize-1);
   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("N"));
   tab_vline(this->t,TAL_2,2,0,vsize-1);
   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("N"));
@@ -962,7 +962,7 @@ trbox_independent_samples_init(struct trbox *self,
   self->populate = trbox_independent_samples_populate;
 
   trbox_base_init(self,cmd->n_variables*2,hsize);
   self->populate = trbox_independent_samples_populate;
 
   trbox_base_init(self,cmd->n_variables*2,hsize);
-  tab_title(self->t,0,_("Independent Samples Test"));
+  tab_title(self->t,_("Independent Samples Test"));
   tab_hline(self->t,TAL_1,2,hsize-1,1);
   tab_vline(self->t,TAL_2,2,0,vsize-1);
   tab_vline(self->t,TAL_1,4,0,vsize-1);
   tab_hline(self->t,TAL_1,2,hsize-1,1);
   tab_vline(self->t,TAL_2,2,0,vsize-1);
   tab_vline(self->t,TAL_1,4,0,vsize-1);
@@ -1150,14 +1150,14 @@ trbox_paired_init(struct trbox *self,
   self->populate = trbox_paired_populate;
 
   trbox_base_init(self,n_pairs,hsize);
   self->populate = trbox_paired_populate;
 
   trbox_base_init(self,n_pairs,hsize);
-  tab_title (self->t, 0, _("Paired Samples Test"));
+  tab_title (self->t, _("Paired Samples Test"));
   tab_hline(self->t,TAL_1,2,6,1);
   tab_vline(self->t,TAL_2,2,0,vsize - 1);
   tab_joint_text(self->t,2,0,6,0,TAB_CENTER,_("Paired Differences"));
   tab_box(self->t,-1,-1,-1,TAL_1, 2,1,6,vsize-1);
   tab_box(self->t,-1,-1,-1,TAL_1, 6,0,hsize-1,vsize-1);
   tab_hline(self->t,TAL_1,5,6, 2);
   tab_hline(self->t,TAL_1,2,6,1);
   tab_vline(self->t,TAL_2,2,0,vsize - 1);
   tab_joint_text(self->t,2,0,6,0,TAB_CENTER,_("Paired Differences"));
   tab_box(self->t,-1,-1,-1,TAL_1, 2,1,6,vsize-1);
   tab_box(self->t,-1,-1,-1,TAL_1, 6,0,hsize-1,vsize-1);
   tab_hline(self->t,TAL_1,5,6, 2);
-  tab_vline(self->t,TAL_0,6,0,1);
+  tab_vline(self->t,TAL_GAP,6,0,1);
 
   tab_joint_text(self->t, 5, 1, 6, 1, TAB_CENTER | TAT_PRINTF, 
                 _("%g%% Confidence Interval of the Difference"),
 
   tab_joint_text(self->t, 5, 1, 6, 1, TAB_CENTER | TAT_PRINTF, 
                 _("%g%% Confidence Interval of the Difference"),
@@ -1244,7 +1244,7 @@ trbox_one_sample_init(struct trbox *self, struct cmd_t_test *cmd )
   self->populate = trbox_one_sample_populate;
 
   trbox_base_init(self, cmd->n_variables,hsize);
   self->populate = trbox_one_sample_populate;
 
   trbox_base_init(self, cmd->n_variables,hsize);
-  tab_title (self->t, 0, _("One-Sample Test"));
+  tab_title (self->t, _("One-Sample Test"));
   tab_hline(self->t, TAL_1, 1, hsize - 1, 1);
   tab_vline(self->t, TAL_2, 1, 0, vsize - 1);
 
   tab_hline(self->t, TAL_1, 1, hsize - 1, 1);
   tab_vline(self->t, TAL_2, 1, 0, vsize - 1);
 
@@ -1258,7 +1258,7 @@ trbox_one_sample_init(struct trbox *self, struct cmd_t_test *cmd )
                 _("%g%% Confidence Interval of the Difference"),
                 cmd->criteria*100.0);
 
                 _("%g%% Confidence Interval of the Difference"),
                 cmd->criteria*100.0);
 
-  tab_vline(self->t,TAL_0,6,1,1);
+  tab_vline(self->t,TAL_GAP,6,1,1);
   tab_hline(self->t,TAL_1,5,6,2);
   tab_text (self->t, 1, 2, TAB_CENTER | TAT_TITLE, _("t"));
   tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("df"));
   tab_hline(self->t,TAL_1,5,6,2);
   tab_text (self->t, 1, 2, TAB_CENTER | TAT_TITLE, _("t"));
   tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("df"));
@@ -1359,7 +1359,7 @@ pscbox(void)
   tab_hline(table, TAL_2, 0, cols - 1, 1);
   tab_vline(table, TAL_2, 2, 0, rows - 1);
   tab_dim(table, tab_natural_dimensions);
   tab_hline(table, TAL_2, 0, cols - 1, 1);
   tab_vline(table, TAL_2, 2, 0, rows - 1);
   tab_dim(table, tab_natural_dimensions);
-  tab_title(table, 0, _("Paired Samples Correlations"));
+  tab_title(table, _("Paired Samples Correlations"));
 
   /* column headings */
   tab_text(table, 2,0, TAB_CENTER | TAT_TITLE, _("N"));
 
   /* column headings */
   tab_text(table, 2,0, TAB_CENTER | TAT_TITLE, _("N"));
index 2dc9e0ba001aa00a453d57492937ce8577d53474..112de5e10f2e32e7bc44c99aa5e546f4b329b470 100644 (file)
@@ -1,3 +1,10 @@
+Mon Apr  3 11:10:21 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c: (ds_separate) Change interface for cleanliness and
+       consistency with ds_tokenize(), and rewrite to shorten and
+       simplify.  Updated all callers.
+       (ds_tokenize) New function.
+
 Fri Mar 31 10:38:46 2006  Ben Pfaff  <blp@gnu.org>
 
        Add freaderror() analogous to fwriteerror() in gnulib.
 Fri Mar 31 10:38:46 2006  Ben Pfaff  <blp@gnu.org>
 
        Add freaderror() analogous to fwriteerror() in gnulib.
index e84021be4c41b036d7fb8105eec52e2f732d9128..c72f19969ec8f1090f958e39c36a276f6b5b1f8f 100644 (file)
@@ -431,7 +431,7 @@ ds_chomp (struct string *st, char c_)
    empty string if no tokens remain.  Returns true if a token was
    obtained, false otherwise.
 
    empty string if no tokens remain.  Returns true if a token was
    obtained, false otherwise.
 
-   Before the first call, initialize *SAVE_IDX to -1.  Do not
+   Before the first call, initialize *SAVE_IDX to 0.  Do not
    modify *SAVE_IDX between calls.
 
    ST divides into exactly one more tokens than it contains
    modify *SAVE_IDX between calls.
 
    ST divides into exactly one more tokens than it contains
@@ -440,28 +440,36 @@ ds_chomp (struct string *st, char c_)
    empty string contains a single token. */
 bool
 ds_separate (const struct string *st, struct string *token,
    empty string contains a single token. */
 bool
 ds_separate (const struct string *st, struct string *token,
-             const char *delimiters, int *save_idx)
+             const char *delimiters, size_t *save_idx)
 {
 {
-  int start_idx;
-
-  ds_clear (token);
-  if (*save_idx < 0) 
+  if (*save_idx <= ds_length (st))
     {
     {
-      *save_idx = 0;
-      if (ds_is_empty (st))
-        return true;
+      size_t length = ds_cspan (st, *save_idx, delimiters);
+      ds_assign_substring (token, st, *save_idx, length);
+      *save_idx += length + 1;
+      return true;
     }
     }
-  else if (*save_idx < ds_length (st))
-    ++*save_idx;
-  else
+  else 
     return false;
     return false;
+}
 
 
-  start_idx = *save_idx;
-  while (*save_idx < ds_length (st)
-         && strchr (delimiters, ds_data (st)[*save_idx]) == NULL)
-    ++*save_idx;
-  ds_assign_substring (token, st, start_idx, *save_idx - start_idx);
-  return true;
+/* Divides ST into tokens separated by any of the DELIMITERS,
+   merging adjacent delimiters so that the empty string is never
+   produced as a token.  Each call replaces TOKEN by the next
+   token in ST, or by an empty string if no tokens remain.
+   Returns true if a token was obtained, false otherwise.
+
+   Before the first call, initialize *SAVE_IDX to 0.  Do not
+   modify *SAVE_IDX between calls. */
+bool
+ds_tokenize (const struct string *st, struct string *token,
+             const char *delimiters, size_t *save_idx)
+{
+  size_t start = *save_idx + ds_span (st, *save_idx, delimiters);
+  size_t length = ds_cspan (st, start, delimiters);
+  ds_assign_substring (token, st, start, length);
+  *save_idx = start + length;
+  return length > 0;
 }
 
 /* Returns true if ST is empty, false otherwise. */
 }
 
 /* Returns true if ST is empty, false otherwise. */
index 6f34c200d054d59c3da3f453db211d198fd798fe..77d918e28ce8881cf7f6fa5ca8765c4952ef566e 100644 (file)
@@ -144,7 +144,9 @@ int ds_ltrim_spaces (struct string *);
 void ds_trim_spaces (struct string *);
 bool ds_chomp (struct string *, char);
 bool ds_separate (const struct string *src, struct string *token,
 void ds_trim_spaces (struct string *);
 bool ds_chomp (struct string *, char);
 bool ds_separate (const struct string *src, struct string *token,
-                  const char *delimiters, int *save_idx);
+                  const char *delimiters, size_t *save_idx);
+bool ds_tokenize (const struct string *src, struct string *token,
+                  const char *delimiters, size_t *save_idx);
 
 /* Inspectors. */
 bool ds_is_empty (const struct string *);
 
 /* Inspectors. */
 bool ds_is_empty (const struct string *);
index 7af231d1b8b2ab06fb66fcec5dd8ae34adb28641..1e5f86d74698e0c9792d60a9bbabbd834563ecb7 100644 (file)
@@ -1,3 +1,120 @@
+Mon Apr  3 11:14:38 2006  Ben Pfaff  <blp@gnu.org>
+
+       Rewrite a lot of the output drivers and infrastructure.
+       Started transitioning from msg() to error().
+       Vertical rules in tables now default to putting a small gap
+       between columns, instead of no gap or rule at all.
+       See NEWS for user-visible changes.
+
+       * automake.mk: (output_sources) Add afm.c, afm.h.  Remove font.h,
+       groff-font.c.
+       
+       * afm.c, afm.h: New files.
+
+       * font.h: Removed.
+
+       * groff-font.c: Removed.
+       
+       * ascii.c: Rewrote and simplified.
+
+       * html.c: Ditto.
+
+       * postscript.c: Ditto.
+
+       * output.c: (struct outp_driver_class_list) Move here from
+       output.h.  Remove ref_count member and all references to it.
+       (outp_init) Remove epsf_class references.
+       (init_default_drivers) Use new configure_driver_line() interface.
+       (parse_options) Renamed outp_parse_options(), changed interface.
+       (configure_driver) Changed args from `const char *'s to `const
+       struct string *'s.  Rewrote.  Don't call ->open_global().  Now
+       just calls ->open_driver() instead of ->preopen_driver(),
+       ->option(), ->postopen_driver().
+       (configure_driver_line) Adapt to new configure_driver() interface.
+       (destroy_driver) Don't call ->close_global().
+       (option_cmp) Removed.
+       (outp_match_keyword) Rewrite for simplicity.
+       (outp_open_page) New function.  Changed all equivalent
+       functionality to use this function instead.
+       (outp_close_page) Ditto.
+       (outp_eject_page) Use above functions.
+       (outp_string_width) Add font argument and change all callers to
+       pass one.
+
+       * output.h: (struct rect) Removed.
+       (OUTP_L_*) Name this enumeration "enum outp_line_style".
+       (OUTP_L_SPECIAL) Removed.
+       (struct color) Removed.
+       (OUTP_F_*) Removed.
+       (struct outp_styles) Removed.
+       (OUTP_T_*) Removed.
+       (enum outp_justification) New, containing OUTP_RIGHT, OUTP_LEFT,
+       OUTP_CENTER.
+       (enum outp_font) New, containing OUTP_FIXED, OUTP_PROPORTIONAL,
+       and OUTP_EMPHASIS.
+       (struct outp_text) Replaced `options' member by `font' and
+       `justification'.  Renamed `s' to `string'.  Removed `w', `l'.
+       Updated all usages.
+       (struct outp_class) Removed `magic', `open_global',
+       `close_global', `font_sizes', `preopen_driver', `option',
+       `postopen_driver', `line_horz', `line_vert', `line_intersection',
+       `box', `polyline_begin', `polyline_point', `polyline_end',
+       `text_set_font_by_name', `text_set_font_by_position',
+       `text_set_font_family', `text_get_font_name',
+       `text_get_font_family', `text_set_Size', and `text_get_size'
+       members.  Added `open_driver', `close_driver', `line' members.
+       Changed interface of `open_page', `close_page', `text_metrics',
+       `text_draw' members.  Updated all usages.
+       (struct outp_driver) Rearranged members.  Removed `driver_open',
+       `res', `horiz', `vert', `horiz_line_spacing', `vert_line_spacing'
+       members.
+       (struct outp_option_info) Removed.
+       (struct outp_driver_class_list) Removed.
+       (outp_match_keyword) Changed interface.
+
+       * table.c: (tab_create) Now ignores reallocable argument: tables
+       can always be reallocated.  Use pool_create_container().
+       Initialize vertical rules to UCHAR_MAX.
+       (options_to_font) New function.
+       (tab_destroy) Remove futile assignment.
+       (tab_realloc) Initialize vertical rules to UCHAR_MAX.
+       (text_format) Use xvasprintf() instead of local_alloc().
+       (tab_title) Always format the argument, and drop the option
+       argument.  Change all callers to agree.
+       (tab_natural_width) Adapt to new ->text_metrics() interface.
+       (tab_natural_height) Ditto.
+       (tab_joint_text) Clear rules within the joined cell.  Now
+       necessary because of the default to put spacing between cells.
+       (tab_output_text) Use xvasprintf() instead of local_alloc().
+       Remove special cases for fixed-width font.
+       (rule_to_spacing_type) New function.
+       (tabi_driver) Calculate rule widths manually now that we don't
+       have ->trh or ->trv.  Implement new default for vertical rules.
+       (render_rows) New function.
+       (tabi_render) Rewrite in terms of render_rows() for clarity.
+       (translate_justification) New function.
+       (rule_to_draw_type) New function.
+       (get_hrule) New function.
+       (get_vrule) New function.
+       (render_horz_rule) New function.
+       (render_vert_rule) New function.
+       (render_rule_intersection) New function.
+       (strip_width) New function.
+       (strip_height) New function.
+       (render_cell) New function.
+       (render_strip) Rewrite in terms of new functions.
+
+       * table.h: (TAB_EMPH) New flag.
+       (TAB_FIX) New flag.
+       (TAL_3) Removed.
+       (TAL_GAP) Added.
+       (TAL_SPACING) Removed.
+       (struct tab_table) Members `trh', `hrv', `hr_tot', `vr_tot'
+       removed.
+       [DEBUGGING] (reallocable) Removed.
+       (TAT_FIX) Removed.  All references replaced by TAB_FIX.
+       (TAT_TITLE) Now implies TAB_EMPH.
+               
 Thu Mar 30 16:26:56 2006  Ben Pfaff  <blp@gnu.org>
 
        * output.c: (colon_tokenize) Removed.
 Thu Mar 30 16:26:56 2006  Ben Pfaff  <blp@gnu.org>
 
        * output.c: (colon_tokenize) Removed.
diff --git a/src/output/afm.c b/src/output/afm.c
new file mode 100644 (file)
index 0000000..8e6d691
--- /dev/null
@@ -0,0 +1,1158 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <config.h>
+#include "afm.h"
+#include "c-ctype.h"
+#include "c-strtod.h"
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include "error.h"
+#include "minmax.h"
+#include <libpspp/pool.h>
+#include <libpspp/str.h>
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+/* A kern pair entry. */
+struct afm_kern_pair 
+  {
+    struct afm_character *successor; /* Second character. */
+    int adjust;                 /* Adjustment. */
+  };
+
+/* A ligature. */
+struct afm_ligature 
+  {
+    struct afm_character *successor; /* Second character. */
+    struct afm_character *ligature;  /* Resulting ligature. */
+  };
+
+/* How to map between byte strings and character values. */
+enum mapping_scheme 
+  {
+    MAP_UNKNOWN,                /* Not yet determined. */
+    MAP_ONE_BYTE,               /* 8-bit coding. */
+    MAP_TWO_BYTE,               /* 16-bit coding. */
+    MAP_ESCAPE,                 /* 8-bit coding with escape to change fonts. */
+    MAP_DOUBLE_ESCAPE,          /* 8-bit coding with multiple escapes. */
+    MAP_SHIFT                   /* 8-bit coding with 2 fonts that toggle. */
+  };
+
+/* AFM file data.  */
+struct afm
+  {
+    struct pool *pool;         /* Containing pool. */
+    char *findfont_name;        /* Name for PostScript /findfont operator. */
+    int ascent;                 /* Height above the baseline (non-negative). */
+    int descent;                /* Depth below the baseline (non-negative). */
+
+    /* Encoding characters into strings. */
+    enum mapping_scheme mapping; /* Basic mapping scheme. */
+    char escape_char;           /* MAP_ESCAPE only: escape character to use. */
+    char shift_out;             /* MAP_SHIFT only: selects font 0. */
+    char shift_in;              /* MAP_SHIFT only: selects font 1. */
+
+    /* Characters. */
+    struct afm_character *undefined_codes[256];
+    struct afm_character **codes[256];
+    struct afm_character **chars;
+    size_t char_cnt;
+  };
+
+/* AFM file parser. */
+struct parser 
+  {
+    struct pool *pool;          /* Containing pool. */
+    struct afm *afm;            /* AFM being parsed. */
+    FILE *file;                 /* File being parsed. */
+    const char *file_name;      /* Name of file being parsed. */
+    int line_number;            /* Current line number in file. */
+    jmp_buf bail_out;           /* longjmp() target for error handling. */
+
+    size_t char_allocated;
+    int max_code;
+  };
+
+static struct afm *create_afm (void);
+static struct afm_character *create_character (struct afm *);
+
+static void afm_error (struct parser *, const char *, ...)
+     PRINTF_FORMAT (2, 3)
+     NO_RETURN;
+
+static void parse_afm (struct parser *);
+static void skip_section (struct parser *, const char *end_key);
+static bool parse_set_specific (struct parser *, const char *end_key);
+static void parse_direction (struct parser *);
+static void parse_char_metrics (struct parser *);
+static void parse_kern_pairs (struct parser *);
+static void add_kern_pair (struct parser *p,
+                           struct afm_character *, struct afm_character *,
+                           int adjust);
+
+static int skip_spaces (struct parser *);
+static char *parse_key (struct parser *);
+static void skip_line (struct parser *);
+static void force_eol (struct parser *);
+static bool get_integer (struct parser *, int *);
+static int force_get_integer (struct parser *);
+static bool get_number (struct parser *, int *);
+static int force_get_number (struct parser *);
+static bool get_hex_code (struct parser *, int *);
+static int force_get_hex_code (struct parser *);
+static bool get_word (struct parser *, char **);
+static char *force_get_word (struct parser *);
+static bool get_string (struct parser *, char **);
+static char *force_get_string (struct parser *);
+
+static struct afm_character *get_char_by_name (struct parser *, const char *);
+static struct afm_character *get_char_by_code (const struct afm *, int code);
+
+/* Reads FILE_NAME as an AFM file and returns the metrics data.
+   Returns a null pointer if the file cannot be parsed. */
+struct afm *
+afm_open (const char *file_name) 
+{
+  struct afm *volatile afm;
+  struct parser *parser;
+
+  parser = pool_create_container (struct parser, pool);
+  afm = parser->afm = create_afm ();
+  parser->file = pool_fopen (parser->pool, file_name, "r");
+  parser->file_name = file_name;
+  parser->line_number = 0;
+  if (parser->file == NULL) 
+    {
+      error (0, errno, _("opening font metrics file \"%s\""), file_name);
+      goto error; 
+    }
+
+  if (setjmp (parser->bail_out))
+    goto error;
+
+  parse_afm (parser);
+  pool_destroy (parser->pool);
+  return afm;
+
+ error:
+  pool_destroy (parser->pool);
+  pool_destroy (afm->pool);
+  return create_afm ();
+}
+
+/* Creates and returns an empty set of metrics. */
+static struct afm *
+create_afm (void) 
+{
+  struct afm *afm;
+  struct afm_character *def_char;
+  size_t i;
+
+  afm = pool_create_container (struct afm, pool);
+  afm->findfont_name = NULL;
+  afm->ascent = 0;
+  afm->descent = 0;
+  afm->mapping = MAP_UNKNOWN;
+  afm->escape_char = 255;
+  afm->shift_out = 14;
+  afm->shift_in = 15;
+  def_char = create_character (afm);
+  for (i = 0; i < 256; i++) 
+    afm->undefined_codes[i] = def_char;
+  for (i = 0; i < 256; i++) 
+    afm->codes[i] = afm->undefined_codes; 
+  afm->chars = NULL;
+  afm->char_cnt = 0;
+
+  return afm;
+}
+
+/* Creates and returns an initialized character within AFM. */
+static struct afm_character *
+create_character (struct afm *afm) 
+{
+  struct afm_character *c = pool_alloc (afm->pool, sizeof *c);
+  c->code = ' ';
+  c->name = NULL;
+  c->width = 12000;
+  c->ascent = 0;
+  c->descent = 0;
+  c->kern_pairs = NULL;
+  c->kern_pair_cnt = 0;
+  c->ligatures = NULL;
+  c->ligature_cnt = 0;
+  return c;
+}
+
+/* Reports the given MESSAGE at the current line in parser P
+   and bails out with longjmp(). */
+static void
+afm_error (struct parser *p, const char *message, ...) 
+{
+  va_list args;
+  char *msg;
+
+  va_start (args, message);
+  msg = xasprintf (message, args);
+  va_end (args);
+
+  error_at_line (0, 0, p->file_name, p->line_number, "%s", msg);
+  free (msg);
+
+  longjmp (p->bail_out, 1);
+}
+
+/* Parses an AFM file with parser P. */
+static void
+parse_afm (struct parser *p) 
+{
+  char *key;
+
+  p->char_allocated = 0;
+  p->max_code = 0;
+
+  key = force_get_word (p);
+  if (strcmp (key, "StartFontMetrics"))
+    afm_error (p, _("first line must be StartFontMetrics"));
+  skip_line (p);
+
+  do
+    {
+      key = parse_key (p);
+      if (!strcmp (key, "FontName")) 
+        p->afm->findfont_name = pool_strdup (p->afm->pool,
+                                             force_get_string (p));
+      else if (!strcmp (key, "Ascender"))
+        p->afm->ascent = force_get_integer (p);
+      else if (!strcmp (key, "Descender"))
+        p->afm->descent = force_get_integer (p);
+      else if (!strcmp (key, "MappingScheme")) 
+        {
+          int scheme = force_get_integer (p);
+          if (scheme == 4)
+            p->afm->mapping = MAP_ONE_BYTE;
+          else if (scheme == 2 || scheme == 5 || scheme == 6)
+            p->afm->mapping = MAP_TWO_BYTE;
+          else if (scheme == 3)
+            p->afm->mapping = MAP_ESCAPE;
+          else if (scheme == 7)
+            p->afm->mapping = MAP_DOUBLE_ESCAPE;
+          else if (scheme == 8)
+            p->afm->mapping = MAP_SHIFT;
+          else
+            afm_error (p, _("unsupported MappingScheme %d"), scheme);
+        }
+      else if (!strcmp (key, "EscChar"))
+        p->afm->escape_char = force_get_integer (p);
+      else if (!strcmp (key, "StartDirection"))
+        parse_direction (p);
+      else if (!strcmp (key, "StartCharMetrics"))
+        parse_char_metrics (p);
+      else if (!strcmp (key, "StartKernPairs")
+               || !strcmp (key, "StartKernPairs0"))
+        parse_kern_pairs (p);
+      else if (!strcmp (key, "StartTrackKern")) 
+        skip_section (p, "EndTrackKern");
+      else if (!strcmp (key, "StartComposites")) 
+        skip_section (p, "EndComposites");
+      else 
+        skip_line (p);
+    }
+  while (strcmp (key, "EndFontMetrics"));
+
+  if (p->afm->findfont_name == NULL)
+    afm_error (p, _("required FontName is missing"));
+  if (p->afm->mapping == MAP_UNKNOWN) 
+    {
+      /* There seem to be a number of fonts out there that use a
+         2-byte encoding but don't announce it with
+         MappingScheme. */
+      p->afm->mapping = p->max_code > 255 ? MAP_TWO_BYTE : MAP_ONE_BYTE;
+    }
+}
+
+/* Reads lines from parser P until one starts with END_KEY. */
+static void
+skip_section (struct parser *p, const char *end_key)
+{
+  const char *key;
+  skip_line (p);
+  do 
+    {
+      key = parse_key (p);
+      skip_line (p);
+    }
+  while (strcmp (key, end_key));
+}
+
+/* Attempts to read an integer from parser P.
+   If one is found, and it is nonzero, skips lines until END_KEY
+   is encountered and returns false.
+   Otherwise, skips the rest of the line and returns true.
+   (This is useful because AFM files can have multiple sets of
+   metrics.  Set 0 is for normal text, other sets are for
+   vertical text, etc.  We only care about set 0.) */
+static bool
+parse_set_specific (struct parser *p, const char *end_key) 
+{
+  int set;
+  
+  if (get_integer (p, &set) && set != 0) 
+    {
+      skip_section (p, end_key);
+      return false; 
+    }
+  else 
+    {
+      force_eol (p);
+      return true;
+    }
+}
+
+/* Parses a StartDirection...EndDirection section in parser P. */
+static void
+parse_direction (struct parser *p) 
+{
+  const char *key;
+
+  if (!parse_set_specific (p, "EndDirection"))
+    return;
+
+  do 
+    {
+      key = parse_key (p);
+      if (!strcmp (key, "CharWidth")) 
+        p->afm->codes[0][0]->width = force_get_integer (p);
+      skip_line (p);
+    }
+  while (strcmp (key, "EndDirection"));
+}
+
+/* Parses a StartCharMetrics...EndCharMetrics section in parser
+   P. */
+static void
+parse_char_metrics (struct parser *p) 
+{
+  struct parsing_ligature 
+    {
+      struct afm_character *first;
+      char *successor;
+      char *ligature;
+    };
+
+  struct parsing_ligature *ligatures = NULL;
+  size_t ligature_cnt = 0;
+  size_t ligature_allocated = 0;
+
+  size_t i;
+
+  skip_line (p);
+  
+  for (;;)
+    {
+      char *key;
+      struct afm_character *c;
+
+      key = parse_key (p);
+      if (!strcmp (key, "EndCharMetrics"))
+        break;
+      
+      if (p->afm->char_cnt == p->char_allocated)
+        p->afm->chars = pool_2nrealloc (p->afm->pool, p->afm->chars,
+                                        &p->char_allocated,
+                                        sizeof *p->afm->chars);
+      c = create_character (p->afm);
+
+      if (!strcmp (key, "C")) 
+        c->code = force_get_integer (p);
+      else if (!strcmp (key, "CH"))
+        c->code = force_get_hex_code (p);
+      else
+        afm_error (p, _("CharMetrics line must start with C or CH"));
+      if (c->code < 0 || c->code > 65535)
+        c->code = -1;
+
+      if (c->code > p->max_code)
+        p->max_code = c->code;        
+
+      p->afm->chars[p->afm->char_cnt++] = c;
+      if (c->code != -1)
+        p->afm->codes[c->code >> 8][c->code & 0xff] = c;
+
+      key = force_get_word (p);
+      while (!strcmp (key, ";")) 
+        {
+          if (!get_word (p, &key))
+            break;
+
+          if (!strcmp (key, "N"))
+            c->name = force_get_word (p);
+          else if (!strcmp (key, "WX") || !strcmp (key, "W0X"))
+            c->width = force_get_number (p);
+          else if (!strcmp (key, "W") || !strcmp (key, "W0")) 
+            {
+              c->width = force_get_number (p);
+              force_get_number (p);
+            }
+          else if (!strcmp (key, "B")) 
+            {
+              int llx, lly, urx, ury;
+              llx = force_get_number (p);
+              lly = force_get_number (p);
+              urx = force_get_number (p);
+              ury = force_get_number (p);
+              c->ascent = MAX (0, ury);
+              c->descent = MAX (0, -lly);
+            }
+          else if (!strcmp (key, "L")) 
+            {
+              struct parsing_ligature *ligature;
+              if (ligature_cnt == ligature_allocated)
+                ligatures = pool_2nrealloc (p->pool, ligatures,
+                                            &ligature_allocated,
+                                            sizeof *ligatures);
+              ligature = &ligatures[ligature_cnt++];
+              ligature->first = c;
+              ligature->successor = force_get_word (p);
+              ligature->ligature = force_get_word (p);
+            }
+          else 
+            {
+              while (strcmp (key, ";"))
+                key = force_get_word (p);
+              continue;
+            }
+          if (!get_word (p, &key))
+            break;
+        }
+    }
+  skip_line (p);
+
+  for (i = 0; i < ligature_cnt; i++) 
+    {
+      struct parsing_ligature *src = &ligatures[i];
+      struct afm_ligature *dst;
+      src->first->ligatures = pool_nrealloc (p->afm->pool,
+                                             src->first->ligatures,
+                                             src->first->ligature_cnt + 1,
+                                             sizeof *src->first->ligatures);
+      dst = &src->first->ligatures[src->first->ligature_cnt++];
+      dst->successor = get_char_by_name (p, src->successor);
+      dst->ligature = get_char_by_name (p, src->ligature);
+    }
+}
+
+/* Parses a StartKernPairs...EndKernPairs section in parser P. */
+static void
+parse_kern_pairs (struct parser *p) 
+{
+  char *key;
+  
+  skip_line (p);
+
+  do
+    {
+      struct afm_character *c1, *c2;
+      int adjust;
+
+      key = parse_key (p);
+      if (!strcmp (key, "KP") || !strcmp (key, "KPX")) 
+        {
+          c1 = get_char_by_name (p, force_get_word (p));
+          c2 = get_char_by_name (p, force_get_word (p));
+          adjust = force_get_number (p);
+          if (!strcmp (key, "KP"))
+            force_get_number (p);
+          add_kern_pair (p, c1, c2, adjust);
+        }
+      else if (!strcmp (key, "KPH")) 
+        {
+          c1 = get_char_by_code (p->afm, force_get_hex_code (p));
+          c2 = get_char_by_code (p->afm, force_get_hex_code (p));
+          adjust = force_get_number (p);
+          force_get_number (p);
+          add_kern_pair (p, c1, c2, adjust);
+        }
+      else
+        skip_line (p);
+    }
+  while (strcmp (key, "EndKernPairs"));
+}
+
+/* Adds a kern pair that adjusts (FIRST, SECOND) by ADJUST units
+   to the metrics within parser P. */
+static void
+add_kern_pair (struct parser *p, struct afm_character *first,
+               struct afm_character *second, int adjust) 
+{
+  struct afm_kern_pair *kp;
+  
+  first->kern_pairs = pool_nrealloc (p->afm->pool, first->kern_pairs,
+                                     first->kern_pair_cnt + 1,
+                                     sizeof *first->kern_pairs);
+  kp = &first->kern_pairs[first->kern_pair_cnt++];
+  kp->successor = second;
+  kp->adjust = adjust;
+}
+
+/* Returns the character with the given NAME with the metrics for
+   parser P.  Reports an error if no character has the given
+   name. */
+static struct afm_character *
+get_char_by_name (struct parser *p, const char *name) 
+{
+  size_t i;
+
+  for (i = 0; i < p->afm->char_cnt; i++) 
+    {
+      struct afm_character *c = p->afm->chars[i];
+      if (c->name != NULL && !strcmp (c->name, name))
+        return c;
+    }
+  afm_error (p, _("reference to unknown character \"%s\""), name);
+}
+
+/* Returns the character with the given CODE within AFM.
+   Returns a default character if the font doesn't have a
+   character with that code. */
+static struct afm_character *
+get_char_by_code (const struct afm *afm, int code_) 
+{
+  uint16_t code = code_;
+  return afm->codes[code >> 8][code & 0xff];
+}
+\f
+/* Skips white space, except for new-lines, within parser P. */
+static int
+skip_spaces (struct parser *p) 
+{
+  int c;
+  while (isspace (c = getc (p->file)) && c != '\n')
+    continue;
+  ungetc (c, p->file);
+  return c;
+}
+
+/* Parses a word at the beginning of a line.
+   Skips comments.
+   Reports an error if not at the beginning of a line. */
+static char *
+parse_key (struct parser *p) 
+{
+  force_eol (p);
+  for (;;) 
+    {
+      char *key;
+
+      do 
+        {
+          p->line_number++;
+          getc (p->file); 
+        }
+      while (skip_spaces (p) == '\n');
+
+      key = force_get_word (p);
+      if (strcmp (key, "Comment")) 
+        return key;
+
+      skip_line (p);
+    }
+}
+
+/* Skips to the next line within parser P. */
+static void
+skip_line (struct parser *p) 
+{
+  for (;;) 
+    {
+      int c = getc (p->file);
+      if (c == EOF)
+        afm_error (p, _("expected end of file"));
+      if (c == '\n')
+        break;
+    }
+  ungetc ('\n', p->file);
+}
+
+/* Ensures that parser P is at the end of a line. */
+static void
+force_eol (struct parser *p) 
+{
+  if (skip_spaces (p) != '\n')
+    afm_error (p, _("syntax error expecting end of line"));
+}
+  
+/* Tries to read an integer into *INTEGER at the current position
+   in parser P.
+   Returns success. */
+static bool
+get_integer (struct parser *p, int *integer) 
+{
+  int c = skip_spaces (p);
+  if (isdigit (c) || c == '-') 
+    {
+      char *tail;
+      long tmp;
+
+      errno = 0;
+      tmp = strtol (force_get_word (p), &tail, 10);
+      if (errno == ERANGE || tmp < INT_MIN || tmp > INT_MAX) 
+        afm_error (p, _("number out of valid range"));
+      if (*tail != '\0')
+        afm_error (p, _("invalid numeric syntax"));
+      *integer = tmp;
+
+      return true;
+    }
+  else
+    return false;
+}
+
+/* Returns an integer read from the current position in P.
+   Reports an error if unsuccessful. */
+static int
+force_get_integer (struct parser *p) 
+{
+  int integer;
+  if (!get_integer (p, &integer))
+    afm_error (p, _("syntax error expecting integer"));
+  return integer;
+}
+
+/* Tries to read a floating-point number at the current position
+   in parser P.  Stores the number's integer part into *INTEGER.
+   Returns success. */
+static bool
+get_number (struct parser *p, int *integer) 
+{
+  int c = skip_spaces (p);
+  if (c == '-' || c == '.' || isdigit (c))
+    {
+      char *tail;
+      double number;
+
+      errno = 0;
+      number = c_strtod (force_get_word (p), &tail);
+      if (errno == ERANGE || number < INT_MIN || number > INT_MAX) 
+        afm_error (p, _("number out of valid range"));
+      if (*tail != '\0')
+        afm_error (p, _("invalid numeric syntax"));
+      *integer = number;
+
+      return true;
+    }
+  else
+    return false;
+}
+
+/* Returns the integer part of a floating-point number read from
+   the current position in P.
+   Reports an error if unsuccessful. */
+static int
+force_get_number (struct parser *p) 
+{
+  int integer;
+  if (!get_number (p, &integer))
+    afm_error (p, _("syntax error expecting number"));
+  return integer;
+}
+
+/* Tries to read an integer expressed in hexadecimal into
+   *INTEGER from P.
+   Returns success. */
+static bool
+get_hex_code (struct parser *p, int *integer) 
+{
+  if (skip_spaces (p) == '<') 
+    {
+      if (fscanf (p->file, "<%x", integer) != 1 || getc (p->file) != '>')
+        afm_error (p, _("syntax error in hex constant"));
+      return true;
+    }
+  else
+    return false;
+}
+
+/* Reads an integer expressed in hexadecimal and returns its
+   value.
+   Reports an error if unsuccessful. */
+static int
+force_get_hex_code (struct parser *p)
+{
+  int integer;
+  if (!get_hex_code (p, &integer))
+    afm_error (p, _("syntax error expecting hex constant"));
+  return integer;
+}
+
+/* Tries to read a word from P into *WORD.
+   The word is allocated in P's pool.
+   Returns success. */
+static bool
+get_word (struct parser *p, char **word) 
+{
+  if (skip_spaces (p) != '\n') 
+    {
+      struct string s;
+      int c;
+
+      ds_init (&s, 0);
+      while (!isspace (c = getc (p->file)) && c != EOF)
+        ds_putc (&s, c);
+      ungetc (c, p->file);
+      *word = ds_c_str (&s);
+      pool_register (p->pool, free, *word);
+      return true;
+    }
+  else 
+    {
+      *word = NULL;
+      return false;
+    }
+}
+
+/* Reads a word from P and returns it.
+   The word is allocated in P's pool.
+   Reports an error if unsuccessful. */
+static char *
+force_get_word (struct parser *p) 
+{
+  char *word;
+  if (!get_word (p, &word))
+    afm_error (p, _("unexpected end of line"));
+  return word;
+}
+
+/* Reads a string, consisting of the remainder of the current
+   line, from P, and stores it in *STRING.
+   Leading and trailing spaces are removed.
+   The word is allocated in P's pool.
+   Returns true if a non-empty string was successfully read,
+   false otherwise. */
+static bool
+get_string (struct parser *p, char **string)
+{
+  struct string s;
+
+  ds_init (&s, 0);
+  skip_spaces (p);
+  for (;;) 
+    {
+      int c = getc (p->file);
+      if (c == EOF || c == '\n')
+        break;
+      ds_putc (&s, c);
+    }
+  ungetc ('\n', p->file);
+  ds_rtrim_spaces (&s);
+
+  if (!ds_is_empty (&s)) 
+    {
+      *string = ds_c_str (&s);
+      pool_register (p->pool, free, *string);
+      return true;
+    }
+  else 
+    {
+      *string = NULL;
+      ds_destroy (&s);
+      return false;
+    }
+}
+
+/* Reads a string, consisting of the remainder of the current
+   line, from P, and returns it.
+   Leading and trailing spaces are removed.
+   The word is allocated in P's pool.
+   Reports an error if the string is empty. */
+static char *
+force_get_string (struct parser *p) 
+{
+  char *string;
+  if (!get_string (p, &string))
+    afm_error (p, _("unexpected end of line expecting string"));
+  return string;
+}
+\f
+/* Closes AFM and frees its storage. */
+void
+afm_close (struct afm *afm) 
+{
+  if (afm != NULL)
+    pool_destroy (afm->pool);
+}
+
+/* Returns the string that must be passed to the PostScript
+   "findfont" operator to obtain AFM's font. */
+const char *
+afm_get_findfont_name (const struct afm *afm) 
+{
+  return afm->findfont_name;
+}
+
+/* Returns the ascent for AFM, that is, the font's height above
+   the baseline, in units of 1/1000 of the nominal font size. */
+int
+afm_get_ascent (const struct afm *afm) 
+{
+  return afm->ascent;
+}
+
+/* Returns the descent for AFM, that is, the font's depth below
+   the baseline, in units of 1/1000 of the nominal font size. */
+int
+afm_get_descent (const struct afm *afm) 
+{
+  return afm->descent;
+}
+
+/* Returns the character numbered CODE within AFM,
+   or a default character if the font has none. */
+const struct afm_character *
+afm_get_character (const struct afm *afm, int code) 
+{
+  return get_char_by_code (afm, code);
+}
+
+/* Returns the ligature formed when FIRST is followed by SECOND,
+   or a null pointer if there is no such ligature. */
+const struct afm_character *
+afm_get_ligature (const struct afm_character *first,
+                  const struct afm_character *second) 
+{
+  size_t i;
+
+  for (i = 0; i < first->ligature_cnt; i++)
+    if (first->ligatures[i].successor == second)
+      return first->ligatures[i].ligature;
+  return NULL;
+}
+
+/* Returns the pair kerning x-adjustment when FIRST is followed
+   by SECOND, or 0 if no pair kerning should be done for the
+   given pair of characters. */
+int
+afm_get_kern_adjustment (const struct afm_character *first,
+                         const struct afm_character *second)
+{
+  size_t i;
+
+  for (i = 0; i < first->kern_pair_cnt; i++)
+    if (first->kern_pairs[i].successor == second)
+      return first->kern_pairs[i].adjust;
+  return 0;
+}
+\f
+/* Encodes the N characters in S as a PostScript string in OUT,
+   using a single-byte encoding.
+   Returns the number of characters remaining after all those
+   that could be successfully encoded were. */
+static size_t
+encode_one_byte (const struct afm_character **s, size_t n,
+                 struct string *out)
+{
+  ds_putc (out, '(');
+  for (; n > 0; s++, n--)
+    {
+      uint8_t code = (*s)->code;
+      if (code != (*s)->code)
+        break;
+          
+      if (code == '(' || code == ')' || code == '\\')
+        ds_printf (out, "\\%c", code);
+      else if (!c_isprint (code))
+        ds_printf (out, "\\%03o", code);
+      else
+        ds_putc (out, code); 
+    }
+  ds_putc (out, ')');
+  return n;
+}
+
+/* State of binary encoder for PostScript. */
+struct binary_encoder
+  {
+    struct string *out;         /* Output string. */
+    uint32_t b;                 /* Accumulated bytes for base-85 encoding. */
+    size_t n;                   /* Number of bytes in b (0...3). */
+  };
+
+/* Initializes encoder E for output to OUT. */
+static void
+binary_init (struct binary_encoder *e, struct string *out) 
+{
+  e->out = out;
+  e->b = e->n = 0;
+}
+
+/* Returns the character that represents VALUE in ASCII85
+   encoding. */
+static int
+value_to_ascii85 (int value) 
+{
+  assert (value >= 0 && value < 85);
+#if C_CTYPE_ASCII
+  return value + 33;
+#else
+  return ("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK"
+          "LMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstu")[value];
+#endif
+}
+
+/* Appends the first N characters of the ASCII85 representation
+   of B to string OUT. */
+static void
+append_ascii85_block (unsigned b, size_t n, struct string *out) 
+{
+  char c[5];
+  int i;
+
+  for (i = 4; i >= 0; i--) 
+    {
+      c[i] = value_to_ascii85 (b % 85);
+      b /= 85; 
+    }
+  ds_concat (out, c, n);
+}
+
+/* Encodes BYTE with encoder E. */
+static void
+binary_put (struct binary_encoder *e, uint8_t byte) 
+{
+  e->b = (e->b << 8) | byte;
+  e->n++;
+  if (e->n % 4 == 0)
+    {
+      if (e->n == 4)
+        ds_puts (e->out, "<~");
+
+      if (e->b != 0)
+        append_ascii85_block (e->b, 5, e->out);
+      else 
+        ds_putc (e->out, 'z');
+    }
+}
+
+/* Finishes up encoding with E. */
+static void
+binary_finish (struct binary_encoder *e) 
+{
+  if (e->n >= 4) 
+    {
+      /* We output at least one complete ASCII85 block.
+         Finish up. */
+      size_t n = e->n % 4;
+      if (n > 0)
+        append_ascii85_block (e->b << 8 * (4 - n), n + 1, e->out); 
+      ds_puts (e->out, "~>");
+    }
+  else if (e->n > 0)
+    {
+      /* It's cheaper (or at least the same cost) to encode this
+         string in hexadecimal. */
+      uint32_t b;
+      size_t i;
+
+      ds_puts (e->out, "<");
+      b = e->b << 8 * (4 - e->n);
+      for (i = 0; i < e->n; i++) 
+        {
+          ds_printf (e->out, "%02x", b >> 24);
+          b <<= 8;
+        }
+      ds_puts (e->out, ">");
+    }
+  else 
+    {
+      /* Empty string. */
+      ds_puts (e->out, "()"); 
+    }
+}
+
+/* Encodes the N characters in S into encoder E,
+   using a two-byte encoding.
+   Returns the number of characters remaining after all those
+   that could be successfully encoded were. */
+static size_t
+encode_two_byte (const struct afm_character **s, size_t n,
+                 struct binary_encoder *e)
+{
+  for (; n > 0; s++, n--) 
+    {
+      uint16_t code = (*s)->code;
+      if (code != (*s)->code)
+        break;
+
+      binary_put (e, code >> 8);
+      binary_put (e, code);
+    }
+  return n;
+}
+
+/* Encodes the N characters in S into encoder E,
+   using an escape-based encoding with ESCAPE_CHAR as escape.
+   Returns the number of characters remaining after all those
+   that could be successfully encoded were. */
+static size_t
+encode_escape (const struct afm_character **s, size_t n,
+               unsigned char escape_char,
+               struct binary_encoder *e)
+{
+  uint8_t cur_font = 0;
+
+  for (; n > 0; s++, n--)
+    {
+      uint16_t code = (*s)->code;
+      uint8_t font_num = code >> 8;
+      uint8_t char_num = code & 0xff;
+      if (code != (*s)->code)
+        break;
+
+      if (font_num != cur_font) 
+        {
+          if (font_num == escape_char)
+            break;
+          binary_put (e, escape_char);
+          binary_put (e, font_num);
+          cur_font = font_num;
+        }
+      binary_put (e, char_num);
+    }
+  return n;
+}
+
+/* Encodes the N characters in S into encoder E,
+   using an double escape-based encoding with ESCAPE_CHAR as
+   escape.
+   Returns the number of characters remaining after all those
+   that could be successfully encoded were. */
+static size_t
+encode_double_escape (const struct afm_character **s, size_t n,
+                      unsigned char escape_char,
+                      struct binary_encoder *e)
+{
+  unsigned cur_font = 0;
+
+  for (; n > 0; s++, n--)
+    {
+      unsigned font_num = (*s)->code >> 8;
+      uint8_t char_num = (*s)->code & 0xff;
+      if ((*s)->code & ~0x1ffff)
+        break;
+
+      if (font_num != cur_font) 
+        {
+          if (font_num == (escape_char & 0xff))
+            break;
+          if (font_num >= 256)
+            binary_put (e, escape_char);
+          binary_put (e, escape_char);
+          binary_put (e, font_num & 0xff);
+          cur_font = font_num;
+        }
+      binary_put (e, char_num);
+    }
+  return n;
+}
+
+/* Encodes the N characters in S into encoder E,
+   using a shift-based encoding with SHIFT_IN and SHIFT_OUT as
+   shift characters.
+   Returns the number of characters remaining after all those
+   that could be successfully encoded were. */
+static size_t
+encode_shift (const struct afm_character **s, size_t n,
+              unsigned char shift_in, unsigned char shift_out,
+              struct binary_encoder *e)
+{
+  unsigned cur_font = 0;
+
+  for (; n > 0; s++, n--)
+    {
+      int font_num = ((*s)->code & 0x100) != 0;
+      uint8_t char_num = (*s)->code & 0xff;
+      if ((*s)->code & ~0x1ff)
+        break;
+
+      if (font_num != cur_font) 
+        {
+          binary_put (e, font_num ? shift_out : shift_in);
+          cur_font = font_num;
+        }
+      binary_put (e, char_num);
+    }
+  return n;
+}
+
+/* Encodes the N characters in S into a PostScript string in OUT,
+   according to AFM's character encoding.
+   Returns the number of characters successfully encoded,
+   which may be less than N if an unencodable character was
+   encountered. */
+size_t
+afm_encode_string (const struct afm *afm,
+                   const struct afm_character **s, size_t n,
+                   struct string *out) 
+{
+  size_t initial_length = ds_length (out);
+  size_t chars_left;
+
+  if (afm->mapping == MAP_ONE_BYTE)
+    chars_left = encode_one_byte (s, n, out);
+  else 
+    {
+      struct binary_encoder e;
+
+      binary_init (&e, out);
+      switch (afm->mapping) 
+        {
+        case MAP_TWO_BYTE:
+          chars_left = encode_two_byte (s, n, &e);
+          break;
+
+        case MAP_ESCAPE:
+          chars_left = encode_escape (s, n, afm->escape_char, &e);
+          break;
+      
+        case MAP_DOUBLE_ESCAPE:
+          chars_left = encode_double_escape (s, n, afm->escape_char, &e);
+          break;
+
+        case MAP_SHIFT:
+          chars_left = encode_shift (s, n, afm->shift_in, afm->shift_out, &e);
+          break;
+      
+        default:
+          abort ();
+        }
+      binary_finish (&e);
+    }
+
+  if (chars_left == n)
+    ds_truncate (out, initial_length);
+  return n - chars_left;
+}
diff --git a/src/output/afm.h b/src/output/afm.h
new file mode 100644 (file)
index 0000000..0a5754f
--- /dev/null
@@ -0,0 +1,64 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#ifndef AFM_H
+#define AFM_H 1
+
+#include <stddef.h>
+#include <libpspp/str.h>
+
+/* Metrics for a single character.  */
+struct afm_character
+  {
+    int code;                   /* Non-negative character code, -1 if none. */
+    const char *name;           /* Character name, if any. */
+    int width;                 /* Width. */
+    int ascent;                        /* Height above baseline, never negative. */
+    int descent;                /* Depth below baseline, never negative. */
+
+    /* Pairwise kerning data for this character in the first
+       position, other characters in the second position. */
+    struct afm_kern_pair *kern_pairs;
+    size_t kern_pair_cnt;
+    
+    /* Ligature data for this character in the first position,
+       other characters in the second position. */
+    struct afm_ligature *ligatures;
+    size_t ligature_cnt;
+  };
+
+struct afm *afm_open (const char *file_name);
+void afm_close (struct afm *);
+
+int afm_get_ascent (const struct afm *);
+int afm_get_descent (const struct afm *);
+const char *afm_get_findfont_name (const struct afm *);
+
+const struct afm_character *afm_get_character (const struct afm *,
+                                               int code);
+const struct afm_character *afm_get_ligature (const struct afm_character *,
+                                              const struct afm_character *);
+int afm_get_kern_adjustment (const struct afm_character *,
+                             const struct afm_character *);
+
+size_t afm_encode_string (const struct afm *,
+                          const struct afm_character **, size_t,
+                          struct string *);
+
+#endif /* afm.h */
index f6bc7a6f91b3bb6fbe96f920f46639ac5819071f..a0dc1b0109191087288d635fd16891eb8c8c40e9 100644 (file)
    02110-1301, USA. */
 
 #include <config.h>
    02110-1301, USA. */
 
 #include <config.h>
-#include <libpspp/message.h>
+
 #include <ctype.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
+
+#include <data/filename.h>
 #include <libpspp/alloc.h>
 #include <libpspp/alloc.h>
-#include <libpspp/message.h>
-#include "chart.h"
 #include <libpspp/compiler.h>
 #include <libpspp/compiler.h>
-#include <data/filename.h>
-#include <libpspp/misc.h>
-#include "output.h"
+#include <libpspp/message.h>
 #include <libpspp/pool.h>
 #include <libpspp/start-date.h>
 #include <libpspp/version.h>
 
 #include <libpspp/pool.h>
 #include <libpspp/start-date.h>
 #include <libpspp/version.h>
 
+#include "chart.h"
+#include "error.h"
+#include "minmax.h"
+#include "output.h"
+
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
 /* ASCII driver options: (defaults listed first)
 
    output-file="pspp.list"
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
 /* ASCII driver options: (defaults listed first)
 
    output-file="pspp.list"
-   char-set=ascii|latin1
-   form-feed-string="\f"        Written as a formfeed.
-   newline-string=default|"\r\n"|"\n"   
-                                Written as a newline.
    paginate=on|off              Formfeeds are desired?
    tab-width=8                  Width of a tab; 0 to not use tabs.
    paginate=on|off              Formfeeds are desired?
    tab-width=8                  Width of a tab; 0 to not use tabs.
-   init=""                      Written at beginning of output.
-   done=""                      Written at end of output.
    
    headers=on|off               Put headers at top of page?
    
    headers=on|off               Put headers at top of page?
+   emphasis=bold|underline|none Style to use for emphasis.
    length=66
    width=130
    length=66
    width=130
-   lpi=6                        Only used to determine font size.
-   cpi=10                       
    squeeze=off|on               Squeeze multiple newlines into exactly one.
 
    squeeze=off|on               Squeeze multiple newlines into exactly one.
 
-   left-margin=0
-   right-margin=0
    top-margin=2
    bottom-margin=2
 
    box[x]="strng"               Sets box character X (X in base 4: 0-3333).
    top-margin=2
    bottom-margin=2
 
    box[x]="strng"               Sets box character X (X in base 4: 0-3333).
-   italic-on=overstrike|"strng" Turns on italic (underline).
-   italic-off=""|"strng"        Turns off italic; ignored for overstrike.
-   bold-on=overstrike|"strng"   Turns on bold.
-   bold-off=""|"strng"          Turns off bold; ignored for overstrike.
-   bold-italic-on=overstrike|"strng" Turns on bold-italic.
-   bold-italic-off=""|"strng"   Turns off bold-italic; ignored for overstrike.
-   overstrike-style=single|line Can we print a whole line then BS over it, or
-   must we go char by char, as on a terminal?
-   carriage-return-style=bs|cr  Must we return the carriage with a sequence of
-   BSes, or will a single CR do it?
  */
 
 /* Disable messages by failed range checks. */
 /*#define SUPPRESS_WARNINGS 1 */
 
  */
 
 /* Disable messages by failed range checks. */
 /*#define SUPPRESS_WARNINGS 1 */
 
-/* Character set. */
-enum
-  {
-    CHS_ASCII,                 /* 7-bit ASCII */
-    CHS_LATIN1                 /* Latin 1; not really supported at the moment */
-  };
-
-/* Overstrike style. */
-enum
-  {
-    OVS_SINGLE,                        /* Overstrike each character: "a\b_b\b_c\b_" */
-    OVS_LINE                   /* Overstrike lines: "abc\b\b\b___" (or if
-                                  newline is "\r\n", then "abc\r___").  Easier
-                                  on the printer, doesn't work on a tty. */
-  };
-
-/* Basic output strings. */
-enum
-  {
-    OPS_INIT,                  /* Document initialization string. */
-    OPS_DONE,                  /* Document uninit string. */
-    OPS_FORMFEED,              /* Formfeed string. */
-    OPS_NEWLINE,               /* Newline string. */
-
-    OPS_COUNT                  /* Number of output strings. */
-  };
-
 /* Line styles bit shifts. */
 enum
   {
 /* Line styles bit shifts. */
 enum
   {
@@ -115,36 +72,9 @@ enum
     LNS_COUNT = 256
   };
 
     LNS_COUNT = 256
   };
 
-/* Carriage return style. */
-enum
-  {
-    CRS_BS,                    /* Multiple backspaces. */
-    CRS_CR                     /* Single carriage return. */
-  };
-
-/* Assembles a byte from four taystes. */
-#define TAYSTE2BYTE(T, L, B, R)                        \
-       (((T) << LNS_TOP)                       \
-        | ((L) << LNS_LEFT)                    \
-        | ((B) << LNS_BOTTOM)                  \
-        | ((R) << LNS_RIGHT))
-
-/* Extract tayste with shift value S from byte B. */
-#define BYTE2TAYSTE(B, S)                      \
-       (((B) >> (S)) & 3)
-
-/* Font style; take one of the first group |'d with one of the second group. */
-enum
-  {
-    FSTY_ON = 000,             /* Turn font on. */
-    FSTY_OFF = 001,            /* Turn font off. */
-
-    FSTY_ITALIC = 0,           /* Italic font. */
-    FSTY_BOLD = 2,             /* Bold font. */
-    FSTY_BOLD_ITALIC = 4,      /* Bold-italic font. */
-
-    FSTY_COUNT = 6             /* Number of font styles. */
-  };
+/* Character attributes. */
+#define ATTR_EMPHASIS   0x100   /* Bold-face. */
+#define ATTR_BOX        0x200   /* Line drawing character. */
 
 /* A line of text. */
 struct line 
 
 /* A line of text. */
 struct line 
@@ -154,330 +84,195 @@ struct line
     int char_cap;               /* Allocated bytes. */
   };
 
     int char_cap;               /* Allocated bytes. */
   };
 
+/* How to emphasize text. */
+enum emphasis_style 
+  {
+    EMPH_BOLD,                  /* Overstrike for bold. */
+    EMPH_UNDERLINE,             /* Overstrike for underlining. */
+    EMPH_NONE                   /* No emphasis. */
+  };
+
 /* ASCII output driver extension record. */
 struct ascii_driver_ext
   {
 /* ASCII output driver extension record. */
 struct ascii_driver_ext
   {
+    struct pool *pool;
+
     /* User parameters. */
     /* User parameters. */
-    int char_set;              /* CHS_ASCII/CHS_LATIN1; no-op right now. */
-    int headers;               /* 1=print headers at top of page. */
-    int page_length;           /* Page length in lines. */
-    int page_width;            /* Page width in characters. */
-    int lpi;                   /* Lines per inch. */
-    int cpi;                   /* Characters per inch. */
-    int left_margin;           /* Left margin in characters. */
-    int right_margin;          /* Right margin in characters. */
+    bool headers;              /* Print headers at top of page? */
+    bool paginate;             /* Insert formfeeds? */
+    bool squeeze_blank_lines;   /* Squeeze multiple blank lines into one? */
+    enum emphasis_style emphasis; /* How to emphasize text. */
+    int tab_width;             /* Width of a tab; 0 not to use tabs. */
+
+    int page_length;           /* Page length before subtracting margins. */
     int top_margin;            /* Top margin in lines. */
     int bottom_margin;         /* Bottom margin in lines. */
     int top_margin;            /* Top margin in lines. */
     int bottom_margin;         /* Bottom margin in lines. */
-    int paginate;              /* 1=insert formfeeds. */
-    int tab_width;             /* Width of a tab; 0 not to use tabs. */
-    struct fixed_string ops[OPS_COUNT]; /* Basic output strings. */
-    struct fixed_string box[LNS_COUNT]; /* Line & box drawing characters. */
-    struct fixed_string fonts[FSTY_COUNT]; /* Font styles; NULL=overstrike. */
-    int overstrike_style;      /* OVS_SINGLE or OVS_LINE. */
-    int carriage_return_style; /* Carriage return style. */
-    int squeeze_blank_lines;    /* 1=squeeze multiple blank lines into one. */
+
+    char *box[LNS_COUNT];       /* Line & box drawing characters. */
 
     /* Internal state. */
 
     /* Internal state. */
-    struct file_ext file;      /* Output file. */
+    char *file_name;            /* Output file name. */
+    FILE *file;                 /* Output file. */
     int page_number;           /* Current page number. */
     struct line *lines;         /* Page content. */
     int page_number;           /* Current page number. */
     struct line *lines;         /* Page content. */
-    int lines_cap;              /* Number of lines allocated. */
-    int w, l;                  /* Actual width & length w/o margins, etc. */
-    int cur_font;              /* Current font by OUTP_F_*. */
-#if DEBUGGING
-    int debug;                 /* Set by som_text_draw(). */
-#endif
+    int line_cap;               /* Number of lines allocated. */
   };
 
   };
 
-static int postopen (struct file_ext *);
-static int preclose (struct file_ext *);
-
-static struct outp_option_info *option_info;
-
-static int
-ascii_open_global (struct outp_class *this UNUSED)
-{
-  option_info = xmalloc (sizeof *option_info);
-  option_info->initial = 0;
-  option_info->options = 0;
-  return 1;
-}
-
-
-static char *s;
-static int
-ascii_close_global (struct outp_class *this UNUSED)
-{
-  free(option_info->initial);
-  free(option_info->options);
-  free(option_info);
-  free(s);
-  return 1;
-}
-
-static int *
-ascii_font_sizes (struct outp_class *this UNUSED, int *n_valid_sizes)
-{
-  static int valid_sizes[] = {12, 12, 0, 0};
-
-  assert (n_valid_sizes);
-  *n_valid_sizes = 1;
-  return valid_sizes;
-}
+static int get_default_box_char (size_t idx);
+static bool handle_option (struct outp_driver *this, const char *key,
+                           const struct string *val);
 
 
-static int
-ascii_preopen_driver (struct outp_driver *this)
+static bool
+ascii_open_driver (struct outp_driver *this, const char *options)
 {
   struct ascii_driver_ext *x;
   int i;
 {
   struct ascii_driver_ext *x;
   int i;
-  
-  assert (this->driver_open == 0);
-  msg (VM (1), _("ASCII driver initializing as `%s'..."), this->name);
-  this->ext = x = xmalloc (sizeof *x);
-  x->char_set = CHS_ASCII;
-  x->headers = 1;
+
+  this->width = 79;
+  this->font_height = 1;
+  this->prop_em_width = 1;
+  this->fixed_width = 1;
+  for (i = 0; i < OUTP_L_COUNT; i++)
+    this->horiz_line_width[i] = this->vert_line_width[i] = i != OUTP_L_NONE;
+
+  this->ext = x = pool_create_container (struct ascii_driver_ext, pool);
+  x->headers = true;
+  x->paginate = true;
+  x->squeeze_blank_lines = false;
+  x->emphasis = EMPH_BOLD;
+  x->tab_width = 8;
   x->page_length = 66;
   x->page_length = 66;
-  x->page_width = 79;
-  x->lpi = 6;
-  x->cpi = 10;
-  x->left_margin = 0;
-  x->right_margin = 0;
   x->top_margin = 2;
   x->bottom_margin = 2;
   x->top_margin = 2;
   x->bottom_margin = 2;
-  x->paginate = 1;
-  x->tab_width = 8;
-  for (i = 0; i < OPS_COUNT; i++)
-    ls_null (&x->ops[i]);
   for (i = 0; i < LNS_COUNT; i++)
   for (i = 0; i < LNS_COUNT; i++)
-    ls_null (&x->box[i]);
-  for (i = 0; i < FSTY_COUNT; i++)
-    ls_null (&x->fonts[i]);
-  x->overstrike_style = OVS_SINGLE;
-  x->carriage_return_style = CRS_BS;
-  x->squeeze_blank_lines = 0;
-  x->file.filename = NULL;
-  x->file.mode = "wb";
-  x->file.file = NULL;
-  x->file.sequence_no = &x->page_number;
-  x->file.param = x;
-  x->file.postopen = postopen;
-  x->file.preclose = preclose;
+    x->box[i] = NULL;
+  x->file_name = pool_strdup (x->pool, "pspp.list");
+  x->file = NULL;
   x->page_number = 0;
   x->lines = NULL;
   x->page_number = 0;
   x->lines = NULL;
-  x->lines_cap = 0;
-  x->cur_font = OUTP_F_R;
-#if DEBUGGING
-  x->debug = 0;
-#endif
-  return 1;
-}
+  x->line_cap = 0;
 
 
-static int
-ascii_postopen_driver (struct outp_driver *this)
-{
-  struct ascii_driver_ext *x = this->ext;
-  
-  assert (this->driver_open == 0);
-  
-  if (NULL == x->file.filename)
-    x->file.filename = xstrdup ("pspp.list");
-  
-  x->w = x->page_width - x->left_margin - x->right_margin;
-  x->l = (x->page_length - (x->headers ? 3 : 0) - x->top_margin
-         - x->bottom_margin - 1);
-  if (x->w < 59 || x->l < 15)
+  if (!outp_parse_options (options, handle_option, this))
+    goto error;
+
+  x->file = pool_fopen (x->pool, x->file_name, "w");
+  if (x->file == NULL)
     {
     {
-      msg (SE, _("ascii driver: Area of page excluding margins and headers "
-                "must be at least 59 characters wide by 15 lines long.  Page as "
-                "configured is only %d characters by %d lines."), x->w, x->l);
-      return 0;
+      error (0, errno, _("ascii: opening output file \"%s\""), x->file_name);
+      goto error;
     }
     }
+
+  this->length = x->page_length - x->top_margin - x->bottom_margin - 1;
+  if (x->headers)
+    this->length -= 3;
   
   
-  this->res = x->lpi * x->cpi;
-  this->horiz = x->lpi;
-  this->vert = x->cpi;
-  this->width = x->w * this->horiz;
-  this->length = x->l * this->vert;
-  
-  if (ls_null_p (&x->ops[OPS_FORMFEED]))
-    ls_create (&x->ops[OPS_FORMFEED], "\f");
-  if (ls_null_p (&x->ops[OPS_NEWLINE])
-      || !strcmp (ls_c_str (&x->ops[OPS_NEWLINE]), "default"))
+  if (this->width < 59 || this->length < 15)
     {
     {
-      ls_create (&x->ops[OPS_NEWLINE], "\n");
-      x->file.mode = "wt";
+      error (0, 0,
+             _("ascii: page excluding margins and headers "
+               "must be at least 59 characters wide by 15 lines long, but as "
+               "configured is only %d characters by %d lines"),
+             this->width, this->length);
+      return false;
     }
     }
-  
-  {
-    int i;
-    
-    for (i = 0; i < LNS_COUNT; i++)
+
+  for (i = 0; i < LNS_COUNT; i++)
+    if (x->box[i] == NULL) 
       {
       {
-       char c[2];
-       c[1] = 0;
-       if (!ls_null_p (&x->box[i]))
-         continue;
-       switch (i)
-         {
-         case TAYSTE2BYTE (0, 0, 0, 0):
-           c[0] = ' ';
-           break;
+        char s[2];
+        s[0] = get_default_box_char (i);
+        s[1] = '\0';
+        x->box[i] = pool_strdup (x->pool, s);
+      }
+  
+  return true;
 
 
-         case TAYSTE2BYTE (0, 1, 0, 0):
-         case TAYSTE2BYTE (0, 1, 0, 1):
-         case TAYSTE2BYTE (0, 0, 0, 1):
-           c[0] = '-';
-           break;
+ error:
+  pool_destroy (x->pool);
+  return false;
+}
 
 
-         case TAYSTE2BYTE (1, 0, 0, 0):
-         case TAYSTE2BYTE (1, 0, 1, 0):
-         case TAYSTE2BYTE (0, 0, 1, 0):
-           c[0] = '|';
-           break;
+static int
+get_default_box_char (size_t idx)
+{
+  /* Disassemble IDX into components. */
+  unsigned top = (idx >> LNS_TOP) & 3;
+  unsigned left = (idx >> LNS_LEFT) & 3;
+  unsigned bottom = (idx >> LNS_BOTTOM) & 3;
+  unsigned right = (idx >> LNS_RIGHT) & 3;
 
 
-         case TAYSTE2BYTE (0, 3, 0, 0):
-         case TAYSTE2BYTE (0, 3, 0, 3):
-         case TAYSTE2BYTE (0, 0, 0, 3):
-         case TAYSTE2BYTE (0, 2, 0, 0):
-         case TAYSTE2BYTE (0, 2, 0, 2):
-         case TAYSTE2BYTE (0, 0, 0, 2):
-           c[0] = '=';
-           break;
+  /* Reassemble components into nibbles in the order TLBR.
+     This makes it easy to read the case labels. */
+  unsigned value = (top << 12) | (left << 8) | (bottom << 4) | (right << 0);
+  switch (value)
+    {
+    case 0x0000:
+      return ' ';
 
 
-         case TAYSTE2BYTE (3, 0, 0, 0):
-         case TAYSTE2BYTE (3, 0, 3, 0):
-         case TAYSTE2BYTE (0, 0, 3, 0):
-         case TAYSTE2BYTE (2, 0, 0, 0):
-         case TAYSTE2BYTE (2, 0, 2, 0):
-         case TAYSTE2BYTE (0, 0, 2, 0):
-           c[0] = '#';
-           break;
+    case 0x0100: case 0x0101: case 0x0001:
+      return '-';
 
 
-         default:
-           if (BYTE2TAYSTE (i, LNS_LEFT) > 1
-               || BYTE2TAYSTE (i, LNS_TOP) > 1
-               || BYTE2TAYSTE (i, LNS_RIGHT) > 1
-               || BYTE2TAYSTE (i, LNS_BOTTOM) > 1)
-             c[0] = '#';
-           else
-             c[0] = '+';
-           break;
-         }
-       ls_create (&x->box[i], c);
-      }
-  }
-  
-  {
-    int i;
-    
-    this->cp_x = this->cp_y = 0;
-    this->font_height = this->vert;
-    this->prop_em_width = this->horiz;
-    this->fixed_width = this->horiz;
-
-    this->horiz_line_width[0] = 0;
-    this->vert_line_width[0] = 0;
-    
-    for (i = 1; i < OUTP_L_COUNT; i++)
-      {
-       this->horiz_line_width[i] = this->vert;
-       this->vert_line_width[i] = this->horiz;
-      }
-    
-    for (i = 0; i < (1 << OUTP_L_COUNT); i++)
-      {
-       this->horiz_line_spacing[i] = (i & ~1) ? this->vert : 0;
-       this->vert_line_spacing[i] = (i & ~1) ? this->horiz : 0;
-      }
-  }
-  
-  this->driver_open = 1;
-  msg (VM (2), _("%s: Initialization complete."), this->name);
+    case 0x1000: case 0x1010: case 0x0010:
+      return '|';
+
+    case 0x0300: case 0x0303: case 0x0003:
+    case 0x0200: case 0x0202: case 0x0002:
+      return '=';
 
 
-  return 1;
+    default:
+      return left > 1 || top > 1 || right > 1 || bottom > 1 ? '#' : '+';
+    }
 }
 
 }
 
-static int
+static bool
 ascii_close_driver (struct outp_driver *this)
 {
   struct ascii_driver_ext *x = this->ext;
 ascii_close_driver (struct outp_driver *this)
 {
   struct ascii_driver_ext *x = this->ext;
-  int i;
-  
-  assert (this->driver_open == 1);
-  msg (VM (2), _("%s: Beginning closing..."), this->name);
-  
-  x = this->ext;
-  for (i = 0; i < OPS_COUNT; i++)
-    ls_destroy (&x->ops[i]);
-  for (i = 0; i < LNS_COUNT; i++)
-    ls_destroy (&x->box[i]);
-  for (i = 0; i < FSTY_COUNT; i++)
-    ls_destroy (&x->fonts[i]);
-  if (x->lines != NULL) 
-    {
-      int line;
-      
-      for (line = 0; line < x->lines_cap; line++) 
-        free (x->lines[line].chars);
-      free (x->lines); 
-    }
-  fn_close_ext (&x->file);
-  free (x->file.filename);
-  free (x);
   
   
-  this->driver_open = 0;
-  msg (VM (3), _("%s: Finished closing."), this->name);
+  if (fn_close (x->file_name, x->file) != 0)
+    error (0, errno, _("ascii: closing output file \"%s\""), x->file_name);
+  pool_detach_file (x->pool, x->file);
+  pool_destroy (x->pool);
   
   
-  return 1;
+  return true;
 }
 
 /* Generic option types. */
 enum
   {
 }
 
 /* Generic option types. */
 enum
   {
-    pos_int_arg = -10,
-    nonneg_int_arg,
+    boolean_arg,
     string_arg,
     string_arg,
-    font_string_arg,
-    boolean_arg
+    nonneg_int_arg,
+    pos_int_arg,
+    output_file_arg
   };
 
 static struct outp_option option_tab[] =
   {
     {"headers", boolean_arg, 0},
   };
 
 static struct outp_option option_tab[] =
   {
     {"headers", boolean_arg, 0},
-    {"output-file", 1, 0},
-    {"char-set", 2, 0},
-    {"length", pos_int_arg, 0},
-    {"width", pos_int_arg, 1},
-    {"lpi", pos_int_arg, 2},
-    {"cpi", pos_int_arg, 3},
-    {"init", string_arg, 0},
-    {"done", string_arg, 1},
-    {"left-margin", nonneg_int_arg, 0},
-    {"right-margin", nonneg_int_arg, 1},
-    {"top-margin", nonneg_int_arg, 2},
-    {"bottom-margin", nonneg_int_arg, 3},
     {"paginate", boolean_arg, 1},
     {"paginate", boolean_arg, 1},
-    {"form-feed-string", string_arg, 2},
-    {"newline-string", string_arg, 3},
-    {"italic-on", font_string_arg, 0},
-    {"italic-off", font_string_arg, 1},
-    {"bold-on", font_string_arg, 2},
-    {"bold-off", font_string_arg, 3},
-    {"bold-italic-on", font_string_arg, 4},
-    {"bold-italic-off", font_string_arg, 5},
-    {"overstrike-style", 3, 0},
-    {"tab-width", nonneg_int_arg, 4},
-    {"carriage-return-style", 4, 0},
     {"squeeze", boolean_arg, 2},
     {"squeeze", boolean_arg, 2},
-    {"", 0, 0},
+
+    {"emphasis", string_arg, 3},
+
+    {"output-file", output_file_arg, 0},
+
+    {"length", pos_int_arg, 0},
+    {"width", pos_int_arg, 1},
+
+    {"top-margin", nonneg_int_arg, 0},
+    {"bottom-margin", nonneg_int_arg, 1},
+    {"tab-width", nonneg_int_arg, 2},
+
+    {NULL, 0, 0},
   };
 
   };
 
-static void
-ascii_option (struct outp_driver *this, const char *key,
-             const struct string *val)
+static bool
+handle_option (struct outp_driver *this, const char *key,
+               const struct string *val)
 {
   struct ascii_driver_ext *x = this->ext;
 {
   struct ascii_driver_ext *x = this->ext;
-  int cat, subcat;
+  int subcat;
   const char *value;
 
   value = ds_c_str (val);
   const char *value;
 
   value = ds_c_str (val);
@@ -487,54 +282,25 @@ ascii_option (struct outp_driver *this, const char *key,
       int indx = strtol (&key[4], &tail, 4);
       if (*tail != ']' || indx < 0 || indx > LNS_COUNT)
        {
       int indx = strtol (&key[4], &tail, 4);
       if (*tail != ']' || indx < 0 || indx > LNS_COUNT)
        {
-         msg (SE, _("Bad index value for `box' key: syntax is box[INDEX], "
-              "0 <= INDEX < %d decimal, with INDEX expressed in base 4."),
-              LNS_COUNT);
-         return;
+         error (0, 0, _("ascii: bad index value for `box' key: syntax "
+                         "is box[INDEX], 0 <= INDEX < %d decimal, with INDEX "
+                         "expressed in base 4"),
+                 LNS_COUNT);
+         return false;
        }
        }
-      if (!ls_null_p (&x->box[indx]))
-       msg (SW, _("Duplicate value for key `%s'."), key);
-      ls_create (&x->box[indx], value);
-      return;
+      if (x->box[indx] != NULL)
+       error (0, 0, _("ascii: multiple values for %s"), key);
+      x->box[indx] = pool_strdup (x->pool, value);
+      return true;
     }
 
     }
 
-  cat = outp_match_keyword (key, option_tab, option_info, &subcat);
-  switch (cat)
+  switch (outp_match_keyword (key, option_tab, &subcat))
     {
     {
-    case 0:
-      msg (SE, _("Unknown configuration parameter `%s' for ascii device driver."),
-          key);
-      break;
-    case 1:
-      free (x->file.filename);
-      x->file.filename = xstrdup (value);
+    case -1:
+      error (0, 0, _("ascii: unknown parameter `%s'"), key);
       break;
       break;
-    case 2:
-      if (!strcmp (value, "ascii"))
-       x->char_set = CHS_ASCII;
-      else if (!strcmp (value, "latin1"))
-       x->char_set = CHS_LATIN1;
-      else
-       msg (SE, _("Unknown character set `%s'.  Valid character sets are "
-            "`ascii' and `latin1'."), value);
-      break;
-    case 3:
-      if (!strcmp (value, "single"))
-       x->overstrike_style = OVS_SINGLE;
-      else if (!strcmp (value, "line"))
-       x->overstrike_style = OVS_LINE;
-      else
-       msg (SE, _("Unknown overstrike style `%s'.  Valid overstrike styles "
-            "are `single' and `line'."), value);
-      break;
-    case 4:
-      if (!strcmp (value, "bs"))
-       x->carriage_return_style = CRS_BS;
-      else if (!strcmp (value, "cr"))
-       x->carriage_return_style = CRS_CR;
-      else
-       msg (SE, _("Unknown carriage return style `%s'.  Valid carriage "
-            "return styles are `cr' and `bs'."), value);
+    case output_file_arg:
+      x->file_name = pool_strdup (x->pool, value);
       break;
     case pos_int_arg:
       {
       break;
     case pos_int_arg:
       {
@@ -545,7 +311,8 @@ ascii_option (struct outp_driver *this, const char *key,
        arg = strtol (value, &tail, 0);
        if (arg < 1 || errno == ERANGE || *tail)
          {
        arg = strtol (value, &tail, 0);
        if (arg < 1 || errno == ERANGE || *tail)
          {
-           msg (SE, _("Positive integer required as value for `%s'."), key);
+           error (0, 0, _("ascii: positive integer required as `%s' value"),
+                   key);
            break;
          }
        switch (subcat)
            break;
          }
        switch (subcat)
@@ -554,19 +321,25 @@ ascii_option (struct outp_driver *this, const char *key,
            x->page_length = arg;
            break;
          case 1:
            x->page_length = arg;
            break;
          case 1:
-           x->page_width = arg;
-           break;
-         case 2:
-           x->lpi = arg;
-           break;
-         case 3:
-           x->cpi = arg;
+           this->width = arg;
            break;
          default:
            break;
          default:
-           assert (0);
+           abort ();
          }
       }
       break;
          }
       }
       break;
+    case string_arg:
+      if (!strcmp (value, "bold"))
+        x->emphasis = EMPH_BOLD;
+      else if (!strcmp (value, "underline"))
+        x->emphasis = EMPH_UNDERLINE;
+      else if (!strcmp (value, "none"))
+        x->emphasis = EMPH_NONE;
+      else 
+        error (0, 0,
+               _("ascii: `emphasis' value must be `bold', "
+                 "`underline', or `none'"));
+      break;
     case nonneg_int_arg:
       {
        char *tail;
     case nonneg_int_arg:
       {
        char *tail;
@@ -576,79 +349,40 @@ ascii_option (struct outp_driver *this, const char *key,
        arg = strtol (value, &tail, 0);
        if (arg < 0 || errno == ERANGE || *tail)
          {
        arg = strtol (value, &tail, 0);
        if (arg < 0 || errno == ERANGE || *tail)
          {
-           msg (SE, _("Zero or positive integer required as value for `%s'."),
-                key);
+           error (0, 0,
+                   _("ascii: zero or positive integer required as `%s' value"),
+                   key);
            break;
          }
        switch (subcat)
          {
          case 0:
            break;
          }
        switch (subcat)
          {
          case 0:
-           x->left_margin = arg;
-           break;
-         case 1:
-           x->right_margin = arg;
-           break;
-         case 2:
            x->top_margin = arg;
            break;
            x->top_margin = arg;
            break;
-         case 3:
-           x->bottom_margin = arg;
-           break;
-         case 4:
-           x->tab_width = arg;
-           break;
-         default:
-           assert (0);
-         }
-      }
-      break;
-    case string_arg:
-      {
-       struct fixed_string *s;
-       switch (subcat)
-         {
-         case 0:
-           s = &x->ops[OPS_INIT];
-           break;
          case 1:
          case 1:
-           s = &x->ops[OPS_DONE];
+           x->bottom_margin = arg;
            break;
          case 2:
            break;
          case 2:
-           s = &x->ops[OPS_FORMFEED];
-           break;
-         case 3:
-           s = &x->ops[OPS_NEWLINE];
+           x->tab_width = arg;
            break;
          default:
            break;
          default:
-           assert (0);
-            abort ();
-         }
-       ls_create (s, value);
-      }
-      break;
-    case font_string_arg:
-      {
-       if (!strcmp (value, "overstrike"))
-         {
-           ls_destroy (&x->fonts[subcat]);
-           return;
+           abort ();
          }
          }
-       ls_create (&x->fonts[subcat], value);
       }
       break;
     case boolean_arg:
       {
       }
       break;
     case boolean_arg:
       {
-       int setting;
+       bool setting;
        if (!strcmp (value, "on") || !strcmp (value, "true")
            || !strcmp (value, "yes") || atoi (value))
        if (!strcmp (value, "on") || !strcmp (value, "true")
            || !strcmp (value, "yes") || atoi (value))
-         setting = 1;
+         setting = true;
        else if (!strcmp (value, "off") || !strcmp (value, "false")
                 || !strcmp (value, "no") || !strcmp (value, "0"))
        else if (!strcmp (value, "off") || !strcmp (value, "false")
                 || !strcmp (value, "no") || !strcmp (value, "0"))
-         setting = 0;
+         setting = false;
        else
          {
        else
          {
-           msg (SE, _("Boolean value expected for %s."), key);
-           return;
+           error (0, 0, _("ascii: boolean value expected for `%s'"), key);
+           return false;
          }
        switch (subcat)
          {
          }
        switch (subcat)
          {
@@ -662,988 +396,340 @@ ascii_option (struct outp_driver *this, const char *key,
             x->squeeze_blank_lines = setting;
             break;
          default:
             x->squeeze_blank_lines = setting;
             break;
          default:
-           assert (0);
+           abort ();
          }
       }
       break;
     default:
          }
       }
       break;
     default:
-      assert (0);
+      abort ();
     }
     }
-}
-
-int
-postopen (struct file_ext *f)
-{
-  struct ascii_driver_ext *x = f->param;
-  struct fixed_string *s = &x->ops[OPS_INIT];
 
 
-  if (!ls_empty_p (s) && fwrite (ls_c_str (s), ls_length (s), 1, f->file) < 1)
-    {
-      msg (ME, _("ASCII output driver: %s: %s"),
-          f->filename, strerror (errno));
-      return 0;
-    }
-  return 1;
+  return true;
 }
 
 }
 
-int
-preclose (struct file_ext *f)
-{
-  struct ascii_driver_ext *x = f->param;
-  struct fixed_string *d = &x->ops[OPS_DONE];
-
-  if (!ls_empty_p (d) && fwrite (ls_c_str (d), ls_length (d), 1, f->file) < 1)
-    {
-      msg (ME, _("ASCII output driver: %s: %s"),
-          f->filename, strerror (errno));
-      return 0;
-    }
-  return 1;
-}
-
-static int
+static void
 ascii_open_page (struct outp_driver *this)
 {
   struct ascii_driver_ext *x = this->ext;
   int i;
 
 ascii_open_page (struct outp_driver *this)
 {
   struct ascii_driver_ext *x = this->ext;
   int i;
 
-  assert (this->driver_open && !this->page_open);
   x->page_number++;
   x->page_number++;
-  if (!fn_open_ext (&x->file))
-    {
-      msg (ME, _("ASCII output driver: %s: %s"), x->file.filename,
-          strerror (errno));
-      return 0;
-    }
 
 
-  if (x->l > x->lines_cap)
+  if (this->length > x->line_cap)
     {
     {
-      x->lines = xnrealloc (x->lines, x->l, sizeof *x->lines);
-      for (i = x->lines_cap; i < x->l; i++) 
+      x->lines = pool_nrealloc (x->pool,
+                                x->lines, this->length, sizeof *x->lines);
+      for (i = x->line_cap; i < this->length; i++) 
         {
           struct line *line = &x->lines[i];
           line->chars = NULL;
           line->char_cap = 0;
         }
         {
           struct line *line = &x->lines[i];
           line->chars = NULL;
           line->char_cap = 0;
         }
-      x->lines_cap = x->l;
+      x->line_cap = this->length;
     }
 
     }
 
-  for (i = 0; i < x->l; i++)
+  for (i = 0; i < this->length; i++)
     x->lines[i].char_cnt = 0;
     x->lines[i].char_cnt = 0;
-
-  this->page_open = 1;
-  return 1;
 }
 
 }
 
-/* Ensures that at least the first L characters of line I in the
-   driver identified by struct ascii_driver_ext *X have been cleared out. */
+/* Ensures that at least the first LENGTH characters of line Y in
+   THIS driver identified X have been cleared out. */
 static inline void
 static inline void
-expand_line (struct ascii_driver_ext *x, int i, int l)
-{
-  struct line *line;
-  int j;
-
-  assert (i < x->lines_cap);
-  line = &x->lines[i];
-  if (l > line->char_cap) 
-    {
-      line->char_cap = l * 2;
-      line->chars = xnrealloc (line->chars,
-                               line->char_cap, sizeof *line->chars); 
-    }
-  for (j = line->char_cnt; j < l; j++)
-    line->chars[j] = ' ';
-  line->char_cnt = l;
-}
-
-/* Puts line L at (H,K) in the current output page.  Assumes
-   struct ascii_driver_ext named `ext'. */
-#define draw_line(H, K, L)                             \
-        ext->lines[K].chars[H] = (L) | 0x800
-
-/* Line styles for each position. */
-#define T(STYLE) (STYLE<<LNS_TOP)
-#define L(STYLE) (STYLE<<LNS_LEFT)
-#define B(STYLE) (STYLE<<LNS_BOTTOM)
-#define R(STYLE) (STYLE<<LNS_RIGHT)
-
-static void
-ascii_line_horz (struct outp_driver *this, const struct rect *r,
-                const struct color *c UNUSED, int style)
+expand_line (struct outp_driver *this, int y, int length)
 {
   struct ascii_driver_ext *ext = this->ext;
 {
   struct ascii_driver_ext *ext = this->ext;
-  int x1 = r->x1 / this->horiz;
-  int x2 = r->x2 / this->horiz;
-  int y1 = r->y1 / this->vert;
-  int x;
-
-  assert (this->driver_open && this->page_open);
-  if (x1 == x2)
-    return;
-#if DEBUGGING
-  if (x1 > x2
-      || x1 < 0 || x1 >= ext->w
-      || x2 <= 0 || x2 > ext->w
-      || y1 < 0 || y1 >= ext->l)
+  struct line *line = &ext->lines[y];
+  if (line->char_cnt < length) 
     {
     {
-#if !SUPPRESS_WARNINGS
-      printf (_("ascii_line_horz: bad hline (%d,%d),%d out of (%d,%d)\n"),
-             x1, x2, y1, ext->w, ext->l);
-#endif
-      return;
+      int x;
+      if (line->char_cap < length) 
+        {
+          line->char_cap = MIN (length * 2, this->width);
+          line->chars = pool_nrealloc (ext->pool,
+                                       line->chars,
+                                       line->char_cap, sizeof *line->chars); 
+        }
+      for (x = line->char_cnt; x < length; x++)
+        line->chars[x] = ' ';
+      line->char_cnt = length; 
     }
     }
-#endif
-
-  if (ext->lines[y1].char_cnt < x2)
-    expand_line (ext, y1, x2);
-
-  for (x = x1; x < x2; x++)
-    draw_line (x, y1, (style << LNS_LEFT) | (style << LNS_RIGHT));
 }
 
 static void
 }
 
 static void
-ascii_line_vert (struct outp_driver *this, const struct rect *r,
-                const struct color *c UNUSED, int style)
+ascii_line (struct outp_driver *this, 
+            int x0, int y0, int x1, int y1,
+            enum outp_line_style top, enum outp_line_style left,
+            enum outp_line_style bottom, enum outp_line_style right)
 {
   struct ascii_driver_ext *ext = this->ext;
 {
   struct ascii_driver_ext *ext = this->ext;
-  int x1 = r->x1 / this->horiz;
-  int y1 = r->y1 / this->vert;
-  int y2 = r->y2 / this->vert;
   int y;
   int y;
+  unsigned short value;
 
 
-  assert (this->driver_open && this->page_open);
-  if (y1 == y2)
-    return;
+  assert (this->page_open);
 #if DEBUGGING
 #if DEBUGGING
-  if (y1 > y2
-      || x1 < 0 || x1 >= ext->w
-      || y1 < 0 || y1 >= ext->l
-      || y2 < 0 || y2 > ext->l)
+  if (x0 < 0 || x1 > this->width || y0 < 0 || y1 > this->length)
     {
 #if !SUPPRESS_WARNINGS
     {
 #if !SUPPRESS_WARNINGS
-      printf (_("ascii_line_vert: bad vline %d,(%d,%d) out of (%d,%d)\n"),
-             x1, y1, y2, ext->w, ext->l);
+      printf (_("ascii: bad line (%d,%d)-(%d,%d) out of (%d,%d)\n"),
+             x0, y0, x1, y1, this->width, this->length);
 #endif
       return;
     }
 #endif
 
 #endif
       return;
     }
 #endif
 
-  for (y = y1; y < y2; y++)
-    if (ext->lines[y].char_cnt <= x1)
-      expand_line (ext, y, x1 + 1);
-
-  for (y = y1; y < y2; y++)
-    draw_line (x1, y, (style << LNS_TOP) | (style << LNS_BOTTOM));
-}
-
-static void
-ascii_line_intersection (struct outp_driver *this, const struct rect *r,
-                        const struct color *c UNUSED,
-                        const struct outp_styles *style)
-{
-  struct ascii_driver_ext *ext = this->ext;
-  int x = r->x1 / this->horiz;
-  int y = r->y1 / this->vert;
-  int l;
-
-  assert (this->driver_open && this->page_open);
-#if DEBUGGING
-  if (x < 0 || x >= ext->w || y < 0 || y >= ext->l)
+  value = ((left << LNS_LEFT) | (right << LNS_RIGHT)
+           | (top << LNS_TOP) | (bottom << LNS_BOTTOM) | ATTR_BOX);
+  for (y = y0; y < y1; y++) 
     {
     {
-#if !SUPPRESS_WARNINGS
-      printf (_("ascii_line_intersection: bad intsct (%d,%d) out of (%d,%d)\n"),
-             x, y, ext->w, ext->l);
-#endif
-      return;
-    }
-#endif
-
-  l = ((style->l << LNS_LEFT) | (style->r << LNS_RIGHT)
-       | (style->t << LNS_TOP) | (style->b << LNS_BOTTOM));
-
-  if (ext->lines[y].char_cnt <= x)
-    expand_line (ext, y, x + 1);
-  draw_line (x, y, l);
-}
-
-/* FIXME: Later we could set this up so that for certain devices it
-   performs shading? */
-static void
-ascii_box (struct outp_driver *this UNUSED, const struct rect *r UNUSED,
-          const struct color *bord UNUSED, const struct color *fill UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-}
+      int x;
 
 
-/* Polylines not supported. */
-static void
-ascii_polyline_begin (struct outp_driver *this UNUSED, const struct color *c UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-}
-static void
-ascii_polyline_point (struct outp_driver *this UNUSED, int x UNUSED, int y UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-}
-static void
-ascii_polyline_end (struct outp_driver *this UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-}
-
-static void
-ascii_text_set_font_by_name (struct outp_driver * this, const char *s)
-{
-  struct ascii_driver_ext *x = this->ext;
-  int len = strlen (s);
-
-  assert (this->driver_open && this->page_open);
-  x->cur_font = OUTP_F_R;
-  if (len == 0)
-    return;
-  if (s[len - 1] == 'I')
-    {
-      if (len > 1 && s[len - 2] == 'B')
-       x->cur_font = OUTP_F_BI;
-      else
-       x->cur_font = OUTP_F_I;
+      expand_line (this, y, x1);
+      for (x = x0; x < x1; x++)
+        ext->lines[y].chars[x] = value; 
     }
     }
-  else if (s[len - 1] == 'B')
-    x->cur_font = OUTP_F_B;
 }
 
 static void
 }
 
 static void
-ascii_text_set_font_by_position (struct outp_driver *this, int pos)
+text_draw (struct outp_driver *this,
+           enum outp_font font,
+           int x, int y,
+           enum outp_justification justification, int width,
+           const char *string, size_t length)
 {
 {
-  struct ascii_driver_ext *x = this->ext;
-  assert (this->driver_open && this->page_open);
-  x->cur_font = pos >= 0 && pos < 4 ? pos : 0;
-}
-
-static void
-ascii_text_set_font_by_family (struct outp_driver *this UNUSED, const char *s UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-}
+  struct ascii_driver_ext *ext = this->ext;
+  unsigned short attr = font == OUTP_EMPHASIS ? ATTR_EMPHASIS : 0;
 
 
-static const char *
-ascii_text_get_font_name (struct outp_driver *this)
-{
-  struct ascii_driver_ext *x = this->ext;
+  int line_len;
 
 
-  assert (this->driver_open && this->page_open);
-  switch (x->cur_font)
+  switch (justification)
     {
     {
-    case OUTP_F_R:
-      return "R";
-    case OUTP_F_I:
-      return "I";
-    case OUTP_F_B:
-      return "B";
-    case OUTP_F_BI:
-      return "BI";
+    case OUTP_LEFT:
+      break;
+    case OUTP_CENTER:
+      x += (width - length + 1) / 2;
+      break;
+    case OUTP_RIGHT:
+      x += width - length;
+      break;
     default:
     default:
-      assert (0);
+      abort ();
     }
     }
-  abort ();
-}
 
 
-static const char *
-ascii_text_get_font_family (struct outp_driver *this UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-  return "";
-}
+  if (y >= this->length || x >= this->width)
+    return;
 
 
-static int
-ascii_text_set_size (struct outp_driver *this, int size)
-{
-  assert (this->driver_open && this->page_open);
-  return size == this->vert;
-}
+  if (x + length > this->width)
+    length = this->width - x;
 
 
-static int
-ascii_text_get_size (struct outp_driver *this, int *em_width)
-{
-  assert (this->driver_open && this->page_open);
-  if (em_width)
-    *em_width = this->horiz;
-  return this->vert;
-}
+  line_len = x + length;
 
 
-static void text_draw (struct outp_driver *this, struct outp_text *t);
+  expand_line (this, y, line_len);
+  while (length-- > 0)
+    ext->lines[y].chars[x++] = *string++ | attr;
+}
 
 /* Divides the text T->S into lines of width T->H.  Sets T->V to the
    number of lines necessary.  Actually draws the text if DRAW is
 
 /* Divides the text T->S into lines of width T->H.  Sets T->V to the
    number of lines necessary.  Actually draws the text if DRAW is
-   nonzero.
-
-   You probably don't want to look at this code. */
+   true. */
 static void
 static void
-delineate (struct outp_driver *this, struct outp_text *t, int draw)
+delineate (struct outp_driver *this, const struct outp_text *text, bool draw,
+           int *width, int *height)
 {
 {
-  /* Width we're fitting everything into. */
-  int width = t->h / this->horiz;
+  int max_width;
+  int height_left;
 
 
-  /* Maximum `y' position we can write to. */
-  int max_y;
+  const char *cp = ls_c_str (&text->string);
 
 
-  /* Current position in string, character following end of string. */
-  const char *s = ls_c_str (&t->s);
-  const char *end = ls_end (&t->s);
-
-  /* Temporary struct outp_text to pass to low-level function. */
-  struct outp_text temp;
-
-#if DEBUGGING && 0
-  if (!ext->debug)
-    {
-      ext->debug = 1;
-      printf (_("%s: horiz=%d, vert=%d\n"), this->name, this->horiz, this->vert);
-    }
-#endif
+  max_width = 0;
+  height_left = text->v;
 
 
-  if (!width)
+  while (height_left > 0)
     {
     {
-      t->h = t->v = 0;
-      return;
-    }
+      size_t chars_left;
+      size_t line_len;
+      const char *end;
 
 
-  if (draw)
-    {
-      temp.options = t->options;
-      ls_shallow_copy (&temp.s, &t->s);
-      temp.h = t->h / this->horiz;
-      temp.x = t->x / this->horiz;
-    }
-  else
-    t->y = 0;
-  temp.y = t->y / this->vert;
-
-  if (t->options & OUTP_T_VERT)
-    max_y = (t->v / this->vert) + temp.y - 1;
-  else
-    max_y = INT_MAX;
-  
-  while (end - s > width)
-    {
-      const char *beg = s;
-      const char *space;
+      /* Initially the line is up to text->h characters long. */
+      chars_left = ls_end (&text->string) - cp;
+      if (chars_left == 0)
+        break;
+      line_len = MIN (chars_left, text->h);
 
 
-      /* Find first space before &s[width]. */
-      space = &s[width];
-      for (;;)
-       {
-         if (space > s)
-           {
-             if (!isspace ((unsigned char) space[-1]))
-               {
-                 space--;
-                 continue;
-               }
-             else
-               s = space;
-           }
-         else
-           s = space = &s[width];
-         break;
-       }
+      /* A new-line terminates the line prematurely. */
+      end = memchr (cp, '\n', line_len);
+      if (end != NULL)
+        line_len = end - cp;
 
 
+      /* Don't cut off words if it can be avoided. */
+      if (cp + line_len < ls_end (&text->string)) 
+        {
+          size_t space_len = line_len;
+          while (space_len > 0 && !isspace ((unsigned char) cp[space_len]))
+            space_len--;
+          if (space_len > 0)
+            line_len = space_len;
+        }
+      
       /* Draw text. */
       if (draw)
       /* Draw text. */
       if (draw)
-       {
-         ls_init (&temp.s, beg, space - beg);
-         temp.w = space - beg;
-         text_draw (this, &temp);
-       }
-      if (++temp.y > max_y)
-       return;
+        text_draw (this,
+                   text->font,
+                   text->x, text->y + (text->v - height_left),
+                   text->justification, text->h,
+                   cp, line_len);
 
 
-      /* Find first nonspace after space. */
-      while (s < end && isspace ((unsigned char) *s))
-       s++;
-    }
-  if (s < end)
-    {
-      if (draw)
-       {
-         ls_init (&temp.s, s, end - s);
-         temp.w = end - s;
-         text_draw (this, &temp);
-       }
-      temp.y++;
+      /* Update. */
+      height_left--;
+      if (line_len > max_width)
+        max_width = line_len;
+
+      /* Next line. */
+      cp += line_len;
+      if (cp < ls_end (&text->string) && isspace ((unsigned char) *cp))
+        cp++;
     }
 
     }
 
-  t->v = (temp.y * this->vert) - t->y;
+  if (width != NULL)
+    *width = max_width;
+  if (height != NULL)
+    *height = text->v - height_left;
 }
 
 static void
 }
 
 static void
-ascii_text_metrics (struct outp_driver *this, struct outp_text *t)
+ascii_text_metrics (struct outp_driver *this, const struct outp_text *t,
+                    int *width, int *height)
 {
 {
-  assert (this->driver_open && this->page_open);
-  if (!(t->options & OUTP_T_HORZ))
-    {
-      t->v = this->vert;
-      t->h = ls_length (&t->s) * this->horiz;
-    }
-  else
-    delineate (this, t, 0);
+  delineate (this, t, false, width, height);
 }
 
 static void
 }
 
 static void
-ascii_text_draw (struct outp_driver *this, struct outp_text *t)
+ascii_text_draw (struct outp_driver *this, const struct outp_text *t)
 {
 {
-  /* FIXME: orientations not supported. */
-  assert (this->driver_open && this->page_open);
-  if (!(t->options & OUTP_T_HORZ))
-    {
-      struct outp_text temp;
-
-      temp.options = t->options;
-      temp.s = t->s;
-      temp.h = temp.v = 0;
-      temp.x = t->x / this->horiz;
-      temp.y = t->y / this->vert;
-      text_draw (this, &temp);
-      ascii_text_metrics (this, t);
-      
-      return;
-    }
-  delineate (this, t, 1);
+  assert (this->page_open);
+  delineate (this, t, true, NULL, NULL);
 }
 
 }
 
-static void
-text_draw (struct outp_driver *this, struct outp_text *t)
-{
-  struct ascii_driver_ext *ext = this->ext;
-  unsigned attr = ext->cur_font << 8;
-
-  int x = t->x;
-  int y = t->y;
-
-  char *s = ls_c_str (&t->s);
-
-  /* Expand the line with the assumption that S takes up LEN character
-     spaces (sometimes it takes up less). */
-  int min_len;
-
-  assert (this->driver_open && this->page_open);
-  switch (t->options & OUTP_T_JUST_MASK)
-    {
-    case OUTP_T_JUST_LEFT:
-      break;
-    case OUTP_T_JUST_CENTER:
-      x -= (t->h - t->w) / 2;  /* fall through */
-    case OUTP_T_JUST_RIGHT:
-      x += (t->h - t->w);
-      break;
-    default:
-      assert (0);
-    }
-
-  if (!(t->y < ext->l && x < ext->w))
-    return;
-  min_len = min (x + ls_length (&t->s), ext->w);
-  if (ext->lines[t->y].char_cnt < min_len)
-    expand_line (ext, t->y, min_len);
-
-  {
-    int len = ls_length (&t->s);
-
-    if (len + x > ext->w)
-      len = ext->w - x;
-    while (len--)
-      ext->lines[y].chars[x++] = *s++ | attr;
-  }
-}
 \f
 /* ascii_close_page () and support routines. */
 
 \f
 /* ascii_close_page () and support routines. */
 
-#define LINE_BUF_SIZE 1024
-static char *line_buf;
-static char *line_p;
-
-static inline int
-commit_line_buf (struct outp_driver *this)
-{
-  struct ascii_driver_ext *x = this->ext;
-  
-  if ((int) fwrite (line_buf, 1, line_p - line_buf, x->file.file)
-      < line_p - line_buf)
-    {
-      msg (ME, _("Writing `%s': %s"), x->file.filename, strerror (errno));
-      return 0;
-    }
-
-  line_p = line_buf;
-  return 1;
-}
-
-/* Writes everything from BP to EP exclusive into line_buf, or to
-   THIS->output if line_buf overflows. */
-static inline void
-output_string (struct outp_driver *this, const char *bp, const char *ep)
-{
-  if (LINE_BUF_SIZE - (line_p - line_buf) >= ep - bp)
-    {
-      memcpy (line_p, bp, ep - bp);
-      line_p += ep - bp;
-    }
-  else
-    while (bp < ep)
-      {
-       if (LINE_BUF_SIZE - (line_p - line_buf) <= 1 && !commit_line_buf (this))
-         return;
-       *line_p++ = *bp++;
-      }
-}
-
-/* Writes everything from BP to EP exclusive into line_buf, or to
-   THIS->output if line_buf overflows.  Returns 1 if additional passes
-   over the line are required.  FIXME: probably could do a lot of
-   optimization here. */
-static inline int
-output_shorts (struct outp_driver *this,
-              const unsigned short *bp, const unsigned short *ep)
+/* Writes the LENGTH characters in S to OUT.  */
+static void
+output_line (struct outp_driver *this, const struct line *line,
+             struct string *out)
 {
   struct ascii_driver_ext *ext = this->ext;
 {
   struct ascii_driver_ext *ext = this->ext;
-  size_t remaining = LINE_BUF_SIZE - (line_p - line_buf);
-  int result = 0;
+  const unsigned short *s = line->chars;
+  size_t length;
 
 
-  for (; bp < ep; bp++)
-    {
-      if (*bp & 0x800)
-       {
-         struct fixed_string *box = &ext->box[*bp & 0xff];
-         size_t len = ls_length (box);
-
-         if (remaining >= len)
-           {
-             memcpy (line_p, ls_c_str (box), len);
-             line_p += len;
-             remaining -= len;
-           }
-         else
-           {
-             if (!commit_line_buf (this))
-               return 0;
-             output_string (this, ls_c_str (box), ls_end (box));
-             remaining = LINE_BUF_SIZE - (line_p - line_buf);
-           }
-       }
-      else if (*bp & 0x0300)
-       {
-         struct fixed_string *on;
-         char buf[5];
-         int len;
-
-         switch (*bp & 0x0300)
-           {
-           case OUTP_F_I << 8:
-             on = &ext->fonts[FSTY_ON | FSTY_ITALIC];
-             break;
-           case OUTP_F_B << 8:
-             on = &ext->fonts[FSTY_ON | FSTY_BOLD];
-             break;
-           case OUTP_F_BI << 8:
-             on = &ext->fonts[FSTY_ON | FSTY_BOLD_ITALIC];
-             break;
-           default:
-             assert (0);
-              abort ();
-           }
-         if (!on)
-           {
-             if (ext->overstrike_style == OVS_SINGLE)
-               switch (*bp & 0x0300)
-                 {
-                 case OUTP_F_I << 8:
-                   buf[0] = '_';
-                   buf[1] = '\b';
-                   buf[2] = *bp;
-                   len = 3;
-                   break;
-                 case OUTP_F_B << 8:
-                   buf[0] = *bp;
-                   buf[1] = '\b';
-                   buf[2] = *bp;
-                   len = 3;
-                   break;
-                 case OUTP_F_BI << 8:
-                   buf[0] = '_';
-                   buf[1] = '\b';
-                   buf[2] = *bp;
-                   buf[3] = '\b';
-                   buf[4] = *bp;
-                   len = 5;
-                   break;
-                 default:
-                   assert (0);
-                    abort ();
-                 }
-             else
-               {
-                 buf[0] = *bp;
-                 result = len = 1;
-               }
-           }
-         else
-           {
-             buf[0] = *bp;
-             len = 1;
-           }
-         output_string (this, buf, &buf[len]);
-       }
-      else if (remaining)
-       {
-         *line_p++ = *bp;
-         remaining--;
-       }
-      else
-       {
-         if (!commit_line_buf (this))
-           return 0;
-         remaining = LINE_BUF_SIZE - (line_p - line_buf);
-         *line_p++ = *bp;
-       }
-    }
-
-  return result;
-}
-
-/* Writes CH into line_buf N times, or to THIS->output if line_buf
-   overflows. */
-static inline void
-output_char (struct outp_driver *this, int n, char ch)
-{
-  if (LINE_BUF_SIZE - (line_p - line_buf) >= n)
-    {
-      memset (line_p, ch, n);
-      line_p += n;
-    }
-  else
-    while (n--)
+  for (length = line->char_cnt; length-- > 0; s++)
+    if (*s & ATTR_BOX)
+      ds_puts (out, ext->box[*s & 0xff]);
+    else
       {
       {
-       if (LINE_BUF_SIZE - (line_p - line_buf) <= 1 && !commit_line_buf (this))
-         return;
-       *line_p++ = ch;
+        if (*s & ATTR_EMPHASIS) 
+          {
+            if (ext->emphasis == EMPH_BOLD)
+              {
+                ds_putc (out, *s);
+                ds_putc (out, '\b'); 
+              }
+            else if (ext->emphasis == EMPH_UNDERLINE)
+              ds_puts (out, "_\b"); 
+          }
+        ds_putc (out, *s);
       }
 }
 
       }
 }
 
-/* Advance the carriage from column 0 to the left margin. */
 static void
 static void
-advance_to_left_margin (struct outp_driver *this)
+append_lr_justified (struct string *out, int width,
+                     const char *left, const char *right)
 {
 {
-  struct ascii_driver_ext *ext = this->ext;
-  int margin;
-
-  margin = ext->left_margin;
-  if (margin == 0)
-    return;
-  if (ext->tab_width && margin >= ext->tab_width)
+  ds_putc_multiple (out, ' ', width);
+  if (left != NULL) 
     {
     {
-      output_char (this, margin / ext->tab_width, '\t');
-      margin %= ext->tab_width;
+      size_t length = MIN (strlen (left), width);
+      memcpy (ds_end (out) - width, left, length); 
     }
     }
-  if (margin)
-    output_char (this, margin, ' ');
-}
-
-/* Move the output file carriage N_CHARS left, to the left margin. */
-static void
-return_carriage (struct outp_driver *this, int n_chars)
-{
-  struct ascii_driver_ext *ext = this->ext;
-
-  switch (ext->carriage_return_style)
+  if (right != NULL)
     {
     {
-    case CRS_BS:
-      output_char (this, n_chars, '\b');
-      break;
-    case CRS_CR:
-      output_char (this, 1, '\r');
-      advance_to_left_margin (this);
-      break;
-    default:
-      assert (0);
-      abort ();
+      size_t length = MIN (strlen (right), width);
+      memcpy (ds_end (out) - length, right, length);
     }
     }
+  ds_putc (out, '\n');
 }
 
 }
 
-/* Writes COUNT lines from the line buffer in THIS, starting at line
-   number FIRST. */
 static void
 static void
-output_lines (struct outp_driver *this, int first, int count)
+dump_output (struct outp_driver *this, struct string *out) 
 {
 {
-  struct ascii_driver_ext *ext = this->ext;
-  int line_num;
-
-  struct fixed_string *newline = &ext->ops[OPS_NEWLINE];
-
-  int n_chars;
-  int n_passes;
-
-  if (NULL == ext->file.file)
-    return;
-
-  /* Iterate over all the lines to be output. */
-  for (line_num = first; line_num < first + count; line_num++)
-    {
-      struct line *line = &ext->lines[line_num];
-      unsigned short *p = line->chars;
-      unsigned short *end_p = p + line->char_cnt;
-      unsigned short *bp, *ep;
-      unsigned short attr = 0;
-
-      assert (end_p >= p);
-
-      /* Squeeze multiple blank lines into a single blank line if
-         requested. */
-      if (ext->squeeze_blank_lines
-          && line_num > first
-          && ext->lines[line_num].char_cnt == 0
-          && ext->lines[line_num - 1].char_cnt == 0)
-        continue;
-
-      /* Output every character in the line in the appropriate
-         manner. */
-      n_passes = 1;
-      bp = ep = p;
-      n_chars = 0;
-      advance_to_left_margin (this);
-      for (;;)                 
-       {
-         while (ep < end_p && attr == (*ep & 0x0300))
-           ep++;
-         if (output_shorts (this, bp, ep))
-           n_passes = 2;
-         n_chars += ep - bp;
-         bp = ep;
-
-         if (bp >= end_p)
-           break;
-
-         /* Turn off old font. */
-         if (attr != (OUTP_F_R << 8))
-           {
-             struct fixed_string *off;
-
-             switch (attr)
-               {
-               case OUTP_F_I << 8:
-                 off = &ext->fonts[FSTY_OFF | FSTY_ITALIC];
-                 break;
-               case OUTP_F_B << 8:
-                 off = &ext->fonts[FSTY_OFF | FSTY_BOLD];
-                 break;
-               case OUTP_F_BI << 8:
-                 off = &ext->fonts[FSTY_OFF | FSTY_BOLD_ITALIC];
-                 break;
-               default:
-                 assert (0);
-                  abort ();
-               }
-             if (off)
-               output_string (this, ls_c_str (off), ls_end (off));
-           }
-
-         /* Turn on new font. */
-         attr = (*bp & 0x0300);
-         if (attr != (OUTP_F_R << 8))
-           {
-             struct fixed_string *on;
-
-             switch (attr)
-               {
-               case OUTP_F_I << 8:
-                 on = &ext->fonts[FSTY_ON | FSTY_ITALIC];
-                 break;
-               case OUTP_F_B << 8:
-                 on = &ext->fonts[FSTY_ON | FSTY_BOLD];
-                 break;
-               case OUTP_F_BI << 8:
-                 on = &ext->fonts[FSTY_ON | FSTY_BOLD_ITALIC];
-                 break;
-               default:
-                 assert (0);
-                  abort ();
-               }
-             if (on)
-               output_string (this, ls_c_str (on), ls_end (on));
-           }
-
-         ep = bp + 1;
-       }
-      if (n_passes > 1)
-       {
-         char ch;
-
-         return_carriage (this, n_chars);
-         n_chars = 0;
-         bp = ep = p;
-         for (;;)
-           {
-             while (ep < end_p && (*ep & 0x0300) == (OUTP_F_R << 8))
-               ep++;
-             if (ep >= end_p)
-               break;
-             output_char (this, ep - bp, ' ');
-
-             switch (*ep & 0x0300)
-               {
-               case OUTP_F_I << 8:
-                 ch = '_';
-                 break;
-               case OUTP_F_B << 8:
-                 ch = *ep;
-                 break;
-               case OUTP_F_BI << 8:
-                 ch = *ep;
-                 n_passes = 3;
-                 break;
-                default:
-                  assert (0);
-                  abort ();
-               }
-             output_char (this, 1, ch);
-             n_chars += ep - bp + 1;
-             bp = ep + 1;
-             ep = bp;
-           }
-       }
-      if (n_passes > 2)
-       {
-         return_carriage (this, n_chars);
-         bp = ep = p;
-         for (;;)
-           {
-             while (ep < end_p && (*ep & 0x0300) != (OUTP_F_BI << 8))
-               ep++;
-             if (ep >= end_p)
-               break;
-             output_char (this, ep - bp, ' ');
-             output_char (this, 1, '_');
-             bp = ep + 1;
-             ep = bp;
-           }
-       }
-
-      output_string (this, ls_c_str (newline), ls_end (newline));
-    }
+  struct ascii_driver_ext *x = this->ext;
+  fwrite (ds_data (out), ds_length (out), 1, x->file);
+  ds_clear (out);
 }
 
 }
 
-
-static int
+static void
 ascii_close_page (struct outp_driver *this)
 {
 ascii_close_page (struct outp_driver *this)
 {
-  static int s_len;
-
   struct ascii_driver_ext *x = this->ext;
   struct ascii_driver_ext *x = this->ext;
-  int nl_len, ff_len, total_len;
-  char *cp;
-  int i;
-
-  assert (this->driver_open && this->page_open);
-  
-  if (!line_buf)
-    line_buf = xmalloc (LINE_BUF_SIZE);
-  line_p = line_buf;
-
-  nl_len = ls_length (&x->ops[OPS_NEWLINE]);
-  if (x->top_margin)
-    {
-      total_len = x->top_margin * nl_len;
-      if (s_len < total_len)
-       {
-         s_len = total_len;
-         s = xrealloc (s, s_len);
-       }
-      for (cp = s, i = 0; i < x->top_margin; i++)
-       {
-         memcpy (cp, ls_c_str (&x->ops[OPS_NEWLINE]), nl_len);
-         cp += nl_len;
-       }
-      output_string (this, s, &s[total_len]);
-    }
+  struct string out;
+  int line_num;
+  ds_init (&out, 128);
+  ds_putc_multiple (&out, '\n', x->top_margin);
   if (x->headers)
     {
   if (x->headers)
     {
-      int len;
-
-      total_len = nl_len + x->w;
-      if (s_len < total_len + 1)
-       {
-         s_len = total_len + 1;
-         s = xrealloc (s, s_len);
-       }
-      
-      memset (s, ' ', x->w);
-
-      {
-       char temp[40];
-
-       snprintf (temp, 80, _("%s - Page %d"), get_start_date (),
-                  x->page_number);
-       memcpy (&s[x->w - strlen (temp)], temp, strlen (temp));
-      }
-
-      if (outp_title && outp_subtitle)
-       {
-         len = min ((int) strlen (outp_title), x->w);
-         memcpy (s, outp_title, len);
-       }
-      memcpy (&s[x->w], ls_c_str (&x->ops[OPS_NEWLINE]), nl_len);
-      output_string (this, s, &s[total_len]);
-
-      memset (s, ' ', x->w);
-      len = strlen (version) + 3 + strlen (host_system);
-      if (len < x->w)
-       sprintf (&s[x->w - len], "%s - %s" , version, host_system);
-      if (outp_subtitle || outp_title)
-       {
-         char *string = outp_subtitle ? outp_subtitle : outp_title;
-         len = min ((int) strlen (string), x->w);
-         memcpy (s, string, len);
-       }
-      memcpy (&s[x->w], ls_c_str (&x->ops[OPS_NEWLINE]), nl_len);
-      output_string (this, s, &s[total_len]);
-      output_string (this, &s[x->w], &s[total_len]);
-    }
-  if (line_p != line_buf && !commit_line_buf (this))
-    return 0;
-
-  output_lines (this, 0, x->l);
-
-  ff_len = ls_length (&x->ops[OPS_FORMFEED]);
-  total_len = x->bottom_margin * nl_len + ff_len;
-  if (s_len < total_len)
-    s = xrealloc (s, total_len);
-  for (cp = s, i = 0; i < x->bottom_margin; i++)
-    {
-      memcpy (cp, ls_c_str (&x->ops[OPS_NEWLINE]), nl_len);
-      cp += nl_len;
+      char *r1, *r2;
+      r1 = xasprintf (_("%s - Page %d"), get_start_date (), x->page_number);
+      r2 = xasprintf ("%s - %s" , version, host_system);
+      append_lr_justified (&out, this->width, outp_title, r1);
+      append_lr_justified (&out, this->width, outp_subtitle, r2);
+      ds_putc (&out, '\n');
+      free (r1);
+      free (r2);
+    }
+  dump_output (this, &out);
+  for (line_num = 0; line_num < this->length; line_num++)
+    {
+      /* Squeeze multiple blank lines into a single blank line if
+         requested. */
+      if (x->squeeze_blank_lines) 
+        {
+          if (line_num >= x->line_cap)
+            break;
+          if (line_num > 0
+              && x->lines[line_num].char_cnt == 0
+              && x->lines[line_num - 1].char_cnt == 0)
+            continue; 
+        }
+      if (line_num < x->line_cap) 
+        output_line (this, &x->lines[line_num], &out); 
+      ds_putc (&out, '\n');
+      dump_output (this, &out);
     }
     }
-  memcpy (cp, ls_c_str (&x->ops[OPS_FORMFEED]), ff_len);
-  if ( x->paginate ) 
-         output_string (this, s, &s[total_len]);
-
-  if (line_p != line_buf && !commit_line_buf (this))
-    return 0;
+  ds_putc_multiple (&out, '\n', x->bottom_margin);
+  if (x->paginate) 
+    ds_putc (&out, '\f');
 
 
-  this->page_open = 0;
-  return 1;
+  dump_output (this, &out);
+  ds_destroy (&out);
 }
 
 }
 
-
-
 static void
 static void
-ascii_chart_initialise(struct outp_driver *d UNUSED, struct chart *ch )
+ascii_chart_initialise (struct outp_driver *d UNUSED, struct chart *ch)
 {
 {
-  msg(MW, _("Charts are unsupported with ascii drivers."));
+  error (0, 0, _("ascii: charts are unsupported by this driver"));
   ch->lp = 0;
 }
 
 static void 
   ch->lp = 0;
 }
 
 static void 
-ascii_chart_finalise(struct outp_driver *d UNUSED, struct chart *ch UNUSED)
+ascii_chart_finalise (struct outp_driver *d UNUSED, struct chart *ch UNUSED)
 {
   
 }
 {
   
 }
@@ -1652,15 +738,8 @@ struct outp_class ascii_class =
 {
   "ascii",
   0,
 {
   "ascii",
   0,
-  0,
-
-  ascii_open_global,
-  ascii_close_global,
-  ascii_font_sizes,
 
 
-  ascii_preopen_driver,
-  ascii_option,
-  ascii_postopen_driver,
+  ascii_open_driver,
   ascii_close_driver,
 
   ascii_open_page,
   ascii_close_driver,
 
   ascii_open_page,
@@ -1668,22 +747,7 @@ struct outp_class ascii_class =
 
   NULL,
 
 
   NULL,
 
-  ascii_line_horz,
-  ascii_line_vert,
-  ascii_line_intersection,
-
-  ascii_box,
-  ascii_polyline_begin,
-  ascii_polyline_point,
-  ascii_polyline_end,
-
-  ascii_text_set_font_by_name,
-  ascii_text_set_font_by_position,
-  ascii_text_set_font_by_family,
-  ascii_text_get_font_name,
-  ascii_text_get_font_family,
-  ascii_text_set_size,
-  ascii_text_get_size,
+  ascii_line,
   ascii_text_metrics,
   ascii_text_draw,
 
   ascii_text_metrics,
   ascii_text_draw,
 
index 3c423203ace2c2d7763af3fb96a753b7471e35f5..4bb4780c90ea4883af5b960e5fe55f559f4afae8 100644 (file)
@@ -6,9 +6,9 @@ include $(top_srcdir)/src/output/charts/automake.mk
 noinst_LIBRARIES += src/output/liboutput.a 
 
 output_sources = \
 noinst_LIBRARIES += src/output/liboutput.a 
 
 output_sources = \
+       src/output/afm.c \
+       src/output/afm.h \
        src/output/ascii.c \
        src/output/ascii.c \
-       src/output/font.h \
-       src/output/groff-font.c \
        src/output/html.c \
        src/output/htmlP.h \
        src/output/output.c \
        src/output/html.c \
        src/output/htmlP.h \
        src/output/output.c \
diff --git a/src/output/font.h b/src/output/font.h
deleted file mode 100644 (file)
index a709667..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA. */
-
-#if !font_h
-#define font_h 1
-
-/* Possible ligatures. */
-#define LIG_ff  001
-#define LIG_ffi 002
-#define LIG_ffl 004
-#define LIG_fi  010
-#define LIG_fl  020
-
-/* Character type constants. */
-#define CTYP_NONE      000     /* Neither ascenders nor descenders. */
-#define CTYP_ASCENDER  001     /* Character has an ascender. */
-#define CTYP_DESCENDER 002     /* Character has a descender. */
-
-/* Font metrics for a single character.  */
-struct char_metrics
-  {
-    int code;                  /* Character code. */
-    int type;                  /* CTYP_* constants. */
-    int width;                 /* Width. */
-    int height;                        /* Height above baseline, never negative. */
-    int depth;                 /* Depth below baseline, never negative. */
-
-    /* These fields are not yet used, so to save memory, they are left
-       out. */
-#if 0
-    int italic_correction;     /* Italic correction. */
-    int left_italic_correction;        /* Left italic correction. */
-    int subscript_correction;  /* Subscript correction. */
-#endif
-  };
-
-/* Kerning for a pair of characters.  */
-struct kern_pair
-  {
-    int ch1;                   /* First character. */
-    int ch2;                   /* Second character. */
-    int adjust;                        /* Kern amount. */
-  };
-
-/* Font description.  */
-struct font_desc
-  {
-    /* Housekeeping data. */
-    struct pool *owner;                /* Containing pool. */
-    char *name;                        /* Font name.  FIXME: this field's
-                                  role is uncertain. */
-    char *filename;            /* Normalized filename. */
-
-    /* PostScript-specific courtesy data. */
-    char *internal_name;       /* Font internal name. */
-    char *encoding;            /* Name of encoding file. */
-
-    /* Basic font characteristics. */
-    int space_width;           /* Width of a space character. */
-    double slant;              /* Slant angle, in degrees of forward slant. */
-    unsigned ligatures;                /* Characters that have ligatures. */
-    int special;               /* 1=This is a special font that will be
-                                  searched when a character is not present in
-                                  another font. */
-    int ascent, descent;       /* Height above, below the baseline. */
-
-    /* First dereferencing level is font_char_name_to_index(NAME). */
-    /* Second dereferencing level. */
-    short *deref;              /* Each entry is an index into metric.
-                                  metric[deref[lookup(NAME)]] is the metric
-                                  for character with name NAME. */
-    int deref_size;            /* Number of spaces for entries in deref. */
-
-    /* Third dereferencing level. */
-    struct char_metrics **metric;      /* Metrics for font characters. */
-    int metric_size;           /* Number of spaces for entries in metric. */
-    int metric_used;           /* Number of spaces used in metric. */
-
-    /* Kern pairs. */
-    struct kern_pair *kern;    /* Hash table for kerns. */
-    int kern_size;             /* Number of spaces for kerns in kern. */
-    int *kern_size_p;          /* Next larger hash table size. */
-    int kern_used;             /* Number of used spaces in kern. */
-    int kern_max_used;         /* Max number used before rehashing. */
-  };
-
-/* Index into deref[] of character with name "space". */
-extern int space_index;
-
-/* A set of fonts. */
-struct font_set
-  {
-    struct font_set *next, *prev;      /* Next, previous in chain. */
-    struct font_desc *font;            /* Current font. */
-  };
-
-/* Functions to work with any font. */
-#define destroy_font(FONT)                     \
-       pool_destroy (FONT->owner)
-
-int font_char_name_to_index (const char *);
-struct char_metrics *font_get_char_metrics (const struct font_desc *font,
-                                           int ch);
-int font_get_kern_adjust (const struct font_desc *font, int ch1, int ch2);
-
-/* groff fonts. */
-struct groff_device_info
-  {
-    /* See groff_font man page. */
-    int res, horiz, vert;
-    int size_scale, unit_width;
-    int (*sizes)[2], n_sizes;
-    char *font_name[4];                /* Names of 4 default fonts. */
-    char *family;              /* Name of default font family. */
-  };
-
-struct outp_driver;
-struct font_desc *groff_read_font (const char *fn);
-struct font_desc *groff_find_font (const char *dev, const char *name);
-int groff_read_DESC (const char *dev_name, struct groff_device_info * dev);
-void groff_init (void);
-void groff_done (void);
-
-struct font_desc *default_font (void);
-
-#endif /* font_h */
diff --git a/src/output/groff-font.c b/src/output/groff-font.c
deleted file mode 100644 (file)
index 4817084..0000000
+++ /dev/null
@@ -1,1032 +0,0 @@
-/* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA. */
-
-#include <config.h>
-#include "font.h"
-#include <libpspp/message.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <libpspp/alloc.h>
-#include <libpspp/compiler.h>
-#include <libpspp/message.h>
-#include <data/filename.h>
-#include "getline.h"
-#include <libpspp/hash.h>
-#include "intprops.h"
-#include <libpspp/pool.h>
-#include <libpspp/str.h>
-#include <libpspp/version.h>
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
-int font_number_to_index (int);
-
-int space_index;
-
-static int font_msg (int, const char *,...)
-     PRINTF_FORMAT (2, 3);
-static void scan_badchars (char *, int);
-static void dup_char_metric (struct font_desc * font, int dest, int src);
-static void add_char_metric (struct font_desc * font, struct char_metrics *metrics,
-                            int code);
-static void add_kern (struct font_desc * font, int ch1, int ch2, int adjust);
-
-/* Typical whitespace characters for tokenizing. */
-static const char whitespace[] = " \t\n\r\v";
-
-/* Some notes on the groff_font manpage:
-
-   DESC file format: A typical PostScript `res' would be 72000, with
-   `hor' and `vert' set to 1 to indicate that all those positions are
-   valid.  `sizescale' of 1000 would indicate that a scaled point is
-   1/1000 of a point (which is 1/72000 of an inch, the same as the
-   number of machine units per inch indicated on `res').  `unitwidth'
-   of 1000 would indicate that font files are set up for fonts with
-   point size of 1000 scaled points, which would equal 1/72 inch or 1
-   point (this would tell Groff's postprocessor that it needs to scale
-   the font 12 times larger to get a 12-point font). */
-
-/* Reads a Groff font description file and converts it to a usable
-   binary format in memory.  Installs the binary format in the global
-   font table.  See groff_font for a description of the font
-   description format supported.  Returns nonzero on success. */
-struct font_desc *
-groff_read_font (const char *fn)
-{
-  struct char_metrics *metrics;
-
-  /* Pool created for font, font being created, font file. */
-  struct pool *font_pool = NULL;
-  struct font_desc *font = NULL;
-  FILE *f = NULL;
-
-  /* Current line, size of line buffer, length of line. */
-  char *line = NULL;
-  size_t size;
-  int len;
-
-  /* Tokenization saved pointer. */
-  char *sp;
-  
-  /* First token on line. */
-  char *key;
-
-  /* 0=kernpairs section, 1=charset section. */
-  int charset = 0;
-
-  /* Index for previous line. */
-  int prev_index = -1;
-
-  /* Current location in file, used for error reporting. */
-  struct file_locator where;
-
-#ifdef unix
-  fn = fn_tilde_expand (fn);
-#endif
-
-  msg (VM (1), _("%s: Opening Groff font file..."), fn);
-
-  where.filename = fn;
-  where.line_number = 1;
-  err_push_file_locator (&where);
-
-  f = fopen (fn, "r");
-  if (!f)
-    goto file_lossage;
-
-  font_pool = pool_create ();
-  font = pool_alloc (font_pool, sizeof *font);
-  font->owner = font_pool;
-  font->name = NULL;
-  font->internal_name = NULL;
-  font->encoding = NULL;
-  font->space_width = 0;
-  font->slant = 0.0;
-  font->ligatures = 0;
-  font->special = 0;
-  font->deref = NULL;
-  font->deref_size = 0;
-  font->metric = NULL;
-  font->metric_size = 0;
-  font->metric_used = 0;
-  font->kern = NULL;
-  font->kern_size = 8;
-  font->kern_used = 0;
-  font->kern_max_used = 0;
-
-  /* Parses first section of font file. */
-  for (;;)
-    {
-      /* Location of '#' in line. */
-      char *p;
-
-      len = getline (&line, &size, f);
-      if (len == -1)
-       break;
-      
-      scan_badchars (line, len);
-      p = strchr (line, '#');
-      if (p)
-       *p = '\0';              /* Reject comments. */
-
-      key = strtok_r (line, whitespace, &sp);
-      if (!key)
-       goto next_iteration;
-
-      if (!strcmp (key, "internalname"))
-       {
-         font->internal_name = strtok_r (NULL, whitespace, &sp);
-         if (font->internal_name == NULL)
-           {
-             font_msg (SE, _("Missing font name."));
-             goto lose;
-           }
-         font->internal_name = pool_strdup (font_pool, font->internal_name);
-       }
-      else if (!strcmp (key, "encoding"))
-       {
-         font->encoding = strtok_r (NULL, whitespace, &sp);
-         if (font->encoding == NULL)
-           {
-             font_msg (SE, _("Missing encoding filename."));
-             goto lose;
-           }
-         font->encoding = pool_strdup (font_pool, font->encoding);
-       }
-      else if (!strcmp (key, "spacewidth"))
-       {
-         char *n = strtok_r (NULL, whitespace, &sp);
-         char *tail;
-         if (n)
-           font->space_width = strtol (n, &tail, 10);
-         if (n == NULL || tail == n)
-           {
-             font_msg (SE, _("Bad spacewidth value."));
-             goto lose;
-           }
-       }
-      else if (!strcmp (key, "slant"))
-       {
-         char *n = strtok_r (NULL, whitespace, &sp);
-         char *tail;
-         if (n)
-           font->slant = strtod (n, &tail);
-         if (n == NULL || tail == n)
-           {
-             font_msg (SE, _("Bad slant value."));
-             goto lose;
-           }
-       }
-      else if (!strcmp (key, "ligatures"))
-       {
-         char *lig;
-
-         for (;;)
-           {
-             lig = strtok_r (NULL, whitespace, &sp);
-             if (!lig || !strcmp (lig, "0"))
-               break;
-             else if (!strcmp (lig, "ff"))
-               font->ligatures |= LIG_ff;
-             else if (!strcmp (lig, "ffi"))
-               font->ligatures |= LIG_ffi;
-             else if (!strcmp (lig, "ffl"))
-               font->ligatures |= LIG_ffl;
-             else if (!strcmp (lig, "fi"))
-               font->ligatures |= LIG_fi;
-             else if (!strcmp (lig, "fl"))
-               font->ligatures |= LIG_fl;
-             else
-               {
-                 font_msg (SE, _("Unknown ligature `%s'."), lig);
-                 goto lose;
-               }
-           }
-       }
-      else if (!strcmp (key, "special"))
-       font->special = 1;
-      else if (!strcmp (key, "charset") || !strcmp (key, "kernpairs"))
-       break;
-
-      where.line_number++;
-    }
-  if (ferror (f))
-    goto file_lossage;
-
-  /* Parses second section of font file (metrics & kerning data). */
-  do
-    {
-      key = strtok_r (line, whitespace, &sp);
-      if (!key)
-       goto next_iteration;
-
-      if (!strcmp (key, "charset"))
-       charset = 1;
-      else if (!strcmp (key, "kernpairs"))
-       charset = 0;
-      else if (charset)
-       {
-         struct char_metrics *metrics = pool_alloc (font_pool,
-                                                    sizeof *metrics);
-         char *m, *type, *code, *tail;
-
-         m = strtok_r (NULL, whitespace, &sp);
-         if (!m)
-           {
-             font_msg (SE, _("Unexpected end of line reading character "
-                             "set."));
-             goto lose;
-           }
-         if (!strcmp (m, "\""))
-           {
-             if (!prev_index)
-               {
-                 font_msg (SE, _("Can't use ditto mark for first character."));
-                 goto lose;
-               }
-             if (!strcmp (key, "---"))
-               {
-                 font_msg (SE, _("Can't ditto into an unnamed character."));
-                 goto lose;
-               }
-             dup_char_metric (font, font_char_name_to_index (key), prev_index);
-             where.line_number++;
-             goto next_iteration;
-           }
-
-         if (m)
-           {
-             metrics->code = metrics->width
-               = metrics->height = metrics->depth = 0;
-           }
-         
-         if (m == NULL || 1 > sscanf (m, "%d,%d,%d", &metrics->width,
-                                      &metrics->height, &metrics->depth))
-           {
-             font_msg (SE, _("Missing metrics for character `%s'."), key);
-             goto lose;
-           }
-
-         type = strtok_r (NULL, whitespace, &sp);
-         if (type)
-           metrics->type = strtol (type, &tail, 10);
-         if (!type || tail == type)
-           {
-             font_msg (SE, _("Missing type for character `%s'."), key);
-             goto lose;
-           }
-
-         code = strtok_r (NULL, whitespace, &sp);
-         if (code)
-           metrics->code = strtol (code, &tail, 0);
-         if (tail == code)
-           {
-             font_msg (SE, _("Missing code for character `%s'."), key);
-             goto lose;
-           }
-
-         if (strcmp (key, "---"))
-           prev_index = font_char_name_to_index (key);
-         else
-           prev_index = font_number_to_index (metrics->code);
-         add_char_metric (font, metrics, prev_index);
-       }
-      else
-       {
-         char *c1 = key;
-         char *c2 = strtok_r (NULL, whitespace, &sp);
-         char *n, *tail;
-         int adjust;
-
-         if (c2 == NULL)
-           {
-             font_msg (SE, _("Malformed kernpair."));
-             goto lose;
-           }
-
-         n = strtok_r (NULL, whitespace, &sp);
-         if (!n)
-           {
-             font_msg (SE, _("Unexpected end of line reading kernpairs."));
-             goto lose;
-           }
-         adjust = strtol (n, &tail, 10);
-         if (tail == n || *tail)
-           {
-             font_msg (SE, _("Bad kern value."));
-             goto lose;
-           }
-         add_kern (font, font_char_name_to_index (c1),
-                   font_char_name_to_index (c2), adjust);
-       }
-
-    next_iteration:
-      where.line_number++;
-
-      len = getline (&line, &size, f);
-    }
-  while (len != -1);
-  
-  if (ferror (f))
-    goto file_lossage;
-  if (fclose (f) == EOF)
-    {
-      f = NULL;
-      goto file_lossage;
-    }
-  free (line);
-#ifdef unix
-  free ((char *) fn);
-#endif
-
-  /* Get font ascent and descent. */
-  metrics = font_get_char_metrics (font, font_char_name_to_index ("d"));
-  font->ascent = metrics ? metrics->height : 0;
-  metrics = font_get_char_metrics (font, font_char_name_to_index ("p"));
-  font->descent = metrics ? metrics->depth : 0;
-
-  msg (VM (2), _("Font read successfully with internal name %s."),
-       font->internal_name == NULL ? "<none>" : font->internal_name);
-  
-  err_pop_file_locator (&where);
-
-  return font;
-
-  /* Come here on a file error. */
-file_lossage:
-  msg (ME, "%s: %s", fn, strerror (errno));
-
-  /* Come here on any error. */
-lose:
-  if (f != NULL)
-    fclose (f);
-  pool_destroy (font_pool);
-#ifdef unix
-  free ((char *) fn);
-#endif
-  err_pop_file_locator (&where);
-
-  msg (VM (1), _("Error reading font."));
-  return NULL;
-}
-
-/* Prints a font error on stderr. */
-static int
-font_msg (int class, const char *format,...)
-{
-  struct error error;
-  va_list args;
-
-  error.class = class;
-  err_location (&error.where);
-  error.title = _("installation error: Groff font error: ");
-
-  va_start (args, format);
-  err_vmsg (&error, format, args);
-  va_end (args);
-
-  return 0;
-}
-
-/* Scans string LINE of length LEN (not incl. null terminator) for bad
-   characters, converts to spaces; reports warnings on file FN. */
-static void
-scan_badchars (char *line, int len)
-{
-  char *cp = line;
-
-  /* Same bad characters as Groff. */
-  static unsigned char badchars[32] =
-  {
-    0x01, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  };
-
-  for (; len--; cp++) 
-    {
-      int c = (unsigned char) *cp;
-      if (badchars[c >> 3] & (1 << (c & 7)))
-        {
-          font_msg (SE, _("Bad character \\%3o."), *cp);
-          *cp = ' ';
-        } 
-    }
-}
-\f
-/* Character name hashing. */
-
-/* Associates a character index with a character name. */
-struct index_hash
-  {
-    char *name;
-    int index;
-  };
-
-/* Character index hash table. */
-static struct
-  {
-    int size;                  /* Size of table (must be power of 2). */
-    int used;                  /* Number of full entries. */
-    int next_index;            /* Next index to allocate. */
-    struct index_hash *tab;    /* Hash table proper. */
-    struct pool *ar;           /* Pool for names. */
-  }
-hash;
-
-void
-groff_init (void)
-{
-  space_index = font_char_name_to_index ("space");
-}
-
-void
-groff_done (void)
-{
-  free (hash.tab) ;
-  pool_destroy(hash.ar);
-}
-
-
-/* Searches for NAME in the global character code table, returns the
-   index if found; otherwise inserts NAME and returns the new
-   index. */
-int
-font_char_name_to_index (const char *name)
-{
-  int i;
-
-  if (name[0] == ' ')
-    return space_index;
-  if (name[0] == '\0' || name[1] == '\0')
-    return name[0];
-  if (0 == strncmp (name, "char", 4))
-    {
-      char *tail;
-      int x = strtol (name + 4, &tail, 10);
-      if (tail != name + 4 && *tail == 0 && x >= 0 && x <= 255)
-       return x;
-    }
-
-  if (!hash.tab)
-    {
-      hash.size = 128;
-      hash.used = 0;
-      hash.next_index = 256;
-      hash.tab = xnmalloc (hash.size, sizeof *hash.tab);
-      hash.ar = pool_create ();
-      for (i = 0; i < hash.size; i++)
-       hash.tab[i].name = NULL;
-    }
-
-  for (i = hsh_hash_string (name) & (hash.size - 1); hash.tab[i].name; )
-    {
-      if (!strcmp (hash.tab[i].name, name))
-       return hash.tab[i].index;
-      if (++i >= hash.size)
-       i = 0;
-    }
-
-  hash.used++;
-  if (hash.used >= hash.size / 2)
-    {
-      struct index_hash *old_tab = hash.tab;
-      int old_size = hash.size;
-      int i, j;
-
-      hash.size *= 2;
-      hash.tab = xnmalloc (hash.size, sizeof *hash.tab);
-      for (i = 0; i < hash.size; i++)
-       hash.tab[i].name = NULL;
-      for (i = 0; i < old_size; i++)
-       if (old_tab[i].name)
-         {
-           for (j = hsh_hash_string (old_tab[i].name) & (hash.size - 1);
-                 hash.tab[j].name;)
-             if (++j >= hash.size)
-               j = 0;
-           hash.tab[j] = old_tab[i];
-         }
-      free (old_tab);
-    }
-
-  hash.tab[i].name = pool_strdup (hash.ar, name);
-  hash.tab[i].index = hash.next_index;
-  return hash.next_index++;
-}
-
-/* Returns an index for a character that has only a code, not a
-   name. */
-int
-font_number_to_index (int x)
-{
-  char name[INT_STRLEN_BOUND (x) + 2];
-
-  /* Note that space is the only character that can't appear in a
-     character name.  That makes it an excellent choice for a name
-     that won't conflict. */
-  sprintf (name, " %d", x);
-  return font_char_name_to_index (name);
-}
-\f
-/* Font character metric entries. */
-
-/* Ensures room for at least MIN_SIZE metric indexes in deref of
-   FONT. */
-static void
-check_deref_space (struct font_desc *font, int min_size)
-{
-  if (min_size >= font->deref_size)
-    {
-      int i = font->deref_size;
-
-      font->deref_size = min_size + 16;
-      if (font->deref_size < 256)
-       font->deref_size = 256;
-      font->deref = pool_nrealloc (font->owner, font->deref,
-                                   font->deref_size, sizeof *font->deref);
-      for (; i < font->deref_size; i++)
-       font->deref[i] = -1;
-    }
-}
-
-/* Inserts METRICS for character with code CODE into FONT. */
-static void
-add_char_metric (struct font_desc *font, struct char_metrics *metrics, int code)
-{
-  check_deref_space (font, code);
-  if (font->metric_used >= font->metric_size)
-    {
-      font->metric_size += 64;
-      font->metric = pool_nrealloc (font->owner, font->metric,
-                                    font->metric_size, sizeof *font->metric);
-    }
-  font->metric[font->metric_used] = metrics;
-  font->deref[code] = font->metric_used++;
-}
-
-/* Copies metric in FONT from character with code SRC to character
-   with code DEST. */
-static void
-dup_char_metric (struct font_desc *font, int dest, int src)
-{
-  check_deref_space (font, dest);
-  assert (font->deref[src] != -1);
-  font->deref[dest] = font->deref[src];
-}
-\f
-/* Kerning. */
-
-/* Returns a hash value for characters with codes CH1 and CH2. */
-#define hash_kern(CH1, CH2)                    \
-       ((unsigned) (((CH1) << 16) ^ (CH2)))
-
-/* Adds an ADJUST-size kern to FONT between characters with codes CH1
-   and CH2. */
-static void
-add_kern (struct font_desc *font, int ch1, int ch2, int adjust)
-{
-  int i;
-
-  if (font->kern_used >= font->kern_max_used)
-    {
-      struct kern_pair *old_kern = font->kern;
-      int old_kern_size = font->kern_size;
-      int j;
-
-      font->kern_size *= 2;
-      font->kern_max_used = font->kern_size / 2;
-      font->kern = pool_nmalloc (font->owner,
-                                 font->kern_size, sizeof *font->kern);
-      for (i = 0; i < font->kern_size; i++)
-       font->kern[i].ch1 = -1;
-
-      if (old_kern)
-        {
-          for (i = 0; i < old_kern_size; i++)
-            {
-              if (old_kern[i].ch1 == -1)
-                continue;
-
-              j = (hash_kern (old_kern[i].ch1, old_kern[i].ch2)
-                   & (font->kern_size - 1));
-              while (font->kern[j].ch1 != -1)
-                if (0 == j--)
-                  j = font->kern_size - 1;
-              font->kern[j] = old_kern[i];
-            }
-          pool_free (font->owner, old_kern);
-        }
-    }
-
-  for (i = hash_kern (ch1, ch2) & (font->kern_size - 1);
-       font->kern[i].ch1 != -1; )
-    if (0 == i--)
-      i = font->kern_size - 1;
-  font->kern[i].ch1 = ch1;
-  font->kern[i].ch2 = ch2;
-  font->kern[i].adjust = adjust;
-  font->kern_used++;
-}
-
-/* Finds a font file corresponding to font NAME for device DEV. */
-static char *
-find_font_file (const char *dev, const char *name)
-{
-  char *basename = xmalloc (3 + strlen (dev) + 1 + strlen (name) + 1);
-  char *cp;
-  char *filename;
-  char *path;
-
-  cp = stpcpy (basename, "dev");
-  cp = stpcpy (cp, dev);
-  *cp++ = DIR_SEPARATOR;
-  strcpy (cp, name);
-
-  /* Search order:
-     1. $STAT_GROFF_FONT_PATH
-     2. $GROFF_FONT_PATH
-     3. GROFF_FONT_PATH from pref.h
-     4. config_path
-   */
-  if ((path = getenv ("STAT_GROFF_FONT_PATH")) != NULL
-      && (filename = fn_search_path (basename, path, NULL)) != NULL)
-    goto win;
-
-  if ((path = getenv ("GROFF_FONT_PATH")) != NULL
-      && (filename = fn_search_path (basename, path, NULL)) != NULL)
-    goto win;
-
-  if ((filename = fn_search_path (basename, groff_font_path, NULL)) != NULL)
-    goto win;
-
-  if ((filename = fn_search_path (basename, config_path, NULL)) != NULL)
-    goto win;
-
-  msg (IE, _("Groff font error: Cannot find \"%s\"."), basename);
-
-win:
-  free (basename);
-  return filename;
-}
-
-/* Finds a font for device DEV with name NAME, reads it with
-   groff_read_font(), and returns the resultant font. */
-struct font_desc *
-groff_find_font (const char *dev, const char *name)
-{
-  char *filename = find_font_file (dev, name);
-  struct font_desc *fd;
-
-  if (!filename)
-    return NULL;
-  fd = groff_read_font (filename);
-  free (filename);
-  return fd;
-}
-
-/* Reads a DESC file for device DEV and sets the appropriate fields in
-   output driver *DRIVER, which must be previously allocated.  Returns
-   nonzero on success. */
-int
-groff_read_DESC (const char *dev_name, struct groff_device_info * dev)
-{
-  char *filename;              /* Full name of DESC file. */
-  FILE *f;                     /* DESC file. */
-
-  char *line = NULL;           /* Current line. */
-  int line_len;                        /* Number of chars in current line. */
-  size_t line_size = 0;                /* Number of chars allocated for line. */
-
-  char *token;                 /* strtok()'d token inside line. */
-
-  unsigned found = 0;          /* Bitmask showing what settings
-                                  have been encountered. */
-
-  int m_sizes = 0;             /* Number of int[2] items that
-                                  can fit in driver->sizes. */
-
-  char *sp;                    /* Tokenization string pointer. */
-  struct file_locator where;
-
-  int i;
-
-  dev->horiz = 1;
-  dev->vert = 1;
-  dev->size_scale = 1;
-  dev->n_sizes = 0;
-  dev->sizes = NULL;
-  dev->family = NULL;
-  for (i = 0; i < 4; i++)
-    dev->font_name[i] = NULL;
-
-  filename = find_font_file (dev_name, "DESC");
-  if (!filename)
-    return 0;
-
-  where.filename = filename;
-  where.line_number = 0;
-  err_push_file_locator (&where);
-
-  msg (VM (1), _("%s: Opening Groff description file..."), filename);
-  f = fopen (filename, "r");
-  if (!f)
-    goto file_lossage;
-
-  while ((line_len = getline (&line, &line_size, f)) != -1)
-    {
-      where.line_number++;
-
-      token = strtok_r (line, whitespace, &sp);
-      if (!token)
-       continue;
-
-      if (!strcmp (token, "sizes"))
-       {
-         if (found & 0x10000)
-           font_msg (SW, _("Multiple `sizes' declarations."));
-         for (;;)
-           {
-             char *tail;
-             int lower, upper;
-
-             for (;;)
-               {
-                 token = strtok_r (NULL, whitespace, &sp);
-                 if (token)
-                   break;
-
-                 where.line_number++;
-                 if ((line_len = getline (&line, &line_size, f)) != -1)
-                   {
-                     if (ferror (f))
-                       goto file_lossage;
-                     font_msg (SE, _("Unexpected end of file.  "
-                               "Missing 0 terminator to `sizes' command?"));
-                     goto lossage;
-                   }
-               }
-
-             if (!strcmp (token, "0"))
-               break;
-
-             errno = 0;
-             if (0 == (lower = strtol (token, &tail, 0)) || errno == ERANGE)
-               {
-                 font_msg (SE, _("Bad argument to `sizes'."));
-                 goto lossage;
-               }
-             if (*tail == '-')
-               {
-                 if (0 == (upper = strtol (&tail[1], &tail, 0)) || errno == ERANGE)
-                   {
-                     font_msg (SE, _("Bad argument to `sizes'."));
-                     goto lossage;
-                   }
-                 if (lower < upper)
-                   {
-                     font_msg (SE, _("Bad range in argument to `sizes'."));
-                     goto lossage;
-                   }
-               }
-             else
-               upper = lower;
-             if (*tail)
-               {
-                 font_msg (SE, _("Bad argument to `sizes'."));
-                 goto lossage;
-               }
-
-             if (dev->n_sizes + 2 >= m_sizes)
-               {
-                 m_sizes += 1;
-                 dev->sizes = xnrealloc (dev->sizes,
-                                          m_sizes, sizeof *dev->sizes);
-               }
-             dev->sizes[dev->n_sizes++][0] = lower;
-             dev->sizes[dev->n_sizes][1] = upper;
-
-             found |= 0x10000;
-           }
-       }
-      else if (!strcmp (token, "family"))
-       {
-         token = strtok_r (NULL, whitespace, &sp);
-         if (!token)
-           {
-             font_msg (SE, _("Family name expected."));
-             goto lossage;
-           }
-         if (found & 0x20000)
-           {
-             font_msg (SE, _("This command already specified."));
-             goto lossage;
-           }
-         dev->family = xstrdup (token);
-       }
-      else if (!strcmp (token, "charset"))
-       break;
-      else
-       {
-         static const char *id[]
-           = {"res", "hor", "vert", "sizescale", "unitwidth", NULL};
-         const char **cp;
-         int value;
-
-         for (cp = id; *cp; cp++)
-           if (!strcmp (token, *cp))
-             break;
-         if (*cp == NULL)
-           continue;           /* completely ignore unrecognized lines */
-         if (found & (1 << (cp - id)))
-           font_msg (SW, _("%s: Device characteristic already defined."), *cp);
-
-         token = strtok_r (NULL, whitespace, &sp);
-         errno = 0;
-         if (!token || (value = strtol (token, NULL, 0)) <= 0 || errno == ERANGE)
-           {
-             font_msg (SE, _("%s: Invalid numeric format."), *cp);
-             goto lossage;
-           }
-         found |= (1 << (cp - id));
-         switch (cp - id)
-           {
-           case 0:
-             dev->res = value;
-             break;
-           case 1:
-             dev->horiz = value;
-             break;
-           case 2:
-             dev->vert = value;
-             break;
-           case 3:
-             dev->size_scale = value;
-             break;
-           case 4:
-             dev->unit_width = value;
-             break;
-           default:
-             assert (0);
-           }
-       }
-    }
-  if (ferror (f))
-    goto file_lossage;
-  if ((found & 0x10011) != 0x10011)
-    {
-      font_msg (SE, _("Missing `res', `unitwidth', and/or `sizes' line(s)."));
-      goto lossage;
-    }
-
-  /* Font name = family name + suffix. */
-  {
-    static const char *suffix[4] =
-      {"R", "I", "B", "BI"};   /* match OUTP_F_* */
-    int len;                   /* length of family name */
-    int i;
-
-    if (!dev->family)
-      dev->family = xstrdup ("");
-    len = strlen (dev->family);
-    for (i = 0; i < 4; i++)
-      {
-       char *cp;
-       dev->font_name[i] = xmalloc (len + strlen (suffix[i]) + 1);
-       cp = stpcpy (dev->font_name[i], dev->family);
-       strcpy (cp, suffix[i]);
-      }
-  }
-
-  dev->sizes[dev->n_sizes][0] = 0;
-  dev->sizes[dev->n_sizes][1] = 0;
-
-  msg (VM (2), _("Description file read successfully."));
-  
-  err_pop_file_locator (&where);
-  free (filename);
-  free (line);
-  return 1;
-
-  /* Come here on a file error. */
-file_lossage:
-  msg (ME, "%s: %s", filename, strerror (errno));
-
-  /* Come here on any error. */
-lossage:
-  fclose (f);
-  free (line);
-  free (dev->family);
-  dev->family = NULL;
-  free (filename);
-  free (dev->sizes);
-  dev->sizes = NULL;
-  dev->n_sizes = 0;
-#if 0                          /* at the moment, no errors can come here when dev->font_name[*] are
-                                  nonzero. */
-  for (i = 0; i < 4; i++)
-    {
-      free (dev->font_name[i]);
-      dev->font_name[i] = NULL;
-    }
-#endif
-
-  err_pop_file_locator (&where);
-  
-  msg (VM (1), _("Error reading description file."));
-  
-  return 0;
-}
-
-/* Finds character with index CH (as returned by name_to_index() or
-   number_to_index()) in font FONT and returns the associated metrics.
-   Nonexistent characters have width 0. */
-struct char_metrics *
-font_get_char_metrics (const struct font_desc *font, int ch)
-{
-  short index;
-
-  if (ch < 0 || ch >= font->deref_size)
-    return 0;
-
-  index = font->deref[ch];
-  if (index == -1)
-    return 0;
-
-  return font->metric[index];
-}
-
-/* Finds kernpair consisting of CH1 and CH2, in that order, in font
-   FONT and returns the associated kerning adjustment. */
-int
-font_get_kern_adjust (const struct font_desc *font, int ch1, int ch2)
-{
-  unsigned i;
-
-  if (!font->kern)
-    return 0;
-  for (i = hash_kern (ch1, ch2) & (font->kern_size - 1);
-       font->kern[i].ch1 != -1;)
-    {
-      if (font->kern[i].ch1 == ch1 && font->kern[i].ch2 == ch2)
-       return font->kern[i].adjust;
-      if (0 == i--)
-       i = font->kern_size - 1;
-    }
-  return 0;
-}
-
-/* Returns a twelve-point fixed-pitch font that can be used as a
-   last-resort fallback. */
-struct font_desc *
-default_font (void)
-{
-  struct pool *font_pool;
-  static struct font_desc *font;
-
-  if (font)
-    return font;
-  font_pool = pool_create ();
-  font = pool_alloc (font_pool, sizeof *font);
-  font->owner = font_pool;
-  font->name = NULL;
-  font->internal_name = pool_strdup (font_pool, _("<<fallback>>"));
-  font->encoding = pool_strdup (font_pool, "text.enc");
-  font->space_width = 12000;
-  font->slant = 0.0;
-  font->ligatures = 0;
-  font->special = 0;
-  font->ascent = 8000;
-  font->descent = 4000;
-  font->deref = NULL;
-  font->deref_size = 0;
-  font->metric = NULL;
-  font->metric_size = 0;
-  font->metric_used = 0;
-  font->kern = NULL;
-  font->kern_size = 8;
-  font->kern_used = 0;
-  font->kern_max_used = 0;
-  return font;
-}
index 658858be3f6ddaca01688759c8e5dd341b1a9a63..7451efdc381d47ee4da21300a418604621b4d8a6 100644 (file)
@@ -31,6 +31,7 @@
 #include <libpspp/compiler.h>
 #include <libpspp/message.h>
 #include <data/filename.h>
 #include <libpspp/compiler.h>
 #include <libpspp/message.h>
 #include <data/filename.h>
+#include "error.h"
 #include "getline.h"
 #include "getlogin_r.h"
 #include "output.h"
 #include "getline.h"
 #include "getlogin_r.h"
 #include "output.h"
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
-/* Prototypes. */
-static int postopen (struct file_ext *);
-static int preclose (struct file_ext *);
+static void escape_string (FILE *file,
+                           const char *text, size_t length,
+                           const char *space);
+static bool handle_option (struct outp_driver *this,
+                           const char *key, const struct string *val);
+static void print_title_tag (FILE *file, const char *name,
+                             const char *content);
 
 
-static int
-html_open_global (struct outp_class *this UNUSED)
-{
-  return 1;
-}
-
-static int
-html_close_global (struct outp_class *this UNUSED)
-{
-  return 1;
-}
-
-static int
-html_preopen_driver (struct outp_driver *this)
+static bool
+html_open_driver (struct outp_driver *this, const char *options)
 {
   struct html_driver_ext *x;
 
 {
   struct html_driver_ext *x;
 
-  assert (this->driver_open == 0);
-  msg (VM (1), _("HTML driver initializing as `%s'..."), this->name);
-
   this->ext = x = xmalloc (sizeof *x);
   this->ext = x = xmalloc (sizeof *x);
-  this->res = 0;
-  this->horiz = this->vert = 0;
-  this->width = this->length = 0;
-
-  this->cp_x = this->cp_y = 0;
-
-  x->prologue_fn = NULL;
-
-  x->file.filename = NULL;
-  x->file.mode = "w";
-  x->file.file = NULL;
-  x->file.sequence_no = &x->sequence_no;
-  x->file.param = this;
-  x->file.postopen = postopen;
-  x->file.preclose = preclose;
+  x->file_name = xstrdup ("pspp.html");
+  x->file = NULL;
 
 
-  x->sequence_no = 0;
+  outp_parse_options (options, handle_option, this);
 
 
-  return 1;
+  x->file = fn_open (x->file_name, "w");
+  if (x->file == NULL)
+    {
+      error (0, errno, _("opening HTML output file: %s"), x->file_name);
+      goto error;
+    }
+  fputs ("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n"
+         "   \"http://www.w3.org/TR/html4/loose.dtd\">\n", x->file);
+  fputs ("<HTML>\n", x->file);
+  fputs ("<HEAD>\n", x->file);
+  /* The <TITLE> tag is required, so we use a default if the user
+     didn't provide one. */
+  print_title_tag (x->file,
+                   "TITLE", outp_title ? outp_title : _("PSPP Output"));
+  fprintf (x->file, "<META NAME=\"generator\" CONTENT=\"%s\">\n", version);
+  fputs ("<META HTTP-EQUIV=\"Content-Type\" "
+         "CONTENT=\"text/html; charset=ISO-8859-1\">\n", x->file);
+  fputs ("</HEAD>\n", x->file);
+  fputs ("<BODY BGCOLOR=\"#ffffff\" TEXT=\"#000000\"\n", x->file);
+  fputs (" LINK=\"#1f00ff\" ALINK=\"#ff0000\" VLINK=\"#9900dd\">\n", x->file);
+  print_title_tag (x->file, "H1", outp_title);
+  print_title_tag (x->file, "H2", outp_subtitle);
+
+  return true;
+
+ error:
+  this->class->close_driver (this);
+  return false;
 }
 
 }
 
-static int
-html_postopen_driver (struct outp_driver *this)
+/* Emits <NAME>CONTENT</NAME> to the output, escaping CONTENT as
+   necessary for HTML. */
+static void
+print_title_tag (FILE *file, const char *name, const char *content) 
 {
 {
-  struct html_driver_ext *x = this->ext;
-
-  assert (this->driver_open == 0);
-  if (NULL == x->file.filename)
-    x->file.filename = xstrdup ("pspp.html");
-       
-  if (x->prologue_fn == NULL)
-    x->prologue_fn = xstrdup ("html-prologue");
-
-  msg (VM (2), _("%s: Initialization complete."), this->name);
-  this->driver_open = 1;
-
-  return 1;
+  if (content != NULL) 
+    {
+      fprintf (file, "<%s>", name);
+      escape_string (file, content, strlen (content), " ");
+      fprintf (file, "</%s>\n", name);
+    }
 }
 
 }
 
-static int
+static bool
 html_close_driver (struct outp_driver *this)
 {
   struct html_driver_ext *x = this->ext;
 html_close_driver (struct outp_driver *this)
 {
   struct html_driver_ext *x = this->ext;
-
-  assert (this->driver_open);
-  msg (VM (2), _("%s: Beginning closing..."), this->name);
-  fn_close_ext (&x->file);
-  free (x->prologue_fn);
-  free (x->file.filename);
+  bool ok;
+  if (x->file != NULL) 
+    {
+      fprintf (x->file,
+               "</BODY>\n"
+               "</HTML>\n"
+               "<!-- end of file -->\n");
+      ok = fn_close (x->file_name, x->file) == 0;
+      x->file = NULL; 
+    }
+  else
+    ok = true;
+  free (x->file_name);
   free (x);
   free (x);
-  msg (VM (3), _("%s: Finished closing."), this->name);
-  this->driver_open = 0;
-  
-  return 1;
+   
+  return ok;
 }
 
 }
 
-
-/* Link the image contained in FILENAME to the 
-   HTML stream in file F. */
-static int
-link_image (struct file_ext *f, char *filename)
+/* Link the image contained in FILE_NAME to the 
+   HTML stream in FILE. */
+static void
+link_image (FILE *file, char *file_name)
 {
 {
-  fprintf (f->file,
-          "<IMG SRC=\"%s\"/>", filename);
-
-  if (ferror (f->file))
-    return 0;
-
-  return 1;
-}
-
+  fprintf (file, "<IMG SRC=\"%s\"/>", file_name);
+ }
 
 /* Generic option types. */
 enum
 
 /* Generic option types. */
 enum
-{
-  boolean_arg = -10,
-  string_arg,
-  nonneg_int_arg
-};
+  {
+    string_arg,
+    nonneg_int_arg
+  };
 
 /* All the options that the HTML driver supports. */
 static struct outp_option option_tab[] =
 
 /* All the options that the HTML driver supports. */
 static struct outp_option option_tab[] =
-{
-  /* *INDENT-OFF* */
-  {"output-file",              1,              0},
-  {"prologue-file",            string_arg,     0},
-  {"", 0, 0},
-  /* *INDENT-ON* */
-};
-static struct outp_option_info option_info;
+  {
+    {"output-file",            string_arg,     0},
+    {NULL, 0, 0},
+  };
 
 
-static void
-html_option (struct outp_driver *this, const char *key, const struct string *val)
+static bool
+handle_option (struct outp_driver *this,
+               const char *key, const struct string *val)
 {
   struct html_driver_ext *x = this->ext;
 {
   struct html_driver_ext *x = this->ext;
-  int cat, subcat;
+  int subcat;
 
 
-  cat = outp_match_keyword (key, option_tab, &option_info, &subcat);
-  switch (cat)
+  switch (outp_match_keyword (key, option_tab, &subcat))
     {
     {
-    case 0:
-      msg (SE, _("Unknown configuration parameter `%s' for HTML device "
-          "driver."), key);
-      break;
-    case 1:
-      free (x->file.filename);
-      x->file.filename = xstrdup (ds_c_str (val));
+    case -1:
+      error (0, 0,
+             _("unknown configuration parameter `%s' for HTML device driver"),
+             key);
       break;
     case string_arg:
       break;
     case string_arg:
-      {
-       char **dest;
-       switch (subcat)
-         {
-         case 0:
-           dest = &x->prologue_fn;
-           break;
-         default:
-           assert (0);
-            abort ();
-         }
-       if (*dest)
-         free (*dest);
-       *dest = xstrdup (ds_c_str (val));
-      }
+      free (x->file_name);
+      x->file_name = xstrdup (ds_c_str (val));
       break;
     default:
       break;
     default:
-      assert (0);
+      abort ();
     }
     }
-}
-
-/* Variables for the prologue. */
-struct html_variable
-  {
-    const char *key;
-    const char *value;
-  };
   
   
-static struct html_variable *html_var_tab;
-
-/* Searches html_var_tab for a html_variable with key KEY, and returns
-   the associated value. */
-static const char *
-html_get_var (const char *key)
-{
-  struct html_variable *v;
-
-  for (v = html_var_tab; v->key; v++)
-    if (!strcmp (key, v->key))
-      return v->value;
-  return NULL;
-}
-
-/* Writes the HTML prologue to file F. */
-static int
-postopen (struct file_ext *f)
-{
-  static struct html_variable dict[] =
-    {
-      {"generator", 0},
-      {"date", 0},
-      {"user", 0},
-      {"host", 0},
-      {"title", 0},
-      {"subtitle", 0},
-      {0, 0},
-    };
-  char login[128], host[128];
-  time_t curtime;
-  struct tm *loctime;
-
-  struct outp_driver *this = f->param;
-  struct html_driver_ext *x = this->ext;
-
-  char *prologue_fn = fn_search_path (x->prologue_fn, config_path, NULL);
-  FILE *prologue_file;
-
-  char *buf = NULL;
-  size_t buf_size = 0;
-
-  if (prologue_fn == NULL)
-    {
-      msg (IE, _("Cannot find HTML prologue.  The use of `-vv' "
-                "on the command line is suggested as a debugging aid."));
-      return 0;
-    }
-
-  msg (VM (1), _("%s: %s: Opening HTML prologue..."), this->name, prologue_fn);
-  prologue_file = fopen (prologue_fn, "rb");
-  if (prologue_file == NULL)
-    {
-      fclose (prologue_file);
-      free (prologue_fn);
-      msg (IE, "%s: %s", prologue_fn, strerror (errno));
-      goto error;
-    }
-
-  dict[0].value = version;
-
-  curtime = time (NULL);
-  loctime = localtime (&curtime);
-  dict[1].value = asctime (loctime);
-  {
-    char *cp = strchr (dict[1].value, '\n');
-    if (cp)
-      *cp = 0;
-  }
-
-  if (getenv ("LOGNAME") != NULL)
-    str_copy_rpad (login, sizeof login, getenv ("LOGNAME"));
-  else if (getlogin_r (login, sizeof login))
-    strcpy (login, _("nobody"));
-  dict[2].value = login;
-
-#ifdef HAVE_UNISTD_H
-  if (gethostname (host, 128) == -1)
-    {
-      if (errno == ENAMETOOLONG)
-       host[127] = 0;
-      else
-       strcpy (host, _("nowhere"));
-    }
-#else
-  strcpy (host, _("nowhere"));
-#endif
-  dict[3].value = host;
-
-  dict[4].value = outp_title ? outp_title : "";
-  dict[5].value = outp_subtitle ? outp_subtitle : "";
-
-  html_var_tab = dict;
-  while (-1 != getline (&buf, &buf_size, prologue_file))
-    {
-
-      int len;
-
-      if (strstr (buf, "!!!"))
-       continue;
-      
-      {
-       char *cp = strstr (buf, "!title");
-       if (cp)
-         {
-           if (outp_title == NULL)
-             continue;
-           else
-             *cp = '\0';
-         }
-      }
-      
-      {
-       char *cp = strstr (buf, "!subtitle");
-       if (cp)
-         {
-           if (outp_subtitle == NULL)
-             continue;
-           else
-             *cp = '\0';
-         }
-      }
-      
-      /* PORTME: Line terminator. */
-      struct string line;
-      ds_create(&line, buf);
-      fn_interp_vars(&line, html_get_var);
-      len = ds_length(&line);
-      fwrite (ds_c_str(&line), len, 1, f->file);
-      if (ds_c_str(&line)[len - 1] != '\n')
-       putc ('\n', f->file);
-      ds_destroy(&line);
-    }
-  if (ferror (f->file))
-    msg (IE, _("Reading `%s': %s."), prologue_fn, strerror (errno));
-  fclose (prologue_file);
-
-  free (prologue_fn);
-  free (buf);
-
-  if (ferror (f->file))
-    goto error;
-
-  msg (VM (2), _("%s: HTML prologue read successfully."), this->name);
-  return 1;
-
-error:
-  msg (VM (1), _("%s: Error reading HTML prologue."), this->name);
-  return 0;
-}
-
-/* Writes the HTML epilogue to file F. */
-static int
-preclose (struct file_ext *f)
-{
-  fprintf (f->file,
-          "</BODY>\n"
-          "</HTML>\n"
-          "<!-- end of file -->\n");
-
-  if (ferror (f->file))
-    return 0;
-  return 1;
-}
-
-static int
-html_open_page (struct outp_driver *this)
-{
-  struct html_driver_ext *x = this->ext;
-
-  assert (this->driver_open && this->page_open == 0);
-  x->sequence_no++;
-  if (!fn_open_ext (&x->file))
-    {
-      if (errno)
-       msg (ME, _("HTML output driver: %s: %s"), x->file.filename,
-            strerror (errno));
-      return 0;
-    }
-
-  if (!ferror (x->file.file))
-    this->page_open = 1;
-  return !ferror (x->file.file);
-}
-
-static int
-html_close_page (struct outp_driver *this)
-{
-  struct html_driver_ext *x = this->ext;
-
-  assert (this->driver_open && this->page_open);
-  this->page_open = 0;
-  return !ferror (x->file.file);
+  return true;
 }
 
 static void output_tab_table (struct outp_driver *, struct tab_table *);
 }
 
 static void output_tab_table (struct outp_driver *, struct tab_table *);
@@ -407,14 +184,7 @@ html_submit (struct outp_driver *this, struct som_entity *s)
   extern struct som_table_class tab_table_class;
   struct html_driver_ext *x = this->ext;
   
   extern struct som_table_class tab_table_class;
   struct html_driver_ext *x = this->ext;
   
-  assert (this->driver_open && this->page_open);
-  if (x->sequence_no == 0 && !html_open_page (this))
-    {
-      msg (ME, _("Cannot open first page on HTML device %s."), this->name);
-      return;
-    }
-
-  assert ( s->class == &tab_table_class ) ;
+  assert (s->class == &tab_table_class ) ;
 
   switch (s->type) 
     {
 
   switch (s->type) 
     {
@@ -422,49 +192,76 @@ html_submit (struct outp_driver *this, struct som_entity *s)
       output_tab_table ( this, (struct tab_table *) s->ext);
       break;
     case SOM_CHART:
       output_tab_table ( this, (struct tab_table *) s->ext);
       break;
     case SOM_CHART:
-      link_image( &x->file, ((struct chart *)s->ext)->filename);
+      link_image (x->file, ((struct chart *)s->ext)->filename);
       break;
     default:
       break;
     default:
-      assert(0);
-      break;
+      abort ();
     }
     }
-
 }
 
 }
 
-/* Write string S of length LEN to file F, escaping characters as
-   necessary for HTML. */
+/* Write LENGTH characters in TEXT to file F, escaping characters
+   as necessary for HTML.  Spaces are replaced by SPACE, which
+   should be " " or "&nbsp;". */
 static void
 static void
-escape_string (FILE *f, char *s, int len)
+escape_string (FILE *file,
+               const char *text, size_t length,
+               const char *space)
 {
 {
-  char *ep = &s[len];
-  char *bp, *cp;
-
-  for (bp = cp = s; bp < ep; bp = cp)
+  while (length-- > 0)
     {
     {
-      while (cp < ep && *cp != '&' && *cp != '<' && *cp != '>' && *cp)
-       cp++;
-      if (cp > bp)
-       fwrite (bp, 1, cp - bp, f);
-      if (cp < ep)
-       switch (*cp++)
-         {
-         case '&':
-           fputs ("&amp;", f);
-           break;
-         case '<':
-           fputs ("&lt;", f);
-           break;
-         case '>':
-           fputs ("&gt;", f);
-           break;
-         case 0:
-           break;
-         default:
-           assert (0);
-         }
+      char c = *text++;
+      switch (c)
+        {
+        case '&':
+          fputs ("&amp;", file);
+          break;
+        case '<':
+          fputs ("&lt;", file);
+          break;
+        case '>':
+          fputs ("&gt;", file);
+          break;
+        case ' ':
+          fputs (space, file);
+          break;
+        default:
+          putc (c, file);
+          break;
+        }
     }
 }
   
     }
 }
   
+/* Outputs content for a cell with options OPTS and contents
+   TEXT. */
+void
+html_put_cell_contents (struct outp_driver *this,
+                        unsigned int opts, struct fixed_string *text)
+{
+  struct html_driver_ext *x = this->ext;
+
+  if (!(opts & TAB_EMPTY)) 
+    {
+      if (opts & TAB_EMPH)
+        fputs ("<EM>", x->file);
+      if (opts & TAB_FIX) 
+        {
+          fputs ("<TT>", x->file);
+          escape_string (x->file, ls_c_str (text), ls_length (text), "&nbsp;");
+          fputs ("</TT>", x->file);
+        }
+      else 
+        {
+          size_t initial_spaces = strspn (ls_c_str (text), " \t");
+          escape_string (x->file,
+                         ls_c_str (text) + initial_spaces,
+                         ls_length (text) - initial_spaces,
+                         " "); 
+        }
+      if (opts & TAB_EMPH)
+        fputs ("</EM>", x->file);
+    }
+}
+
 /* Write table T to THIS output driver. */
 static void
 output_tab_table (struct outp_driver *this, struct tab_table *t)
 /* Write table T to THIS output driver. */
 static void
 output_tab_table (struct outp_driver *this, struct tab_table *t)
@@ -473,22 +270,21 @@ output_tab_table (struct outp_driver *this, struct tab_table *t)
   
   if (t->nr == 1 && t->nc == 1)
     {
   
   if (t->nr == 1 && t->nc == 1)
     {
-      fputs ("<P>", x->file.file);
-      if (!ls_empty_p (t->cc))
-       escape_string (x->file.file, ls_c_str (t->cc), ls_length (t->cc));
-      fputs ("</P>\n", x->file.file);
+      fputs ("<P>", x->file);
+      html_put_cell_contents (this, t->ct[0], t->cc);
+      fputs ("</P>\n", x->file);
       
       return;
     }
 
       
       return;
     }
 
-  fputs ("<TABLE BORDER=1>\n", x->file.file);
+  fputs ("<TABLE BORDER=1>\n", x->file);
   
   if (!ls_empty_p (&t->title))
     {
   
   if (!ls_empty_p (&t->title))
     {
-      fprintf (x->file.file, "  <TR>\n    <TH COLSPAN=%d>", t->nc);
-      escape_string (x->file.file, ls_c_str (&t->title),
-                    ls_length (&t->title));
-      fputs ("</TH>\n  </TR>\n", x->file.file);
+      fprintf (x->file, "  <CAPTION>");
+      escape_string (x->file, ls_c_str (&t->title), ls_length (&t->title),
+                     " ");
+      fputs ("</CAPTION>\n", x->file);
     }
   
   {
     }
   
   {
@@ -499,17 +295,15 @@ output_tab_table (struct outp_driver *this, struct tab_table *t)
       {
        int c;
        
       {
        int c;
        
-       fputs ("  <TR>\n", x->file.file);
+       fputs ("  <TR>\n", x->file);
        for (c = 0; c < t->nc; c++, ct++)
          {
             struct fixed_string *cc;
        for (c = 0; c < t->nc; c++, ct++)
          {
             struct fixed_string *cc;
-           int tag;
-           char header[128];
-           char *cp;
+            const char *tag;
             struct tab_joined_cell *j = NULL;
 
             cc = t->cc + c + r * t->nc;
             struct tab_joined_cell *j = NULL;
 
             cc = t->cc + c + r * t->nc;
-           if (*ct & TAB_JOIN) 
+           if (*ct & TAB_JOIN)
               {
                 j = (struct tab_joined_cell *) ls_c_str (cc);
                 cc = &j->contents;
               {
                 j = (struct tab_joined_cell *) ls_c_str (cc);
                 cc = &j->contents;
@@ -517,62 +311,34 @@ output_tab_table (struct outp_driver *this, struct tab_table *t)
                   continue; 
               }
 
                   continue; 
               }
 
-           if (r < t->t || r >= t->nr - t->b
-               || c < t->l || c >= t->nc - t->r)
-             tag = 'H';
-           else
-             tag = 'D';
-           cp = stpcpy (header, "    <T");
-           *cp++ = tag;
-           
-           switch (*ct & TAB_ALIGN_MASK)
-             {
-             case TAB_RIGHT:
-               cp = stpcpy (cp, " ALIGN=RIGHT");
-               break;
-             case TAB_LEFT:
-               break;
-             case TAB_CENTER:
-               cp = stpcpy (cp, " ALIGN=CENTER");
-               break;
-             default:
-               assert (0);
-             }
-
+            /* Output <TD> or <TH> tag. */
+            tag = (r < t->t || r >= t->nr - t->b
+                   || c < t->l || c >= t->nc - t->r) ? "TH" : "TD";
+            fprintf (x->file, "    <%s ALIGN=%s",
+                     tag,
+                     (*ct & TAB_ALIGN_MASK) == TAB_LEFT ? "LEFT"
+                     : (*ct & TAB_ALIGN_MASK) == TAB_RIGHT ? "RIGHT"
+                     : "CENTER");
            if (*ct & TAB_JOIN)
              {
                if (j->x2 - j->x1 > 1)
            if (*ct & TAB_JOIN)
              {
                if (j->x2 - j->x1 > 1)
-                 cp = spprintf (cp, " COLSPAN=%d", j->x2 - j->x1);
+                 fprintf (x->file, " COLSPAN=%d", j->x2 - j->x1);
                if (j->y2 - j->y1 > 1)
                if (j->y2 - j->y1 > 1)
-                 cp = spprintf (cp, " ROWSPAN=%d", j->y2 - j->y1);
-
-                cc = &j->contents;
-             }
-           
-           strcpy (cp, ">");
-           fputs (header, x->file.file);
-           
-           if ( ! (*ct & TAB_EMPTY)  ) 
-             {
-               char *s = ls_c_str (cc);
-               size_t l = ls_length (cc);
-
-               while (l && isspace ((unsigned char) *s))
-                 {
-                   l--;
-                   s++;
-                 }
-             
-               escape_string (x->file.file, s, l);
+                 fprintf (x->file, " ROWSPAN=%d", j->y2 - j->y1);
              }
              }
+           putc ('>', x->file);
+
+            /* Output cell contents. */
+            html_put_cell_contents (this, *ct, cc);
 
 
-           fprintf (x->file.file, "</T%c>\n", tag);
+            /* Output </TH> or </TD>. */
+           fprintf (x->file, "</%s>\n", tag);
          }
          }
-       fputs ("  </TR>\n", x->file.file);
+       fputs ("  </TR>\n", x->file);
       }
   }
              
       }
   }
              
-  fputs ("</TABLE>\n\n", x->file.file);
+  fputs ("</TABLE>\n\n", x->file);
 }
 
 static void
 }
 
 static void
@@ -602,45 +368,21 @@ html_finalise_chart(struct outp_driver *d UNUSED, struct chart *ch)
 
 /* HTML driver class. */
 struct outp_class html_class =
 
 /* HTML driver class. */
 struct outp_class html_class =
-{
-  "html",
-  0xfaeb,
-  1,
-
-  html_open_global,
-  html_close_global,
-  NULL,
-
-  html_preopen_driver,
-  html_option,
-  html_postopen_driver,
-  html_close_driver,
-
-  html_open_page,
-  html_close_page,
-
-  html_submit,
-
-  NULL,
-  NULL,
-  NULL,
-
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-
-  html_initialise_chart,
-  html_finalise_chart
-
-};
+  {
+    "html",
+    1,
+
+    html_open_driver,
+    html_close_driver,
+
+    NULL,
+    NULL,
+
+    html_submit,
+
+    NULL,
+    NULL,
+    NULL,
+    html_initialise_chart,
+    html_finalise_chart
+  };
index 673ca48410f928496654ada31b69bb4871a3ab20..fe63843d90e8278e8b6c087abe6e26ddb8bf5df5 100644 (file)
 /* HTML output driver extension record. */
 struct html_driver_ext
   {
 /* HTML output driver extension record. */
 struct html_driver_ext
   {
-    /* User parameters. */
-    char *prologue_fn;         /* Prologue's filename relative to font dir. */
-
-    /* Internal state. */
-    struct file_ext file;      /* Output file. */
-    int sequence_no;           /* Sequence number. */
+    char *file_name;
+    FILE *file;
   };
 
 extern struct outp_class html_class;
 
   };
 
 extern struct outp_class html_class;
 
+struct outp_driver;
+void html_put_cell_contents (struct outp_driver *this,
+                             unsigned int opts, struct fixed_string *text);
+
 #endif /* !htmlP_h */
 #endif /* !htmlP_h */
index f7d0b5eb749483a30ef7530fa89394b07e098c38..8fd90a5e26bbcfa774b5534b9a6e7e96ee49c601 100644 (file)
@@ -147,13 +147,7 @@ output_entity (struct outp_driver *driver, struct som_entity *entity)
   bool fits_width, fits_length;
   d = driver;
 
   bool fits_width, fits_length;
   d = driver;
 
-  assert (d->driver_open);
-  if (!d->page_open && !d->class->open_page (d))
-    {
-      d->device = OUTP_DEV_DISABLED;
-      return;
-    }
-  
+  outp_open_page (d);
   if (d->class->special || entity->type == SOM_CHART)
     {
       driver->class->submit (d, entity);
   if (d->class->special || entity->type == SOM_CHART)
     {
       driver->class->submit (d, entity);
index 0390e1af73c7f56563def75ca14a9c9f2c6af2f7..0ea8ea49ad3230d091cbc0df06c4426a5e08db6c 100644 (file)
@@ -68,6 +68,13 @@ struct outp_defn
 static struct outp_defn *outp_macros;
 static struct outp_names *outp_configure_vec;
 
 static struct outp_defn *outp_macros;
 static struct outp_names *outp_configure_vec;
 
+/* A list of driver classes. */
+struct outp_driver_class_list
+  {
+    struct outp_class *class;
+    struct outp_driver_class_list *next;
+  };
+
 struct outp_driver_class_list *outp_class_list;
 struct outp_driver *outp_driver_list;
 
 struct outp_driver_class_list *outp_class_list;
 struct outp_driver *outp_driver_list;
 
@@ -80,8 +87,8 @@ static int disabled_devices;
 
 static void destroy_driver (struct outp_driver *);
 static void configure_driver_line (struct string *);
 
 static void destroy_driver (struct outp_driver *);
 static void configure_driver_line (struct string *);
-static void configure_driver (const char *, const char *,
-                              const char *, const char *);
+static void configure_driver (const struct string *, const struct string *,
+                              const struct string *, const struct string *);
 
 /* Add a class to the class list. */
 static void
 
 /* Add a class to the class list. */
 static void
@@ -90,7 +97,6 @@ add_class (struct outp_class *class)
   struct outp_driver_class_list *new_list = xmalloc (sizeof *new_list);
 
   new_list->class = class;
   struct outp_driver_class_list *new_list = xmalloc (sizeof *new_list);
 
   new_list->class = class;
-  new_list->ref_count = 0;
 
   if (!outp_class_list)
     {
 
   if (!outp_class_list)
     {
@@ -221,13 +227,11 @@ outp_init (void)
 {
   extern struct outp_class ascii_class;
   extern struct outp_class postscript_class;
 {
   extern struct outp_class ascii_class;
   extern struct outp_class postscript_class;
-  extern struct outp_class epsf_class;
   extern struct outp_class html_class;
 
   char def[] = "default";
 
   add_class (&html_class);
   extern struct outp_class html_class;
 
   char def[] = "default";
 
   add_class (&html_class);
-  add_class (&epsf_class);
   add_class (&postscript_class);
   add_class (&ascii_class);
 
   add_class (&postscript_class);
   add_class (&ascii_class);
 
@@ -252,11 +256,15 @@ delete_macros (void)
 static void
 init_default_drivers (void) 
 {
 static void
 init_default_drivers (void) 
 {
+  struct string s;
+
   msg (MM, _("Using default output driver configuration."));
   msg (MM, _("Using default output driver configuration."));
-  configure_driver ("list-ascii", "ascii", "listing",
-                    "length=66 width=79 char-set=ascii "
-                    "output-file=\"pspp.list\" "
-                    "bold-on=\"\" italic-on=\"\" bold-italic-on=\"\"");
+
+  ds_create (&s,
+             "list:ascii:listing:"
+             "length=66 width=79 output-file=\"pspp.list\"");
+  configure_driver_line (&s);
+  ds_destroy (&s);
 }
 
 /* Reads the initialization file; initializes
 }
 
 /* Reads the initialization file; initializes
@@ -290,7 +298,6 @@ outp_read_devices (void)
       goto exit;
     }
 
       goto exit;
     }
 
-  msg (VM (1), _("%s: Opening device description file..."), init_fn);
   f = fopen (init_fn, "r");
   if (f == NULL)
     {
   f = fopen (init_fn, "r");
   if (f == NULL)
     {
@@ -344,7 +351,6 @@ exit:
 
   if (result) 
     {
 
   if (result) 
     {
-      msg (VM (2), _("Device definition file read successfully."));
       if (outp_driver_list == NULL) 
         msg (MW, _("No output drivers are active.")); 
     }
       if (outp_driver_list == NULL) 
         msg (MW, _("No output drivers are active.")); 
     }
@@ -612,16 +618,19 @@ tokener (void)
   return 1;
 }
 
   return 1;
 }
 
-/* Applies the user-specified options in string S to output driver D
-   (at configuration time). */
-static void
-parse_options (const char *s, struct outp_driver * d)
+bool
+outp_parse_options (const char *options,
+                    bool (*callback) (struct outp_driver *, const char *key,
+                                      const struct string *value),
+                    struct outp_driver *driver)
 {
 {
-  prog = s;
+  bool ok = true;
+
+  prog = options;
   op_token = -1;
 
   ds_init (&op_tokstr, 64);
   op_token = -1;
 
   ds_init (&op_tokstr, 64);
-  while (tokener ())
+  while (ok && tokener ())
     {
       char key[65];
 
     {
       char key[65];
 
@@ -647,9 +656,11 @@ parse_options (const char *s, struct outp_driver * d)
          msg (IS, _("Syntax error in options (value expected after `=')."));
          break;
        }
          msg (IS, _("Syntax error in options (value expected after `=')."));
          break;
        }
-      d->class->option (d, key, &op_tokstr);
+      ok = callback (driver, key, &op_tokstr);
     }
   ds_destroy (&op_tokstr);
     }
   ds_destroy (&op_tokstr);
+
+  return ok;
 }
 
 /* Find the driver in outp_driver_list with name NAME. */
 }
 
 /* Find the driver in outp_driver_list with name NAME. */
@@ -669,97 +680,79 @@ find_driver (char *name)
    Adds a driver to outp_driver_list pursuant to the specification
    provided.  */
 static void
    Adds a driver to outp_driver_list pursuant to the specification
    provided.  */
 static void
-configure_driver (const char *driver_name, const char *class_name,
-                  const char *device_type, const char *options)
+configure_driver (const struct string *driver_name,
+                  const struct string *class_name,
+                  const struct string *device_type,
+                  const struct string *options)
 {
 {
-  struct outp_driver *d = NULL, *iter;
-  struct outp_driver_class_list *c = NULL;
-
-  d = xmalloc (sizeof *d);
-  d->class = NULL;
-  d->name = xstrdup (driver_name);
-  d->driver_open = 0;
-  d->page_open = 0;
-  d->next = d->prev = NULL;
-  d->device = OUTP_DEV_NONE;
-  d->ext = NULL;
+  struct outp_driver *d, *iter;
+  struct outp_driver_class_list *c;
+  int device;
 
 
+  /* Find class. */
   for (c = outp_class_list; c; c = c->next)
   for (c = outp_class_list; c; c = c->next)
-    if (!strcmp (c->class->name, class_name))
+    if (!strcmp (c->class->name, ds_c_str (class_name)))
       break;
       break;
-  if (!c)
+  if (c == NULL)
     {
     {
-      msg (IS, _("Unknown output driver class `%s'."), class_name);
-      goto error;
+      msg (IS, _("Unknown output driver class `%s'."), ds_c_str (class_name));
+      return;
     }
   
     }
   
-  d->class = c->class;
-  if (!c->ref_count && !d->class->open_global (d->class))
-    {
-      msg (IS, _("Can't initialize output driver class `%s'."),
-          d->class->name);
-      goto error;
-    }
-  c->ref_count++;
-  if (!d->class->preopen_driver (d))
-    {
-      msg (IS, _("Can't initialize output driver `%s' of class `%s'."),
-          d->name, d->class->name);
-      goto error;
-    }
-
-  /* Device types. */
+  /* Parse device type. */
+  device = 0;
   if (device_type != NULL)
     {
   if (device_type != NULL)
     {
-      char *copy = xstrdup (device_type);
-      char *sp, *type;
+      struct string token = DS_INITIALIZER;
+      size_t save_idx = 0;
 
 
-      for (type = strtok_r (copy, " \t\r\v", &sp); type;
-          type = strtok_r (NULL, " \t\r\v", &sp))
-       {
+      while (ds_tokenize (device_type, &token, " \t\r\v", &save_idx)) 
+        {
+          const char *type = ds_c_str (&token);
          if (!strcmp (type, "listing"))
          if (!strcmp (type, "listing"))
-           d->device |= OUTP_DEV_LISTING;
+           device |= OUTP_DEV_LISTING;
          else if (!strcmp (type, "screen"))
          else if (!strcmp (type, "screen"))
-           d->device |= OUTP_DEV_SCREEN;
+           device |= OUTP_DEV_SCREEN;
          else if (!strcmp (type, "printer"))
          else if (!strcmp (type, "printer"))
-           d->device |= OUTP_DEV_PRINTER;
+           device |= OUTP_DEV_PRINTER;
          else
          else
-           {
-             msg (IS, _("Unknown device type `%s'."), type);
-              free (copy);
-             goto error;
-           }
+            msg (IS, _("Unknown device type `%s'."), type);
        }
        }
-      free (copy);
+      ds_destroy (&token);
     }
     }
-  
-  /* Options. */
-  if (options != NULL)
-    parse_options (options, d);
-  if (!d->class->postopen_driver (d))
+
+  /* Open the device. */
+  d = xmalloc (sizeof *d);
+  d->next = d->prev = NULL;
+  d->class = c->class;
+  d->name = xstrdup (ds_c_str (driver_name));
+  d->page_open = false;
+  d->device = OUTP_DEV_NONE;
+  d->cp_x = d->cp_y = 0;
+  d->ext = NULL;
+  d->prc = NULL;
+
+  /* Open driver. */
+  if (!d->class->open_driver (d, ds_c_str (options)))
     {
     {
-      msg (IS, _("Can't complete initialization of output driver `%s' of "
-          "class `%s'."), d->name, d->class->name);
-      goto error;
+      msg (IS, _("Can't initialize output driver `%s' of class `%s'."),
+          d->name, d->class->name);
+      free (d->name);
+      free (d);
+      return;
     }
 
   /* Find like-named driver and delete. */
   iter = find_driver (d->name);
     }
 
   /* Find like-named driver and delete. */
   iter = find_driver (d->name);
-  if (iter)
+  if (iter != NULL)
     destroy_driver (iter);
 
   /* Add to list. */
   d->next = outp_driver_list;
   d->prev = NULL;
     destroy_driver (iter);
 
   /* Add to list. */
   d->next = outp_driver_list;
   d->prev = NULL;
-  if (outp_driver_list)
+  if (outp_driver_list != NULL)
     outp_driver_list->prev = d;
   outp_driver_list = d;
     outp_driver_list->prev = d;
   outp_driver_list = d;
-  return;
-
-error:
-  if (d)
-    destroy_driver (d);
-  return;
 }
 
 /* String LINE is in format:
 }
 
 /* String LINE is in format:
@@ -770,12 +763,12 @@ static void
 configure_driver_line (struct string *line)
 {
   struct string tokens[4];
 configure_driver_line (struct string *line)
 {
   struct string tokens[4];
-  int save_idx;
+  size_t save_idx;
   size_t i;
 
   fn_interp_vars (line, find_defn_value);
 
   size_t i;
 
   fn_interp_vars (line, find_defn_value);
 
-  save_idx = -1;
+  save_idx = 0;
   for (i = 0; i < 4; i++) 
     {
       struct string *token = &tokens[i];
   for (i = 0; i < 4; i++) 
     {
       struct string *token = &tokens[i];
@@ -785,8 +778,7 @@ configure_driver_line (struct string *line)
     }
 
   if (!ds_is_empty (&tokens[0]) && !ds_is_empty (&tokens[1]))
     }
 
   if (!ds_is_empty (&tokens[0]) && !ds_is_empty (&tokens[1]))
-    configure_driver (ds_c_str (&tokens[0]), ds_c_str (&tokens[1]), 
-                      ds_c_str (&tokens[2]), ds_c_str (&tokens[3]));
+    configure_driver (&tokens[0], &tokens[1], &tokens[2], &tokens[3]);
   else
     msg (IS, _("Driver definition line missing driver name or class name"));
 
   else
     msg (IS, _("Driver definition line missing driver name or class name"));
 
@@ -798,27 +790,17 @@ configure_driver_line (struct string *line)
 static void
 destroy_driver (struct outp_driver *d)
 {
 static void
 destroy_driver (struct outp_driver *d)
 {
-  if (d->page_open)
-    d->class->close_page (d);
+  outp_close_page (d);
   if (d->class)
     {
       struct outp_driver_class_list *c;
 
   if (d->class)
     {
       struct outp_driver_class_list *c;
 
-      if (d->driver_open)
-       d->class->close_driver (d);
+      d->class->close_driver (d);
 
       for (c = outp_class_list; c; c = c->next)
        if (c->class == d->class)
          break;
       assert (c != NULL);
 
       for (c = outp_class_list; c; c = c->next)
        if (c->class == d->class)
          break;
       assert (c != NULL);
-      
-      c->ref_count--;
-      if (c->ref_count == 0)
-       {
-         if (!d->class->close_global (d->class))
-           msg (IS, _("Can't deinitialize output driver class `%s'."),
-                d->class->name);
-       }
     }
   free (d->name);
 
     }
   free (d->name);
 
@@ -831,82 +813,20 @@ destroy_driver (struct outp_driver *d)
     outp_driver_list = d->next;
 }
 
     outp_driver_list = d->next;
 }
 
-static int
-option_cmp (const void *a, const void *b)
-{
-  const struct outp_option *o1 = a;
-  const struct outp_option *o2 = b;
-  return strcmp (o1->keyword, o2->keyword);
-}
-
-/* Tries to match S as one of the keywords in TAB, with corresponding
-   information structure INFO.  Returns category code or 0 on failure;
-   if category code is negative then stores subcategory in *SUBCAT. */
+/* Tries to match S as one of the keywords in TAB, with
+   corresponding information structure INFO.  Returns category
+   code and stores subcategory in *SUBCAT on success.  Returns -1
+   on failure. */
 int
 int
-outp_match_keyword (const char *s, struct outp_option *tab,
-                   struct outp_option_info *info, int *subcat)
+outp_match_keyword (const char *s, struct outp_option *tab, int *subcat)
 {
 {
-  char *cp;
-  struct outp_option *oip;
-
-  /* Form hash table. */
-  if (NULL == info->initial)
-    {
-      /* Count items. */
-      int count, i;
-      char s[256], *cp;
-      struct outp_option *ptr[255], **oip;
-
-      for (count = 0; tab[count].keyword[0]; count++)
-       ;
-
-      /* Sort items. */
-      qsort (tab, count, sizeof *tab, option_cmp);
-
-      cp = s;
-      oip = ptr;
-      *cp = tab[0].keyword[0];
-      *oip++ = &tab[0];
-      for (i = 0; i < count; i++)
-       if (tab[i].keyword[0] != *cp)
-         {
-           *++cp = tab[i].keyword[0];
-           *oip++ = &tab[i];
-         }
-      *++cp = 0;
-
-      info->initial = xstrdup (s);
-      info->options = xnmalloc (cp - s, sizeof *info->options);
-      memcpy (info->options, ptr, sizeof *info->options * (cp - s));
-    }
-
-  cp = info->initial;
-  oip = *info->options;
-
-  if (s[0] == 0)
-    return 0;
-  cp = strchr (info->initial, s[0]);
-  if (!cp)
-    return 0;
-#if 0
-  printf (_("Trying to find keyword `%s'...\n"), s);
-#endif
-  oip = info->options[cp - info->initial];
-  while (oip->keyword[0] == s[0])
-    {
-#if 0
-      printf ("- %s\n", oip->keyword);
-#endif
-      if (!strcmp (s, oip->keyword))
-       {
-         if (oip->cat < 0)
-           *subcat = oip->subcat;
-         return oip->cat;
-       }
-      oip++;
-    }
-
-  return 0;
+  for (; tab->keyword != NULL; tab++)
+    if (!strcmp (s, tab->keyword))
+      {
+        *subcat = tab->subcat;
+        return tab->cat;
+      }
+  return -1;
 }
 
 /* Encapsulate two characters in a single int. */
 }
 
 /* Encapsulate two characters in a single int. */
@@ -1141,7 +1061,6 @@ outp_get_paper_size (char *size, int *h, int *v)
       goto exit;
     }
 
       goto exit;
     }
 
-  msg (VM (1), _("%s: Opening paper size definition file..."), pprsz_fn);
   f = fopen (pprsz_fn, "r");
   if (!f)
     {
   f = fopen (pprsz_fn, "r");
   if (!f)
     {
@@ -1211,9 +1130,7 @@ exit:
   if (free_it)
     free (size);
 
   if (free_it)
     free (size);
 
-  if (result)
-    msg (VM (2), _("Paper size definition file read successfully."));
-  else
+  if (!result)
     msg (VM (1), _("Error reading paper size definition file."));
   
   return result;
     msg (VM (1), _("Error reading paper size definition file."));
   
   return result;
@@ -1238,9 +1155,7 @@ outp_drivers (struct outp_driver *d)
        d = d->next;
 
       if (d == NULL
        d = d->next;
 
       if (d == NULL
-         || (d->driver_open
-             && (d->device == 0
-                 || (d->device & disabled_devices) != d->device)))
+         || (d->device == 0 || (d->device & disabled_devices) != d->device))
        break;
     }
 
        break;
     }
 
@@ -1258,40 +1173,57 @@ outp_enable_device (int enable, int device)
     disabled_devices |= device;
 }
 
     disabled_devices |= device;
 }
 
-/* Ejects the paper on device D, if the page is not blank. */
-int
-outp_eject_page (struct outp_driver *d)
+/* Opens a page on driver D (if one is not open). */
+void
+outp_open_page (struct outp_driver *d) 
 {
 {
-  if (d->page_open == 0)
-    return 1;
-  
-  if (d->cp_y != 0)
+  if (!d->page_open) 
     {
       d->cp_x = d->cp_y = 0;
 
     {
       d->cp_x = d->cp_y = 0;
 
-      if (d->class->close_page (d) == 0)
-       msg (ME, _("Error closing page on %s device of %s class."),
-            d->name, d->class->name);
-      if (d->class->open_page (d) == 0)
-       {
-         msg (ME, _("Error opening page on %s device of %s class."),
-              d->name, d->class->name);
-         return 0;
-       }
+      d->page_open = true;
+      if (d->class->open_page != NULL)
+        d->class->open_page (d);
+    }
+}
+
+/* Closes the page on driver D (if one is open). */
+void
+outp_close_page (struct outp_driver *d) 
+{
+  if (d->page_open) 
+    {
+      if (d->class->close_page != NULL)
+        d->class->close_page (d);
+      d->page_open = false;
+    }
+}
+
+/* Ejects the paper on device D, if a page is open and is not
+   blank. */
+void
+outp_eject_page (struct outp_driver *d)
+{
+  if (d->page_open && d->cp_y != 0)
+    {
+      outp_close_page (d);
+      outp_open_page (d);
     }
     }
-  return 1;
 }
 
 /* Returns the width of string S, in device units, when output on
    device D. */
 int
 }
 
 /* Returns the width of string S, in device units, when output on
    device D. */
 int
-outp_string_width (struct outp_driver *d, const char *s)
+outp_string_width (struct outp_driver *d, const char *s, enum outp_font font)
 {
   struct outp_text text;
 {
   struct outp_text text;
+  int width;
+  
+  text.font = font;
+  text.justification = OUTP_LEFT;
+  ls_init (&text.string, (char *) s, strlen (s));
+  text.h = text.v = INT_MAX;
+  d->class->text_metrics (d, &text, &width, NULL);
 
 
-  text.options = OUTP_T_JUST_LEFT;
-  ls_init (&text.s, (char *) s, strlen (s));
-  d->class->text_metrics (d, &text);
-
-  return text.h;
+  return width;
 }
 }
index 9694fcb4d88bef10a0cd7395737d0e2fa556a1e4..cf3101e28a3060dfa9bca2ca70c095920994cbde 100644 (file)
 #include <libpspp/str.h>
 
 
 #include <libpspp/str.h>
 
 
-/* A rectangle. */
-struct rect
+/* Line styles.  */
+enum outp_line_style
   {
   {
-    int x1, y1;                        /* Upper left. */
-    int x2, y2;                        /* Lower right, not part of the rectangle. */
+    OUTP_L_NONE,               /* No line. */
+    OUTP_L_SINGLE,             /* Single line. */
+    OUTP_L_DOUBLE,             /* Double line. */
+    OUTP_L_COUNT
   };
 
   };
 
-/* Color descriptor. */
-struct color
+/* Text justification. */
+enum outp_justification
   {
   {
-    int flags;                 /* 0=normal, 1=transparent (ignore r,g,b). */
-    int r;                     /* Red component, 0-65535. */
-    int g;                     /* Green component, 0-65535. */
-    int b;                     /* Blue component, 0-65535. */
+    OUTP_RIGHT,                 /* Right justification. */
+    OUTP_LEFT,                  /* Left justification. */
+    OUTP_CENTER,                /* Center justification. */
   };
 
   };
 
-/* Mount positions for the four basic fonts.  Do not change the values. */
-enum
-  {
-    OUTP_F_R,                  /* Roman font. */
-    OUTP_F_I,                  /* Italic font. */
-    OUTP_F_B,                  /* Bold font. */
-    OUTP_F_BI                  /* Bold-italic font. */
-  };
-
-/* Line styles.  These must match:
-   som.h:SLIN_*
-   ascii.c:ascii_line_*() 
-   postscript.c:ps_line_*() */
-enum
+enum outp_font 
   {
   {
-    OUTP_L_NONE = 0,           /* No line. */
-    OUTP_L_SINGLE = 1,         /* Single line. */
-    OUTP_L_DOUBLE = 2,         /* Double line. */
-    OUTP_L_SPECIAL = 3,                /* Special line of driver-defined style. */
-
-    OUTP_L_COUNT               /* Number of line styles. */
-  };
-
-/* Contains a line style for each part of an intersection. */
-struct outp_styles
-  {
-    int l;                     /* left */
-    int t;                     /* top */
-    int r;                     /* right */
-    int b;                     /* bottom */
-  };
-
-/* Text display options. */
-enum
-  {
-    OUTP_T_NONE = 0,
-
-    /* Must match tab.h:TAB_*. */
-    OUTP_T_JUST_MASK = 00003,  /* Justification mask. */
-    OUTP_T_JUST_RIGHT = 00000, /* Right justification. */
-    OUTP_T_JUST_LEFT = 00001,  /* Left justification. */
-    OUTP_T_JUST_CENTER = 00002,        /* Center justification. */
-
-    OUTP_T_HORZ = 00010,       /* Horizontal size is specified. */
-    OUTP_T_VERT = 00020,       /* (Max) vertical size is specified. */
-
-    OUTP_T_0 = 00140,          /* Normal orientation. */
-    OUTP_T_CC90 = 00040,       /* 90 degrees counterclockwise. */
-    OUTP_T_CC180 = 00100,      /* 180 degrees counterclockwise. */
-    OUTP_T_CC270 = 00140,      /* 270 degrees counterclockwise. */
-    OUTP_T_C90 = 00140,                /* 90 degrees clockwise. */
-    OUTP_T_C180 = 00100,       /* 180 degrees clockwise. */
-    OUTP_T_C270 = 00040,       /* 270 degrees clockwise. */
-
-    /* Internal use by drivers only. */
-    OUTP_T_INTERNAL_DRAW = 01000       /* 1=Draw the text, 0=Metrics only. */
+    OUTP_FIXED,                 /* Fixed-width font. */
+    OUTP_PROPORTIONAL,          /* Proportional font. */
+    OUTP_EMPHASIS,              /* Proportional font used for emphasis. */
+    OUTP_FONT_CNT               /* Number of fonts. */
   };
 
 /* Describes text output. */
 struct outp_text
   {
   };
 
 /* Describes text output. */
 struct outp_text
   {
-    /* Public. */
-    int options;               /* What is specified. */
-    struct fixed_string s;     /* String. */
+    enum outp_font font;
+    enum outp_justification justification;
+    struct fixed_string string;
     int h, v;                  /* Horizontal, vertical size. */
     int x, y;                  /* Position. */
     int h, v;                  /* Horizontal, vertical size. */
     int x, y;                  /* Position. */
-
-    /* Internal use only. */
-    int w, l;                  /* Width, length. */
   };
 
 struct som_entity;
   };
 
 struct som_entity;
@@ -119,61 +67,27 @@ struct chart;
 /* Defines a class of output driver. */
 struct outp_class
   {
 /* Defines a class of output driver. */
 struct outp_class
   {
-    /* Basic class information. */
     const char *name;          /* Name of this driver class. */
     const char *name;          /* Name of this driver class. */
-    int magic;                 /* Driver-specific constant. */
     int special;               /* Boolean value. */
 
     int special;               /* Boolean value. */
 
-    /* Static member functions. */
-    int (*open_global) (struct outp_class *);
-    int (*close_global) (struct outp_class *);
-    int *(*font_sizes) (struct outp_class *, int *n_valid_sizes);
-
-    /* Virtual member functions. */
-    int (*preopen_driver) (struct outp_driver *);
-    void (*option) (struct outp_driver *, const char *key,
-                   const struct string *value);
-    int (*postopen_driver) (struct outp_driver *);
-    int (*close_driver) (struct outp_driver *);
+    bool (*open_driver) (struct outp_driver *, const char *options);
+    bool (*close_driver) (struct outp_driver *);
 
 
-    int (*open_page) (struct outp_driver *);
-    int (*close_page) (struct outp_driver *);
+    void (*open_page) (struct outp_driver *);
+    void (*close_page) (struct outp_driver *);
 
 
-    /* special != 0: Used to submit entities for output. */
+    /* special != 0 only. */
     void (*submit) (struct outp_driver *, struct som_entity *);
     
     void (*submit) (struct outp_driver *, struct som_entity *);
     
-    /* special != 0: Methods below need not be defined. */
-    
-    /* Line methods. */
-    void (*line_horz) (struct outp_driver *, const struct rect *,
-                      const struct color *, int style);
-    void (*line_vert) (struct outp_driver *, const struct rect *,
-                      const struct color *, int style);
-    void (*line_intersection) (struct outp_driver *, const struct rect *,
-                              const struct color *,
-                              const struct outp_styles *style);
-
-    /* Drawing methods. */
-    void (*box) (struct outp_driver *, const struct rect *,
-                const struct color *bord, const struct color *fill);
-    void (*polyline_begin) (struct outp_driver *, const struct color *);
-    void (*polyline_point) (struct outp_driver *, int, int);
-    void (*polyline_end) (struct outp_driver *);
-
-    /* Text methods. */
-    void (*text_set_font_by_name) (struct outp_driver *, const char *s);
-    void (*text_set_font_by_position) (struct outp_driver *, int);
-    void (*text_set_font_family) (struct outp_driver *, const char *s);
-    const char *(*text_get_font_name) (struct outp_driver *);
-    const char *(*text_get_font_family) (struct outp_driver *);
-    int (*text_set_size) (struct outp_driver *, int);
-    int (*text_get_size) (struct outp_driver *, int *em_width);
-    void (*text_metrics) (struct outp_driver *, struct outp_text *);
-    void (*text_draw) (struct outp_driver *, struct outp_text *);
-
+    /* special == 0 only.  */
+    void (*line) (struct outp_driver *, int x0, int y0, int x1, int y1,
+                  enum outp_line_style top, enum outp_line_style left,
+                  enum outp_line_style bottom, enum outp_line_style right);
+    void (*text_metrics) (struct outp_driver *, const struct outp_text *,
+                          int *width, int *height);
+    void (*text_draw) (struct outp_driver *, const struct outp_text *);
     void (*initialise_chart)(struct outp_driver *, struct chart *);
     void (*finalise_chart)(struct outp_driver *, struct chart *);
     void (*initialise_chart)(struct outp_driver *, struct chart *);
     void (*finalise_chart)(struct outp_driver *, struct chart *);
-
   };
 
 /* Device types. */
   };
 
 /* Device types. */
@@ -183,31 +97,24 @@ enum
     OUTP_DEV_LISTING = 001,    /* Listing device. */
     OUTP_DEV_SCREEN = 002,     /* Screen device. */
     OUTP_DEV_PRINTER = 004,    /* Printer device. */
     OUTP_DEV_LISTING = 001,    /* Listing device. */
     OUTP_DEV_SCREEN = 002,     /* Screen device. */
     OUTP_DEV_PRINTER = 004,    /* Printer device. */
-    OUTP_DEV_DISABLED = 010    /* Broken device. */
   };
 
 /* Defines the configuration of an output driver. */
 struct outp_driver
   {
   };
 
 /* Defines the configuration of an output driver. */
 struct outp_driver
   {
-    struct outp_class *class;          /* Driver class. */
+    struct outp_driver *next, *prev; /* List of drivers. */
+    struct outp_class *class;  /* Driver class. */
     char *name;                        /* Name of this driver. */
     char *name;                        /* Name of this driver. */
-    int driver_open;           /* 1=driver is open, 0=driver is closed. */
-    int page_open;             /* 1=page is open, 0=page is closed. */
-
-    struct outp_driver *next, *prev;   /* Next, previous output driver in list. */
-
+    bool page_open;            /* 1=page is open, 0=page is closed. */
     int device;                        /* Zero or more of OUTP_DEV_*. */
     int device;                        /* Zero or more of OUTP_DEV_*. */
-    int res, horiz, vert;      /* Device resolution. */
-    int width, length;         /* Page size. */
-
     int cp_x, cp_y;            /* Current position. */
     int cp_x, cp_y;            /* Current position. */
+
+    int width, length;         /* Page size. */
     int font_height;           /* Default font character height. */
     int prop_em_width;         /* Proportional font em width. */
     int fixed_width;           /* Fixed-pitch font character width. */
     int horiz_line_width[OUTP_L_COUNT];        /* Width of horizontal lines. */
     int vert_line_width[OUTP_L_COUNT]; /* Width of vertical lines. */
     int font_height;           /* Default font character height. */
     int prop_em_width;         /* Proportional font em width. */
     int fixed_width;           /* Fixed-pitch font character width. */
     int horiz_line_width[OUTP_L_COUNT];        /* Width of horizontal lines. */
     int vert_line_width[OUTP_L_COUNT]; /* Width of vertical lines. */
-    int horiz_line_spacing[1 << OUTP_L_COUNT];
-    int vert_line_spacing[1 << OUTP_L_COUNT];
 
     void *ext;                 /* Private extension record. */
     void *prc;                 /* Per-procedure extension record. */
 
     void *ext;                 /* Private extension record. */
     void *prc;                 /* Per-procedure extension record. */
@@ -221,21 +128,6 @@ struct outp_option
     int subcat;                        /* Subcategory. */
   };
 
     int subcat;                        /* Subcategory. */
   };
 
-/* Information structure for the keyword recognizer. */
-struct outp_option_info
-  {
-    char *initial;                     /* Initial characters. */
-    struct outp_option **options;      /* Search starting points. */
-  };
-
-/* A list of driver classes. */
-struct outp_driver_class_list
-  {
-    int ref_count;
-    struct outp_class *class;
-    struct outp_driver_class_list *next;
-  };
-
 /* List of configured output drivers. */
 extern struct outp_driver *outp_driver_list;
 
 /* List of configured output drivers. */
 extern struct outp_driver *outp_driver_list;
 
@@ -256,15 +148,20 @@ void outp_list_classes (void);
 void outp_enable_device (int enable, int device);
 struct outp_driver *outp_drivers (struct outp_driver *);
 
 void outp_enable_device (int enable, int device);
 struct outp_driver *outp_drivers (struct outp_driver *);
 
-int outp_match_keyword (const char *, struct outp_option *,
-                       struct outp_option_info *, int *);
+bool outp_parse_options (const char *options,
+                         bool (*) (struct outp_driver *, const char *key,
+                                   const struct string *value),
+                         struct outp_driver *);
+int outp_match_keyword (const char *, struct outp_option *, int *);
 
 int outp_evaluate_dimension (char *, char **);
 int outp_get_paper_size (char *, int *h, int *v);
 
 
 int outp_evaluate_dimension (char *, char **);
 int outp_get_paper_size (char *, int *h, int *v);
 
-int outp_eject_page (struct outp_driver *);
+void outp_open_page (struct outp_driver *);
+void outp_close_page (struct outp_driver *);
+void outp_eject_page (struct outp_driver *);
 
 
-int outp_string_width (struct outp_driver *, const char *);
+int outp_string_width (struct outp_driver *, const char *, enum outp_font);
 
 /* Imported from som-frnt.c. */
 void som_destroy_driver (struct outp_driver *);
 
 /* Imported from som-frnt.c. */
 void som_destroy_driver (struct outp_driver *);
index b26676a92096c441254e9ab67245ad2120792e93..53e81104f87851069ce7d3598876f786bf141001 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <blp@gnu.org>.
 
    This program is free software; you can redistribute it and/or
    Written by Ben Pfaff <blp@gnu.org>.
 
    This program is free software; you can redistribute it and/or
 #include <config.h>
 
 #include <ctype.h>
 #include <config.h>
 
 #include <ctype.h>
-#include "chart.h"
-#include <libpspp/message.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <time.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <time.h>
-
-#if HAVE_UNISTD_H
 #include <unistd.h>
 #include <unistd.h>
-#endif
 
 #include <libpspp/alloc.h>
 #include <libpspp/bit-vector.h>
 #include <libpspp/compiler.h>
 
 #include <libpspp/alloc.h>
 #include <libpspp/bit-vector.h>
 #include <libpspp/compiler.h>
+#include <libpspp/freaderror.h>
+#include <libpspp/hash.h>
 #include <libpspp/message.h>
 #include <libpspp/message.h>
+#include <libpspp/misc.h>
+#include <libpspp/start-date.h>
+#include <libpspp/version.h>
+
 #include <data/filename.h>
 #include <data/filename.h>
-#include "font.h"
+
+#include "afm.h"
+#include "chart.h"
+#include "error.h"
 #include "getline.h"
 #include "getline.h"
-#include <libpspp/hash.h>
 #include "intprops.h"
 #include "intprops.h"
-#include <libpspp/misc.h>
-#include "output.h"
 #include "manager.h"
 #include "manager.h"
-#include <libpspp/start-date.h>
-#include <libpspp/version.h>
+#include "minmax.h"
+#include "output.h"
+#include "size_max.h"
+#include "strsep.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
-/* FIXMEs:
-
-   optimize-text-size not implemented.
-   
-   Line buffering is the only possibility; page buffering should also
-   be possible.
-
-   max-fonts-simult
-   
-   Should add a field to give a file that has a list of fonts
-   typically used.
-   
-   Should add an option that tells the driver it can emit %%Include:'s.
-   
-   Should have auto-encode=true stream-edit or whatever to allow
-   addition to list of encodings.
-   
-   Should align fonts of different sizes along their baselines (see
-   text()).  */
-
 /* PostScript driver options: (defaults listed first)
 
    output-file="pspp.ps"
 /* PostScript driver options: (defaults listed first)
 
    output-file="pspp.ps"
-   color=yes|no
-   data=clean7bit|clean8bit|binary
-   line-ends=lf|crlf
 
    paper-size=letter (see "papersize" file)
    orientation=portrait|landscape
    headers=on|off
 
    paper-size=letter (see "papersize" file)
    orientation=portrait|landscape
    headers=on|off
-   
+
    left-margin=0.5in
    right-margin=0.5in
    top-margin=0.5in
    bottom-margin=0.5in
 
    left-margin=0.5in
    right-margin=0.5in
    top-margin=0.5in
    bottom-margin=0.5in
 
-   font-dir=devps
-   prologue-file=ps-prologue
-   device-file=DESC
-   encoding-file=ps-encodings
-   auto-encode=true|false
-
-   prop-font-family=T
-   fixed-font-family=C
+   prop-font=Times-Roman
+   emph-font=Times-Italic
+   fixed-font=Courier
    font-size=10000
 
    font-size=10000
 
-   line-style=thick|double
-   line-gutter=0.5pt
-   line-spacing=0.5pt
+   line-gutter=1pt
+   line-spacing=1pt
    line-width=0.5pt
    line-width=0.5pt
-   line-width-thick=1pt
-
-   optimize-text-size=1|0|2
-   optimize-line-size=1|0
-   max-fonts-simult=0     Max # of fonts in printer memory at once (0=infinite)
  */
 
  */
 
-/* The number of `psus' (PostScript driver UnitS) per inch.  Although
-   this is a #define, the value is expected never to change.  If it
-   does, review all uses.  */
+/* The number of `psus' (PostScript driver UnitS) per inch. */
 #define PSUS 72000
 
 #define PSUS 72000
 
-/* Magic numbers for PostScript and EPSF drivers. */
-enum
-  {
-    MAGIC_PS,
-    MAGIC_EPSF
-  };
-
-/* Orientations. */
-enum
-  {
-    OTN_PORTRAIT,              /* Portrait. */
-    OTN_LANDSCAPE              /* Landscape. */
-  };
-
-/* Output options. */
-enum
-  {
-    OPO_MIRROR_HORZ = 001,     /* 1=Mirror across a horizontal axis. */
-    OPO_MIRROR_VERT = 002,     /* 1=Mirror across a vertical axis. */
-    OPO_ROTATE_180 = 004,      /* 1=Rotate the page 180 degrees. */
-    OPO_COLOR = 010,           /* 1=Enable color. */
-    OPO_HEADERS = 020,         /* 1=Draw headers at top of page. */
-    OPO_AUTO_ENCODE = 040,     /* 1=Add encodings semi-intelligently. */
-    OPO_DOUBLE_LINE = 0100     /* 1=Double lines instead of thick lines. */
-  };
-
-/* Data allowed in output. */
-enum
-  {
-    ODA_CLEAN7BIT,             /* 0x09, 0x0a, 0x0d, 0x1b...0x7e */
-    ODA_CLEAN8BIT,             /* 0x09, 0x0a, 0x0d, 0x1b...0xff */
-    ODA_BINARY,                        /* 0x00...0xff */
-    ODA_COUNT
-  };
-
-/* Types of lines for purpose of caching. */
-enum
-  {
-    horz,                      /* Single horizontal. */
-    dbl_horz,                  /* Double horizontal. */
-    spl_horz,                  /* Special horizontal. */
-    vert,                      /* Single vertical. */
-    dbl_vert,                  /* Double vertical. */
-    spl_vert,                  /* Special vertical. */
-    n_line_types
-  };
-
-/* Cached line. */
-struct line_form
-  {
-    int ind;                   /* Independent var.  Don't reorder. */
-    int mdep;                  /* Maximum number of dependent var pairs. */
-    int ndep;                  /* Current number of dependent var pairs. */
-    int dep[1][2];             /* Dependent var pairs. */
-  };
-
-/* Contents of ps_driver_ext.loaded. */
-struct font_entry
-  {
-    char *dit;                 /* Font Groff name. */
-    struct font_desc *font;    /* Font descriptor. */
-  };
-
-/* Combines a font with a font size for benefit of generated code. */
-struct ps_font_combo
-  {
-    struct font_entry *font;   /* Font. */
-    int size;                  /* Font size. */
-    int index;                 /* PostScript index. */
-  };
-
-/* A font encoding. */
-struct ps_encoding
+/* A PostScript font. */
+struct font
   {
   {
-    char *filename;            /* Normalized filename of this encoding. */
-    int index;                 /* Index value. */
+    struct afm *metrics;        /* Metrics. */
+    char *embed_fn;             /* Name of file to embed. */
+    char *encoding_fn;          /* Name of file with encoding. */
   };
 
 /* PostScript output driver extension record. */
 struct ps_driver_ext
   {
   };
 
 /* PostScript output driver extension record. */
 struct ps_driver_ext
   {
-    /* User parameters. */
-    int orientation;           /* OTN_PORTRAIT or OTN_LANDSCAPE. */
-    int output_options;                /* OPO_*. */
-    int data;                  /* ODA_*. */
+    char *file_name;            /* Output file name. */
+    FILE *file;                 /* Output file. */
+
+    bool draw_headers;          /* Draw headers at top of page? */
+    int page_number;           /* Current page number. */
 
 
+    bool portrait;              /* Portrait mode? */
+    int paper_width;            /* Width of paper before dropping margins. */
+    int paper_length;           /* Length of paper before dropping margins. */
     int left_margin;           /* Left margin in psus. */
     int right_margin;          /* Right margin in psus. */
     int top_margin;            /* Top margin in psus. */
     int bottom_margin;         /* Bottom margin in psus. */
 
     int left_margin;           /* Left margin in psus. */
     int right_margin;          /* Right margin in psus. */
     int top_margin;            /* Top margin in psus. */
     int bottom_margin;         /* Bottom margin in psus. */
 
-    char eol[3];               /* End of line--CR, LF, or CRLF. */
-    
-    char *font_dir;            /* Font directory relative to font path. */
-    char *prologue_fn;         /* Prologue's filename relative to font dir. */
-    char *desc_fn;             /* DESC filename relative to font dir. */
-    char *encoding_fn;         /* Encoding's filename relative to font dir. */
-
-    char *prop_family;         /* Default proportional font family. */
-    char *fixed_family;                /* Default fixed-pitch font family. */
-    int font_size;             /* Default font size (psus). */
-
     int line_gutter;           /* Space around lines. */
     int line_space;            /* Space between lines. */
     int line_width;            /* Width of lines. */
     int line_gutter;           /* Space around lines. */
     int line_space;            /* Space between lines. */
     int line_width;            /* Width of lines. */
-    int line_width_thick;      /* Width of thick lines. */
 
 
-    int text_opt;              /* Text optimization level. */
-    int line_opt;              /* Line optimization level. */
-    int max_fonts;             /* Max # of simultaneous fonts (0=infinite). */
-
-    /* Internal state. */
-    struct file_ext file;      /* Output file. */
-    int page_number;           /* Current page number. */
-    int file_page_number;      /* Page number in this file. */
-    int w, l;                  /* Paper size. */
-    struct hsh_table *lines[n_line_types];     /* Line buffers. */
-    
-    struct font_entry *prop;   /* Default Roman proportional font. */
-    struct font_entry *fixed;  /* Default Roman fixed-pitch font. */
-    struct hsh_table *loaded;  /* Fonts in memory. */
-
-    struct hsh_table *combos;  /* Combinations of fonts with font sizes. */
-    struct ps_font_combo *last_font;   /* PostScript selected font. */
-    int next_combo;            /* Next font combo position index. */
-
-    struct hsh_table *encodings;/* Set of encodings. */
-    int next_encoding;         /* Next font encoding index. */
-
-    /* Currently selected font. */
-    struct font_entry *current;        /* Current font. */
-    char *family;              /* Font family. */
-    int size;                  /* Size in psus. */
+    struct font *fonts[OUTP_FONT_CNT];
+    int last_font;              /* Index of last font set with setfont. */
   }
 ps_driver_ext;
 
 /* Transform logical y-ordinate Y into a page ordinate. */
 #define YT(Y) (this->length - (Y))
 
   }
 ps_driver_ext;
 
 /* Transform logical y-ordinate Y into a page ordinate. */
 #define YT(Y) (this->length - (Y))
 
-/* Prototypes. */
-static int postopen (struct file_ext *);
-static int preclose (struct file_ext *);
+static bool handle_option (struct outp_driver *this, const char *key,
+                           const struct string *val);
 static void draw_headers (struct outp_driver *this);
 
 static void draw_headers (struct outp_driver *this);
 
-static int compare_font_entry (const void *, const void *, void *param);
-static unsigned hash_font_entry (const void *, void *param);
-static void free_font_entry (void *, void *foo);
-static struct font_entry *load_font (struct outp_driver *, const char *dit);
-static void init_fonts (void);
-static void done_fonts (void);
+static void write_ps_prologue (struct outp_driver *);
 
 
-static void dump_lines (struct outp_driver *this);
+static char *quote_ps_name (const char *string);
 
 
-static void read_ps_encodings (struct outp_driver *this);
-static int compare_ps_encoding (const void *pa, const void *pb, void *foo);
-static unsigned hash_ps_encoding (const void *pa, void *foo);
-static void free_ps_encoding (void *a, void *foo);
-static void add_encoding (struct outp_driver *this, char *filename);
-static struct ps_encoding *default_encoding (struct outp_driver *this);
-
-static int compare_ps_combo (const void *pa, const void *pb, void *foo);
-static unsigned hash_ps_combo (const void *pa, void *foo);
-static void free_ps_combo (void *a, void *foo);
-
-static char *quote_ps_name (char *dest, const char *string);
-static char *quote_ps_string (char *dest, const char *string);
+static struct font *load_font (const char *string);
+static void free_font (struct font *);
+static void setup_font (struct outp_driver *this, struct font *, int index);
 \f
 /* Driver initialization. */
 
 \f
 /* Driver initialization. */
 
-static int
-ps_open_global (struct outp_class *this UNUSED)
-{
-  init_fonts ();
-  groff_init ();
-  return 1;
-}
-
-static int
-ps_close_global (struct outp_class *this UNUSED)
-{
-  groff_done ();
-  done_fonts ();
-  return 1;
-}
-
-static int *
-ps_font_sizes (struct outp_class *this UNUSED, int *n_valid_sizes)
-{
-  /* Allow fonts up to 1" in height. */
-  static int valid_sizes[] =
-  {1, PSUS, 0, 0};
-
-  assert (n_valid_sizes != NULL);
-  *n_valid_sizes = 1;
-  return valid_sizes;
-}
-
-static int
-ps_preopen_driver (struct outp_driver *this)
+static bool
+ps_open_driver (struct outp_driver *this, const char *options)
 {
   struct ps_driver_ext *x;
 {
   struct ps_driver_ext *x;
-  
-  int i;
+  size_t i;
 
 
-  assert (this->driver_open == 0);
-  msg (VM (1), _("PostScript driver initializing as `%s'..."), this->name);
-       
-  this->ext = x = xmalloc (sizeof *x);
-  this->res = PSUS;
-  this->horiz = this->vert = 1;
   this->width = this->length = 0;
   this->width = this->length = 0;
+  this->font_height = PSUS * 10 / 72;
 
 
-  x->orientation = OTN_PORTRAIT;
-  x->output_options = OPO_COLOR | OPO_HEADERS | OPO_AUTO_ENCODE;
-  x->data = ODA_CLEAN7BIT;
-       
-  x->left_margin = x->right_margin =
-    x->top_margin = x->bottom_margin = PSUS / 2;
-       
-  strcpy (x->eol, "\n");
-
-  x->font_dir = NULL;
-  x->prologue_fn = NULL;
-  x->desc_fn = NULL;
-  x->encoding_fn = NULL;
-
-  x->prop_family = NULL;
-  x->fixed_family = NULL;
-  x->font_size = PSUS * 10 / 72;
-
-  x->line_gutter = PSUS / 144;
-  x->line_space = PSUS / 144;
-  x->line_width = PSUS / 144;
-  x->line_width_thick = PSUS / 48;
-
-  x->text_opt = -1;
-  x->line_opt = -1;
-  x->max_fonts = 0;
-
-  x->file.filename = NULL;
-  x->file.mode = "wb";
-  x->file.file = NULL;
-  x->file.sequence_no = &x->page_number;
-  x->file.param = this;
-  x->file.postopen = postopen;
-  x->file.preclose = preclose;
+  this->ext = x = xmalloc (sizeof *x);
+  x->file_name = xstrdup ("pspp.ps");
+  x->file = NULL;
+  x->draw_headers = true;
   x->page_number = 0;
   x->page_number = 0;
-  x->w = x->l = 0;
-
-  x->file_page_number = 0;
-  for (i = 0; i < n_line_types; i++)
-    x->lines[i] = NULL;
-  x->last_font = NULL;
-
-  x->prop = NULL;
-  x->fixed = NULL;
-  x->loaded = NULL;
-
-  x->next_combo = 0;
-  x->combos = NULL;
-
-  x->encodings = hsh_create (31, compare_ps_encoding, hash_ps_encoding,
-                            free_ps_encoding, NULL);
-  x->next_encoding = 0;
-
-  x->current = NULL;
-  x->family = NULL;
-  x->size = 0;
-
-  return 1;
-}
+  x->portrait = true;
+  x->paper_width = PSUS * 17 / 2;
+  x->paper_length = PSUS * 11;
+  x->left_margin = PSUS / 2;
+  x->right_margin = PSUS / 2;
+  x->top_margin = PSUS / 2;
+  x->bottom_margin = PSUS / 2;
+  x->line_gutter = PSUS / 72;
+  x->line_space = PSUS / 72;
+  x->line_width = PSUS / 144;
+  for (i = 0; i < OUTP_FONT_CNT; i++)
+    x->fonts[i] = NULL;
 
 
-static int
-ps_postopen_driver (struct outp_driver *this)
-{
-  struct ps_driver_ext *x = this->ext;
-  
-  assert (this->driver_open == 0);
+  outp_parse_options (options, handle_option, this);
 
 
-  if (this->width == 0)
+  x->file = fn_open (x->file_name, "w");
+  if (x->file == NULL)
     {
     {
-      this->width = PSUS * 17 / 2;     /* Defaults to 8.5"x11". */
-      this->length = PSUS * 11;
+      error (0, errno, _("opening PostScript output file \"%s\""),
+             x->file_name);
+      goto error;
     }
 
     }
 
-  if (x->text_opt == -1)
-    x->text_opt = (this->device & OUTP_DEV_SCREEN) ? 0 : 1;
-  if (x->line_opt == -1)
-    x->line_opt = (this->device & OUTP_DEV_SCREEN) ? 0 : 1;
-
-  x->w = this->width;
-  x->l = this->length;
-  if (x->orientation == OTN_LANDSCAPE)
+  if (x->portrait) 
     {
     {
-      int temp = this->width;
-      this->width = this->length;
-      this->length = temp;
+      this->width = x->paper_width;
+      this->length = x->paper_length;
     }
     }
+  else
+    {
+      this->width = x->paper_length;
+      this->length = x->paper_width;
+    }    
   this->width -= x->left_margin + x->right_margin;
   this->length -= x->top_margin + x->bottom_margin;
   this->width -= x->left_margin + x->right_margin;
   this->length -= x->top_margin + x->bottom_margin;
-  if (x->output_options & OPO_HEADERS)
+  if (x->draw_headers)
     {
     {
-      this->length -= 3 * x->font_size;
-      x->top_margin += 3 * x->font_size;
+      int header_length = 3 * this->font_height;
+      this->length -= header_length;
+      x->top_margin += header_length;
     }
     }
-  if (NULL == x->file.filename)
-    x->file.filename = xstrdup ("pspp.ps");
 
 
-  if (x->font_dir == NULL)
-    x->font_dir = xstrdup ("devps");
-  if (x->prologue_fn == NULL)
-    x->prologue_fn = xstrdup ("ps-prologue");
-  if (x->desc_fn == NULL)
-    x->desc_fn = xstrdup ("DESC");
-  if (x->encoding_fn == NULL)
-    x->encoding_fn = xstrdup ("ps-encodings");
+  for (i = 0; i < OUTP_FONT_CNT; i++)
+    if (x->fonts[i] == NULL)
+      {
+        const char *default_fonts[OUTP_FONT_CNT];
+        default_fonts[OUTP_FIXED] = "Courier.afm";
+        default_fonts[OUTP_PROPORTIONAL] = "Times-Roman.afm";
+        default_fonts[OUTP_EMPHASIS] = "Times-Italic.afm";
+        x->fonts[i] = load_font (default_fonts[i]);
+        if (x->fonts[i] == NULL)
+          goto error;
+      }
 
 
-  if (x->prop_family == NULL)
-    x->prop_family = xstrdup ("H");
-  if (x->fixed_family == NULL)
-    x->fixed_family = xstrdup ("C");
+  if (this->length / this->font_height < 15)
+    {
+      error (0, 0, _("The defined PostScript page is not long "
+                     "enough to hold margins and headers, plus least 15 "
+                     "lines of the default fonts.  In fact, there's only "
+                     "room for %d lines of each font at the default size "
+                     "of %d.%03d points."),
+          this->length / this->font_height,
+          this->font_height / 1000, this->font_height % 1000);
+      goto error;
+    }
 
 
-  read_ps_encodings (this);
+  this->fixed_width =
+    afm_get_character (x->fonts[OUTP_FIXED]->metrics, '0')->width
+    * this->font_height / 1000;
+  this->prop_em_width =
+    afm_get_character (x->fonts[OUTP_PROPORTIONAL]->metrics, '0')->width
+    * this->font_height / 1000;
 
 
-  x->family = NULL;
-  x->size = PSUS / 6;
+  this->horiz_line_width[OUTP_L_NONE] = 0;
+  this->horiz_line_width[OUTP_L_SINGLE] = 2 * x->line_gutter + x->line_width;
+  this->horiz_line_width[OUTP_L_DOUBLE] = (2 * x->line_gutter + x->line_space
+                                           + 2 * x->line_width);
+  memcpy (this->vert_line_width, this->horiz_line_width,
+          sizeof this->vert_line_width);
 
 
-  if (this->length / x->font_size < 15)
-    {
-      msg (SE, _("PostScript driver: The defined page is not long "
-                "enough to hold margins and headers, plus least 15 "
-                "lines of the default fonts.  In fact, there's only "
-                "room for %d lines of each font at the default size "
-                "of %d.%03d points."),
-          this->length / x->font_size,
-          x->font_size / 1000, x->font_size % 1000);
-      return 0;
-    }
+  write_ps_prologue (this);
 
 
-  this->driver_open = 1;
-  msg (VM (2), _("%s: Initialization complete."), this->name);
+  return true;
 
 
-  return 1;
+ error:
+  this->class->close_driver (this);
+  return false;
 }
 
 }
 
-static int
+static bool
 ps_close_driver (struct outp_driver *this)
 {
   struct ps_driver_ext *x = this->ext;
 ps_close_driver (struct outp_driver *this)
 {
   struct ps_driver_ext *x = this->ext;
-  
-  int i;
-
-  assert (this->driver_open == 1);
-  msg (VM (2), _("%s: Beginning closing..."), this->name);
-  
-  fn_close_ext (&x->file);
-  free (x->file.filename);
-  free (x->font_dir);
-  free (x->prologue_fn);
-  free (x->desc_fn);
-  free (x->encoding_fn);
-  free (x->prop_family);
-  free (x->fixed_family);
-  free (x->family);
-  for (i = 0; i < n_line_types; i++)
-    hsh_destroy (x->lines[i]);
-  hsh_destroy (x->encodings);
-  hsh_destroy (x->combos);
-  hsh_destroy (x->loaded);
+  bool ok;
+  size_t i;
+
+  fprintf (x->file,
+          "%%%%Trailer\n"
+           "%%%%Pages: %d\n"
+           "%%%%EOF\n",
+           x->page_number);
+
+  ok = fn_close (x->file_name, x->file) == 0;
+  if (!ok)
+    error (0, errno, _("closing PostScript output file \"%s\""), x->file_name);
+  free (x->file_name);
+  for (i = 0; i < OUTP_FONT_CNT; i++)
+    free_font (x->fonts[i]);
   free (x);
   free (x);
-  
-  this->driver_open = 0;
-  msg (VM (3), _("%s: Finished closing."), this->name);
-
-  return 1;
-}
-
-/* font_entry comparison function for hash tables. */
-static int
-compare_font_entry (const void *a, const void *b, void *foobar UNUSED)
-{
-  return strcmp (((struct font_entry *) a)->dit, ((struct font_entry *) b)->dit);
-}
-
-/* font_entry hash function for hash tables. */
-static unsigned
-hash_font_entry (const void *fe_, void *foobar UNUSED)
-{
-  const struct font_entry *fe = fe_;
-  return hsh_hash_string (fe->dit);
-}
 
 
-/* font_entry destructor function for hash tables. */
-static void
-free_font_entry (void *pa, void *foo UNUSED)
-{
-  struct font_entry *a = pa;
-  free (a->dit);
-  free (a);
+  return ok;
 }
 
 /* Generic option types. */
 enum
 {
 }
 
 /* Generic option types. */
 enum
 {
-  boolean_arg = -10,
+  output_file_arg,
+  paper_size_arg,
+  orientation_arg,
+  line_style_arg,
+  boolean_arg,
   pos_int_arg,
   dimension_arg,
   string_arg,
   pos_int_arg,
   dimension_arg,
   string_arg,
@@ -525,145 +273,71 @@ enum
 /* All the options that the PostScript driver supports. */
 static struct outp_option option_tab[] =
 {
 /* All the options that the PostScript driver supports. */
 static struct outp_option option_tab[] =
 {
-  /* *INDENT-OFF* */
-  {"output-file",              1,              0},
-  {"paper-size",               2,              0},
-  {"orientation",              3,              0},
-  {"color",                    boolean_arg,    0},
-  {"data",                     4,              0},
-  {"auto-encode",              boolean_arg,    5},
+  {"output-file",              output_file_arg,0},
+  {"paper-size",               paper_size_arg, 0},
+  {"orientation",              orientation_arg,0},
+
   {"headers",                  boolean_arg,    1},
   {"headers",                  boolean_arg,    1},
+
+  {"prop-font",                string_arg,     OUTP_PROPORTIONAL},
+  {"emph-font",                string_arg,     OUTP_EMPHASIS},
+  {"fixed-font",               string_arg,     OUTP_FIXED},
+
   {"left-margin",              pos_int_arg,    0},
   {"right-margin",             pos_int_arg,    1},
   {"top-margin",               pos_int_arg,    2},
   {"bottom-margin",            pos_int_arg,    3},
   {"left-margin",              pos_int_arg,    0},
   {"right-margin",             pos_int_arg,    1},
   {"top-margin",               pos_int_arg,    2},
   {"bottom-margin",            pos_int_arg,    3},
-  {"font-dir",                 string_arg,     0},
-  {"prologue-file",            string_arg,     1},
-  {"device-file",              string_arg,     2},
-  {"encoding-file",            string_arg,     3},
-  {"prop-font-family",         string_arg,     5},
-  {"fixed-font-family",                string_arg,     6},
   {"font-size",                        pos_int_arg,    4},
   {"font-size",                        pos_int_arg,    4},
-  {"optimize-text-size",       nonneg_int_arg, 0},
-  {"optimize-line-size",       nonneg_int_arg, 1},
-  {"max-fonts-simult",         nonneg_int_arg, 2},
-  {"line-ends",                        6,              0},
-  {"line-style",               7,              0},
+
+  {"line-width",               dimension_arg,  0},
+  {"line-gutter",              dimension_arg,  1},
   {"line-width",               dimension_arg,  2},
   {"line-width",               dimension_arg,  2},
-  {"line-gutter",              dimension_arg,  3},
-  {"line-width",               dimension_arg,  4},
-  {"line-width-thick",         dimension_arg,  5},
-  {"", 0, 0},
-  /* *INDENT-ON* */
+  {NULL, 0, 0},
 };
 };
-static struct outp_option_info option_info;
 
 
-static void
-ps_option (struct outp_driver *this, const char *key, const struct string *val)
+static bool
+handle_option (struct outp_driver *this, const char *key,
+               const struct string *val)
 {
   struct ps_driver_ext *x = this->ext;
 {
   struct ps_driver_ext *x = this->ext;
-  int cat, subcat;
+  int subcat;
   char *value = ds_c_str (val);
 
   char *value = ds_c_str (val);
 
-  cat = outp_match_keyword (key, option_tab, &option_info, &subcat);
-
-  switch (cat)
+  switch (outp_match_keyword (key, option_tab, &subcat))
     {
     {
-    case 0:
-      msg (SE, _("Unknown configuration parameter `%s' for PostScript device "
-          "driver."), key);
+    case -1:
+      error (0, 0,
+             _("unknown configuration parameter `%s' for PostScript device "
+               "driver"), key);
       break;
       break;
-    case 1:
-      free (x->file.filename);
-      x->file.filename = xstrdup (value);
+    case output_file_arg:
+      free (x->file_name);
+      x->file_name = xstrdup (value);
       break;
       break;
-    case 2:
+    case paper_size_arg:
       outp_get_paper_size (value, &this->width, &this->length);
       break;
       outp_get_paper_size (value, &this->width, &this->length);
       break;
-    case 3:
+    case orientation_arg:
       if (!strcmp (value, "portrait"))
       if (!strcmp (value, "portrait"))
-       x->orientation = OTN_PORTRAIT;
+       x->portrait = true;
       else if (!strcmp (value, "landscape"))
       else if (!strcmp (value, "landscape"))
-       x->orientation = OTN_LANDSCAPE;
-      else
-       msg (SE, _("Unknown orientation `%s'.  Valid orientations are "
-            "`portrait' and `landscape'."), value);
-      break;
-    case 4:
-      if (!strcmp (value, "clean7bit") || !strcmp (value, "Clean7Bit"))
-       x->data = ODA_CLEAN7BIT;
-      else if (!strcmp (value, "clean8bit")
-              || !strcmp (value, "Clean8Bit"))
-       x->data = ODA_CLEAN8BIT;
-      else if (!strcmp (value, "binary") || !strcmp (value, "Binary"))
-       x->data = ODA_BINARY;
-      else
-       msg (SE, _("Unknown value for `data'.  Valid values are `clean7bit', "
-            "`clean8bit', and `binary'."));
-      break;
-    case 6:
-      if (!strcmp (value, "lf"))
-       strcpy (x->eol, "\n");
-      else if (!strcmp (value, "crlf"))
-       strcpy (x->eol, "\r\n");
-      else
-       msg (SE, _("Unknown value for `line-ends'.  Valid values are `lf' and "
-                  "`crlf'."));
-      break;
-    case 7:
-      if (!strcmp (value, "thick"))
-       x->output_options &= ~OPO_DOUBLE_LINE;
-      else if (!strcmp (value, "double"))
-       x->output_options |= OPO_DOUBLE_LINE;
+       x->portrait = false;
       else
       else
-       msg (SE, _("Unknown value for `line-style'.  Valid values are `thick' "
-                  "and `double'."));
+       error (0, 0, _("unknown orientation `%s' (valid orientations are "
+                       "`portrait' and `landscape')"), value);
       break;
     case boolean_arg:
       break;
     case boolean_arg:
-      {
-       int setting;
-       int mask;
-
-       if (!strcmp (value, "on") || !strcmp (value, "true")
-           || !strcmp (value, "yes") || atoi (value))
-         setting = 1;
-       else if (!strcmp (value, "off") || !strcmp (value, "false")
-                || !strcmp (value, "no") || !strcmp (value, "0"))
-         setting = 0;
-       else
-         {
-           msg (SE, _("Boolean value expected for %s."), key);
-           return;
-         }
-       switch (subcat)
-         {
-         case 0:
-           mask = OPO_COLOR;
-           break;
-         case 1:
-           mask = OPO_HEADERS;
-           break;
-         case 2:
-           mask = OPO_MIRROR_HORZ;
-           break;
-         case 3:
-           mask = OPO_MIRROR_VERT;
-           break;
-         case 4:
-           mask = OPO_ROTATE_180;
-           break;
-         case 5:
-           mask = OPO_AUTO_ENCODE;
-           break;
-         default:
-           assert (0);
-            abort ();
-         }
-       if (setting)
-         x->output_options |= mask;
-       else
-         x->output_options &= ~mask;
-      }
+      if (!strcmp (value, "on") || !strcmp (value, "true")
+          || !strcmp (value, "yes") || atoi (value))
+        x->draw_headers = true;
+      else if (!strcmp (value, "off") || !strcmp (value, "false")
+               || !strcmp (value, "no") || !strcmp (value, "0"))
+        x->draw_headers = false;
+      else
+        {
+          error (0, 0, _("boolean value expected for %s"), key);
+          return false;
+        }
       break;
     case pos_int_arg:
       {
       break;
     case pos_int_arg:
       {
@@ -674,13 +348,13 @@ ps_option (struct outp_driver *this, const char *key, const struct string *val)
        arg = strtol (value, &tail, 0);
        if (arg < 1 || errno == ERANGE || *tail)
          {
        arg = strtol (value, &tail, 0);
        if (arg < 1 || errno == ERANGE || *tail)
          {
-           msg (SE, _("Positive integer required as value for `%s'."), key);
+           error (0, 0, _("positive integer value required for `%s'"), key);
            break;
          }
        if ((subcat == 4 || subcat == 5) && arg < 1000)
          {
            break;
          }
        if ((subcat == 4 || subcat == 5) && arg < 1000)
          {
-           msg (SE, _("Default font size must be at least 1 point (value "
-                "of 1000 for key `%s')."), key);
+           error (0, 0, _("default font size must be at least 1 point (value "
+                           "of 1000 for key `%s')"), key);
            break;
          }
        switch (subcat)
            break;
          }
        switch (subcat)
@@ -698,10 +372,10 @@ ps_option (struct outp_driver *this, const char *key, const struct string *val)
            x->bottom_margin = arg;
            break;
          case 4:
            x->bottom_margin = arg;
            break;
          case 4:
-           x->font_size = arg;
+           this->font_height = arg;
            break;
          default:
            break;
          default:
-           assert (0);
+           abort ();
          }
       }
       break;
          }
       }
       break;
@@ -711,2167 +385,709 @@ ps_option (struct outp_driver *this, const char *key, const struct string *val)
 
        if (dimension <= 0)
          {
 
        if (dimension <= 0)
          {
-           msg (SE, _("Value for `%s' must be a dimension of positive "
-                "length (i.e., `1in')."), key);
+           error (0, 0, _("value for `%s' must be a dimension of positive "
+                           "length (i.e., `1in')"), key);
            break;
          }
        switch (subcat)
          {
            break;
          }
        switch (subcat)
          {
-         case 2:
+         case 0:
            x->line_width = dimension;
            break;
            x->line_width = dimension;
            break;
-         case 3:
+         case 1:
            x->line_gutter = dimension;
            break;
            x->line_gutter = dimension;
            break;
-         case 4:
+         case 2:
            x->line_width = dimension;
            break;
            x->line_width = dimension;
            break;
-         case 5:
-           x->line_width_thick = dimension;
-           break;
          default:
          default:
-           assert (0);
+           abort ();
          }
       }
       break;
     case string_arg:
       {
          }
       }
       break;
     case string_arg:
       {
-       char **dest;
-       switch (subcat)
-         {
-         case 0:
-           dest = &x->font_dir;
-           break;
-         case 1:
-           dest = &x->prologue_fn;
-           break;
-         case 2:
-           dest = &x->desc_fn;
-           break;
-         case 3:
-           dest = &x->encoding_fn;
-           break;
-         case 5:
-           dest = &x->prop_family;
-           break;
-         case 6:
-           dest = &x->fixed_family;
-           break;
-         default:
-           assert (0);
-            abort ();
-         }
-       if (*dest)
-         free (*dest);
-       *dest = xstrdup (value);
-      }
-      break;
-    case nonneg_int_arg:
-      {
-       char *tail;
-       int arg;
-
-       errno = 0;
-       arg = strtol (value, &tail, 0);
-       if (arg < 0 || errno == ERANGE || *tail)
-         {
-           msg (SE, _("Nonnegative integer required as value for `%s'."), key);
-           break;
-         }
-       switch (subcat)
-         {
-         case 0:
-           x->text_opt = arg;
-           break;
-         case 1:
-           x->line_opt = arg;
-           break;
-         case 2:
-           x->max_fonts = arg;
-           break;
-         default:
-           assert (0);
-         }
+        struct font *font = load_font (value);
+        if (font != NULL)
+          {
+            struct font **dst = &x->fonts[subcat];
+            if (*dst != NULL)
+              free_font (*dst);
+            *dst = font;
+          }
       }
       break;
     default:
       }
       break;
     default:
-      assert (0);
+      abort ();
     }
     }
+
+  return true;
 }
 
 /* Looks for a PostScript font file or config file in all the
    appropriate places.  Returns the filename on success, NULL on
    failure. */
 }
 
 /* Looks for a PostScript font file or config file in all the
    appropriate places.  Returns the filename on success, NULL on
    failure. */
-/* PORTME: Filename operations. */
 static char *
 static char *
-find_ps_file (struct outp_driver *this, const char *name)
+find_ps_file (const char *name)
 {
 {
-  struct ps_driver_ext *x = this->ext;
-  char *cp;
-
-  /* x->font_dir + name: "devps/ps-encodings". */
-  char *basename;
-
-  /* Usually equal to groff_font_path. */
-  char *pathname;
-
-  /* Final filename. */
-  char *fn;
-
-  /* Make basename. */
-  basename = local_alloc (strlen (x->font_dir) + 1 + strlen (name) + 1);
-  cp = stpcpy (basename, x->font_dir);
-  *cp++ = DIR_SEPARATOR;
-  strcpy (cp, name);
-
-  /* Decide on search path. */
-  {
-    const char *pre_pathname;
-    
-    pre_pathname = getenv ("STAT_GROFF_FONT_PATH");
-    if (pre_pathname == NULL)
-      pre_pathname = getenv ("GROFF_FONT_PATH");
-    if (pre_pathname == NULL)
-      pre_pathname = groff_font_path;
-    pathname = fn_tilde_expand (pre_pathname);
-  }
-
-  /* Search all possible places for the file. */
-  fn = fn_search_path (basename, pathname, NULL);
-  if (fn == NULL)
-    fn = fn_search_path (basename, config_path, NULL);
-  if (fn == NULL)
-    fn = fn_search_path (name, pathname, NULL);
-  if (fn == NULL)
-    fn = fn_search_path (name, config_path, NULL);
-  free (pathname);
-  local_free (basename);
-
-  return fn;
+  if (fn_absolute_p (name))
+    return xstrdup (name);
+  else
+    {
+      char *base_name = xasprintf ("psfonts%c%s", DIR_SEPARATOR, name);
+      char *file_name = fn_search_path (base_name, config_path, NULL);
+      free (base_name);
+      return file_name;
+    }
 }
 \f
 }
 \f
-/* Encodings. */
-
-/* Hash table comparison function for ps_encoding's. */
-static int
-compare_ps_encoding (const void *pa, const void *pb, void *foo UNUSED)
-{
-  const struct ps_encoding *a = pa;
-  const struct ps_encoding *b = pb;
-
-  return strcmp (a->filename, b->filename);
-}
+/* Basic file operations. */
 
 
-/* Hash table hash function for ps_encoding's. */
-static unsigned
-hash_ps_encoding (const void *pa, void *foo UNUSED)
+/* Writes the PostScript prologue to file F. */
+static void
+write_ps_prologue (struct outp_driver *this)
 {
 {
-  const struct ps_encoding *a = pa;
+  struct ps_driver_ext *x = this->ext;
+  size_t embedded_cnt, preloaded_cnt;
+  size_t i;
 
 
-  return hsh_hash_string (a->filename);
-}
+  fputs ("%!PS-Adobe-3.0\n", x->file);
+  fputs ("%%Pages: (atend)\n", x->file);
 
 
-/* Hash table free function for ps_encoding's. */
-static void
-free_ps_encoding (void *pa, void *foo UNUSED)
+  embedded_cnt = preloaded_cnt = 0;
+  for (i = 0; i < OUTP_FONT_CNT; i++)
+    {
+      bool embed = x->fonts[i]->embed_fn != NULL;
+      embedded_cnt += embed;
+      preloaded_cnt += !embed;
+    }
+  if (preloaded_cnt > 0)
+    {
+      fputs ("%%DocumentNeededResources: font", x->file);
+      for (i = 0; i < OUTP_FONT_CNT; i++)
+        {
+          struct font *f = x->fonts[i];
+          if (f->embed_fn == NULL)
+            fprintf (x->file, " %s", afm_get_findfont_name (f->metrics));
+        }
+      fputs ("\n", x->file);
+    }
+  if (embedded_cnt > 0)
+    {
+      fputs ("%%DocumentSuppliedResources: font", x->file);
+      for (i = 0; i < OUTP_FONT_CNT; i++)
+        {
+          struct font *f = x->fonts[i];
+          if (f->embed_fn != NULL)
+            fprintf (x->file, " %s", afm_get_findfont_name (f->metrics));
+        }
+      fputs ("\n", x->file);
+    }
+  fputs ("%%Copyright: This prologue is public domain.\n", x->file);
+  fprintf (x->file, "%%%%Creator: %s\n", version);
+  fprintf (x->file, "%%%%DocumentMedia: Plain %g %g 75 white ()\n",
+           x->paper_width / (PSUS / 72.0), x->paper_length / (PSUS / 72.0));
+  fprintf (x->file, "%%%%Orientation: %s\n",
+           x->portrait ? "Portrait" : "Landscape");
+  fputs ("%%EndComments\n", x->file);
+  fputs ("%%BeginDefaults\n", x->file);
+  fputs ("%%PageResources: font", x->file);
+  for (i = 0; i < OUTP_FONT_CNT; i++)
+    fprintf (x->file, " %s", afm_get_findfont_name (x->fonts[i]->metrics));
+  fputs ("\n", x->file);
+  fputs ("%%EndDefaults\n", x->file);
+  fputs ("%%BeginProlog\n", x->file);
+  fputs ("/ED{exch def}bind def\n", x->file);
+  fputs ("/L{moveto lineto stroke}bind def\n", x->file);
+  fputs ("/D{moveto lineto moveto lineto stroke}bind def\n", x->file);
+  fputs ("/S{show}bind def\n", x->file);
+  fputs ("/GS{glyphshow}def\n", x->file);
+  fputs ("/RF{\n", x->file);
+  fputs (" exch dup maxlength 1 add dict begin\n", x->file);
+  fputs (" {\n", x->file);
+  fputs ("  1 index/FID ne{def}{pop pop}ifelse\n", x->file);
+  fputs (" }forall\n", x->file);
+  fputs (" /Encoding ED\n", x->file);
+  fputs (" currentdict end\n", x->file);
+  fputs ("}bind def\n", x->file);
+  fputs ("/F{setfont}bind def\n", x->file);
+  fputs ("/EP{\n", x->file);
+  fputs (" pg restore\n", x->file);
+  fputs (" showpage\n", x->file);
+  fputs ("}bind def\n", x->file);
+  fputs ("/GB{\n", x->file);
+  fputs (" /y2 ED/x2 ED/y1 ED/x1 ED\n", x->file);
+  fputs (" x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto closepath\n",
+         x->file);
+  fputs (" gsave 0.9 setgray fill grestore stroke\n", x->file);
+  fputs ("}bind def\n", x->file);
+  fputs ("/K{0 rmoveto}bind def\n", x->file);
+  fputs ("%%EndProlog\n", x->file);
+  fputs ("%%BeginSetup\n", x->file);
+  for (i = 0; i < OUTP_FONT_CNT; i++)
+    setup_font (this, x->fonts[i], i);
+  fputs ("%%EndSetup\n", x->file);
+}
+
+/* Returns STRING as a Postscript name, which is just '/'
+   followed by STRING unless characters need to be quoted.
+   The caller must free the string. */
+static char *
+quote_ps_name (const char *string)
 {
 {
-  struct ps_encoding *a = pa;
+  const char *cp;
 
 
-  free (a->filename);
-  free (a);
+  for (cp = string; *cp != '\0'; cp++)
+    {
+      unsigned char c = *cp;
+      if (!isalpha (c) && strchr ("^_|!$&:;.,-+", c) == NULL
+          && (cp == string || !isdigit (c)))
+        {
+          struct string out = DS_INITIALIZER;
+          ds_putc (&out, '<');
+         for (cp = string; *cp != '\0'; cp++)
+            {
+              c = *cp;
+              ds_printf (&out, "%02x", c);
+            }
+         ds_puts (&out, ">cvn");
+          return ds_c_str (&out);
+        }
+    }
+  return xasprintf ("/%s", string);
 }
 
 }
 
-/* Iterates through the list of encodings used for this driver
-   instance, reads each of them from disk, and writes them as
-   PostScript code to the output file. */
 static void
 static void
-output_encodings (struct outp_driver *this)
+ps_open_page (struct outp_driver *this)
 {
   struct ps_driver_ext *x = this->ext;
 
 {
   struct ps_driver_ext *x = this->ext;
 
-  struct hsh_iterator iter;
-  struct ps_encoding *pe;
+  /* Assure page independence. */
+  x->last_font = -1;
 
 
-  struct string line, buf;
+  x->page_number++;
 
 
-  ds_init (&line, 128);
-  ds_init (&buf, 128);
-  for (pe = hsh_first (x->encodings, &iter); pe != NULL;
-       pe = hsh_next (x->encodings, &iter)) 
-    {
-      FILE *f;
+  fprintf (x->file,
+          "%%%%Page: %d %d\n"
+          "%%%%BeginPageSetup\n"
+          "/pg save def 0.001 dup scale\n",
+          x->page_number, x->page_number);
 
 
-      msg (VM (1), _("%s: %s: Opening PostScript font encoding..."),
-          this->name, pe->filename);
-      
-      f = fopen (pe->filename, "r");
-      if (!f)
-       {
-         msg (IE, _("PostScript driver: Cannot open encoding file `%s': %s.  "
-              "Substituting ISOLatin1Encoding for missing encoding."),
-              pe->filename, strerror (errno));
-         fprintf (x->file.file, "/E%x ISOLatin1Encoding def%s",
-                  pe->index, x->eol);
-       }
-      else
-       {
-         struct file_locator where;
-         
-         const char *tab[256];
-
-         char *pschar;
-         char *code;
-         int code_val;
-         char *fubar;
-
-         const char *notdef = ".notdef";
-
-         int i;
-
-         for (i = 0; i < 256; i++)
-           tab[i] = notdef;
-
-         where.filename = pe->filename;
-         where.line_number = 0;
-         err_push_file_locator (&where);
-
-         while (ds_get_config_line (f, &buf, &where.line_number))
-           {
-             char *sp; 
-
-             if (buf.length == 0) 
-               continue;
-
-             pschar = strtok_r (ds_c_str (&buf), " \t\r\n", &sp);
-             code = strtok_r (NULL, " \t\r\n", &sp);
-             if (*pschar == 0 || *code == 0)
-               continue;
-             code_val = strtol (code, &fubar, 0);
-             if (*fubar)
-               {
-                 msg (IS, _("PostScript driver: Invalid numeric format."));
-                 continue;
-               }
-             if (code_val < 0 || code_val > 255)
-               {
-                 msg (IS, _("PostScript driver: Codes must be between 0 "
-                            "and 255.  (%d is not allowed.)"), code_val);
-                 break;
-               }
-             tab[code_val] = local_alloc (strlen (pschar) + 1);
-             strcpy ((char *) (tab[code_val]), pschar);
-           }
-         err_pop_file_locator (&where);
-
-         ds_clear (&line);
-         ds_printf (&line, "/E%x[", pe->index);
-         for (i = 0; i < 257; i++)
-           {
-             char temp[288];
-
-             if (i < 256)
-               {
-                 quote_ps_name (temp, tab[i]);
-                 if (tab[i] != notdef)
-                   local_free (tab[i]);
-               }
-             else
-               strcpy (temp, "]def");
-             
-             if (ds_length (&line) + strlen (temp) > 70)
-               {
-                 ds_puts (&line, x->eol);
-                 fputs (ds_c_str (&line), x->file.file);
-                 ds_clear (&line);
-               }
-             ds_puts (&line, temp);
-           }
-         ds_puts (&line, x->eol);
-         fputs (ds_c_str (&line), x->file.file);
-
-         if (fclose (f) == EOF)
-           msg (MW, _("PostScript driver: Error closing encoding file `%s'."),
-                pe->filename);
-
-         msg (VM (2), _("%s: PostScript font encoding read successfully."),
-              this->name);
-       }
-    }
-  ds_destroy (&line);
-  ds_destroy (&buf);
-}
+  if (!x->portrait)
+    fprintf (x->file,
+            "%d 0 translate 90 rotate\n",
+            x->paper_width);
 
 
-/* Finds the ps_encoding in THIS that corresponds to the file with
-   name NORM_FILENAME, which must have previously been normalized with
-   normalize_filename(). */
-static struct ps_encoding *
-get_encoding (struct outp_driver *this, const char *norm_filename)
-{
-  struct ps_driver_ext *x = this->ext;
-  struct ps_encoding *pe;
+  if (x->bottom_margin != 0 || x->left_margin != 0)
+    fprintf (x->file,
+            "%d %d translate\n",
+            x->left_margin, x->bottom_margin);
 
 
-  pe = (struct ps_encoding *) hsh_find (x->encodings, (void *) &norm_filename);
-  return pe;
-}
+  fprintf (x->file,
+          "/LW %d def %d setlinewidth\n"
+          "%%%%EndPageSetup\n",
+          x->line_width, x->line_width);
 
 
-/* Searches the filesystem for an encoding file with name FILENAME;
-   returns its malloc'd, normalized name if found, otherwise NULL. */
-static char *
-find_encoding_file (struct outp_driver *this, char *filename)
-{
-  char *cp, *temp;
-
-  if (filename == NULL)
-    return NULL;
-  while (isspace ((unsigned char) *filename))
-    filename++;
-  for (cp = filename; *cp && !isspace ((unsigned char) *cp); cp++)
-    ;
-  if (cp == filename)
-    return NULL;
-  *cp = 0;
-
-  temp = find_ps_file (this, filename);
-  if (temp == NULL)
-    return NULL;
-
-  filename = fn_normalize (temp);
-  assert (filename != NULL);
-  free (temp);
-
-  return filename;
+  if (x->draw_headers)
+    draw_headers (this);
 }
 
 }
 
-/* Adds the encoding represented by the not-necessarily-normalized
-   file FILENAME to the list of encodings, if it exists and is not
-   already in the list. */
 static void
 static void
-add_encoding (struct outp_driver *this, char *filename)
+ps_close_page (struct outp_driver *this)
 {
   struct ps_driver_ext *x = this->ext;
 {
   struct ps_driver_ext *x = this->ext;
-  struct ps_encoding **pe;
-
-  filename = find_encoding_file (this, filename);
-  if (!filename)
-    return;
-
-  pe = (struct ps_encoding **) hsh_probe (x->encodings, &filename);
-  if (*pe)
-    {
-      free (filename);
-      return;
-    }
-  *pe = xmalloc (sizeof **pe);
-  (*pe)->filename = filename;
-  (*pe)->index = x->next_encoding++;
+  fputs ("%%PageTrailer\n"
+         "EP\n",
+         x->file);
 }
 
 }
 
-/* Finds the file on disk that contains the list of encodings to
-   include in the output file, then adds those encodings to the list
-   of encodings. */
 static void
 static void
-read_ps_encodings (struct outp_driver *this)
+ps_submit (struct outp_driver *this UNUSED, struct som_entity *s)
 {
 {
-  struct ps_driver_ext *x = this->ext;
-
-  /* Encodings file. */
-  char *encoding_fn;           /* `ps-encodings' filename. */
-  FILE *f;
-
-  struct string line;
-  struct file_locator where;
-
-  /* It's okay if there's no list of encodings; not everyone cares. */
-  encoding_fn = find_ps_file (this, x->encoding_fn);
-  if (encoding_fn == NULL)
-    return;
-  free (encoding_fn);
-
-  msg (VM (1), _("%s: %s: Opening PostScript encoding list file."),
-       this->name, encoding_fn);
-  f = fopen (encoding_fn, "r");
-  if (!f)
-    {
-      msg (IE, _("Opening %s: %s."), encoding_fn, strerror (errno));
-      return;
-    }
-
-  where.filename = encoding_fn;
-  where.line_number = 0;
-  err_push_file_locator (&where);
-
-  ds_init (&line, 128);
-    
-  for (;;)
-    {
-      if (!ds_get_config_line (f, &line, &where.line_number))
-       {
-         if (ferror (f))
-           msg (ME, _("Reading %s: %s."), encoding_fn, strerror (errno));
-         break;
-       }
-
-      add_encoding (this, line.string);
-    }
-
-  ds_destroy (&line);
-  err_pop_file_locator (&where);
-  
-  if (-1 == fclose (f))
-    msg (MW, _("Closing %s: %s."), encoding_fn, strerror (errno));
-
-  msg (VM (2), _("%s: PostScript encoding list file read successfully."), this->name);
-}
-
-/* Creates a default encoding for driver D that can be substituted for
-   an unavailable encoding. */
-struct ps_encoding *
-default_encoding (struct outp_driver *d)
-{
-  struct ps_driver_ext *x = d->ext;
-  static struct ps_encoding *enc;
-
-  if (!enc)
-    {
-      enc = xmalloc (sizeof *enc);
-      enc->filename = xstrdup (_("<<default encoding>>"));
-      enc->index = x->next_encoding++;
-    }
-  return enc;
-}
-\f
-/* Basic file operations. */
-
-/* Variables for the prologue. */
-struct ps_variable
-  {
-    const char *key;
-    const char *value;
-  };
-
-static struct ps_variable *ps_var_tab;
-
-/* Searches ps_var_tab for a ps_variable with key KEY, and returns the
-   associated value. */
-static const char *
-ps_get_var (const char *key)
-{
-  struct ps_variable *v;
-
-  for (v = ps_var_tab; v->key; v++)
-    if (!strcmp (key, v->key))
-      return v->value;
-  return NULL;
-}
-
-/* Writes the PostScript prologue to file F. */
-static int
-postopen (struct file_ext *f)
-{
-  static struct ps_variable dict[] =
-  {
-    {"bounding-box", 0},
-    {"creator", 0},
-    {"date", 0},
-    {"data", 0},
-    {"orientation", 0},
-    {"user", 0},
-    {"host", 0},
-    {"prop-font", 0},
-    {"fixed-font", 0},
-    {"scale-factor", 0},
-    {"paper-width", 0},
-    {"paper-length", 0},
-    {"left-margin", 0},
-    {"top-margin", 0},
-    {"line-width", 0},
-    {"line-width-thick", 0},
-    {"title", 0},
-    {0, 0},
-  };
-  char boundbox[INT_STRLEN_BOUND (int) * 4 + 4];
-#if HAVE_UNISTD_H
-  char host[128];
-#endif
-  char scaling[INT_STRLEN_BOUND (int) + 5];
-  time_t curtime;
-  struct tm *loctime;
-  char *p, *cp;
-  char paper_width[INT_STRLEN_BOUND (int) + 1];
-  char paper_length[INT_STRLEN_BOUND (int) + 1];
-  char left_margin[INT_STRLEN_BOUND (int) + 1];
-  char top_margin[INT_STRLEN_BOUND (int) + 1];
-  char line_width[INT_STRLEN_BOUND (int) + 1];
-  char line_width_thick[INT_STRLEN_BOUND (int) + 1];
-
-  struct outp_driver *this = f->param;
-  struct ps_driver_ext *x = this->ext;
-
-  char *prologue_fn = find_ps_file (this, x->prologue_fn);
-  FILE *prologue_file;
-
-  char *buf = NULL;
-  size_t buf_size = 0;
-
-  x->loaded = hsh_create (31, compare_font_entry, hash_font_entry,
-                         free_font_entry, NULL);
-  
-  {
-    char *font_name = local_alloc (2 + max (strlen (x->prop_family),
-                                           strlen (x->fixed_family)));
-    
-    strcpy (stpcpy (font_name, x->prop_family), "R");
-    x->prop = load_font (this, font_name);
-
-    strcpy (stpcpy (font_name, x->fixed_family), "R");
-    x->fixed = load_font (this, font_name);
-
-    local_free(font_name);
-  }
-
-  x->current = x->prop;
-  x->family = xstrdup (x->prop_family);
-  x->size = x->font_size;
-  
-  {
-    int *h = this->horiz_line_width, *v = this->vert_line_width;
-    
-    this->cp_x = this->cp_y = 0;
-    this->font_height = x->font_size;
-    {
-      struct char_metrics *metric;
-
-      metric = font_get_char_metrics (x->prop->font, '0');
-      this->prop_em_width = ((metric
-                             ? metric->width : x->prop->font->space_width)
-                            * x->font_size / 1000);
-
-      metric = font_get_char_metrics (x->fixed->font, '0');
-      this->fixed_width = ((metric
-                           ? metric->width : x->fixed->font->space_width)
-                          * x->font_size / 1000);
-    }
-        
-    h[0] = v[0] = 0;
-    h[1] = v[1] = 2 * x->line_gutter + x->line_width;
-    if (x->output_options & OPO_DOUBLE_LINE)
-      h[2] = v[2] = 2 * x->line_gutter + 2 * x->line_width + x->line_space;
-    else
-      h[2] = v[2] = 2 * x->line_gutter + x->line_width_thick;
-    h[3] = v[3] = 2 * x->line_gutter + x->line_width;
-    
-    {
-      int i;
-      
-      for (i = 0; i < (1 << OUTP_L_COUNT); i++)
-       {
-         int bit;
-
-         /* Maximum width of any line type so far. */
-         int max = 0;
-
-         for (bit = 0; bit < OUTP_L_COUNT; bit++)
-           if ((i & (1 << bit)) && h[bit] > max)
-             max = h[bit];
-         this->horiz_line_spacing[i] = this->vert_line_spacing[i] = max;
-       }
-    }
-  }
-
-  if (x->output_options & OPO_AUTO_ENCODE)
-    {
-      /* It's okay if this is done more than once since add_encoding()
-         is idempotent over identical encodings. */
-      add_encoding (this, x->prop->font->encoding);
-      add_encoding (this, x->fixed->font->encoding);
-    }
-
-  x->file_page_number = 0;
-
-  errno = 0;
-  if (prologue_fn == NULL)
-    {
-      msg (IE, _("Cannot find PostScript prologue.  The use of `-vv' "
-                "on the command line is suggested as a debugging aid."));
-      return 0;
-    }
-
-  msg (VM (1), _("%s: %s: Opening PostScript prologue..."),
-       this->name, prologue_fn);
-  prologue_file = fopen (prologue_fn, "rb");
-  if (prologue_file == NULL)
-    {
-      fclose (prologue_file);
-      free (prologue_fn);
-      msg (IE, "%s: %s", prologue_fn, strerror (errno));
-      goto error;
-    }
-
-  sprintf (boundbox, "0 0 %d %d",
-          x->w / (PSUS / 72) + (x->w % (PSUS / 72) > 0),
-          x->l / (PSUS / 72) + (x->l % (PSUS / 72) > 0));
-  dict[0].value = boundbox;
-
-  dict[1].value = (char *) version;
-
-  curtime = time (NULL);
-  loctime = localtime (&curtime);
-  dict[2].value = asctime (loctime);
-  cp = strchr (dict[2].value, '\n');
-  if (cp)
-    *cp = 0;
-
-  switch (x->data)
-    {
-    case ODA_CLEAN7BIT:
-      dict[3].value = "Clean7Bit";
-      break;
-    case ODA_CLEAN8BIT:
-      dict[3].value = "Clean8Bit";
-      break;
-    case ODA_BINARY:
-      dict[3].value = "Binary";
-      break;
-    default:
-      assert (0);
-    }
-
-  if (x->orientation == OTN_PORTRAIT)
-    dict[4].value = "Portrait";
-  else
-    dict[4].value = "Landscape";
-
-  /* PORTME: Determine username, net address. */
-#if HAVE_UNISTD_H
-  dict[5].value = getenv ("LOGNAME");
-  if (!dict[5].value)
-    dict[5].value = getlogin ();
-  if (!dict[5].value)
-    dict[5].value = _("nobody");
-
-  if (gethostname (host, 128) == -1)
-    {
-      if (errno == ENAMETOOLONG)
-       host[127] = 0;
-      else
-       strcpy (host, _("nowhere"));
-    }
-  dict[6].value = host;
-#else /* !HAVE_UNISTD_H */
-  dict[5].value = _("nobody");
-  dict[6].value = _("nowhere");
-#endif /* !HAVE_UNISTD_H */
-
-  cp = stpcpy (p = local_alloc (288), "font ");
-  quote_ps_string (cp, x->prop->font->internal_name);
-  dict[7].value = p;
-
-  cp = stpcpy (p = local_alloc (288), "font ");
-  quote_ps_string (cp, x->fixed->font->internal_name);
-  dict[8].value = p;
-
-  sprintf (scaling, "%.3f", PSUS / 72.0);
-  dict[9].value = scaling;
-
-  sprintf (paper_width, "%g", x->w / (PSUS / 72.0));
-  dict[10].value = paper_width;
-
-  sprintf (paper_length, "%g", x->l / (PSUS / 72.0));
-  dict[11].value = paper_length;
-
-  sprintf (left_margin, "%d", x->left_margin);
-  dict[12].value = left_margin;
-
-  sprintf (top_margin, "%d", x->top_margin);
-  dict[13].value = top_margin;
-
-  sprintf (line_width, "%d", x->line_width);
-  dict[14].value = line_width;
-
-  sprintf (line_width, "%d", x->line_width_thick);
-  dict[15].value = line_width_thick;
-  
-  if (!outp_title)
-    {
-      dict[16].value = cp = local_alloc (16);
-      strcpy (cp, "PSPP");
-    }
-  else
-    {
-      dict[16].value = local_alloc (strlen (outp_title) + 1);
-      strcpy ((char *) (dict[16].value), outp_title);
-    }
-  
-  ps_var_tab = dict;
-  while (-1 != getline (&buf, &buf_size, prologue_file))
-    {
-      char *cp;
-
-      int len;
-
-      cp = strstr (buf, "!eps");
-      if (cp)
-       {
-         if (this->class->magic == MAGIC_PS)
-           continue;
-         else
-           *cp = '\0';
-       }
-      else
-       {
-         cp = strstr (buf, "!ps");
-         if (cp)
-           {
-             if (this->class->magic == MAGIC_EPSF)
-               continue;
-             else
-               *cp = '\0';
-           } else {
-             if (strstr (buf, "!!!"))
-               continue;
-           }
-       }
-
-      if (!strncmp (buf, "!encodings", 10))
-       output_encodings (this);
-      else
-       {
-         struct string line;
-         ds_create(&line, buf);
-         fn_interp_vars(&line, ps_get_var);
-         ds_ltrim_spaces(&line);
-         len = ds_length(&line);
-         fwrite (ds_c_str(&line), len, 1, f->file);
-
-         ds_destroy(&line);
-
-         fputs (x->eol, f->file);
-       }
-    }
-  if (ferror (f->file))
-    msg (IE, _("Reading `%s': %s."), prologue_fn, strerror (errno));
-  fclose (prologue_file);
-
-  free (prologue_fn);
-  free (buf);
-
-  local_free (dict[7].value);
-  local_free (dict[8].value);
-  local_free (dict[16].value);
-
-  if (ferror (f->file))
-    goto error;
-
-  msg (VM (2), _("%s: PostScript prologue read successfully."), this->name);
-  return 1;
-
-error:
-  msg (VM (1), _("%s: Error reading PostScript prologue."), this->name);
-  return 0;
-}
-
-/* Writes the string STRING to buffer DEST (of at least 288
-   characters) as a PostScript name object.  Returns a pointer
-   to the null terminator of the resultant string. */
-static char *
-quote_ps_name (char *dest, const char *string)
-{
-  const char *sp;
-
-  for (sp = string; *sp; sp++)
-    switch (*sp)
-      {
-      case 'a':
-      case 'f':
-      case 'k':
-      case 'p':
-      case 'u':
-      case 'b':
-      case 'g':
-      case 'l':
-      case 'q':
-      case 'v':
-      case 'c':
-      case 'h':
-      case 'm':
-      case 'r':
-      case 'w':
-      case 'd':
-      case 'i':
-      case 'n':
-      case 's':
-      case 'x':
-      case 'e':
-      case 'j':
-      case 'o':
-      case 't':
-      case 'y':
-      case 'z':
-      case 'A':
-      case 'F':
-      case 'K':
-      case 'P':
-      case 'U':
-      case 'B':
-      case 'G':
-      case 'L':
-      case 'Q':
-      case 'V':
-      case 'C':
-      case 'H':
-      case 'M':
-      case 'R':
-      case 'W':
-      case 'D':
-      case 'I':
-      case 'N':
-      case 'S':
-      case 'X':
-      case 'E':
-      case 'J':
-      case 'O':
-      case 'T':
-      case 'Y':
-      case 'Z':
-      case '@':
-      case '^':
-      case '_':
-      case '|':
-      case '!':
-      case '$':
-      case '&':
-      case ':':
-      case ';':
-      case '.':
-      case ',':
-      case '-':
-      case '+':
-       break;
-      default:
-       {
-         char *dp = dest;
-
-         *dp++ = '<';
-         for (sp = string; *sp && dp < &dest[256]; sp++)
-           {
-             sprintf (dp, "%02x", (unsigned char) *sp);
-             dp += 2;
-           }
-         return stpcpy (dp, ">cvn");
-       }
-      }
-  dest[0] = '/';
-  return stpcpy (&dest[1], string);
-}
-
-/* Adds the string STRING to buffer DEST as a PostScript quoted
-   string; returns a pointer to the null terminator added.  Will not
-   add more than 235 characters. */
-static char *
-quote_ps_string (char *dest, const char *string)
-{
-  const char *sp = string;
-  char *dp = dest;
-
-  *dp++ = '(';
-  for (; *sp && dp < &dest[235]; sp++)
-    if (*sp == '(')
-      dp = stpcpy (dp, "\\(");
-    else if (*sp == ')')
-      dp = stpcpy (dp, "\\)");
-    else if (*sp < 32 || (unsigned char) *sp > 127)
-      dp = spprintf (dp, "\\%3o", *sp);
-    else
-      *dp++ = *sp;
-  return stpcpy (dp, ")");
-}
-
-/* Writes the PostScript epilogue to file F. */
-static int
-preclose (struct file_ext *f)
-{
-  struct outp_driver *this = f->param;
-  struct ps_driver_ext *x = this->ext;
-  struct hsh_iterator iter;
-  struct font_entry *fe;
-
-  fprintf (f->file,
-          ("%%%%Trailer%s"
-           "%%%%Pages: %d%s"
-           "%%%%DocumentNeededResources:%s"),
-          x->eol, x->file_page_number, x->eol, x->eol);
-
-  for (fe = hsh_first (x->loaded, &iter); fe != NULL;
-       fe = hsh_next (x->loaded, &iter)) 
-    {
-      char buf[256], *cp;
-
-      cp = stpcpy (buf, "%%+ font ");
-      cp = quote_ps_string (cp, fe->font->internal_name);
-      strcpy (cp, x->eol);
-      fputs (buf, f->file);
-    }
-
-  hsh_destroy (x->loaded);
-  x->loaded = NULL;
-  hsh_destroy (x->combos);
-  x->combos = NULL;
-  x->last_font = NULL;
-  x->next_combo = 0;
-
-  fprintf (f->file, "%%EOF%s", x->eol);
-  if (ferror (f->file))
-    return 0;
-  return 1;
-}
-
-static int
-ps_open_page (struct outp_driver *this)
-{
-  struct ps_driver_ext *x = this->ext;
-
-  assert (this->driver_open && !this->page_open);
-      
-  x->page_number++;
-  if (!fn_open_ext (&x->file))
-    {
-      if (errno)
-       msg (ME, _("PostScript output driver: %s: %s"), x->file.filename,
-            strerror (errno));
-      return 0;
-    }
-  x->file_page_number++;
-
-  hsh_destroy (x->combos);
-  x->combos = hsh_create (31, compare_ps_combo, hash_ps_combo,
-                         free_ps_combo, NULL);
-  x->last_font = NULL;
-  x->next_combo = 0;
-
-  fprintf (x->file.file,
-          "%%%%Page: %d %d%s"
-          "%%%%BeginPageSetup%s"
-          "/pg save def 0.001 dup scale%s",
-          x->page_number, x->file_page_number, x->eol,
-          x->eol,
-          x->eol);
-
-  if (x->orientation == OTN_LANDSCAPE)
-    fprintf (x->file.file,
-            "%d 0 translate 90 rotate%s",
-            x->w, x->eol);
-
-  if (x->bottom_margin != 0 || x->left_margin != 0)
-    fprintf (x->file.file,
-            "%d %d translate%s",
-            x->left_margin, x->bottom_margin, x->eol);
-
-  fprintf (x->file.file,
-          "/LW %d def/TW %d def %d setlinewidth%s"
-          "%%%%EndPageSetup%s",
-          x->line_width, x->line_width_thick, x->line_width, x->eol,
-          x->eol);
-
-  if (!ferror (x->file.file))
-    {
-      this->page_open = 1;
-      if (x->output_options & OPO_HEADERS)
-       draw_headers (this);
-    }
-
-  this->cp_y = 0;
-
-  return !ferror (x->file.file);
-}
-
-static int
-ps_close_page (struct outp_driver *this)
-{
-  struct ps_driver_ext *x = this->ext;
-
-  assert (this->driver_open && this->page_open);
-  
-  if (x->line_opt)
-    dump_lines (this);
-
-  fprintf (x->file.file,
-          "%%PageTrailer%s"
-          "EP%s",
-          x->eol, x->eol);
-
-  this->page_open = 0;
-  return !ferror (x->file.file);
-}
-
-static void
-ps_submit (struct outp_driver *this UNUSED, struct som_entity *s)
-{
-  switch (s->type) 
+  switch (s->type)
     {
     case SOM_CHART:
       break;
     default:
     {
     case SOM_CHART:
       break;
     default:
-      assert(0);
-      break;
-    }
-}
-\f
-/* Lines. */
-
-/* qsort() comparison function for int tuples. */
-static int
-int_2_compare (const void *a_, const void *b_)
-{
-  const int *a = a_;
-  const int *b = b_;
-
-  return *a < *b ? -1 : *a > *b;
-}
-
-/* Hash table comparison function for cached lines. */
-static int
-compare_line (const void *a_, const void *b_, void *foo UNUSED)
-{
-  const struct line_form *a = a_;
-  const struct line_form *b = b_;
-
-  return a->ind < b->ind ? -1 : a->ind > b->ind;
-}
-
-/* Hash table hash function for cached lines. */
-static unsigned
-hash_line (const void *pa, void *foo UNUSED)
-{
-  const struct line_form *a = pa;
-
-  return a->ind;
-}
-
-/* Hash table free function for cached lines. */
-static void
-free_line (void *pa, void *foo UNUSED)
-{
-  free (pa);
-}
-
-/* Writes PostScript code to draw a line from (x1,y1) to (x2,y2) to
-   the output file. */
-#define dump_line(x1, y1, x2, y2)                      \
-       fprintf (ext->file.file, "%d %d %d %d L%s",     \
-                x1, YT (y1), x2, YT (y2), ext->eol)
-
-/* Write PostScript code to draw a thick line from (x1,y1) to (x2,y2)
-   to the output file. */
-#define dump_thick_line(x1, y1, x2, y2)                        \
-       fprintf (ext->file.file, "%d %d %d %d TL%s",    \
-                x1, YT (y1), x2, YT (y2), ext->eol)
-
-/* Writes a line of type TYPE to THIS driver's output file.  The line
-   (or its center, in the case of double lines) has its independent
-   axis coordinate at IND; it extends from DEP1 to DEP2 on the
-   dependent axis. */
-static void
-dump_fancy_line (struct outp_driver *this, int type, int ind, int dep1, int dep2)
-{
-  struct ps_driver_ext *ext = this->ext;
-  int ofs = ext->line_space / 2 + ext->line_width / 2;
-
-  switch (type)
-    {
-    case horz:
-      dump_line (dep1, ind, dep2, ind);
-      break;
-    case dbl_horz:
-      if (ext->output_options & OPO_DOUBLE_LINE)
-       {
-         dump_line (dep1, ind - ofs, dep2, ind - ofs);
-         dump_line (dep1, ind + ofs, dep2, ind + ofs);
-       }
-      else
-       dump_thick_line (dep1, ind, dep2, ind);
-      break;
-    case spl_horz:
-      assert (0);
-    case vert:
-      dump_line (ind, dep1, ind, dep2);
-      break;
-    case dbl_vert:
-      if (ext->output_options & OPO_DOUBLE_LINE)
-       {
-         dump_line (ind - ofs, dep1, ind - ofs, dep2);
-         dump_line (ind + ofs, dep1, ind + ofs, dep2);
-       }
-      else
-       dump_thick_line (ind, dep1, ind, dep2);
-      break;
-    case spl_vert:
-      assert (0);
-    default:
-      assert (0);
-    }
-}
-
-#undef dump_line
-
-/* Writes all the cached lines to the output file, then clears the
-   cache. */
-static void
-dump_lines (struct outp_driver *this)
-{
-  struct ps_driver_ext *x = this->ext;
-
-  struct hsh_iterator iter;
-  int type;
-
-  for (type = 0; type < n_line_types; type++)
-    {
-      struct line_form *line;
-
-      if (x->lines[type] == NULL) 
-        continue;
-
-      for (line = hsh_first (x->lines[type], &iter); line != NULL;
-           line = hsh_next (x->lines[type], &iter)) 
-        {
-         int i;
-         int lo = INT_MIN, hi;
-
-         qsort (line->dep, line->ndep, sizeof *line->dep, int_2_compare);
-         lo = line->dep[0][0];
-         hi = line->dep[0][1];
-         for (i = 1; i < line->ndep; i++)
-           if (line->dep[i][0] <= hi + 1)
-             {
-               int min_hi = line->dep[i][1];
-               if (min_hi > hi)
-                 hi = min_hi;
-             }
-           else
-             {
-               dump_fancy_line (this, type, line->ind, lo, hi);
-               lo = line->dep[i][0];
-               hi = line->dep[i][1];
-             }
-         dump_fancy_line (this, type, line->ind, lo, hi);
-       }
-
-      hsh_destroy (x->lines[type]);
-      x->lines[type] = NULL;
-    }
-}
-
-/* (Same args as dump_fancy_line()).  Either dumps the line directly
-   to the output file, or adds it to the cache, depending on the
-   user-selected line optimization mode. */
-static void
-line (struct outp_driver *this, int type, int ind, int dep1, int dep2)
-{
-  struct ps_driver_ext *ext = this->ext;
-  struct line_form **f;
-
-  assert (dep2 >= dep1);
-  if (ext->line_opt == 0)
-    {
-      dump_fancy_line (this, type, ind, dep1, dep2);
-      return;
-    }
-
-  if (ext->lines[type] == NULL)
-    ext->lines[type] = hsh_create (31, compare_line, hash_line,
-                                  free_line, NULL);
-  f = (struct line_form **) hsh_probe (ext->lines[type], &ind);
-  if (*f == NULL)
-    {
-      *f = xmalloc (sizeof **f + sizeof (int[15][2]));
-      (*f)->ind = ind;
-      (*f)->mdep = 16;
-      (*f)->ndep = 1;
-      (*f)->dep[0][0] = dep1;
-      (*f)->dep[0][1] = dep2;
-      return;
-    }
-  if ((*f)->ndep >= (*f)->mdep)
-    {
-      (*f)->mdep += 16;
-      *f = xrealloc (*f, sizeof **f + sizeof (int[2]) * ((*f)->mdep - 1));
-    }
-  (*f)->dep[(*f)->ndep][0] = dep1;
-  (*f)->dep[(*f)->ndep][1] = dep2;
-  (*f)->ndep++;
-}
-
-static void
-ps_line_horz (struct outp_driver *this, const struct rect *r,
-             const struct color *c UNUSED, int style)
-{
-  /* Must match output.h:OUTP_L_*. */
-  static const int types[OUTP_L_COUNT] =
-  {-1, horz, dbl_horz, spl_horz};
-
-  int y = (r->y1 + r->y2) / 2;
-
-  assert (this->driver_open && this->page_open);
-  assert (style >= 0 && style < OUTP_L_COUNT);
-  style = types[style];
-  if (style != -1)
-    line (this, style, y, r->x1, r->x2);
-}
-
-static void
-ps_line_vert (struct outp_driver *this, const struct rect *r,
-             const struct color *c UNUSED, int style)
-{
-  /* Must match output.h:OUTP_L_*. */
-  static const int types[OUTP_L_COUNT] =
-  {-1, vert, dbl_vert, spl_vert};
-
-  int x = (r->x1 + r->x2) / 2;
-
-  assert (this->driver_open && this->page_open);
-  assert (style >= 0 && style < OUTP_L_COUNT);
-  style = types[style];
-  if (style != -1)
-    line (this, style, x, r->y1, r->y2);
-}
-
-#define L (style->l != OUTP_L_NONE)
-#define R (style->r != OUTP_L_NONE)
-#define T (style->t != OUTP_L_NONE)
-#define B (style->b != OUTP_L_NONE)
-
-static void
-ps_line_intersection (struct outp_driver *this, const struct rect *r,
-                     const struct color *c UNUSED,
-                     const struct outp_styles *style)
-{
-  struct ps_driver_ext *ext = this->ext;
-
-  int x = (r->x1 + r->x2) / 2;
-  int y = (r->y1 + r->y2) / 2;
-  int ofs = (ext->line_space + ext->line_width) / 2;
-  int x1 = x - ofs, x2 = x + ofs;
-  int y1 = y - ofs, y2 = y + ofs;
-
-  assert (this->driver_open && this->page_open);
-  assert (!((style->l != style->r && style->l != OUTP_L_NONE
-            && style->r != OUTP_L_NONE)
-           || (style->t != style->b && style->t != OUTP_L_NONE
-               && style->b != OUTP_L_NONE)));
-
-  switch ((style->l | style->r) | ((style->t | style->b) << 8))
-    {
-    case (OUTP_L_SINGLE) | (OUTP_L_SINGLE << 8):
-    case (OUTP_L_SINGLE) | (OUTP_L_NONE << 8):
-    case (OUTP_L_NONE) | (OUTP_L_SINGLE << 8):
-      if (L)
-       line (this, horz, y, r->x1, x);
-      if (R)
-       line (this, horz, y, x, r->x2);
-      if (T)
-       line (this, vert, x, r->y1, y);
-      if (B)
-       line (this, vert, x, y, r->y2);
-      break;
-    case (OUTP_L_SINGLE) | (OUTP_L_DOUBLE << 8):
-    case (OUTP_L_NONE) | (OUTP_L_DOUBLE << 8):
-      if (L)
-       line (this, horz, y, r->x1, x1);
-      if (R)
-       line (this, horz, y, x2, r->x2);
-      if (T)
-       line (this, dbl_vert, x, r->y1, y);
-      if (B)
-       line (this, dbl_vert, x, y, r->y2);
-      if ((L && R) && !(T && B))
-       line (this, horz, y, x1, x2);
-      break;
-    case (OUTP_L_DOUBLE) | (OUTP_L_SINGLE << 8):
-    case (OUTP_L_DOUBLE) | (OUTP_L_NONE << 8):
-      if (L)
-       line (this, dbl_horz, y, r->x1, x);
-      if (R)
-       line (this, dbl_horz, y, x, r->x2);
-      if (T)
-       line (this, vert, x, r->y1, y);
-      if (B)
-       line (this, vert, x, y, r->y2);
-      if ((T && B) && !(L && R))
-       line (this, vert, x, y1, y2);
-      break;
-    case (OUTP_L_DOUBLE) | (OUTP_L_DOUBLE << 8):
-      if (L)
-       line (this, dbl_horz, y, r->x1, x);
-      if (R)
-       line (this, dbl_horz, y, x, r->x2);
-      if (T)
-       line (this, dbl_vert, x, r->y1, y);
-      if (B)
-       line (this, dbl_vert, x, y, r->y2);
-      if (T && B && !L)
-       line (this, vert, x1, y1, y2);
-      if (T && B && !R)
-       line (this, vert, x2, y1, y2);
-      if (L && R && !T)
-       line (this, horz, y1, x1, x2);
-      if (L && R && !B)
-       line (this, horz, y2, x1, x2);
+      abort ();
       break;
       break;
-    default:
-      assert (0);
     }
 }
     }
 }
-
-static void
-ps_box (struct outp_driver *this UNUSED, const struct rect *r UNUSED,
-       const struct color *bord UNUSED, const struct color *fill UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-}
-
-static void 
-ps_polyline_begin (struct outp_driver *this UNUSED,
-                  const struct color *c UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-}
-static void 
-ps_polyline_point (struct outp_driver *this UNUSED, int x UNUSED, int y UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-}
-static void 
-ps_polyline_end (struct outp_driver *this UNUSED)
-{
-  assert (this->driver_open && this->page_open);
-}
-
-/* Returns the width of string S for THIS driver. */
-static int
-text_width (struct outp_driver *this, char *s)
-{
-  struct outp_text text;
-
-  text.options = OUTP_T_JUST_LEFT;
-  ls_init (&text.s, s, strlen (s));
-  this->class->text_metrics (this, &text);
-  return text.h;
-}
-
-/* Write string S at location (X,Y) with width W for THIS driver. */
-static void
-out_text_plain (struct outp_driver *this, char *s, int x, int y, int w)
-{
-  struct outp_text text;
-
-  text.options = OUTP_T_JUST_LEFT | OUTP_T_HORZ | OUTP_T_VERT;
-  ls_init (&text.s, s, strlen (s));
-  text.h = w;
-  text.v = this->font_height;
-  text.x = x;
-  text.y = y;
-  this->class->text_draw (this, &text);
-}
-
-/* Draw top of page headers for THIS driver. */
-static void
-draw_headers (struct outp_driver *this)
-{
-  struct ps_driver_ext *ext = this->ext;
-  
-  struct font_entry *old_current = ext->current;
-  char *old_family = xstrdup (ext->family); /* FIXME */
-  int old_size = ext->size;
-
-  int fh = this->font_height;
-  int y = -3 * fh;
-
-  fprintf (ext->file.file, "%d %d %d %d GB%s",
-          0, YT (y), this->width, YT (y + 2 * fh + ext->line_gutter),
-          ext->eol);
-  this->class->text_set_font_family (this, "T");
-
-  y += ext->line_width + ext->line_gutter;
-  
-  {
-    int rh_width;
-    char buf[128];
-
-    sprintf (buf, _("%s - Page %d"), get_start_date (), ext->page_number);
-    rh_width = text_width (this, buf);
-
-    out_text_plain (this, buf, this->width - this->prop_em_width - rh_width,
-                   y, rh_width);
-
-    if (outp_title && outp_subtitle)
-      out_text_plain (this, outp_title, this->prop_em_width, y,
-                     this->width - 3 * this->prop_em_width - rh_width);
-
-    y += fh;
-  }
-  
-  {
-    int rh_width;
-    char buf[128];
-    char *string = outp_subtitle ? outp_subtitle : outp_title;
-
-    sprintf (buf, "%s - %s", version, host_system);
-    rh_width = text_width (this, buf);
-    
-    out_text_plain (this, buf, this->width - this->prop_em_width - rh_width,
-                   y, rh_width);
-
-    if (string)
-      out_text_plain (this, string, this->prop_em_width, y,
-                     this->width - 3 * this->prop_em_width - rh_width);
-
-    y += fh;
-  }
-
-  ext->current = old_current;
-  free (ext->family);
-  ext->family = old_family;
-  ext->size = old_size;
-}
-
 \f
 \f
-/* Text. */
-
-static void
-ps_text_set_font_by_name (struct outp_driver *this, const char *dit)
-{
-  struct ps_driver_ext *x = this->ext;
-  struct font_entry *fe;
-
-  assert (this->driver_open && this->page_open);
-  
-  /* Short-circuit common fonts. */
-  if (!strcmp (dit, "PROP"))
-    {
-      x->current = x->prop;
-      x->size = x->font_size;
-      return;
-    }
-  else if (!strcmp (dit, "FIXED"))
-    {
-      x->current = x->fixed;
-      x->size = x->font_size;
-      return;
-    }
-
-  /* Find font_desc corresponding to Groff name dit. */
-  fe = hsh_find (x->loaded, &dit);
-  if (fe == NULL)
-    fe = load_font (this, dit);
-  x->current = fe;
-}
-
+/* Draws a line from (x0,y0) to (x1,y1). */
 static void
 static void
-ps_text_set_font_by_position (struct outp_driver *this, int pos)
-{
-  struct ps_driver_ext *x = this->ext;
-  char *dit;
-
-  assert (this->driver_open && this->page_open);
-
-  /* Determine font name by suffixing position string to font family
-     name. */
-  {
-    char *cp;
-
-    dit = local_alloc (strlen (x->family) + 3);
-    cp = stpcpy (dit, x->family);
-    switch (pos)
-      {
-      case OUTP_F_R:
-       *cp++ = 'R';
-       break;
-      case OUTP_F_I:
-       *cp++ = 'I';
-       break;
-      case OUTP_F_B:
-       *cp++ = 'B';
-       break;
-      case OUTP_F_BI:
-       *cp++ = 'B';
-       *cp++ = 'I';
-       break;
-      default:
-       assert(0);
-      }
-    *cp++ = 0;
-  }
-  
-  /* Find font_desc corresponding to Groff name dit. */
-  {
-    struct font_entry *fe = hsh_find (x->loaded, &dit);
-    if (fe == NULL)
-      fe = load_font (this, dit);
-    x->current = fe;
-  }
-
-  local_free (dit);
-}
-
-static void
-ps_text_set_font_family (struct outp_driver *this, const char *s)
-{
-  struct ps_driver_ext *x = this->ext;
-
-  assert (this->driver_open && this->page_open);
-  
-  free(x->family);
-  x->family = xstrdup (s);
-}
-
-static const char *
-ps_text_get_font_name (struct outp_driver *this)
-{
-  struct ps_driver_ext *x = this->ext;
-
-  assert (this->driver_open && this->page_open);
-  return x->current->font->name;
-}
-
-static const char *
-ps_text_get_font_family (struct outp_driver *this)
+dump_line (struct outp_driver *this, int x0, int y0, int x1, int y1)
 {
 {
-  struct ps_driver_ext *x = this->ext;
-  
-  assert (this->driver_open && this->page_open);
-  return x->family;
+  struct ps_driver_ext *ext = this->ext;
+  fprintf (ext->file, "%d %d %d %d L\n", x0, YT (y0), x1, YT (y1));
 }
 
 }
 
-static int
-ps_text_set_size (struct outp_driver *this, int size)
+/* Draws a horizontal line X0...X2 at Y if LEFT says so,
+   shortening it to X0...X1 if SHORTEN is true.
+   Draws a horizontal line X1...X3 at Y if RIGHT says so,
+   shortening it to X2...X3 if SHORTEN is true. */
+static void
+horz_line (struct outp_driver *this,
+           int x0, int x1, int x2, int x3, int y,
+           enum outp_line_style left, enum outp_line_style right,
+           bool shorten)
 {
 {
-  struct ps_driver_ext *x = this->ext;
-
-  assert (this->driver_open && this->page_open);
-  x->size = PSUS / 72000 * size;
-  return 1;
+  if (left != OUTP_L_NONE && right != OUTP_L_NONE && !shorten)
+    dump_line (this, x0, y, x3, y);
+  else
+    {
+      if (left != OUTP_L_NONE)
+        dump_line (this, x0, y, shorten ? x1 : x2, y);
+      if (right != OUTP_L_NONE)
+        dump_line (this, shorten ? x2 : x1, y, x3, y);
+    }
 }
 
 }
 
-static int
-ps_text_get_size (struct outp_driver *this, int *em_width)
+/* Draws a vertical line Y0...Y2 at X if TOP says so,
+   shortening it to Y0...Y1 if SHORTEN is true.
+   Draws a vertical line Y1...Y3 at X if BOTTOM says so,
+   shortening it to Y2...Y3 if SHORTEN is true. */
+static void
+vert_line (struct outp_driver *this,
+           int y0, int y1, int y2, int y3, int x,
+           enum outp_line_style top, enum outp_line_style bottom,
+           bool shorten)
 {
 {
-  struct ps_driver_ext *x = this->ext;
-
-  assert (this->driver_open && this->page_open);
-  if (em_width)
-    *em_width = (x->current->font->space_width * x->size) / 1000;
-  return x->size / (PSUS / 72000);
+  if (top != OUTP_L_NONE && bottom != OUTP_L_NONE && !shorten)
+    dump_line (this, x, y0, x, y3);
+  else
+    {
+      if (top != OUTP_L_NONE)
+        dump_line (this, x, y0, x, shorten ? y1 : y2);
+      if (bottom != OUTP_L_NONE)
+        dump_line (this, x, shorten ? y2 : y1, x, y3);
+    }
 }
 
 }
 
-/* An output character. */
-struct output_char
-  {
-    struct font_entry *font;   /* Font of character. */
-    int size;                  /* Size of character. */
-    int x, y;                  /* Location of character. */
-    unsigned char ch;          /* Character. */
-    char separate;             /* Must be separate from previous char. */
-  };
+/* Draws a generalized intersection of lines in the rectangle
+   (X0,Y0)-(X3,Y3).  The line coming from the top to the center
+   is of style TOP, from left to center of style LEFT, from
+   bottom to center of style BOTTOM, and from right to center of
+   style RIGHT. */
+static void
+ps_line (struct outp_driver *this,
+         int x0, int y0, int x3, int y3,
+         enum outp_line_style top, enum outp_line_style left,
+         enum outp_line_style bottom, enum outp_line_style right)
+{
+/* The algorithm here is somewhat subtle, to allow it to handle
+   all the kinds of intersections that we need.
+
+   Three additional ordinates are assigned along the x axis.  The
+   first is xc, midway between x0 and x3.  The others are x1 and
+   x2; for a single vertical line these are equal to xc, and for
+   a double vertical line they are the ordinates of the left and
+   right half of the double line.
+
+   yc, y1, and y2 are assigned similarly along the y axis.
+
+   The following diagram shows the coordinate system and output
+   for double top and bottom lines, single left line, and no
+   right line:
+
+               x0       x1 xc  x2      x3
+             y0 ________________________
+                |        #     #       |
+                |        #     #       |
+                |        #     #       |
+                |        #     #       |
+                |        #     #       |
+   y1 = y2 = yc |#########     #       |
+                |        #     #       |
+                |        #     #       |
+                |        #     #       |
+                |        #     #       |
+             y3 |________#_____#_______|
+*/
+  struct ps_driver_ext *ext = this->ext;
 
 
-/* Hash table comparison function for ps_combo structs. */
-static int
-compare_ps_combo (const void *pa, const void *pb, void *foo UNUSED)
-{
-  const struct ps_font_combo *a = pa;
-  const struct ps_font_combo *b = pb;
+  /* Offset from center of each line in a pair of double lines. */
+  int double_line_ofs = (ext->line_space + ext->line_width) / 2;
+
+  /* Are the lines along each axis single or double?
+     (It doesn't make sense to have different kinds of line on the
+     same axis, so we don't try to gracefully handle that case.) */
+  bool double_vert = top == OUTP_L_DOUBLE || bottom == OUTP_L_DOUBLE;
+  bool double_horz = left == OUTP_L_DOUBLE || right == OUTP_L_DOUBLE;
+
+  /* When horizontal lines are doubled,
+     the left-side line along y1 normally runs from x0 to x2,
+     and the right-side line along y1 from x3 to x1.
+     If the top-side line is also doubled, we shorten the y1 lines,
+     so that the left-side line runs only to x1,
+     and the right-side line only to x2.
+     Otherwise, the horizontal line at y = y1 below would cut off
+     the intersection, which looks ugly:
+               x0       x1     x2      x3
+             y0 ________________________
+                |        #     #       |
+                |        #     #       |
+                |        #     #       |
+                |        #     #       |
+             y1 |#########     ########|
+                |                      |
+                |                      |
+             y2 |######################|
+                |                      |
+                |                      |
+             y3 |______________________|
+     It is more of a judgment call when the horizontal line is
+     single.  We actually choose to cut off the line anyhow, as
+     shown in the first diagram above.
+  */
+  bool shorten_y1_lines = top == OUTP_L_DOUBLE;
+  bool shorten_y2_lines = bottom == OUTP_L_DOUBLE;
+  bool shorten_yc_line = shorten_y1_lines && shorten_y2_lines;
+  int horz_line_ofs = double_vert ? double_line_ofs : 0;
+  int xc = (x0 + x3) / 2;
+  int x1 = xc - horz_line_ofs;
+  int x2 = xc + horz_line_ofs;
+
+  bool shorten_x1_lines = left == OUTP_L_DOUBLE;
+  bool shorten_x2_lines = right == OUTP_L_DOUBLE;
+  bool shorten_xc_line = shorten_x1_lines && shorten_x2_lines;
+  int vert_line_ofs = double_horz ? double_line_ofs : 0;
+  int yc = (y0 + y3) / 2;
+  int y1 = yc - vert_line_ofs;
+  int y2 = yc + vert_line_ofs;
+
+  if (!double_horz)
+    horz_line (this, x0, x1, x2, x3, yc, left, right, shorten_yc_line);
+  else
+    {
+      horz_line (this, x0, x1, x2, x3, y1, left, right, shorten_y1_lines);
+      horz_line (this, x0, x1, x2, x3, y2, left, right, shorten_y2_lines);
+    }
 
 
-  return !((a->font == b->font) && (a->size == b->size));
+  if (!double_vert)
+    vert_line (this, y0, y1, y2, y3, xc, top, bottom, shorten_xc_line);
+  else
+    {
+      vert_line (this, y0, y1, y2, y3, x1, top, bottom, shorten_x1_lines);
+      vert_line (this, y0, y1, y2, y3, x2, top, bottom, shorten_x2_lines);
+    }
 }
 
 }
 
-/* Hash table hash function for ps_combo structs. */
-static unsigned
-hash_ps_combo (const void *pa, void *foo UNUSED)
+/* Writes STRING at location (X,Y) trimmed to the given MAX_WIDTH
+   and with the given JUSTIFICATION for THIS driver. */
+static int
+draw_text (struct outp_driver *this,
+           const char *string, int x, int y, int max_width,
+           enum outp_justification justification)
 {
 {
-  const struct ps_font_combo *a = pa;
-  unsigned name_hash = hsh_hash_string (a->font->font->internal_name);
-  return name_hash ^ hsh_hash_int (a->size);
+  struct outp_text text;
+  int width;
+
+  text.font = OUTP_PROPORTIONAL;
+  text.justification = justification;
+  ls_init (&text.string, (char *) string, strlen (string));
+  text.h = max_width;
+  text.v = this->font_height;
+  text.x = x;
+  text.y = y;
+  this->class->text_metrics (this, &text, &width, NULL);
+  this->class->text_draw (this, &text);
+  return width;
 }
 
 }
 
-/* Hash table free function for ps_combo structs. */
+/* Writes LEFT left-justified and RIGHT right-justified within
+   (X0...X1) at Y.  LEFT or RIGHT or both may be null. */
 static void
 static void
-free_ps_combo (void *a, void *foo UNUSED)
+draw_header_line (struct outp_driver *this,
+                  const char *left, const char *right,
+                  int x0, int x1, int y) 
 {
 {
-  free (a);
+  int right_width = 0;
+  if (right != NULL)
+    right_width = (draw_text (this, right, x0, y, x1 - x0, OUTP_RIGHT)
+                   + this->prop_em_width);
+  if (left != NULL)
+    draw_text (this, left, x0, y, x1 - x0 - right_width, OUTP_LEFT);
 }
 
 }
 
-/* Causes PostScript code to be output that switches to the font
-   CP->FONT and font size CP->SIZE.  The first time a particular
-   font/size combination is used on a particular page, this involves
-   outputting PostScript code to load the font. */
+/* Draw top of page headers for THIS driver. */
 static void
 static void
-switch_font (struct outp_driver *this, const struct output_char *cp)
+draw_headers (struct outp_driver *this)
 {
   struct ps_driver_ext *ext = this->ext;
 {
   struct ps_driver_ext *ext = this->ext;
-  struct ps_font_combo srch, **fc;
-
-  srch.font = cp->font;
-  srch.size = cp->size;
-
-  fc = (struct ps_font_combo **) hsh_probe (ext->combos, &srch);
-  if (*fc)
-    {
-      fprintf (ext->file.file, "F%x%s", (*fc)->index, ext->eol);
-    }
-  else
-    {
-      char *filename;
-      struct ps_encoding *encoding;
-      char buf[512], *bp;
-
-      *fc = xmalloc (sizeof **fc);
-      (*fc)->font = cp->font;
-      (*fc)->size = cp->size;
-      (*fc)->index = ext->next_combo++;
-
-      filename = find_encoding_file (this, cp->font->font->encoding);
-      if (filename)
-       {
-         encoding = get_encoding (this, filename);
-         free (filename);
-       }
-      else
-       {
-         msg (IE, _("PostScript driver: Cannot find encoding `%s' for "
-              "PostScript font `%s'."), cp->font->font->encoding,
-              cp->font->font->internal_name);
-         encoding = default_encoding (this);
-       }
-
-      if (cp->font != ext->fixed && cp->font != ext->prop)
-       {
-         bp = stpcpy (buf, "%%IncludeResource: font ");
-         bp = quote_ps_string (bp, cp->font->font->internal_name);
-         bp = stpcpy (bp, ext->eol);
-       }
-      else
-       bp = buf;
+  char *r1, *r2;
+  int x0, x1;
+  int y;
+
+  y = -3 * this->font_height;
+  x0 = this->prop_em_width;
+  x1 = this->width - this->prop_em_width;
+
+  /* Draw box. */
+  fprintf (ext->file, "%d %d %d %d GB\n",
+          0, YT (y),
+           this->width, YT (y + 2 * this->font_height + ext->line_gutter));
+  y += ext->line_width + ext->line_gutter;
 
 
-      bp = spprintf (bp, "/F%x E%x %d", (*fc)->index, encoding->index,
-                    cp->size);
-      bp = quote_ps_name (bp, cp->font->font->internal_name);
-      sprintf (bp, " SF%s", ext->eol);
-      fputs (buf, ext->file.file);
-    }
-  ext->last_font = *fc;
+  r1 = xasprintf (_("%s - Page %d"), get_start_date (), ext->page_number);
+  r2 = xasprintf ("%s - %s", version, host_system);
+  draw_header_line (this, outp_title, r1, x0, x1, y);
+  y += this->font_height;
+  
+  draw_header_line (this, outp_subtitle, r2, x0, x1, y);
+  free (r1);
+  free (r2);
 }
 }
-
-/* (write_text) Writes the accumulated line buffer to the output
-   file. */
-#define output_line()                          \
-       do                                      \
-         {                                     \
-            lp = stpcpy (lp, ext->eol);                \
-           *lp = 0;                            \
-           fputs (line, ext->file.file);       \
-           lp = line;                          \
-         }                                     \
-        while (0)
-
-/* (write_text) Adds the string representing number X to the line
-   buffer, flushing the buffer to disk beforehand if necessary. */
-#define put_number(X)                          \
-       do                                      \
-         {                                     \
-           int n = nsprintf (number, "%d", X); \
-           if (n + lp > &line[75])             \
-             output_line ();                   \
-           lp = stpcpy (lp, number);           \
-         }                                     \
-       while (0)
-
-/* Outputs PostScript code to THIS driver's output file to display the
-   characters represented by the output_char's between CP and END,
-   using the associated outp_text T to determine formatting.  WIDTH is
-   the width of the output region; WIDTH_LEFT is the amount of the
-   WIDTH that is not taken up by text (so it can be used to determine
-   justification). */
+\f
+/* Writes the CHAR_CNT characters in CHARS at (X0,Y0), using the
+   given FONT.
+   The characters are justified according to JUSTIFICATION in a
+   field that has WIDTH_LEFT space remaining after the characters
+   themselves are accounted for.
+   Before character I is written, its x-position is adjusted by
+   KERNS[I]. */
 static void
 write_text (struct outp_driver *this,
 static void
 write_text (struct outp_driver *this,
-           const struct output_char *cp, const struct output_char *end,
-           struct outp_text *t, int width UNUSED, int width_left)
+            int x0, int y0,
+            enum outp_font font, 
+            enum outp_justification justification,
+            const struct afm_character **chars, int *kerns, size_t char_cnt,
+            int width_left)
 {
   struct ps_driver_ext *ext = this->ext;
 {
   struct ps_driver_ext *ext = this->ext;
-  int ofs;
+  struct afm *afm = ext->fonts[font]->metrics;
+  struct string out;
+  size_t i, j;
 
 
-  int last_y;
+  if (justification == OUTP_RIGHT)
+    x0 += width_left;
+  else if (justification == OUTP_CENTER)
+    x0 += width_left / 2;
+  y0 += afm_get_ascent (afm) * this->font_height / 1000;
 
 
-  char number[INT_STRLEN_BOUND (int) + 1];
-  char line[80];
-  char *lp;
+  fprintf (ext->file, "\n%d %d moveto\n", x0, YT (y0));
 
 
-  switch (t->options & OUTP_T_JUST_MASK)
+  if (ext->last_font != font)
     {
     {
-    case OUTP_T_JUST_LEFT:
-      ofs = 0;
-      break;
-    case OUTP_T_JUST_RIGHT:
-      ofs = width_left;
-      break;
-    case OUTP_T_JUST_CENTER:
-      ofs = width_left / 2;
-      break;
-    default:
-      assert (0);
-      abort ();
+      ext->last_font = font;
+      fprintf (ext->file, "F%d setfont\n", font);
     }
 
     }
 
-  lp = line;
-  last_y = INT_MIN;
-  while (cp < end)
+  ds_init (&out, 0);
+  for (i = 0; i < char_cnt; i = j)
     {
     {
-      int x = cp->x + ofs;
-      int y = cp->y + (cp->font->font->ascent * cp->size / 1000);
-
-      if (ext->last_font == NULL
-         || cp->font != ext->last_font->font
-         || cp->size != ext->last_font->size)
-       switch_font (this, cp);
-
-      *lp++ = '(';
-      do
-       {
-         /* PORTME! */
-         static unsigned char literal_chars[ODA_COUNT][32] =
-         {
-           {0x00, 0x00, 0x00, 0xf8, 0xff, 0xfc, 0xff, 0xff,
-            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
-            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-           },
-           {0x00, 0x00, 0x00, 0xf8, 0xff, 0xfc, 0xff, 0xff,
-            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-           },
-           {0x7e, 0xd6, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xff,
-            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-           }
-         };
-
-         if (TEST_BIT (literal_chars[ext->data], cp->ch))
-           *lp++ = cp->ch;
-         else
-           switch ((char) cp->ch)
-             {
-             case '(':
-               lp = stpcpy (lp, "\\(");
-               break;
-             case ')':
-               lp = stpcpy (lp, "\\)");
-               break;
-             default:
-               lp = spprintf (lp, "\\%03o", cp->ch);
-               break;
-             }
-         cp++;
-       }
-      while (cp < end && lp < &line[70] && cp->separate == 0);
-      *lp++ = ')';
-
-      put_number (x);
-
-      if (y != last_y)
-       {
-         *lp++ = ' ';
-         put_number (YT (y));
-         *lp++ = ' ';
-         *lp++ = 'S';
-         last_y = y;
-       }
-      else
-       {
-         *lp++ = ' ';
-         *lp++ = 'T';
-       }
+      for (j = i + 1; j < char_cnt; j++)
+        if (kerns[j] != 0)
+          break;
 
 
-      if (lp >= &line[70])
-       output_line ();
+      if (kerns[i] != 0)
+        fprintf (ext->file, "%d K", kerns[i]);
+      while (i < j)
+        {
+          size_t encoded = afm_encode_string (afm, chars + i, j - i, &out);
+          if (encoded > 0)
+            {
+              fprintf (ext->file, "%sS\n", ds_c_str (&out));
+              ds_clear (&out);
+              i += encoded;
+            }
+
+          if (i < j)
+            {
+              fprintf (ext->file, "/%s GS\n", chars[i]->name);
+              i++;
+            }
+        }
     }
     }
-  if (lp != line)
-    output_line ();
+  ds_destroy (&out);
 }
 
 }
 
-#undef output_line
-#undef put_number
+/* State of a text formatting operation. */
+struct text_state
+  {
+    /* Input. */
+    const struct outp_text *text;
+    bool draw;
+
+    /* Output. */
+    const struct afm_character **glyphs;
+    int *glyph_kerns;
+
+    /* State. */
+    size_t glyph_cnt;           /* Number of glyphs output. */
+    int width_left;            /* Width left over. */
+    int height_left;            /* Height left over. */
+
+    /* State as of last space. */
+    const char *space_char;     /* Just past last space. */
+    size_t space_glyph_cnt;     /* Number of glyphs as of last space. */
+    int space_width_left;       /* Width left over as of last space. */
+
+    /* Statistics. */
+    int max_width;             /* Widest line so far. */
+  };
 
 
-/* Displays the text in outp_text T, if DRAW is nonzero; or, merely
-   determine the text metrics, if DRAW is zero. */
+/* Adjusts S to complete a line of text,
+   and draws the current line if appropriate. */
 static void
 static void
-text (struct outp_driver *this, struct outp_text *t, int draw)
+finish_line (struct outp_driver *this, struct text_state *s)
 {
 {
-  struct ps_driver_ext *ext = this->ext;
-
-  /* Output. */
-  struct output_char *buf;     /* Output buffer. */
-  struct output_char *buf_end; /* End of output buffer. */
-  struct output_char *buf_loc; /* Current location in output buffer. */
+  int width;
 
 
-  /* Saved state. */
-  struct font_entry *old_current = ext->current;
-  char *old_family = xstrdup (ext->family); /* FIXME */
-  int old_size = ext->size;
-
-  /* Input string. */
-  char *cp, *end;
+  if (s->draw)
+    {
+      write_text (this,
+                  s->text->x, s->text->y + (s->text->v - s->height_left),
+                  s->text->font,
+                  s->text->justification,
+                  s->glyphs, s->glyph_kerns, s->glyph_cnt,
+                  s->width_left);
+      s->glyph_cnt = 0;
+    }
 
 
-  /* Current location. */
-  int x, y;
+  /* Update maximum width. */
+  width = s->text->h - s->width_left;
+  if (width > s->max_width)
+    s->max_width = width;
 
 
-  /* Keeping track of what's left over. */
-  int width;                   /* Width available for characters. */
-  int width_left, height_left; /* Width, height left over. */
-  int max_height;              /* Tallest character on this line so far. */
+  /* Move to next line. */
+  s->width_left = s->text->h;
+  s->height_left -= this->font_height;
 
 
-  /* Previous character. */
-  int prev_char;
+  /* No spaces on this line yet. */
+  s->space_char = NULL;
+}
 
 
-  /* Information about location of previous space. */
-  char *space_char;            /* Character after space. */
-  struct output_char *space_buf_loc; /* Buffer location after space. */
-  int space_width_left;                /* Width of characters before space. */
+/* Format TEXT on THIS driver.
+   If DRAW is nonzero, draw the text.
+   The width of the widest line is stored into *WIDTH, if WIDTH
+   is nonnull.
+   The total height of the text written is stored into *HEIGHT,
+   if HEIGHT is nonnull. */
+static void
+text (struct outp_driver *this, const struct outp_text *text, bool draw,
+      int *width, int *height)
+{
+  struct ps_driver_ext *ext = this->ext;
+  struct afm *afm = ext->fonts[text->font]->metrics;
+  const char *cp;
+  size_t glyph_cap;
+  struct text_state s;
 
 
-  /* Name of the current character. */
-  const char *char_name;
-  char local_char_name[2] = {0, 0};
+  s.text = text;
+  s.draw = draw;
 
 
-  local_char_name[0] = local_char_name[1] = 0;
+  s.glyphs = NULL;
+  s.glyph_kerns = NULL;
+  glyph_cap = 0;
 
 
-  buf = local_alloc (sizeof *buf * 128);
-  buf_end = &buf[128];
-  buf_loc = buf;
+  s.glyph_cnt = 0;
+  s.width_left = s.text->h;
+  s.height_left = s.text->v;
 
 
-  assert (!ls_null_p (&t->s));
-  cp = ls_c_str (&t->s);
-  end = ls_end (&t->s);
-  if (draw)
-    {
-      x = t->x;
-      y = t->y;
-    }
-  else
-    x = y = 0;
-  width = width_left = (t->options & OUTP_T_HORZ) ? t->h : INT_MAX;
-  height_left = (t->options & OUTP_T_VERT) ? t->v : INT_MAX;
-  max_height = 0;
-  prev_char = -1;
-  space_char = NULL;
-  space_buf_loc = NULL;
-  space_width_left = 0;
-  
+  s.space_char = 0;
 
 
-  if (!width || !height_left)
-    goto exit;
+  s.max_width = 0;
 
 
-  while (cp < end)
+  cp = ls_c_str (&s.text->string);
+  while (s.height_left >= this->font_height && cp < ls_end (&s.text->string))
     {
     {
-      struct char_metrics *metric;
-      int cur_char;
-      int kern_amt;
+      const struct afm_character *cur;
       int char_width;
       int char_width;
-      int separate = 0;
-
-      /* Set char_name to the name of the character or ligature at
-         *cp. */
-      local_char_name[0] = *cp;
-      char_name = local_char_name;
-      if (ext->current->font->ligatures && *cp == 'f')
-       {
-         int lig = 0;
-          char_name = NULL;
-
-         if (cp < end - 1)
-           switch (cp[1])
-             {
-             case 'i':
-               lig = LIG_fi, char_name = "fi";
-               break;
-             case 'l':
-               lig = LIG_fl, char_name = "fl";
-               break;
-             case 'f':
-               if (cp < end - 2)
-                 switch (cp[2])
-                   {
-                   case 'i':
-                     lig = LIG_ffi, char_name = "ffi";
-                     goto got_ligature;
-                   case 'l':
-                     lig = LIG_ffl, char_name = "ffl";
-                     goto got_ligature;
-                   }
-               lig = LIG_ff, char_name = "ff";
-             got_ligature:
-               break;
-             }
-         if ((lig & ext->current->font->ligatures) == 0)
-           {
-             local_char_name[0] = *cp; /* 'f' */
-             char_name = local_char_name;
-           }
-       }
-      else if (*cp == '\n')
-       {
-         if (draw)
-           {
-             write_text (this, buf, buf_loc, t, width, width_left);
-             buf_loc = buf;
-             x = t->x;
-             y += max_height;
-           }
-
-         width_left = width;
-         height_left -= max_height;
-         max_height = 0;
-         kern_amt = 0;
-         separate = 1;
-         cp++;
-
-         /* FIXME: when we're page buffering it will be necessary to
-            set separate to 1. */
-         continue;
-       }
-      cp += strlen (char_name);
+      int kern_adjust;
 
 
-      /* Figure out what size this character is, and what kern
-         adjustment we need. */
-      cur_char = font_char_name_to_index (char_name);
-      metric = font_get_char_metrics (ext->current->font, cur_char);
-      if (!metric)
-       {
-         static struct char_metrics m;
-         metric = &m;
-         m.width = ext->current->font->space_width;
-         m.code = *char_name;
-       }
-      kern_amt = font_get_kern_adjust (ext->current->font, prev_char,
-                                      cur_char);
-      if (kern_amt)
-       {
-         kern_amt = (kern_amt * ext->size / 1000);
-         separate = 1;
-       }
-      char_width = metric->width * ext->size / 1000;
+      if (*cp == '\n')
+        {
+          finish_line (this, &s);
+          cp++;
+          continue;
+        }
+
+      /* Get character and resolve ligatures. */
+      cur = afm_get_character (afm, *cp);
+      while (++cp < ls_end (&s.text->string))
+        {
+          const struct afm_character *next = afm_get_character (afm, *cp);
+          const struct afm_character *ligature = afm_get_ligature (cur, next);
+          if (ligature == NULL)
+            break;
+          cur = ligature;
+        }
+      char_width = cur->width * this->font_height / 1000;
+
+      /* Get kern adjustment. */
+      if (s.glyph_cnt > 0) 
+        kern_adjust = (afm_get_kern_adjustment (s.glyphs[s.glyph_cnt - 1], cur)
+                       * this->font_height / 1000);
+      else
+        kern_adjust = 0;
 
       /* Record the current status if this is a space character. */
 
       /* Record the current status if this is a space character. */
-      if (cur_char == space_index && buf_loc > buf)
-       {
-         space_char = cp;
-         space_buf_loc = buf_loc;
-         space_width_left = width_left;
-       }
-
-      /* Drop down to a new line if there's no room left on this
-         line. */
-      if (char_width + kern_amt > width_left)
+      if (cur->code == ' ' && cp > ls_c_str (&s.text->string))
        {
        {
-         /* Regress to previous space, if any. */
-         if (space_char)
-           {
-             cp = space_char;
-             width_left = space_width_left;
-             buf_loc = space_buf_loc;
-           }
-
-         if (draw)
-           {
-             write_text (this, buf, buf_loc, t, width, width_left);
-             buf_loc = buf;
-             x = t->x;
-             y += max_height;
-           }
-
-         width_left = width;
-         height_left -= max_height;
-         max_height = 0;
-         kern_amt = 0;
-
-         if (space_char)
-           {
-             space_char = NULL;
-             prev_char = -1;
-             /* FIXME: when we're page buffering it will be
-                necessary to set separate to 1. */
-             continue;
-           }
-         separate = 1;
+         s.space_char = cp;
+         s.space_glyph_cnt = s.glyph_cnt;
+          s.space_width_left = s.width_left;
        }
        }
-      if (ext->size > max_height)
-       max_height = ext->size;
-      if (max_height > height_left)
-       goto exit;
 
 
-      /* Actually draw the character. */
-      if (draw)
+      /* Enough room on this line? */
+      if (char_width + kern_adjust > s.width_left)
        {
        {
-         if (buf_loc >= buf_end)
-           {
-             int buf_len = buf_end - buf;
-
-             if (buf_len == 128)
-               {
-                 struct output_char *new_buf;
-
-                 new_buf = xmalloc (sizeof *new_buf * 256);
-                 memcpy (new_buf, buf, sizeof *new_buf * 128);
-                 buf_loc = new_buf + 128;
-                 buf_end = new_buf + 256;
-                 local_free (buf);
-                 buf = new_buf;
-               }
-             else
-               {
-                 buf = xnrealloc (buf, buf_len * 2, sizeof *buf);
-                 buf_loc = buf + buf_len;
-                 buf_end = buf + buf_len * 2;
-               }
-           }
-
-         x += kern_amt;
-         buf_loc->font = ext->current;
-         buf_loc->size = ext->size;
-         buf_loc->x = x;
-         buf_loc->y = y;
-         buf_loc->ch = metric->code;
-         buf_loc->separate = separate;
-         buf_loc++;
-         x += char_width;
+         if (s.space_char == NULL)
+            {
+              finish_line (this, &s);
+              kern_adjust = 0;
+            }
+          else
+            {
+              cp = s.space_char;
+              s.glyph_cnt = s.space_glyph_cnt;
+              s.width_left = s.space_width_left;
+              finish_line (this, &s);
+              continue;
+            }
        }
 
        }
 
-      /* Prepare for next iteration. */
-      width_left -= char_width + kern_amt;
-      prev_char = cur_char;
+      if (s.glyph_cnt >= glyph_cap)
+        {
+          glyph_cap = 2 * (glyph_cap + 8);
+          s.glyphs = xnrealloc (s.glyphs, glyph_cap, sizeof *s.glyphs);
+          s.glyph_kerns = xnrealloc (s.glyph_kerns,
+                                     glyph_cap, sizeof *s.glyph_kerns);
+        }
+      s.glyphs[s.glyph_cnt] = cur;
+      s.glyph_kerns[s.glyph_cnt] = kern_adjust;
+      s.glyph_cnt++;
+
+      s.width_left -= char_width + kern_adjust;
     }
     }
-  height_left -= max_height;
-  if (buf_loc > buf && draw)
-    write_text (this, buf, buf_loc, t, width, width_left);
-
-exit:
-  if (!(t->options & OUTP_T_HORZ))
-    t->h = INT_MAX - width_left;
-  if (!(t->options & OUTP_T_VERT))
-    t->v = INT_MAX - height_left;
-  else
-    t->v -= height_left;
-  if (buf_end - buf == 128)
-    local_free (buf);
-  else
-    free (buf);
-  ext->current = old_current;
-  free (ext->family);
-  ext->family = old_family;
-  ext->size = old_size;
-}
-
-static void
-ps_text_metrics (struct outp_driver *this, struct outp_text *t)
-{
-  assert (this->driver_open && this->page_open);
-  text (this, t, 0);
-}
-
-static void
-ps_text_draw (struct outp_driver *this, struct outp_text *t)
-{
-  assert (this->driver_open && this->page_open);
-  text (this, t, 1);
-}
-\f
-/* Font loader. */
-
-/* Translate a filename to a font. */
-struct filename2font
-  {
-    char *filename;            /* Normalized filename. */
-    struct font_desc *font;
-  };
-
-/* Table of `filename2font's. */
-static struct hsh_table *ps_fonts;
-
-/* Hash table comparison function for filename2font structs. */
-static int
-compare_filename2font (const void *a, const void *b, void *param UNUSED)
-{
-  return strcmp (((struct filename2font *) a)->filename,
-                ((struct filename2font *) b)->filename);
-}
+  if (s.height_left >= this->font_height && s.glyph_cnt > 0)
+    finish_line (this, &s);
 
 
-/* Hash table hash function for filename2font structs. */
-static unsigned
-hash_filename2font (const void *f2f_, void *param UNUSED)
-{
-  const struct filename2font *f2f = f2f_;
-  return hsh_hash_string (f2f->filename);
+  if (width != NULL)
+    *width = s.max_width;
+  if (height != NULL)
+    *height = text->v - s.height_left;
+  free (s.glyphs);
+  free (s.glyph_kerns);
 }
 
 }
 
-/* Initializes the global font list by creating the hash table for
-   translation of filenames to font_desc structs. */
 static void
 static void
-init_fonts (void)
+ps_text_metrics (struct outp_driver *this, const struct outp_text *t,
+                 int *width, int *height)
 {
 {
-  ps_fonts = hsh_create (31, compare_filename2font, hash_filename2font,
-                        NULL, NULL);
+  text (this, t, false, width, height);
 }
 
 static void
 }
 
 static void
-done_fonts (void)
-{
- hsh_destroy (ps_fonts);
-}
-
-/* Loads the font having Groff name DIT into THIS driver instance.
-   Specifically, adds it into the THIS driver's `loaded' hash
-   table. */
-static struct font_entry *
-load_font (struct outp_driver *this, const char *dit)
+ps_text_draw (struct outp_driver *this, const struct outp_text *t)
 {
 {
-  struct ps_driver_ext *x = this->ext;
-  char *filename1, *filename2;
-  void **entry;
-  struct font_entry *fe;
-
-  filename1 = find_ps_file (this, dit);
-  if (!filename1)
-    filename1 = xstrdup (dit);
-  filename2 = fn_normalize (filename1);
-  free (filename1);
-
-  entry = hsh_probe (ps_fonts, &filename2);
-  if (*entry == NULL)
-    {
-      struct filename2font *f2f;
-      struct font_desc *f = groff_read_font (filename2);
-
-      if (f == NULL)
-       {
-         if (x->fixed)
-           f = x->fixed->font;
-         else
-           f = default_font ();
-       }
-      
-      f2f = xmalloc (sizeof *f2f);
-      f2f->filename = filename2;
-      f2f->font = f;
-      *entry = f2f;
-    }
-  else
-    free (filename2);
-
-  fe = xmalloc (sizeof *fe);
-  fe->dit = xstrdup (dit);
-  fe->font = ((struct filename2font *) * entry)->font;
-  *hsh_probe (x->loaded, &dit) = fe;
-
-  return fe;
+  assert (this->page_open);
+  text (this, t, true, NULL, NULL);
 }
 }
-
+\f
 static void
 ps_chart_initialise (struct outp_driver *this UNUSED, struct chart *ch)
 {
 static void
 ps_chart_initialise (struct outp_driver *this UNUSED, struct chart *ch)
 {
@@ -2884,12 +1100,12 @@ ps_chart_initialise (struct outp_driver *this UNUSED, struct chart *ch)
   int x_origin, y_origin;
 
   ch->file = tmpfile ();
   int x_origin, y_origin;
 
   ch->file = tmpfile ();
-  if (ch->file == NULL) 
+  if (ch->file == NULL)
     {
       ch->lp = NULL;
       return;
     }
     {
       ch->lp = NULL;
       return;
     }
-  
+
   size = this->width < this->length ? this->width : this->length;
   x_origin = x->left_margin + (size - this->width) / 2;
   y_origin = x->bottom_margin + (size - this->length) / 2;
   size = this->width < this->length ? this->width : this->length;
   x_origin = x->left_margin + (size - this->width) / 2;
   y_origin = x->bottom_margin + (size - this->length) / 2;
@@ -2905,7 +1121,7 @@ ps_chart_initialise (struct outp_driver *this UNUSED, struct chart *ch)
 #endif
 }
 
 #endif
 }
 
-static void 
+static void
 ps_chart_finalise (struct outp_driver *this UNUSED, struct chart *ch UNUSED)
 {
 #ifndef NO_CHARTS
 ps_chart_finalise (struct outp_driver *this UNUSED, struct chart *ch UNUSED)
 {
 #ifndef NO_CHARTS
@@ -2913,103 +1129,311 @@ ps_chart_finalise (struct outp_driver *this UNUSED, struct chart *ch UNUSED)
   char buf[BUFSIZ];
   static int doc_num = 0;
 
   char buf[BUFSIZ];
   static int doc_num = 0;
 
-  if (this->page_open) 
-    {
-      this->class->close_page (this);
-      this->page_open = 0; 
-    }
-  this->class->open_page (this);
-  fprintf (x->file.file,
-           "/sp save def%s"
-           "%d %d translate 1000 dup scale%s"
-           "userdict begin%s"
-           "/showpage { } def%s"
-           "0 setgray 0 setlinecap 1 setlinewidth%s"
-           "0 setlinejoin 10 setmiterlimit [ ] 0 setdash newpath clear%s"
-           "%%%%BeginDocument: %d%s",
-           x->eol,
-           -x->left_margin, -x->bottom_margin, x->eol,
-           x->eol,
-           x->eol,
-           x->eol,
-           x->eol,
-           doc_num++, x->eol);
+  outp_eject_page (this);
+  fprintf (x->file,
+           "/sp save def\n"
+           "%d %d translate 1000 dup scale\n"
+           "userdict begin\n"
+           "/showpage { } def\n"
+           "0 setgray 0 setlinecap 1 setlinewidth\n"
+           "0 setlinejoin 10 setmiterlimit [ ] 0 setdash newpath clear\n"
+           "%%%%BeginDocument: %d\n",
+           -x->left_margin, -x->bottom_margin,
+           doc_num++);
 
   rewind (ch->file);
 
   rewind (ch->file);
-  while (fwrite (buf, 1, fread (buf, 1, sizeof buf, ch->file), x->file.file))
+  while (fwrite (buf, 1, fread (buf, 1, sizeof buf, ch->file), x->file))
     continue;
   fclose (ch->file);
 
     continue;
   fclose (ch->file);
 
-  fprintf (x->file.file,
-           "%%%%EndDocument%s"
-           "end%s"
-           "sp restore%s",
-           x->eol,
-           x->eol,
-           x->eol);
-  this->class->close_page (this);
-  this->page_open = 0;
+  fputs ("%%%%EndDocument\n"
+         "end\n"
+         "sp restore\n",
+         x->file);
+  outp_close_page (this);
 #endif
 }
 #endif
 }
+\f
+static void embed_font (struct outp_driver *this, struct font *font);
+static void reencode_font (struct outp_driver *this, struct font *font);
+
+/* Loads and returns the font for STRING, which has the format
+   "AFM,PFA,ENC", where AFM is the AFM file's name, PFA is the
+   PFA or PFB file's name, and ENC is the encoding file's name.
+   PFA and ENC are optional.
+   Returns a null pointer if unsuccessful. */
+static struct font *
+load_font (const char *string_)
+{
+  char *string = xstrdup (string_);
+  struct font *font;
+  char *position = string;
+  char *token;
+  char *afm_file_name;
+
+  font = xmalloc (sizeof *font);
+  font->metrics = NULL;
+  font->embed_fn = NULL;
+  font->encoding_fn = NULL;
+
+  token = strsep (&position, ",");
+  if (token == NULL)
+    {
+      error (0, 0, _("\"%s\": bad font specification"), string);
+      goto error;
+    }
 
 
-/* PostScript driver class. */
-struct outp_class postscript_class =
+  /* Read AFM file. */
+  afm_file_name = find_ps_file (token);
+  if (afm_file_name == NULL)
+    {
+      error (0, 0, _("could not find AFM file \"%s\""), token);
+      goto error;
+    }
+  font->metrics = afm_open (afm_file_name);
+  free (afm_file_name);
+  if (font->metrics == NULL)
+    goto error;
+
+  /* Find font file to embed. */
+  token = strsep (&position, ",");
+  if (token != NULL && *token != '\0')
+    {
+      font->embed_fn = find_ps_file (token);
+      if (font->embed_fn == NULL)
+        error (0, 0, _("could not find font \"%s\""), token);
+    }
+
+  /* Find encoding. */
+  token = strsep (&position, ",");
+  if (token != NULL && *token == '\0')
+    {
+      font->encoding_fn = find_ps_file (token);
+      if (font->encoding_fn == NULL)
+        error (0, 0, _("could not find encoding \"%s\""), token);
+    }
+
+  free (string);
+  return font;
+
+ error:
+  free (string);
+  free_font (font);
+  return NULL;
+}
+
+/* Frees FONT. */
+static void
+free_font (struct font *font)
 {
 {
-  "postscript",
-  MAGIC_PS,
-  0,
+  if (font != NULL)
+    {
+      afm_close (font->metrics);
+      free (font->embed_fn);
+      free (font->encoding_fn);
+      free (font);
+    }
+}
 
 
-  ps_open_global,
-  ps_close_global,
-  ps_font_sizes,
+/* Emits PostScript code to embed FONT (if necessary), scale it
+   to the proper size, re-encode it (if necessary), and store the
+   resulting font as an object named F#, where INDEX is
+   substituted for #. */
+static void
+setup_font (struct outp_driver *this, struct font *font, int index)
+{
+  struct ps_driver_ext *x = this->ext;
+  char *ps_name;
 
 
-  ps_preopen_driver,
-  ps_option,
-  ps_postopen_driver,
-  ps_close_driver,
+  if (font->embed_fn != NULL)
+    embed_font (this, font);
+  else
+    fprintf (x->file, "%%%%IncludeResource: font %s\n",
+             afm_get_findfont_name (font->metrics));
 
 
-  ps_open_page,
-  ps_close_page,
+  ps_name = quote_ps_name (afm_get_findfont_name (font->metrics));
+  fprintf (x->file, "%s findfont %d scalefont\n", ps_name, this->font_height);
+  free (ps_name);
 
 
-  ps_submit,
+  if (font->encoding_fn != NULL)
+    reencode_font (this, font);
 
 
-  ps_line_horz,
-  ps_line_vert,
-  ps_line_intersection,
-
-  ps_box,
-  ps_polyline_begin,
-  ps_polyline_point,
-  ps_polyline_end,
-
-  ps_text_set_font_by_name,
-  ps_text_set_font_by_position,
-  ps_text_set_font_family,
-  ps_text_get_font_name,
-  ps_text_get_font_family,
-  ps_text_set_size,
-  ps_text_get_size,
-  ps_text_metrics,
-  ps_text_draw,
+  fprintf (x->file, "/F%d ED\n", index);
+}
 
 
-  ps_chart_initialise,
-  ps_chart_finalise
-};
+/* Copies up to COPY_BYTES bytes from SRC to DST, stopping at
+   end-of-file or on error. */
+static void
+copy_bytes_literally (FILE *src, FILE *dst, unsigned long copy_bytes)
+{
+  while (copy_bytes > 0)
+    {
+      char buffer[BUFSIZ];
+      unsigned long chunk_bytes = MIN (copy_bytes, sizeof buffer);
+      size_t read_bytes = fread (buffer, 1, chunk_bytes, src);
+      size_t write_bytes = fwrite (buffer, 1, read_bytes, dst);
+      if (write_bytes != chunk_bytes)
+        break;
+      copy_bytes -= chunk_bytes;
+    }
+}
 
 
-/* EPSF driver class.  FIXME: Probably doesn't work right. */
-struct outp_class epsf_class =
+/* Copies up to COPY_BYTES bytes from SRC to DST, stopping at
+   end-of-file or on error.  The bytes are translated into
+   hexadecimal during copying and broken into lines with
+   new-line characters. */
+static void
+copy_bytes_as_hex (FILE *src, FILE *dst, unsigned long copy_bytes)
 {
 {
-  "epsf",
-  MAGIC_EPSF,
-  0,
+  unsigned long i;
+
+  for (i = 0; i < copy_bytes; i++)
+    {
+      int c = getc (src);
+      if (c == EOF)
+        break;
+      if (i > 0 && i % 36 == 0)
+        putc ('\n', dst);
+      fprintf (dst, "%02X", c);
+    }
+  putc ('\n', dst);
+}
+
+/* Embeds the given FONT into THIS driver's output stream. */
+static void
+embed_font (struct outp_driver *this, struct font *font)
+{
+  struct ps_driver_ext *x = this->ext;
+  FILE *file;
+  int c;
+
+  file = fopen (font->embed_fn, "rb");
+  if (file == NULL)
+    {
+      error (errno, 0, _("cannot open font file \"%s\""), font->embed_fn);
+      return;
+    }
+
+  fprintf (x->file, "%%%%BeginResource: font %s\n",
+           afm_get_findfont_name (font->metrics));
+
+  c = getc (file);
+  ungetc (c, file);
+  if (c != 128)
+    {
+      /* PFA file.  Copy literally. */
+      copy_bytes_literally (file, x->file, ULONG_MAX);
+    }
+  else
+    {
+      /* PFB file.  Translate as specified in Adobe Technical
+         Note #5040. */
+      while ((c = getc (file)) == 128)
+        {
+          int type;
+          unsigned long length;
+
+          type = getc (file);
+          if (type == 3)
+            break;
+
+          length = getc (file);
+          length |= (unsigned long) getc (file) << 8;
+          length |= (unsigned long) getc (file) << 16;
+          length |= (unsigned long) getc (file) << 24;
+
+          if (type == 1)
+            copy_bytes_literally (file, x->file, length);
+          else if (type == 2)
+            copy_bytes_as_hex (file, x->file, length);
+          else
+            break;
+        }
+    }
+  if (freaderror (file))
+    error (errno, 0, _("reading font file \"%s\""), font->embed_fn);
+  fputs ("%%EndResource\n", x->file);
+}
+
+/* Re-encodes FONT according to the specified encoding. */
+static void
+reencode_font (struct outp_driver *this, struct font *font)
+{
+  struct ps_driver_ext *x = this->ext;
+
+  struct string line;
 
 
-  ps_open_global,
-  ps_close_global,
-  ps_font_sizes,
+  int line_number;
+  FILE *file;
 
 
-  ps_preopen_driver,
-  ps_option,
-  ps_postopen_driver,
+  char *tab[256];
+
+  int i;
+
+  file = fopen (font->encoding_fn, "r");
+  if (file == NULL)
+    {
+      error (errno, 0, _("cannot open font encoding file \"%s\""),
+             font->encoding_fn);
+      return;
+    }
+
+  for (i = 0; i < 256; i++)
+    tab[i] = NULL;
+
+  line_number = 0;
+
+  ds_init (&line, 0);
+  while (ds_get_config_line (file, &line, &line_number))
+    {
+      char *pschar, *code;
+      char *save_ptr, *tail;
+      int code_val;
+
+      if (ds_is_empty (&line) == 0)
+        continue;
+
+      pschar = strtok_r (ds_c_str (&line), " \t\r\n", &save_ptr);
+      code = strtok_r (NULL, " \t\r\n", &save_ptr);
+      if (pschar == NULL || code == NULL)
+        continue;
+
+      code_val = strtol (code, &tail, 0);
+      if (*tail)
+        {
+          error_at_line (0, 0, font->encoding_fn, line_number,
+                         _("invalid numeric format"));
+          continue;
+        }
+      if (code_val < 0 || code_val > 255)
+        continue;
+      if (tab[code_val] != 0)
+        free (tab[code_val]);
+      tab[code_val] = xstrdup (pschar);
+    }
+  ds_destroy (&line);
+
+  fputs ("[", x->file);
+  for (i = 0; i < 256; i++)
+    {
+      char *name = quote_ps_name (tab[i] != NULL ? tab[i] : ".notdef");
+      fprintf (x->file, "%s\n", name);
+      free (name);
+      free (tab[i]);
+    }
+  fputs ("] RF\n", x->file);
+
+  if (freaderror (file) != 0)
+    error (errno, 0, "closing Postscript encoding \"%s\"", font->encoding_fn);
+}
+
+/* PostScript driver class. */
+struct outp_class postscript_class =
+{
+  "postscript",
+  0,
+
+  ps_open_driver,
   ps_close_driver,
 
   ps_open_page,
   ps_close_driver,
 
   ps_open_page,
@@ -3017,26 +1441,10 @@ struct outp_class epsf_class =
 
   ps_submit,
 
 
   ps_submit,
 
-  ps_line_horz,
-  ps_line_vert,
-  ps_line_intersection,
-
-  ps_box,
-  ps_polyline_begin,
-  ps_polyline_point,
-  ps_polyline_end,
-
-  ps_text_set_font_by_name,
-  ps_text_set_font_by_position,
-  ps_text_set_font_family,
-  ps_text_get_font_name,
-  ps_text_get_font_family,
-  ps_text_set_size,
-  ps_text_get_size,
+  ps_line,
   ps_text_metrics,
   ps_text_draw,
 
   ps_chart_initialise,
   ps_chart_finalise
   ps_text_metrics,
   ps_text_draw,
 
   ps_chart_initialise,
   ps_chart_finalise
-
 };
 };
index 7306ee3cfb76d26016e45d640caf46d6bf3b2be9..a9fc3743a6bec1f91e54a4b5aef377ab51286bfb 100644 (file)
@@ -29,6 +29,7 @@
 #include <data/format.h>
 #include <libpspp/magic.h>
 #include <libpspp/misc.h>
 #include <data/format.h>
 #include <libpspp/magic.h>
 #include <libpspp/misc.h>
+#include "minmax.h"
 #include "output.h"
 #include <libpspp/pool.h>
 #include "manager.h"
 #include "output.h"
 #include <libpspp/pool.h>
 #include "manager.h"
 struct som_table_class tab_table_class;
 static char *command_name;
 
 struct som_table_class tab_table_class;
 static char *command_name;
 
-/* Creates a table with NC columns and NR rows.  If REALLOCABLE is
-   nonzero then the table's size can be increased later; otherwise,
-   its size can only be reduced. */
-struct tab_table *
-tab_create (int nc, int nr, int reallocable)
+/* Returns the font to use for a cell with the given OPTIONS. */
+static enum outp_font
+options_to_font (unsigned options) 
 {
 {
-  void *(*alloc_func) (struct pool *, size_t n);
-  void *(*nalloc_func) (struct pool *, size_t n, size_t s);
+  return (options & TAB_FIX ? OUTP_FIXED
+          : options & TAB_EMPH ? OUTP_EMPHASIS
+          : OUTP_PROPORTIONAL);
+}
 
 
+/* Creates a table with NC columns and NR rows. */
+struct tab_table *
+tab_create (int nc, int nr, int reallocable UNUSED)
+{
   struct tab_table *t;
   struct tab_table *t;
-  
-  {
-    struct pool *container = pool_create ();
-    t = pool_alloc (container, sizeof *t);
-    t->container = container;
-  }
-  
+
+  t = pool_create_container (struct tab_table, container);
   t->col_style = TAB_COL_NONE;
   t->col_group = 0;
   ls_null (&t->title);
   t->col_style = TAB_COL_NONE;
   t->col_group = 0;
   ls_null (&t->title);
@@ -67,38 +67,26 @@ tab_create (int nc, int nr, int reallocable)
   t->nc = t->cf = nc;
   t->l = t->r = t->t = t->b = 0;
 
   t->nc = t->cf = nc;
   t->l = t->r = t->t = t->b = 0;
 
-  nalloc_func = reallocable ? pool_nmalloc : pool_nalloc;
-  alloc_func = reallocable ? pool_malloc : pool_alloc;
-#if DEBUGGING
-  t->reallocable = reallocable;
-#endif
-
-  t->cc = nalloc_func (t->container, nr * nc, sizeof *t->cc);
-  t->ct = alloc_func (t->container, nr * nc);
+  t->cc = pool_nmalloc (t->container, nr * nc, sizeof *t->cc);
+  t->ct = pool_malloc (t->container, nr * nc);
   memset (t->ct, TAB_EMPTY, nc * nr);
 
   memset (t->ct, TAB_EMPTY, nc * nr);
 
-  t->rh = nalloc_func (t->container, nc, nr + 1);
+  t->rh = pool_nmalloc (t->container, nc, nr + 1);
   memset (t->rh, 0, nc * (nr + 1));
 
   memset (t->rh, 0, nc * (nr + 1));
 
-  t->hrh = nalloc_func (t->container, nr + 1, sizeof *t->hrh);
+  t->hrh = pool_nmalloc (t->container, nr + 1, sizeof *t->hrh);
   memset (t->hrh, 0, sizeof *t->hrh * (nr + 1));
 
   memset (t->hrh, 0, sizeof *t->hrh * (nr + 1));
 
-  t->trh = alloc_func (t->container, nr + 1);
-  memset (t->trh, 0, nr + 1);
-
-  t->rv = nalloc_func (t->container, nr, nc + 1);
-  memset (t->rv, 0, (nc + 1) * nr);
+  t->rv = pool_nmalloc (t->container, nr, nc + 1);
+  memset (t->rv, UCHAR_MAX, nr * (nc + 1));
 
 
-  t->wrv = nalloc_func (t->container, nc + 1, sizeof *t->wrv);
+  t->wrv = pool_nmalloc (t->container, nc + 1, sizeof *t->wrv);
   memset (t->wrv, 0, sizeof *t->wrv * (nc + 1));
 
   memset (t->wrv, 0, sizeof *t->wrv * (nc + 1));
 
-  t->trv = alloc_func (t->container, nc + 1);
-  memset (t->trv, 0, nc + 1);
-
   t->dim = NULL;
   t->w = t->h = NULL;
   t->col_ofs = t->row_ofs = 0;
   t->dim = NULL;
   t->w = t->h = NULL;
   t->col_ofs = t->row_ofs = 0;
-  
+
   return t;
 }
 
   return t;
 }
 
@@ -108,7 +96,6 @@ tab_destroy (struct tab_table *t)
 {
   assert (t != NULL);
   pool_destroy (t->container);
 {
   assert (t != NULL);
   pool_destroy (t->container);
-  t=0;
 }
 
 /* Sets the width and height of a table, in columns and rows,
 }
 
 /* Sets the width and height of a table, in columns and rows,
@@ -142,9 +129,6 @@ tab_realloc (struct tab_table *t, int nc, int nr)
   int ro, co;
   
   assert (t != NULL);
   int ro, co;
   
   assert (t != NULL);
-#if DEBUGGING
-  assert (t->reallocable);
-#endif
   ro = t->row_ofs;
   co = t->col_ofs;
   if (ro || co)
   ro = t->row_ofs;
   co = t->col_ofs;
   if (ro || co)
@@ -187,14 +171,12 @@ tab_realloc (struct tab_table *t, int nc, int nr)
 
       t->rh = pool_nrealloc (t->container, t->rh, nc, nr + 1);
       t->rv = pool_nrealloc (t->container, t->rv, nr, nc + 1);
 
       t->rh = pool_nrealloc (t->container, t->rh, nc, nr + 1);
       t->rv = pool_nrealloc (t->container, t->rv, nr, nc + 1);
-      t->trh = pool_realloc (t->container, t->trh, nr + 1);
-      t->hrh = pool_nrealloc (t->container, t->hrh, nr + 1, sizeof *t->hrh);
       
       if (nr > t->nr)
        {
       
       if (nr > t->nr)
        {
-         memset (&t->rh[nc * (t->nr + 1)], 0, (nr - t->nr) * nc);
-         memset (&t->rv[(nc + 1) * t->nr], 0, (nr - t->nr) * (nc + 1));
-         memset (&t->trh[t->nr + 1], 0, nr - t->nr);
+         memset (&t->rh[nc * (t->nr + 1)], TAL_0, (nr - t->nr) * nc);
+         memset (&t->rv[(nc + 1) * t->nr], UCHAR_MAX,
+                  (nr - t->nr) * (nc + 1));
        }
     }
 
        }
     }
 
@@ -247,8 +229,6 @@ tab_columns (struct tab_table *t, int style, int group)
 void
 tab_vline (struct tab_table *t, int style, int x, int y1, int y2)
 {
 void
 tab_vline (struct tab_table *t, int style, int x, int y1, int y2)
 {
-  int y;
-
   assert (t != NULL);
 
 #if DEBUGGING
   assert (t != NULL);
 
 #if DEBUGGING
@@ -278,10 +258,9 @@ tab_vline (struct tab_table *t, int style, int x, int y1, int y2)
 
   if (style != -1)
     {
 
   if (style != -1)
     {
-      if ((style & TAL_SPACING) == 0)
-       for (y = y1; y <= y2; y++)
-         t->rv[x + (t->cf + 1) * y] = style;
-      t->trv[x] |= (1 << (style & ~TAL_SPACING));
+      int y;
+      for (y = y1; y <= y2; y++)
+        t->rv[x + (t->cf + 1) * y] = style;
     }
 }
 
     }
 }
 
@@ -290,8 +269,6 @@ tab_vline (struct tab_table *t, int style, int x, int y1, int y2)
 void
 tab_hline (struct tab_table * t, int style, int x1, int x2, int y)
 {
 void
 tab_hline (struct tab_table * t, int style, int x1, int x2, int y)
 {
-  int x;
-
   assert (t != NULL);
 
   x1 += t->col_ofs;
   assert (t != NULL);
 
   x1 += t->col_ofs;
@@ -306,10 +283,9 @@ tab_hline (struct tab_table * t, int style, int x1, int x2, int y)
 
   if (style != -1)
     {
 
   if (style != -1)
     {
-      if ((style & TAL_SPACING) == 0)
-       for (x = x1; x <= x2; x++)
-         t->rh[x + t->cf * y] = style;
-      t->trh[y] |= (1 << (style & ~TAL_SPACING));
+      int x;
+      for (x = x1; x <= x2; x++)
+        t->rh[x + t->cf * y] = style;
     }
 }
 
     }
 }
 
@@ -357,26 +333,20 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v,
   if (f_h != -1)
     {
       int x;
   if (f_h != -1)
     {
       int x;
-      if ((f_h & TAL_SPACING) == 0)
-       for (x = x1; x <= x2; x++)
-         {
-           t->rh[x + t->cf * y1] = f_h;
-           t->rh[x + t->cf * (y2 + 1)] = f_h;
-         }
-      t->trh[y1] |= (1 << (f_h & ~TAL_SPACING));
-      t->trh[y2 + 1] |= (1 << (f_h & ~TAL_SPACING));
+      for (x = x1; x <= x2; x++)
+        {
+          t->rh[x + t->cf * y1] = f_h;
+          t->rh[x + t->cf * (y2 + 1)] = f_h;
+        }
     }
   if (f_v != -1)
     {
       int y;
     }
   if (f_v != -1)
     {
       int y;
-      if ((f_v & TAL_SPACING) == 0)
-       for (y = y1; y <= y2; y++)
-         {
-           t->rv[x1 + (t->cf + 1) * y] = f_v;
-           t->rv[(x2 + 1) + (t->cf + 1) * y] = f_v;
-         }
-      t->trv[x1] |= (1 << (f_v & ~TAL_SPACING));
-      t->trv[x2 + 1] |= (1 << (f_v & ~TAL_SPACING));
+      for (y = y1; y <= y2; y++)
+        {
+          t->rv[x1 + (t->cf + 1) * y] = f_v;
+          t->rv[(x2 + 1) + (t->cf + 1) * y] = f_v;
+        }
     }
 
   if (i_h != -1)
     }
 
   if (i_h != -1)
@@ -387,11 +357,8 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v,
        {
          int x;
 
        {
          int x;
 
-         if ((i_h & TAL_SPACING) == 0)
-           for (x = x1; x <= x2; x++)
-             t->rh[x + t->cf * y] = i_h;
-
-         t->trh[y] |= (1 << (i_h & ~TAL_SPACING));
+          for (x = x1; x <= x2; x++)
+            t->rh[x + t->cf * y] = i_h;
        }
     }
   if (i_v != -1)
        }
     }
   if (i_v != -1)
@@ -402,11 +369,8 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v,
        {
          int y;
          
        {
          int y;
          
-         if ((i_v & TAL_SPACING) == 0)
-           for (y = y1; y <= y2; y++)
-             t->rv[x + (t->cf + 1) * y] = i_v;
-
-         t->trv[x] |= (1 << (i_v & ~TAL_SPACING));
+          for (y = y1; y <= y2; y++)
+            t->rv[x + (t->cf + 1) * y] = i_v;
        }
     }
 }
        }
     }
 }
@@ -417,37 +381,29 @@ static void
 text_format (struct tab_table *table, int opt, const char *text, va_list args,
             struct fixed_string *s)
 {
 text_format (struct tab_table *table, int opt, const char *text, va_list args,
             struct fixed_string *s)
 {
-  int len;
+  char *tmp = NULL;
   
   assert (table != NULL && text != NULL && s != NULL);
   
   
   assert (table != NULL && text != NULL && s != NULL);
   
-  if (opt & TAT_PRINTF)
-    {
-      char *temp_buf = local_alloc (1024);
-      
-      len = nvsprintf (temp_buf, text, args);
-      text = temp_buf;
-    }
-  else
-    len = strlen (text);
+  if (opt & TAT_PRINTF) 
+    text = tmp = xvasprintf (text, args);
 
 
-  ls_create_buffer (s, text, len);
+  ls_create_buffer (s, text, strlen (text));
   pool_register (table->container, free, s->string);
   
   pool_register (table->container, free, s->string);
   
-  if (opt & TAT_PRINTF)
-    local_free (text);
+  free (tmp);
 }
 
 }
 
-/* Set the title of table T to TITLE, which is formatted with printf
-   if FORMAT is nonzero. */
+/* Set the title of table T to TITLE, which is formatted as if
+   passed to printf(). */
 void
 void
-tab_title (struct tab_table *t, int format, const char *title, ...)
+tab_title (struct tab_table *t, const char *title, ...)
 {
   va_list args;
 
   assert (t != NULL && title != NULL);
   va_start (args, title);
 {
   va_list args;
 
   assert (t != NULL && title != NULL);
   va_start (args, title);
-  text_format (t, format ? TAT_PRINTF : TAT_NONE, title, args, &t->title);
+  text_format (t, TAT_PRINTF, title, args, &t->title);
   va_end (args);
 }
 
   va_end (args);
 }
 
@@ -476,17 +432,20 @@ tab_natural_width (struct tab_table *t, struct outp_driver *d, int c)
       {
        struct outp_text text;
        unsigned char opt = t->ct[c + r * t->cf];
       {
        struct outp_text text;
        unsigned char opt = t->ct[c + r * t->cf];
+        int w;
                
        if (opt & (TAB_JOIN | TAB_EMPTY))
          continue;
 
                
        if (opt & (TAB_JOIN | TAB_EMPTY))
          continue;
 
-       text.s = t->cc[c + r * t->cf];
-       assert (!ls_null_p (&text.s));
-       text.options = OUTP_T_JUST_LEFT;
+       text.string = t->cc[c + r * t->cf];
+       assert (!ls_null_p (&text.string));
+       text.justification = OUTP_LEFT;
+        text.font = options_to_font (opt);
+        text.h = text.v = INT_MAX;
 
 
-       d->class->text_metrics (d, &text);
-       if (text.h > width)
-         width = text.h;
+       d->class->text_metrics (d, &text, &w, NULL);
+       if (w > width)
+         width = w;
       }
   }
 
       }
   }
 
@@ -525,19 +484,22 @@ tab_natural_height (struct tab_table *t, struct outp_driver *d, int r)
       {
        struct outp_text text;
        unsigned char opt = t->ct[c + r * t->cf];
       {
        struct outp_text text;
        unsigned char opt = t->ct[c + r * t->cf];
+        int h;
 
        assert (t->w[c] != NOT_INT);
        if (opt & (TAB_JOIN | TAB_EMPTY))
          continue;
 
 
        assert (t->w[c] != NOT_INT);
        if (opt & (TAB_JOIN | TAB_EMPTY))
          continue;
 
-       text.s = t->cc[c + r * t->cf];
-       assert (!ls_null_p (&text.s));
-       text.options = OUTP_T_HORZ | OUTP_T_JUST_LEFT;
+       text.string = t->cc[c + r * t->cf];
+       assert (!ls_null_p (&text.string));
+        text.justification = OUTP_LEFT;
+        text.font = options_to_font (opt);
        text.h = t->w[c];
        text.h = t->w[c];
-       d->class->text_metrics (d, &text);
+        text.v = INT_MAX;
+       d->class->text_metrics (d, &text, NULL, &h);
 
 
-       if (text.v > height)
-         height = text.v;
+       if (h > height)
+         height = h;
       }
   }
 
       }
   }
 
@@ -670,7 +632,7 @@ tab_text (struct tab_table *table, int c, int r, unsigned opt, const char *text,
       return;
     }
 #endif
       return;
     }
 #endif
-    
+
   va_start (args, text);
   text_format (table, opt, text, args, &table->cc[c + r * table->cf]);
   table->ct[c + r * table->cf] = opt;
   va_start (args, text);
   text_format (table, opt, text, args, &table->cc[c + r * table->cf]);
   table->ct[c + r * table->cf] = opt;
@@ -710,6 +672,8 @@ tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2,
       return;
     }
 #endif
       return;
     }
 #endif
+
+  tab_box (table, -1, -1, TAL_0, TAL_0, x1, y1, x2, y2);
   
   j = pool_alloc (table->container, sizeof *j);
   j->hit = 0;
   
   j = pool_alloc (table->container, sizeof *j);
   j->hit = 0;
@@ -803,60 +767,23 @@ void
 tab_output_text (int options, const char *buf, ...)
 {
   struct tab_table *t = tab_create (1, 1, 0);
 tab_output_text (int options, const char *buf, ...)
 {
   struct tab_table *t = tab_create (1, 1, 0);
+  char *tmp_buf = NULL;
 
 
-  assert (buf != NULL);
   if (options & TAT_PRINTF)
     {
       va_list args;
   if (options & TAT_PRINTF)
     {
       va_list args;
-      char *temp_buf = local_alloc (4096);
       
       va_start (args, buf);
       
       va_start (args, buf);
-      nvsprintf (temp_buf, buf, args);
-      buf = temp_buf;
+      buf = tmp_buf = xvasprintf (buf, args);
       va_end (args);
     }
   
       va_end (args);
     }
   
-  if (options & TAT_FIX)
-    {
-      struct outp_driver *d;
-
-      for (d = outp_drivers (NULL); d; d = outp_drivers (d))
-       {
-         if (!d->page_open)
-           d->class->open_page (d);
-
-          if (d->class->text_set_font_by_name != NULL)
-            d->class->text_set_font_by_name (d, "FIXED");
-          else 
-            {
-              /* FIXME */
-            }
-       }
-    }
-
-  tab_text (t, 0, 0, options &~ TAT_PRINTF, buf);
+  tab_text (t, 0, 0, options & ~TAT_PRINTF, buf);
   tab_flags (t, SOMF_NO_TITLE | SOMF_NO_SPACING);
   tab_flags (t, SOMF_NO_TITLE | SOMF_NO_SPACING);
-  if (options & TAT_NOWRAP)
-    tab_dim (t, nowrap_dim);
-  else
-    tab_dim (t, wrap_dim);
+  tab_dim (t, options & TAT_NOWRAP ? nowrap_dim : wrap_dim);
   tab_submit (t);
   tab_submit (t);
-
-  if (options & TAT_FIX)
-    {
-      struct outp_driver *d;
-
-      for (d = outp_drivers (NULL); d; d = outp_drivers (d))
-        if (d->class->text_set_font_by_name != NULL)
-          d->class->text_set_font_by_name (d, "PROP");
-        else 
-          {
-            /* FIXME */
-          }
-    }
   
   
-  if (options & TAT_PRINTF)
-    local_free (buf);
+  free (tmp_buf);
 }
 
 /* Set table flags to FLAGS. */
 }
 
 /* Set table flags to FLAGS. */
@@ -944,20 +871,64 @@ tabi_table (struct som_entity *table)
   t->h = pool_nalloc (t->container, t->nr, sizeof *t->h);
 }
 
   t->h = pool_nalloc (t->container, t->nr, sizeof *t->h);
 }
 
+/* Returns the line style to use for spacing purposes for a rule
+   of the given TYPE. */
+static enum outp_line_style
+rule_to_spacing_type (unsigned char type) 
+{
+  switch (type) 
+    {
+    case TAL_0:
+      return OUTP_L_NONE;
+    case TAL_GAP:
+    case TAL_1:
+      return OUTP_L_SINGLE;
+    case TAL_2:
+      return OUTP_L_DOUBLE;
+    default:
+      abort ();
+    }
+}
+
 /* Set the current output device to DRIVER. */
 static void
 tabi_driver (struct outp_driver *driver)
 {
 /* Set the current output device to DRIVER. */
 static void
 tabi_driver (struct outp_driver *driver)
 {
+  int c, r;
   int i;
   int i;
-
+  
   assert (driver != NULL);
   d = driver;
   
   /* Figure out sizes of rules. */
   assert (driver != NULL);
   d = driver;
   
   /* Figure out sizes of rules. */
-  for (t->hr_tot = i = 0; i <= t->nr; i++)
-    t->hr_tot += t->hrh[i] = d->horiz_line_spacing[t->trh[i]];
-  for (t->vr_tot = i = 0; i <= t->nc; i++)
-    t->vr_tot += t->wrv[i] = d->vert_line_spacing[t->trv[i]];
+  for (r = 0; r <= t->nr; r++) 
+    {
+      int width = 0;
+      for (c = 0; c < t->nc; c++) 
+        {
+          unsigned char rh = t->rh[c + r * t->cf];
+          int w = driver->horiz_line_width[rule_to_spacing_type (rh)];
+          if (w > width)
+            width = w; 
+        }
+      t->hrh[r] = width; 
+    }
+
+  for (c = 0; c <= t->nc; c++) 
+    {
+      int width = 0;
+      for (r = 0; r < t->nr; r++) 
+        {
+          unsigned char *rv = &t->rv[c + r * (t->cf + 1)];
+          int w;
+          if (*rv == UCHAR_MAX)
+            *rv = c != 0 && c != t->nc ? TAL_GAP : TAL_0;
+          w = driver->vert_line_width[rule_to_spacing_type (*rv)];
+          if (w > width)
+            width = w;
+        }
+      t->wrv[c] = width; 
+    }
 
 #if DEBUGGING
   for (i = 0; i < t->nr; i++)
 
 #if DEBUGGING
   for (i = 0; i < t->nr; i++)
@@ -1091,7 +1062,9 @@ tabi_cumulate (int cumtype, int start, int *end, int max, int *actual)
       d = &t->h[start];
       r = &t->hrh[start + 1];
       total = t->ht + t->hb;
       d = &t->h[start];
       r = &t->hrh[start + 1];
       total = t->ht + t->hb;
-    } else {
+    }
+  else
+    {
       assert (start >= 0 && start < t->nc);
       n = t->nc - t->r;
       d = &t->w[start];
       assert (start >= 0 && start < t->nc);
       n = t->nc - t->r;
       d = &t->w[start];
@@ -1209,8 +1182,9 @@ tabi_title (int x, int y)
   {
     struct outp_text text;
 
   {
     struct outp_text text;
 
-    text.options = OUTP_T_JUST_LEFT | OUTP_T_HORZ | OUTP_T_VERT;
-    ls_init (&text.s, buf, cp - buf);
+    text.font = OUTP_PROPORTIONAL;
+    text.justification = OUTP_LEFT;
+    ls_init (&text.string, buf, cp - buf);
     text.h = d->width;
     text.v = d->font_height;
     text.x = 0;
     text.h = d->width;
     text.v = d->font_height;
     text.x = 0;
@@ -1221,14 +1195,32 @@ tabi_title (int x, int y)
 
 static int render_strip (int x, int y, int r, int c1, int c2, int r1, int r2);
 
 
 static int render_strip (int x, int y, int r, int c1, int c2, int r1, int r2);
 
-/* Draws the table region in rectangle (X1,Y1)-(X2,Y2), where column
-   X2 and row Y2 are not included in the rectangle, at the current
-   position on the current output device.  Draws headers as well. */
+/* Renders columns C0...C1, plus headers, of rows R0...R1,
+   at the given vertical position Y.
+   C0 and C1 count vertical rules as columns,
+   but R0 and R1 do not count horizontal rules as rows.
+   Returns the vertical position after rendering. */
+static int
+render_rows (int y, int c0, int c1, int r0, int r1)
+{
+  int r;
+  for (r = r0; r < r1; r++) 
+    {
+      int x = d->cp_x;
+      x = render_strip (x, y, r, 0, t->l * 2 + 1, r0, r1);
+      x = render_strip (x, y, r, c0 * 2 + 1, c1 * 2, r0, r1);
+      x = render_strip (x, y, r, (t->nc - t->r) * 2, t->nc * 2 + 1, r0, r1);
+      y += (r & 1) ? t->h[r / 2] : t->hrh[r / 2]; 
+    }
+  return y;
+}
+
+/* Draws table region (C0,R0)-(C1,R1), plus headers, at the
+   current position on the current output device.  */
 static void
 static void
-tabi_render (int x1, int y1, int x2, int y2)
+tabi_render (int c0, int r0, int c1, int r1)
 {
 {
-  int i, y;
-  int ranges[3][2];
+  int y;
   
   tab_hit++;
 
   
   tab_hit++;
 
@@ -1236,32 +1228,9 @@ tabi_render (int x1, int y1, int x2, int y2)
   if (!(t->flags & SOMF_NO_TITLE))
     y += d->font_height;
 
   if (!(t->flags & SOMF_NO_TITLE))
     y += d->font_height;
 
-  /* Top headers. */
-  ranges[0][0] = 0;
-  ranges[0][1] = t->t * 2 + 1;
-
-  /* Requested rows. */
-  ranges[1][0] = y1 * 2 + 1;
-  ranges[1][1] = y2 * 2;
-
-  /* Bottom headers. */
-  ranges[2][0] = (t->nr - t->b) * 2;
-  ranges[2][1] = t->nr * 2 + 1;
-
-  for (i = 0; i < 3; i++) 
-    {
-      int r;
-
-      for (r = ranges[i][0]; r < ranges[i][1]; r++) 
-        {
-          int x = d->cp_x;
-          x += render_strip (x, y, r, 0, t->l * 2 + 1, y1, y2);
-          x += render_strip (x, y, r, x1 * 2 + 1, x2 * 2, y1, y2);
-          x += render_strip (x, y, r, (t->nc - t->r) * 2,
-                             t->nc * 2 + 1, y1, y2);
-          y += (r & 1) ? t->h[r / 2] : t->hrh[r / 2]; 
-        }
-    }
+  y = render_rows (y, c0, c1, 0, t->t * 2 + 1);
+  y = render_rows (y, c0, c1, r0 * 2 + 1, r1 * 2);
+  y = render_rows (y, c0, c1, (t->nr - t->b) * 2, t->nr * 2 + 1);
 }
 
 struct som_table_class tab_table_class =
 }
 
 struct som_table_class tab_table_class =
@@ -1290,151 +1259,215 @@ struct som_table_class tab_table_class =
     tabi_render,
   };
 \f
     tabi_render,
   };
 \f
-/* Render contiguous strip consisting of columns C1...C2, exclusive,
-   on row R, at location (X,Y).  Return width of the strip thus
-   rendered.
+static enum outp_justification
+translate_justification (unsigned int opt)
+{
+  switch (opt & TAB_ALIGN_MASK) 
+    {
+    case TAB_RIGHT:
+      return OUTP_RIGHT;
+    case TAB_LEFT:
+      return OUTP_LEFT;
+    case TAB_CENTER:
+      return OUTP_CENTER;
+    default:
+      abort ();
+    }
+}
+
+/* Returns the line style to use for drawing a rule of the given
+   TYPE. */
+static enum outp_line_style
+rule_to_draw_type (unsigned char type) 
+{
+  switch (type) 
+    {
+    case TAL_0:
+    case TAL_GAP:
+      return OUTP_L_NONE;
+    case TAL_1:
+      return OUTP_L_SINGLE;
+    case TAL_2:
+      return OUTP_L_DOUBLE;
+    default:
+      abort ();
+    }
+}
+
+/* Returns the horizontal rule at the given column and row. */
+static int
+get_hrule (int c, int r) 
+{
+  return t->rh[c + r * t->cf];
+}
+
+/* Returns the vertical rule at the given column and row. */
+static int
+get_vrule (int c, int r) 
+{
+  return t->rv[c + r * (t->cf + 1)];
+}
+
+/* Renders the horizontal rule at the given column and row
+   at (X,Y) on the page. */
+static void
+render_horz_rule (int x, int y, int c, int r)
+{
+  enum outp_line_style style = rule_to_draw_type (get_hrule (c, r));
+  if (style != OUTP_L_NONE)
+    d->class->line (d, x, y, x + t->w[c], y + t->hrh[r],
+                    OUTP_L_NONE, style, OUTP_L_NONE, style);
+}
+
+/* Renders the vertical rule at the given column and row
+   at (X,Y) on the page. */
+static void
+render_vert_rule (int x, int y, int c, int r)
+{
+  enum outp_line_style style = rule_to_draw_type (get_vrule (c, r));
+  if (style != OUTP_L_NONE)
+    d->class->line (d, x, y, x + t->wrv[c], y + t->h[r],
+                    style, OUTP_L_NONE, style, OUTP_L_NONE);
+}
+
+/* Renders the rule intersection at the given column and row
+   at (X,Y) on the page. */
+static void
+render_rule_intersection (int x, int y, int c, int r)
+{
+  /* Bounds of intersection. */
+  int x0 = x;
+  int y0 = y;
+  int x1 = x + t->wrv[c];
+  int y1 = y + t->hrh[r];
+
+  /* Lines on each side of intersection. */
+  int top = r > 0 ? get_vrule (c, r - 1) : TAL_0;
+  int left = c > 0 ? get_hrule (c - 1, r) : TAL_0;
+  int bottom = r < t->nr ? get_vrule (c, r) : TAL_0;
+  int right = c < t->nc ? get_hrule (c, r) : TAL_0;
+
+  /* Output style for each line. */
+  enum outp_line_style o_top = rule_to_draw_type (top);
+  enum outp_line_style o_left = rule_to_draw_type (left);
+  enum outp_line_style o_bottom = rule_to_draw_type (bottom);
+  enum outp_line_style o_right = rule_to_draw_type (right);
+
+  if (o_top != OUTP_L_NONE || o_left != OUTP_L_NONE
+      || o_bottom != OUTP_L_NONE || o_right != OUTP_L_NONE)
+    d->class->line (d, x0, y0, x1, y1, o_top, o_left, o_bottom, o_right);
+}
 
 
-   Renders joined cells, even those outside the strip, within the
-   rendering region (C1,R1)-(C2,R2).
+/* Returns the width of columns C1...C2 exclusive,
+   including interior but not exterior rules. */
+static int
+strip_width (int c1, int c2)
+{
+  int width = 0;
+  int c;
 
 
-   For the purposes of counting rows and columns in this function
-   only, horizontal rules are considered rows and vertical rules are
-   considered columns.
+  for (c = c1; c < c2; c++) 
+    width += t->w[c] + t->wrv[c + 1];
+  if (c1 < c2)
+    width -= t->wrv[c2];
+  return width;
+}
 
 
-   FIXME: Doesn't use r1?  Huh?  */
+/* Returns the height of rows R1...R2 exclusive,
+   including interior but not exterior rules. */
 static int
 static int
-render_strip (int x, int y, int r, int c1, int c2, int r1 UNUSED, int r2)
+strip_height (int r1, int r2)
 {
 {
-  int x_origin = x;
+  int height = 0;
+  int r;
 
 
-  /* Horizontal rules. */
-  if ((r & 1) == 0)
+  for (r = r1; r < r2; r++) 
+    height += t->h[r] + t->hrh[r + 1];
+  if (r1 < r2)
+    height -= t->hrh[r2];
+  return height;
+}
+
+/* Renders the cell at the given column and row at (X,Y) on the
+   page.  Also renders joined cells that extend as far to the
+   right as C1 and as far down as R1. */
+static void
+render_cell (int x, int y, int c, int r, int c1, int r1)
+{
+  const int index = c + (r * t->cf);
+  unsigned char type = t->ct[index];
+  struct fixed_string *content = &t->cc[index];
+  
+  if (!(type & TAB_JOIN))
+    {
+      if (!(type & TAB_EMPTY))
+        {
+          struct outp_text text;
+          text.font = options_to_font (type);
+          text.justification = translate_justification (type);
+          text.string = *content;
+          text.h = t->w[c];
+          text.v = t->h[r];
+          text.x = x;
+          text.y = y;
+          d->class->text_draw (d, &text);
+        }
+    }
+  else
     {
     {
-      int hrh = t->hrh[r / 2];
-      int c;
+      struct tab_joined_cell *j
+        = (struct tab_joined_cell *) ls_c_str (content);
 
 
-      for (c = c1; c < c2; c++)
-       {
-         if (c & 1)
-           {
-             int style = t->rh[(c / 2) + (r / 2 * t->cf)];
-
-             if (style != TAL_0)
-               {
-                 const struct color clr = {0, 0, 0, 0};
-                 struct rect rct;
-
-                 rct.x1 = x;
-                 rct.y1 = y;
-                 rct.x2 = x + t->w[c / 2];
-                 rct.y2 = y + hrh;
-                 d->class->line_horz (d, &rct, &clr, style);
-               }
-             x += t->w[c / 2];
-           } else {
-             const struct color clr = {0, 0, 0, 0};
-             struct rect rct;
-             struct outp_styles s;
-
-             rct.x1 = x;
-             rct.y1 = y;
-             rct.x2 = x + t->wrv[c / 2];
-             rct.y2 = y + hrh;
-
-             s.t = r > 0 ? t->rv[(c / 2) + (t->cf + 1) * (r / 2 - 1)] : 0;
-             s.b = r < 2 * t->nr ? t->rv[(c / 2) + (t->cf + 1) * (r / 2)] : 0;
-             s.l = c > 0 ? t->rh[(c / 2 - 1) + t->cf * (r / 2)] : 0;
-             s.r = c < 2 * t->nc ? t->rh[(c / 2) + t->cf * (r / 2)] : 0;
-
-             if (s.t | s.b | s.l | s.r)
-               d->class->line_intersection (d, &rct, &clr, &s);
-             
-             x += t->wrv[c / 2];
-           }
-       }
-    } else {
-      int c;
+      if (j->hit != tab_hit)
+        {
+          j->hit = tab_hit;
 
 
-      for (c = c1; c < c2; c++)
-       {
-         if (c & 1)
-           {
-             const int index = (c / 2) + (r / 2 * t->cf);
-
-             if (!(t->ct[index] & TAB_JOIN))
-               {
-                 struct outp_text text;
-
-                 text.options = ((t->ct[index] & OUTP_T_JUST_MASK)
-                                 | OUTP_T_HORZ | OUTP_T_VERT);
-                 if ((t->ct[index] & TAB_EMPTY) == 0)
-                   {
-                     text.s = t->cc[index];
-                     assert (!ls_null_p (&text.s));
-                     text.h = t->w[c / 2];
-                     text.v = t->h[r / 2];
-                     text.x = x;
-                     text.y = y;
-                     d->class->text_draw (d, &text);
-                   }
-               } else {
-                 struct tab_joined_cell *j =
-                   (struct tab_joined_cell *) ls_c_str (&t->cc[index]);
-
-                 if (j->hit != tab_hit)
-                   {
-                     j->hit = tab_hit;
-
-                     if (j->x1 == c / 2 && j->y1 == r / 2)
-                       {
-                         struct outp_text text;
-
-                         text.options = ((t->ct[index] & OUTP_T_JUST_MASK)
-                                         | OUTP_T_HORZ | OUTP_T_VERT);
-                         text.s = j->contents;
-                         text.x = x;
-                         text.y = y;
-                         
-                         {
-                           int c;
-
-                           for (c = j->x1, text.h = -t->wrv[j->x2];
-                                c < j->x2 && c < c2 / 2; c++) 
-                                text.h += t->w[c] + t->wrv[c + 1]; 
-                         }
-                         
-                         {
-                           int r;
-
-                           for (r = j->y1, text.v = -t->hrh[j->y2];
-                                r < j->y2 && r < r2 / 2; r++)
-                             text.v += t->h[r] + t->hrh[r + 1];
-                         }
-                         d->class->text_draw (d, &text);
-                       }
-                   }
-               }
-             x += t->w[c / 2];
-           } else {
-             int style = t->rv[(c / 2) + (r / 2 * (t->cf + 1))];
-
-             if (style != TAL_0)
-               {
-                 const struct color clr = {0, 0, 0, 0};
-                 struct rect rct;
-
-                 rct.x1 = x;
-                 rct.y1 = y;
-                 rct.x2 = x + t->wrv[c / 2];
-                 rct.y2 = y + t->h[r / 2];
-                 d->class->line_vert (d, &rct, &clr, style);
-               }
-             x += t->wrv[c / 2];
-           }
-       }
+          if (j->x1 == c && j->y1 == r)
+            {
+              struct outp_text text;
+              text.font = options_to_font (type);
+              text.justification = translate_justification (type);
+              text.string = j->contents;
+              text.x = x;
+              text.y = y;
+              text.h = strip_width (j->x1, MIN (j->x2, c1));
+              text.v = strip_height (j->y1, MIN (j->y2, r1));
+              d->class->text_draw (d, &text);
+            }
+        }
     }
     }
+}
 
 
-  return x - x_origin;
+/* Render contiguous strip consisting of columns C0...C1, exclusive,
+   on row R, at (X,Y).  Returns X position after rendering.
+   Also renders joined cells that extend beyond that strip,
+   cropping them to lie within rendering region (C0,R0)-(C1,R1).
+   C0 and C1 count vertical rules as columns.
+   R counts horizontal rules as rows, but R0 and R1 do not. */
+static int
+render_strip (int x, int y, int r, int c0, int c1, int r0 UNUSED, int r1)
+{
+  int c;
+
+  for (c = c0; c < c1; c++)
+    if (c & 1) 
+      {
+        if (r & 1)
+          render_cell (x, y, c / 2, r / 2, c1 / 2, r1);
+        else
+          render_horz_rule (x, y, c / 2, r / 2);
+        x += t->w[c / 2];
+      }
+    else
+      {
+        if (r & 1)
+          render_vert_rule (x, y, c / 2, r / 2);
+        else
+          render_rule_intersection (x, y, c / 2, r / 2);
+        x += t->wrv[c / 2];
+      }
+  
+  return x;
 }
 
 /* Sets COMMAND_NAME as the name of the current command,
 }
 
 /* Sets COMMAND_NAME as the name of the current command,
index 678d6aa3a84b05e57364505c6ae0457485b653d4..51031da23c0e45c11299b8a8393b8f3dd56b032d 100644 (file)
@@ -28,27 +28,28 @@ enum
   {
     TAB_NONE = 0,
 
   {
     TAB_NONE = 0,
 
-    /* Must match output.h: OUTP_T_JUST_*. */
     TAB_ALIGN_MASK = 03,       /* Alignment mask. */
     TAB_RIGHT = 00,            /* Right justify. */
     TAB_LEFT = 01,             /* Left justify. */
     TAB_CENTER = 02,           /* Center. */
 
     TAB_ALIGN_MASK = 03,       /* Alignment mask. */
     TAB_RIGHT = 00,            /* Right justify. */
     TAB_LEFT = 01,             /* Left justify. */
     TAB_CENTER = 02,           /* Center. */
 
-    /* Oddball cell types. */
-    TAB_JOIN = 010,            /* Joined cell. */
-    TAB_EMPTY = 020            /* Empty cell. */
+    /* Cell types. */
+    TAB_JOIN = 004,            /* Joined cell. */
+    TAB_EMPTY = 010,           /* Empty cell. */
+
+    /* Flags. */
+    TAB_EMPH = 020,             /* Emphasize cell contents. */
+    TAB_FIX = 040,              /* Use fixed font. */
   };
 
   };
 
-/* Line styles.  These must match output.h:OUTP_L_*. */
+/* Line styles. */
 enum
   {
     TAL_0 = 0,                 /* No line. */
     TAL_1 = 1,                 /* Single line. */
     TAL_2 = 2,                 /* Double line. */
 enum
   {
     TAL_0 = 0,                 /* No line. */
     TAL_1 = 1,                 /* Single line. */
     TAL_2 = 2,                 /* Double line. */
-    TAL_3 = 3,                 /* Special line of driver-defined style. */
+    TAL_GAP = 3,                /* Spacing but no line. */
     TAL_COUNT,                 /* Number of line styles. */
     TAL_COUNT,                 /* Number of line styles. */
-
-    TAL_SPACING = 0200         /* Don't draw the line, just reserve space. */
   };
 
 /* Column styles.  Must correspond to SOM_COL_*. */
   };
 
 /* Column styles.  Must correspond to SOM_COL_*. */
@@ -87,9 +88,7 @@ struct tab_table
     struct fixed_string *cc;   /* Cell contents; fixed_string *[nr][nc]. */
     unsigned char *ct;         /* Cell types; unsigned char[nr][nc]. */
     unsigned char *rh;         /* Horiz rules; unsigned char[nr+1][nc]. */
     struct fixed_string *cc;   /* Cell contents; fixed_string *[nr][nc]. */
     unsigned char *ct;         /* Cell types; unsigned char[nr][nc]. */
     unsigned char *rh;         /* Horiz rules; unsigned char[nr+1][nc]. */
-    unsigned char *trh;                /* Types of horiz rules; [nr+1]. */
     unsigned char *rv;         /* Vert rules; unsigned char[nr][nc+1]. */
     unsigned char *rv;         /* Vert rules; unsigned char[nr][nc+1]. */
-    unsigned char *trv;                /* Types of vert rules; [nc+1]. */
     tab_dim_func *dim;         /* Calculates cell widths and heights. */
 
     /* Calculated during output. */
     tab_dim_func *dim;         /* Calculates cell widths and heights. */
 
     /* Calculated during output. */
@@ -98,13 +97,9 @@ struct tab_table
     int *hrh;                  /* Heights of horizontal rules; [nr+1]. */
     int *wrv;                  /* Widths of vertical rules; [nc+1]. */
     int wl, wr, ht, hb;                /* Width/height of header rows/columns. */
     int *hrh;                  /* Heights of horizontal rules; [nr+1]. */
     int *wrv;                  /* Widths of vertical rules; [nc+1]. */
     int wl, wr, ht, hb;                /* Width/height of header rows/columns. */
-    int hr_tot, vr_tot;                /* Hrules total height, vrules total width. */
 
     /* Editing info. */
     int col_ofs, row_ofs;      /* X and Y offsets. */
 
     /* Editing info. */
     int col_ofs, row_ofs;      /* X and Y offsets. */
-#if DEBUGGING
-    int reallocable;           /* Can table be reallocated? */
-#endif
   };
 
 extern int tab_hit;
   };
 
 extern int tab_hit;
@@ -134,7 +129,8 @@ void tab_resize (struct tab_table *, int nc, int nr);
 void tab_realloc (struct tab_table *, int nc, int nr);
 void tab_headers (struct tab_table *, int l, int r, int t, int b);
 void tab_columns (struct tab_table *, int style, int group);
 void tab_realloc (struct tab_table *, int nc, int nr);
 void tab_headers (struct tab_table *, int l, int r, int t, int b);
 void tab_columns (struct tab_table *, int style, int group);
-void tab_title (struct tab_table *, int format, const char *, ...);
+void tab_title (struct tab_table *, const char *, ...)
+     PRINTF_FORMAT (2, 3);
 void tab_flags (struct tab_table *, unsigned);
 void tab_submit (struct tab_table *);
 
 void tab_flags (struct tab_table *, unsigned);
 void tab_submit (struct tab_table *);
 
@@ -155,8 +151,7 @@ enum
   {
     TAT_NONE = 0,              /* No options. */
     TAT_PRINTF = 0x0100,       /* Format the text string with sprintf. */
   {
     TAT_NONE = 0,              /* No options. */
     TAT_PRINTF = 0x0100,       /* Format the text string with sprintf. */
-    TAT_TITLE = 0x0204,                /* Title attributes. */
-    TAT_FIX = 0x0400,          /* Use fixed-pitch font. */
+    TAT_TITLE = 0x0200 | TAB_EMPH, /* Title attributes. */
     TAT_NOWRAP = 0x0800         /* No text wrap (tab_output_text() only). */
   };
 
     TAT_NOWRAP = 0x0800         /* No text wrap (tab_output_text() only). */
   };
 
index 58edebca6ad7dd25a67271b47c7efb3871515a13..7f48709e2af4dd7727785f45f26ab56326d88c3a 100644 (file)
@@ -881,8 +881,8 @@ dump_splits (struct ccase *c)
 
   t = tab_create (3, split_cnt + 1, 0);
   tab_dim (t, tab_natural_dimensions);
 
   t = tab_create (3, split_cnt + 1, 0);
   tab_dim (t, tab_natural_dimensions);
-  tab_vline (t, TAL_1 | TAL_SPACING, 1, 0, split_cnt);
-  tab_vline (t, TAL_1 | TAL_SPACING, 2, 0, split_cnt);
+  tab_vline (t, TAL_GAP, 1, 0, split_cnt);
+  tab_vline (t, TAL_GAP, 2, 0, split_cnt);
   tab_text (t, 0, 0, TAB_NONE, _("Variable"));
   tab_text (t, 1, 0, TAB_LEFT, _("Value"));
   tab_text (t, 2, 0, TAB_LEFT, _("Label"));
   tab_text (t, 0, 0, TAB_NONE, _("Variable"));
   tab_text (t, 1, 0, TAB_LEFT, _("Value"));
   tab_text (t, 2, 0, TAB_LEFT, _("Label"));
index 5019569bb48d6e92cb63912f3dff2f66dfd2ec8a..bfd3507ab14c9adeb0996a0a638dca10ee7f9db1 100644 (file)
@@ -1,3 +1,7 @@
+Mon Apr  3 12:32:36 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Updated tests to match changes in output formatting.
+
 2006-03-23  Jason Stover  <jhs@math.gcsu.edu>
 
        * command/regression.sh: New test.
 2006-03-23  Jason Stover  <jhs@math.gcsu.edu>
 
        * command/regression.sh: New test.
index 711d9685e0506597e530dc3c1b4ca336be8b0fdc..31164d9b96dfa7307bf1d0dde07ef8ad459555d4 100755 (executable)
@@ -70,7 +70,7 @@ EOF
 if [ $? -ne 0 ] ; then no_result ; fi
 
 activity="run program"
 if [ $? -ne 0 ] ; then no_result ; fi
 
 activity="run program"
-$SUPERVISOR $PSPP -o raw-ascii $TESTFILE > /dev/null
+$SUPERVISOR $PSPP -o raw-ascii $TESTFILE > /dev/null 2>&1
 if [ $? -ne 0 ] ; then fail ; fi
 
 pass;
 if [ $? -ne 0 ] ; then fail ; fi
 
 pass;
index 5a0a630d7d046911c2eeb8bce3a4d826462dd8e9..5a428aae7b94e2c4735e2fbab376e46f6ae9b8fd 100755 (executable)
@@ -106,23 +106,23 @@ diff -b  $TEMPDIR/pspp.list - << EOF
 #V1#23|   100%|0|     0%|23|   100%#
 #==#==#=======#=#=======#==#=======#
 1.2 EXAMINE.  Extreme Values
 #V1#23|   100%|0|     0%|23|   100%#
 #==#==#=======#=#=======#==#=======#
 1.2 EXAMINE.  Extreme Values
-#==========#===========#=====#
-#          #Case Number|Value#
-#==========#===========#=====#
-#V1Highest1#         21|20.00#
-#         2#         20|19.00#
-#         3#         19|18.00#
-#         4#         19|18.00#
-#         5#         18|17.00#
-#         6#         17|16.00#
-#  --------#-----------+-----#
-#   Lowest1#          1| 1.00#
-#         2#          2| 2.00#
-#         3#          4| 3.00#
-#         4#          3| 3.00#
-#         5#          3| 3.00#
-#         6#          5| 4.00#
-#==========#===========#=====#
+#============#===========#=====#
+#            #Case Number|Value#
+#============#===========#=====#
+#V1 Highest 1#         21|20.00#
+#           2#         20|19.00#
+#           3#         19|18.00#
+#           4#         19|18.00#
+#           5#         18|17.00#
+#           6#         17|16.00#
+#  ----------#-----------+-----#
+#    Lowest 1#          1| 1.00#
+#           2#          2| 2.00#
+#           3#          4| 3.00#
+#           4#          3| 3.00#
+#           5#          3| 3.00#
+#           6#          5| 4.00#
+#============#===========#=====#
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
 
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
 
index 95d91abf4129bbffc3c37b14d3b23be031688934..73d767b8860797d0273fe305584efee8471e2532 100755 (executable)
@@ -110,22 +110,22 @@ diff -b  $TEMPDIR/pspp.list - << EOF
 +--------+------+
 Case#  QUALITY        W    BRAND
 ----- -------- -------- --------
 +--------+------+
 Case#  QUALITY        W    BRAND
 ----- -------- -------- --------
-    1     3.00     1.00     1.00 
-    2     2.00     2.00     1.00 
-    3     1.00     2.00     1.00 
-    4     1.00     1.00     1.00 
-    5     4.00     1.00     1.00 
-    6     4.00     1.00     1.00 
-    7     5.00     1.00     2.00 
-    8     2.00     1.00     2.00 
-    9     4.00     4.00     2.00 
-   10     2.00     1.00     2.00 
-   11     3.00     1.00     2.00 
-   12     7.00     1.00     3.00 
-   13     4.00     2.00     3.00 
-   14     5.00     3.00     3.00 
-   15     3.00     1.00     3.00 
-   16     6.00     1.00     3.00 
+    1     3.00     1.00     1.00
+    2     2.00     2.00     1.00
+    3     1.00     2.00     1.00
+    4     1.00     1.00     1.00
+    5     4.00     1.00     1.00
+    6     4.00     1.00     1.00
+    7     5.00     1.00     2.00
+    8     2.00     1.00     2.00
+    9     4.00     4.00     2.00
+   10     2.00     1.00     2.00
+   11     3.00     1.00     2.00
+   12     7.00     1.00     3.00
+   13     4.00     2.00     3.00
+   14     5.00     3.00     3.00
+   15     3.00     1.00     3.00
+   16     6.00     1.00     3.00
 2.1 EXAMINE.  Case Processing Summary
 #===============#===============================#
 #               #             Cases             #
 2.1 EXAMINE.  Case Processing Summary
 #===============#===============================#
 #               #             Cases             #
@@ -137,121 +137,121 @@ Case#  QUALITY        W    BRAND
 #Breaking Strain#24|   100%|0|     0%|24|   100%#
 #===============#==#=======#=#=======#==#=======#
 2.2 EXAMINE.  Extreme Values
 #Breaking Strain#24|   100%|0|     0%|24|   100%#
 #===============#==#=======#=#=======#==#=======#
 2.2 EXAMINE.  Extreme Values
-#=======================#===========#=====#
-#                       #Case Number|Value#
-#=======================#===========#=====#
-#Breaking StrainHighest1#         12| 7.00#
-#                      2#         16| 6.00#
-#                      3#         14| 5.00#
-#               --------#-----------+-----#
-#                Lowest1#          4| 1.00#
-#                      2#          3| 1.00#
-#                      3#          3| 1.00#
-#=======================#===========#=====#
+#=========================#===========#=====#
+#                         #Case Number|Value#
+#=========================#===========#=====#
+#Breaking Strain Highest 1#         12| 7.00#
+#                        2#         16| 6.00#
+#                               3#         14| 5.00#
+#               ----------#-----------+-----#
+#                 Lowest 1#          4| 1.00#
+#                        2#          3| 1.00#
+#                        3#          3| 1.00#
+#=========================#===========#=====#
 2.3 EXAMINE.  Descriptives
 2.3 EXAMINE.  Descriptives
-#==========================================================#=========#==========#
-#                                                          #Statistic|Std. Error#
-#==========================================================#=========#==========#
-#Breaking StrainMean                                       #   3.54  |   .324   #
-#               95% Confidence Interval for MeanLower Bound#  3.562  |          #
-#                                               Upper Bound#  3.521  |          #
-#               5% Trimmed Mean                            #   3.50  |          #
-#               Median                                     #   4.00  |          #
-#               Variance                                   #  2.520  |          #
-#               Std. Deviation                             #  1.587  |          #
-#               Minimum                                    #  1.000  |          #
-#               Maximum                                    #  7.000  |          #
-#               Range                                      #  6.000  |          #
-#               Interquartile Range                        #   2.75  |          #
-#               Skewness                                   #   .059  |   .472   #
-#               Kurtosis                                   #  -.358  |   .918   #
-#==========================================================#=========#==========#
+#============================================================#=========#==========#
+#                                                            #Statistic|Std. Error#
+#============================================================#=========#==========#
+#Breaking Strain Mean                                        #   3.54  |   .324   #
+#                95% Confidence Interval for Mean Lower Bound#  3.562  |          #
+#                                                 Upper Bound#  3.521  |          #
+#                5% Trimmed Mean                             #   3.50  |          #
+#                Median                                      #   4.00  |          #
+#                Variance                                    #  2.520  |          #
+#                Std. Deviation                              #  1.587  |          #
+#                Minimum                                     #  1.000  |          #
+#                Maximum                                     #  7.000  |          #
+#                Range                                       #  6.000  |          #
+#                Interquartile Range                         #   2.75  |          #
+#                Skewness                                    #   .059  |   .472   #
+#                Kurtosis                                    #  -.358  |   .918   #
+#============================================================#=========#==========#
 2.4 EXAMINE.  Case Processing Summary
 2.4 EXAMINE.  Case Processing Summary
-#===========================#=============================#
-#                           #            Cases            #
-#                           #---------+---------+---------#
-#                           #  Valid  | Missing |  Total  #
-#                           #-+-------+-+-------+-+-------#
-#               Manufacturer#N|Percent|N|Percent|N|Percent#
-#===========================#=#=======#=#=======#=#=======#
-#Breaking StrainAspeger     #8|   100%|0|     0%|8|   100%#
-#               Bloggs      #8|   100%|0|     0%|8|   100%#
-#               Charlies    #8|   100%|0|     0%|8|   100%#
-#===========================#=#=======#=#=======#=#=======#
+#============================#=============================#
+#                            #            Cases            #
+#                            #---------+---------+---------#
+#                            #  Valid  | Missing |  Total  #
+#                            #-+-------+-+-------+-+-------#
+#                Manufacturer#N|Percent|N|Percent|N|Percent#
+#============================#=#=======#=#=======#=#=======#
+#Breaking Strain Aspeger     #8|   100%|0|     0%|8|   100%#
+#                Bloggs      #8|   100%|0|     0%|8|   100%#
+#                Charlies    #8|   100%|0|     0%|8|   100%#
+#============================#=#=======#=#=======#=#=======#
 2.5 EXAMINE.  Extreme Values
 2.5 EXAMINE.  Extreme Values
-#===================================#===========#=====#
-#               Manufacturer        #Case Number|Value#
-#===================================#===========#=====#
-#Breaking StrainAspeger     Highest1#          6| 4.00#
-#                                  2#          5| 4.00#
-#                                  3#          1| 3.00#
-#                           --------#-----------+-----#
-#                            Lowest1#          4| 1.00#
-#                                  2#          3| 1.00#
-#                                  3#          3| 1.00#
-#               --------------------#-----------+-----#
-#               Bloggs      Highest1#          7| 5.00#
-#                                  2#          9| 4.00#
-#                                  3#          9| 4.00#
-#                           --------#-----------+-----#
-#                            Lowest1#         10| 2.00#
-#                                  2#          8| 2.00#
-#                                  3#         11| 3.00#
-#               --------------------#-----------+-----#
-#               Charlies    Highest1#         12| 7.00#
-#                                  2#         16| 6.00#
-#                                  3#         14| 5.00#
-#                           --------#-----------+-----#
-#                            Lowest1#         15| 3.00#
-#                                  2#         13| 4.00#
-#                                  3#         13| 4.00#
-#===================================#===========#=====#
+#======================================#===========#=====#
+#                Manufacturer          #Case Number|Value#
+#======================================#===========#=====#
+#Breaking Strain Aspeger      Highest 1#          6| 4.00#
+#                                     2#          5| 4.00#
+#                                     3#          1| 3.00#
+#                            ----------#-----------+-----#
+#                              Lowest 1#          4| 1.00#
+#                                     2#          3| 1.00#
+#                                     3#          3| 1.00#
+#               -----------------------#-----------+-----#
+#                Bloggs       Highest 1#          7| 5.00#
+#                                     2#          9| 4.00#
+#                                     3#          9| 4.00#
+#                            ----------#-----------+-----#
+#                              Lowest 1#         10| 2.00#
+#                                     2#          8| 2.00#
+#                                     3#         11| 3.00#
+#               -----------------------#-----------+-----#
+#                       Charlies     Highest 1#         12| 7.00#
+#                                     2#         16| 6.00#
+#                                     3#         14| 5.00#
+#                            ----------#-----------+-----#
+#                              Lowest 1#         15| 3.00#
+#                                     2#         13| 4.00#
+#                                     3#         13| 4.00#
+#======================================#===========#=====#
 2.6 EXAMINE.  Descriptives
 2.6 EXAMINE.  Descriptives
-#======================================================================#=========#==========#
-#               Manufacturer                                           #Statistic|Std. Error#
-#======================================================================#=========#==========#
-#Breaking StrainAspeger     Mean                                       #   2.25  |   .453   #
-#                           95% Confidence Interval for MeanLower Bound#  2.279  |          #
-#                                                           Upper Bound#  2.221  |          #
-#                           5% Trimmed Mean                            #   2.22  |          #
-#                           Median                                     #   2.00  |          #
-#                           Variance                                   #  1.643  |          #
-#                           Std. Deviation                             #  1.282  |          #
-#                           Minimum                                    #  1.000  |          #
-#                           Maximum                                    #  4.000  |          #
-#                           Range                                      #  3.000  |          #
-#                           Interquartile Range                        #   2.75  |          #
-#                           Skewness                                   #   .475  |   .752   #
-#                           Kurtosis                                   #  -1.546 |   1.481  #
-#               -------------------------------------------------------#---------+----------#
-#               Bloggs      Mean                                       #   3.50  |   .378   #
-#                           95% Confidence Interval for MeanLower Bound#  3.525  |          #
-#                                                           Upper Bound#  3.475  |          #
-#                           5% Trimmed Mean                            #   3.50  |          #
-#                           Median                                     #   4.00  |          #
-#                           Variance                                   #  1.143  |          #
-#                           Std. Deviation                             #  1.069  |          #
-#                           Minimum                                    #  2.000  |          #
-#                           Maximum                                    #  5.000  |          #
-#                           Range                                      #  3.000  |          #
-#                           Interquartile Range                        #   1.75  |          #
-#                           Skewness                                   #  -.468  |   .752   #
-#                           Kurtosis                                   #  -.831  |   1.481  #
-#               -------------------------------------------------------#---------+----------#
-#               Charlies    Mean                                       #   4.88  |   .441   #
-#                           95% Confidence Interval for MeanLower Bound#  4.904  |          #
-#                                                           Upper Bound#  4.846  |          #
-#                           5% Trimmed Mean                            #   4.86  |          #
-#                           Median                                     #   5.00  |          #
-#                           Variance                                   #  1.554  |          #
-#                           Std. Deviation                             #  1.246  |          #
-#                           Minimum                                    #  3.000  |          #
-#                           Maximum                                    #  7.000  |          #
-#                           Range                                      #  4.000  |          #
-#                           Interquartile Range                        #   1.75  |          #
-#                           Skewness                                   #   .304  |   .752   #
-#                           Kurtosis                                   #   .146  |   1.481  #
-#======================================================================#=========#==========#
+#=========================================================================#=========#==========#
+#                Manufacturer                                            #Statistic|Std. Error#
+#=========================================================================#=========#==========#
+#Breaking Strain Aspeger      Mean                                        #   2.25  |   .453   #
+#                             95% Confidence Interval for Mean Lower Bound#  2.279  |          #
+#                                                              Upper Bound#  2.221  |          #
+#                             5% Trimmed Mean                             #   2.22  |          #
+#                             Median                                      #   2.00  |          #
+#                             Variance                                    #  1.643  |          #
+#                             Std. Deviation                              #  1.282  |          #
+#                             Minimum                                     #  1.000  |          #
+#                             Maximum                                     #  4.000  |          #
+#                             Range                                       #  3.000  |          #
+#                             Interquartile Range                         #   2.75  |          #
+#                             Skewness                                    #   .475  |   .752   #
+#                             Kurtosis                                    #  -1.546 |   1.481  #
+#               ----------------------------------------------------------#---------+----------#
+#                Bloggs       Mean                                        #   3.50  |   .378   #
+#                             95% Confidence Interval for Mean Lower Bound#  3.525  |          #
+#                                                              Upper Bound#  3.475  |          #
+#                             5% Trimmed Mean                             #   3.50  |          #
+#                             Median                                      #   4.00  |          #
+#                             Variance                                    #  1.143  |          #
+#                             Std. Deviation                              #  1.069  |          #
+#                             Minimum                                     #  2.000  |          #
+#                             Maximum                                     #  5.000  |          #
+#                             Range                                       #  3.000  |          #
+#                             Interquartile Range                         #   1.75  |          #
+#                             Skewness                                    #  -.468  |   .752   #
+#                             Kurtosis                                    #  -.831  |   1.481  #
+#               ----------------------------------------------------------#---------+----------#
+#                Charlies     Mean                                        #   4.88  |   .441   #
+#                             95% Confidence Interval for Mean Lower Bound#  4.904  |          #
+#                                                              Upper Bound#  4.846  |          #
+#                             5% Trimmed Mean                             #   4.86  |          #
+#                             Median                                      #   5.00  |          #
+#                             Variance                                    #  1.554  |          #
+#                             Std. Deviation                              #  1.246  |          #
+#                             Minimum                                     #  3.000  |          #
+#                             Maximum                                     #  7.000  |          #
+#                             Range                                       #  4.000  |          #
+#                             Interquartile Range                         #   1.75  |          #
+#                             Skewness                                    #   .304  |   .752   #
+#                             Kurtosis                                    #   .146  |   1.481  #
+#=========================================================================#=========#==========#
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
 
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
 
index 929963e2045e61d945ef9cabffe1ec773dea4cb7..c0d8dc33278e8a8eb8bb1ec53129f50d543fba3f 100755 (executable)
@@ -107,7 +107,7 @@ diff -b  $TEMPDIR/pspp.list - << EOF
 +--------+------+
 2.1 ONEWAY.  Descriptives
 #===============#========#==#====#==============#==========#=======================#=======#=======#
 +--------+------+
 2.1 ONEWAY.  Descriptives
 #===============#========#==#====#==============#==========#=======================#=======#=======#
-#               |        #  |    |              |          |    95% Confidence     |       |       #
+#               |        #  |    |              |          |95% Confidence Interval|       |       #
 #               |        #  |    |              |          +-----------+-----------+       |       #
 #               |        # N|Mean|Std. Deviation|Std. Error|Lower Bound|Upper Bound|Minimum|Maximum#
 #===============#========#==#====#==============#==========#===========#===========#=======#=======#
 #               |        #  |    |              |          +-----------+-----------+       |       #
 #               |        # N|Mean|Std. Deviation|Std. Error|Lower Bound|Upper Bound|Minimum|Maximum#
 #===============#========#==#====#==============#==========#===========#===========#=======#=======#
index fb9901cb1adb0b7b5200fdb24ecbb3a2fbbfdd68..d524b159818bc20bd0617404b48e78ac8f1abe5e 100755 (executable)
@@ -109,7 +109,7 @@ diff  -b $TEMPDIR/pspp.list - <<EOF
 #===========#==#====#==============#========#
 2.2 T-TEST.  Independent Samples Test
 #==============================#=========#===============================================================================#
 #===========#==#====#==============#========#
 2.2 T-TEST.  Independent Samples Test
 #==============================#=========#===============================================================================#
-#                              #Levene's |                          t-test for Equality of Means                         #
+#                              # Levene's|                          t-test for Equality of Means                         #
 #                              #----+----+-----+------+---------------+---------------+---------------------+------------#
 #                              #    |    |     |      |               |               |                     |    95%     #
 #                              #    |    |     |      |               |               |                     +------+-----#
 #                              #----+----+-----+------+---------------+---------------+---------------------+------------#
 #                              #    |    |     |      |               |               |                     |    95%     #
 #                              #    |    |     |      |               |               |                     +------+-----#
index 0deef6dad0424ad04d9fcbcf95a198604013b255..a228cffbdb8c7f3d55a3b046ba49a4b772fd844a 100755 (executable)
@@ -100,7 +100,7 @@ diff  -b $TEMPDIR/pspp.list - <<EOF
 #===========#=====================================================#======#==#===============#
 #           #                  Paired Differences                 |      |  |               #
 #           #-------+--------------+---------------+--------------+      |  |               #
 #===========#=====================================================#======#==#===============#
 #           #                  Paired Differences                 |      |  |               #
 #           #-------+--------------+---------------+--------------+      |  |               #
-#           #       |              |               |     95%      |      |  |               #
+#           #       |              |               |95% Confidence|      |  |               #
 #           #       |              |               +-------+------+      |  |               #
 #           #  Mean |Std. Deviation|Std. Error Mean| Lower | Upper|   t  |df|Sig. (2-tailed)#
 #===========#=======#==============#===============#=======#======#======#==#===============#
 #           #       |              |               +-------+------+      |  |               #
 #           #  Mean |Std. Deviation|Std. Error Mean| Lower | Upper|   t  |df|Sig. (2-tailed)#
 #===========#=======#==============#===============#=======#======#======#==#===============#
index bb8cc227355316bb866077f61ce3a4f99b2f1483..eb4b8f10c9eb50bfcc530f0fe2814b671215d6d9 100755 (executable)
@@ -99,23 +99,23 @@ diff -b  $TEMPDIR/pspp.list - << EOF
 #X#52|   100%|0|     0%|52|   100%#
 #=#==#=======#=#=======#==#=======#
 2.2 EXAMINE.  Descriptives
 #X#52|   100%|0|     0%|52|   100%#
 #=#==#=======#=#=======#==#=======#
 2.2 EXAMINE.  Descriptives
-#============================================#=========#==========#
-#                                            #Statistic|Std. Error#
-#============================================#=========#==========#
-#XMean                                       #   2.02  |   .034   #
-# 95% Confidence Interval for MeanLower Bound#  2.021  |          #
-#                                 Upper Bound#  2.017  |          #
-# 5% Trimmed Mean                            #   2.00  |          #
-# Median                                     #   2.00  |          #
-# Variance                                   #   .058  |          #
-# Std. Deviation                             #   .242  |          #
-# Minimum                                    #  1.000  |          #
-# Maximum                                    #  3.000  |          #
-# Range                                      #  2.000  |          #
-# Interquartile Range                        #   .00   |          #
-# Skewness                                   #  1.194  |   .330   #
-# Kurtosis                                   #  15.732 |   .650   #
-#============================================#=========#==========#
+#==============================================#=========#==========#
+#                                              #Statistic|Std. Error#
+#==============================================#=========#==========#
+#X Mean                                        #   2.02  |   .034   #
+#  95% Confidence Interval for Mean Lower Bound#  2.021  |          #
+#                                   Upper Bound#  2.017  |          #
+#  5% Trimmed Mean                             #   2.00  |          #
+#  Median                                      #   2.00  |          #
+#  Variance                                    #   .058  |          #
+#  Std. Deviation                              #   .242  |          #
+#  Minimum                                     #  1.000  |          #
+#  Maximum                                     #  3.000  |          #
+#  Range                                       #  2.000  |          #
+#  Interquartile Range                         #   .00   |          #
+#  Skewness                                    #  1.194  |   .330   #
+#  Kurtosis                                    #  15.732 |   .650   #
+#==============================================#=========#==========#
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
 
 EOF
 if [ $? -ne 0 ] ; then fail ; fi