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
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.
-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.
+
 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:
 
@@ -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
-    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
diff --git a/Smake b/Smake
index 49a72f32ba21c8878bb94f83fbb30831e9e291f1..b6bedc9d9a7beb966fde31fc60212bd4201e3c16 100644 (file)
--- a/Smake
+++ b/Smake
@@ -35,6 +35,7 @@ GNULIB_MODULES = \
        strcspn \
        strerror \
        strftime \
+       strsep \
        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
index 2843c311b2537f714c78d106c7714890afafe466..a6e4697c5c3300807c36494c706ea0ba3eb49bcf 100644 (file)
@@ -3,10 +3,20 @@
 
 pkgsysconf_DATA = \
        config/devices \
-       config/html-prologue \
        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
@@ -14,10 +24,10 @@ EXTRA_DIST += $(pkgsysconf_DATA)
 # 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 $$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.
-# Macro definitions on the PSPP command-line take precedence without
-# warning.
 
 # 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 no-attributes bold-on="" italic-on="" bold-italic-on=""
-
 # 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.
-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::
 
+# PostScript device.
+list-ps:postscript::
+
 # 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}
 
-# 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:
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
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
 
-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.
-* 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).
@@ -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.
-* Improving output quality::    Hints for producing ever-more-lovely output.
 @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
@@ -231,55 +122,11 @@ even something so simple.  Environment variables are further described
 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
 
-@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
@@ -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
-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}
-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
@@ -737,34 +575,9 @@ signs.
 @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}
@@ -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"}.
 
-@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
@@ -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}.
 
-@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:
-@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}
 
-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}
 
-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}
 
-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
 
-@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
-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}
@@ -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"}.
 
-@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}
 
-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 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,
@@ -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}.
 
-@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
@@ -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}.
 
-@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
@@ -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.
 
-@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
@@ -1329,10 +727,6 @@ Single line.
 
 @item 2
 Double line.
-
-@item 3
-Special device-defined line, if one is available; otherwise, a double
-line.
 @end table
 
 Examples:
@@ -1377,113 +771,22 @@ Defaults:
 @*@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[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 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
@@ -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.
 
-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}
@@ -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"}.
-
-@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
 
-@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
@@ -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
-
-@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
-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
@@ -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}
-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
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.
 
-* Installation::                How to compile and install PSPP.
 * 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 installing.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"
-"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"
@@ -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/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"
@@ -1729,44 +1729,39 @@ msgid ""
 "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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/language/data-io/list.q:203
+#: src/language/data-io/list.q:205
 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 ""
 
@@ -2339,11 +2334,11 @@ msgid ""
 "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 ""
 
-#: 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 ""
 
@@ -2576,98 +2571,98 @@ 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 ""
 
-#: src/language/lexer/lexer.c:366
+#: src/language/lexer/lexer.c:368
 #, 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 ""
 
-#: src/language/lexer/lexer.c:399
+#: src/language/lexer/lexer.c:401
 #, 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 ""
 
-#: src/language/lexer/lexer.c:436
+#: src/language/lexer/lexer.c:438
 #, 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 ""
 
-#: 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 ""
 
-#: src/language/lexer/lexer.c:616
+#: src/language/lexer/lexer.c:618
 msgid "expecting number"
 msgstr ""
 
-#: src/language/lexer/lexer.c:630
+#: src/language/lexer/lexer.c:632
 msgid "expecting identifier"
 msgstr ""
 
-#: src/language/lexer/lexer.c:840
+#: src/language/lexer/lexer.c:842
 msgid "<ERROR>"
 msgstr ""
 
-#: src/language/lexer/lexer.c:986
+#: src/language/lexer/lexer.c:988
 msgid "binary"
 msgstr ""
 
-#: src/language/lexer/lexer.c:991
+#: src/language/lexer/lexer.c:993
 msgid "octal"
 msgstr ""
 
-#: src/language/lexer/lexer.c:996
+#: src/language/lexer/lexer.c:998
 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 ""
 
-#: src/language/lexer/lexer.c:1035
+#: src/language/lexer/lexer.c:1037
 #, 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 ""
 
-#: src/language/lexer/lexer.c:1120
+#: src/language/lexer/lexer.c:1122
 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 ""
 
-#: src/language/lexer/lexer.c:1141
+#: src/language/lexer/lexer.c:1143
 #, 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."
@@ -2784,8 +2779,7 @@ 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 ""
@@ -2905,7 +2899,7 @@ msgid "Missing"
 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"
@@ -2956,6 +2950,10 @@ 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
@@ -2981,6 +2979,10 @@ 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 ""
@@ -2997,6 +2999,10 @@ 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"
@@ -3012,136 +3018,140 @@ 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:1929
+#: src/language/stats/crosstabs.q:1935
 msgid "Pearson Chi-Square"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1930
+#: src/language/stats/crosstabs.q:1936
 msgid "Likelihood Ratio"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1931
+#: src/language/stats/crosstabs.q:1937
 msgid "Fisher's Exact Test"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1932
+#: src/language/stats/crosstabs.q:1938
 msgid "Continuity Correction"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1933
+#: src/language/stats/crosstabs.q:1939
 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/language/stats/crosstabs.q:1988
+#: src/language/stats/crosstabs.q:1994
 msgid "Interval by Interval"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1989
+#: src/language/stats/crosstabs.q:1995
 msgid "Measure of Agreement"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1994
+#: src/language/stats/crosstabs.q:2000
 msgid "Phi"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1995
+#: src/language/stats/crosstabs.q:2001
 msgid "Cramer's V"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1996
+#: src/language/stats/crosstabs.q:2002
 msgid "Contingency Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1997
+#: src/language/stats/crosstabs.q:2003
 msgid "Kendall's tau-b"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1998
+#: src/language/stats/crosstabs.q:2004
 msgid "Kendall's tau-c"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1999
+#: src/language/stats/crosstabs.q:2005
 msgid "Gamma"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2000
+#: src/language/stats/crosstabs.q:2006
 msgid "Spearman Correlation"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2001
+#: src/language/stats/crosstabs.q:2007
 msgid "Pearson's R"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2002
+#: src/language/stats/crosstabs.q:2008
 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 ""
 
-#: src/language/stats/crosstabs.q:2075
+#: src/language/stats/crosstabs.q:2081
 #, 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 ""
 
-#: src/language/stats/crosstabs.q:2086
+#: src/language/stats/crosstabs.q:2092
 #, 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 ""
 
-#: src/language/stats/crosstabs.q:2122
+#: src/language/stats/crosstabs.q:2128
 msgid "Lambda"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2123
+#: src/language/stats/crosstabs.q:2129
 msgid "Goodman and Kruskal tau"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2124
+#: src/language/stats/crosstabs.q:2130
 msgid "Uncertainty Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2125
+#: src/language/stats/crosstabs.q:2131
 msgid "Somers' d"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2126
+#: src/language/stats/crosstabs.q:2132
 msgid "Eta"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2131
+#: src/language/stats/crosstabs.q:2137
 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 ""
@@ -3725,7 +3735,7 @@ msgstr ""
 msgid "SE. Mean"
 msgstr ""
 
-#: src/language/stats/t-test.q:702
+#: src/language/stats/t-test.q:703
 msgid "Group Statistics"
 msgstr ""
 
@@ -4132,630 +4142,376 @@ msgstr ""
 msgid "installation error"
 msgstr ""
 
-#: src/output/ascii.c:235
+#: src/output/afm.c:150
 #, c-format
-msgid "ASCII driver initializing as `%s'..."
+msgid "opening font metrics file \"%s\""
 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 ""
 
-#: src/output/ascii.c:395 src/output/html.c:103 src/output/postscript.c:454
+#: src/output/afm.c:267
 #, c-format
-msgid "%s: Initialization complete."
+msgid "unsupported MappingScheme %d"
 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 ""
 
-#: 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 ""
 
-#: src/output/ascii.c:490
+#: src/output/afm.c:536
 #, 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 ""
 
-#: src/output/ascii.c:496
-#, c-format
-msgid "Duplicate value for key `%s'."
+#: src/output/afm.c:594
+msgid "expected end of file"
 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/output/ascii.c:824
+#: src/output/ascii.c:161
 #, c-format
-msgid "ascii_line_vert: bad vline %d,(%d,%d) out of (%d,%d)\n"
+msgid "ascii: opening output file \"%s\""
 msgstr ""
 
-#: src/output/ascii.c:854
+#: src/output/ascii.c:172
 #, 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 ""
 
-#: src/output/groff-font.c:295
+#: src/output/ascii.c:233
 #, c-format
-msgid "Missing type for character `%s'."
+msgid "ascii: closing output file \"%s\""
 msgstr ""
 
-#: src/output/groff-font.c:304
+#: src/output/ascii.c:285
 #, 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 ""
 
-#: src/output/groff-font.c:432
+#: src/output/ascii.c:292
 #, c-format
-msgid "Bad character \\%3o."
+msgid "ascii: multiple values for %s"
 msgstr ""
 
-#: src/output/groff-font.c:687
+#: src/output/ascii.c:300
 #, c-format
-msgid "Groff font error: Cannot find \"%s\"."
+msgid "ascii: unknown parameter `%s'"
 msgstr ""
 
-#: src/output/groff-font.c:752
+#: src/output/ascii.c:314
 #, 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 ""
 
-#: 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 ""
 
-#: 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
-msgid "%s: Device characteristic already defined."
+msgid "ascii: zero or positive integer required as `%s' value"
 msgstr ""
 
-#: src/output/groff-font.c:869
+#: src/output/ascii.c:384
 #, c-format
-msgid "%s: Invalid numeric format."
+msgid "ascii: boolean value expected for `%s'"
 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
-msgid "HTML driver initializing as `%s'..."
+msgid "ascii: bad line (%d,%d)-(%d,%d) out of (%d,%d)\n"
 msgstr ""
 
-#: src/output/html.c:171
+#: src/output/ascii.c:683 src/output/postscript.c:832
 #, 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/output/html.c:350
+#: src/output/html.c:68
 #, c-format
-msgid "%s: HTML prologue read successfully."
+msgid "opening HTML output file: %s"
 msgstr ""
 
-#: src/output/html.c:354
-#, c-format
-msgid "%s: Error reading HTML prologue."
+#: src/output/html.c:79
+msgid "PSPP Output"
 msgstr ""
 
-#: src/output/html.c:382
+#: src/output/html.c:165
 #, c-format
-msgid "HTML output driver: %s: %s"
+msgid "unknown configuration parameter `%s' for HTML device driver"
 msgstr ""
 
-#: src/output/output.c:160
+#: src/output/output.c:159
 #, 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 ""
 
-#: src/output/output.c:255
+#: src/output/output.c:254
 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/output/output.c:330 src/output/output.c:497
+#: src/output/output.c:330 src/output/output.c:496
 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 ""
 
-#: 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 ""
 
-#: src/output/output.c:352
+#: src/output/output.c:351
 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 ""
 
-#: src/output/output.c:598
+#: src/output/output.c:597
 msgid "Syntax error in string constant."
 msgstr ""
 
-#: src/output/output.c:630
+#: src/output/output.c:632
 msgid "Syntax error in options."
 msgstr ""
 
-#: src/output/output.c:640
+#: src/output/output.c:642
 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 ""
 
-#: src/output/output.c:744
+#: src/output/output.c:691
 #, 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 ""
 
-#: 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
-msgid "Can't deinitialize output driver class `%s'."
+msgid "Can't initialize output driver `%s' of class `%s'."
 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 ""
 
-#: src/output/output.c:1066
+#: src/output/output.c:922
 #, 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 ""
 
-#: src/output/output.c:1107
+#: src/output/output.c:963
 #, 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 ""
 
-#: src/output/output.c:1166
+#: src/output/output.c:1022
 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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
-msgid "Error opening page on %s device of %s class."
+msgid "opening PostScript output file \"%s\""
 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 ""
-"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 ""
 
-#: src/output/postscript.c:573
+#: src/output/postscript.c:250
 #, c-format
-msgid "Unknown configuration parameter `%s' for PostScript device driver."
+msgid "closing PostScript output file \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:589
+#: src/output/postscript.c:310
 #, c-format
-msgid ""
-"Unknown orientation `%s'.  Valid orientations are `portrait' and `landscape'."
+msgid "unknown configuration parameter `%s' for PostScript device driver"
 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 ""
-"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 ""
 
-#: src/output/postscript.c:904
+#: src/output/postscript.c:338
 #, c-format
-msgid "%s: %s: Opening PostScript font encoding..."
+msgid "boolean value expected for %s"
 msgstr ""
 
-#: src/output/postscript.c:910
+#: src/output/postscript.c:351
 #, 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 ""
 
-#: src/output/postscript.c:957
+#: src/output/postscript.c:356
 #, 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 ""
 
-#: src/output/postscript.c:993
+#: src/output/postscript.c:388
 #, 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 ""
 
-#: src/output/postscript.c:996
+#: src/output/postscript.c:1182
 #, c-format
-msgid "%s: PostScript font encoding read successfully."
+msgid "\"%s\": bad font specification"
 msgstr ""
 
-#: src/output/postscript.c:1090
+#: src/output/postscript.c:1190
 #, c-format
-msgid "%s: %s: Opening PostScript encoding list file."
+msgid "could not find AFM file \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:1123
+#: src/output/postscript.c:1204
 #, c-format
-msgid "%s: PostScript encoding list file read successfully."
+msgid "could not find font \"%s\""
 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
-msgid "%s: %s: Opening PostScript prologue..."
+msgid "could not find encoding \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:1465
+#: src/output/postscript.c:1313
 #, c-format
-msgid "%s: PostScript prologue read successfully."
+msgid "cannot open font file \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:1469
+#: src/output/postscript.c:1354
 #, c-format
-msgid "%s: Error reading PostScript prologue."
+msgid "reading font file \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:1639
+#: src/output/postscript.c:1376
 #, c-format
-msgid "PostScript output driver: %s: %s"
+msgid "cannot open font encoding file \"%s\""
 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 ""
 
-#: 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 ""
 
-#: 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"
@@ -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"
-"  -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"
@@ -4948,7 +4702,7 @@ msgid ""
 "\n"
 msgstr ""
 
-#: src/ui/terminal/command-line.c:249
+#: src/ui/terminal/command-line.c:247
 #, 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"
-"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"
@@ -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/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"
@@ -1730,44 +1730,39 @@ msgid ""
 "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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/language/data-io/list.q:203
+#: src/language/data-io/list.q:205
 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 ""
 
@@ -2340,11 +2335,11 @@ msgid ""
 "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 ""
 
-#: 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 ""
 
@@ -2577,98 +2572,98 @@ 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 ""
 
-#: src/language/lexer/lexer.c:366
+#: src/language/lexer/lexer.c:368
 #, 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 ""
 
-#: src/language/lexer/lexer.c:399
+#: src/language/lexer/lexer.c:401
 #, 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 ""
 
-#: src/language/lexer/lexer.c:436
+#: src/language/lexer/lexer.c:438
 #, 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 ""
 
-#: 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 ""
 
-#: src/language/lexer/lexer.c:616
+#: src/language/lexer/lexer.c:618
 msgid "expecting number"
 msgstr ""
 
-#: src/language/lexer/lexer.c:630
+#: src/language/lexer/lexer.c:632
 msgid "expecting identifier"
 msgstr ""
 
-#: src/language/lexer/lexer.c:840
+#: src/language/lexer/lexer.c:842
 msgid "<ERROR>"
 msgstr ""
 
-#: src/language/lexer/lexer.c:986
+#: src/language/lexer/lexer.c:988
 msgid "binary"
 msgstr ""
 
-#: src/language/lexer/lexer.c:991
+#: src/language/lexer/lexer.c:993
 msgid "octal"
 msgstr ""
 
-#: src/language/lexer/lexer.c:996
+#: src/language/lexer/lexer.c:998
 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 ""
 
-#: src/language/lexer/lexer.c:1035
+#: src/language/lexer/lexer.c:1037
 #, 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 ""
 
-#: src/language/lexer/lexer.c:1120
+#: src/language/lexer/lexer.c:1122
 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 ""
 
-#: src/language/lexer/lexer.c:1141
+#: src/language/lexer/lexer.c:1143
 #, 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."
@@ -2785,8 +2780,7 @@ 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 ""
@@ -2906,7 +2900,7 @@ msgid "Missing"
 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"
@@ -2957,6 +2951,10 @@ 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
@@ -2982,6 +2980,10 @@ 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 ""
@@ -2998,6 +3000,10 @@ 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"
@@ -3013,136 +3019,140 @@ 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:1929
+#: src/language/stats/crosstabs.q:1935
 msgid "Pearson Chi-Square"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1930
+#: src/language/stats/crosstabs.q:1936
 msgid "Likelihood Ratio"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1931
+#: src/language/stats/crosstabs.q:1937
 msgid "Fisher's Exact Test"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1932
+#: src/language/stats/crosstabs.q:1938
 msgid "Continuity Correction"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1933
+#: src/language/stats/crosstabs.q:1939
 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/language/stats/crosstabs.q:1988
+#: src/language/stats/crosstabs.q:1994
 msgid "Interval by Interval"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1989
+#: src/language/stats/crosstabs.q:1995
 msgid "Measure of Agreement"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1994
+#: src/language/stats/crosstabs.q:2000
 msgid "Phi"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1995
+#: src/language/stats/crosstabs.q:2001
 msgid "Cramer's V"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1996
+#: src/language/stats/crosstabs.q:2002
 msgid "Contingency Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1997
+#: src/language/stats/crosstabs.q:2003
 msgid "Kendall's tau-b"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1998
+#: src/language/stats/crosstabs.q:2004
 msgid "Kendall's tau-c"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1999
+#: src/language/stats/crosstabs.q:2005
 msgid "Gamma"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2000
+#: src/language/stats/crosstabs.q:2006
 msgid "Spearman Correlation"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2001
+#: src/language/stats/crosstabs.q:2007
 msgid "Pearson's R"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2002
+#: src/language/stats/crosstabs.q:2008
 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 ""
 
-#: src/language/stats/crosstabs.q:2075
+#: src/language/stats/crosstabs.q:2081
 #, 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 ""
 
-#: src/language/stats/crosstabs.q:2086
+#: src/language/stats/crosstabs.q:2092
 #, 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 ""
 
-#: src/language/stats/crosstabs.q:2122
+#: src/language/stats/crosstabs.q:2128
 msgid "Lambda"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2123
+#: src/language/stats/crosstabs.q:2129
 msgid "Goodman and Kruskal tau"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2124
+#: src/language/stats/crosstabs.q:2130
 msgid "Uncertainty Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2125
+#: src/language/stats/crosstabs.q:2131
 msgid "Somers' d"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2126
+#: src/language/stats/crosstabs.q:2132
 msgid "Eta"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2131
+#: src/language/stats/crosstabs.q:2137
 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 ""
@@ -3726,7 +3736,7 @@ msgstr ""
 msgid "SE. Mean"
 msgstr ""
 
-#: src/language/stats/t-test.q:702
+#: src/language/stats/t-test.q:703
 msgid "Group Statistics"
 msgstr ""
 
@@ -4133,630 +4143,376 @@ msgstr ""
 msgid "installation error"
 msgstr ""
 
-#: src/output/ascii.c:235
+#: src/output/afm.c:150
 #, c-format
-msgid "ASCII driver initializing as `%s'..."
+msgid "opening font metrics file \"%s\""
 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 ""
 
-#: src/output/ascii.c:395 src/output/html.c:103 src/output/postscript.c:454
+#: src/output/afm.c:267
 #, c-format
-msgid "%s: Initialization complete."
+msgid "unsupported MappingScheme %d"
 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 ""
 
-#: 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 ""
 
-#: src/output/ascii.c:490
+#: src/output/afm.c:536
 #, 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 ""
 
-#: src/output/ascii.c:496
-#, c-format
-msgid "Duplicate value for key `%s'."
+#: src/output/afm.c:594
+msgid "expected end of file"
 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/output/ascii.c:824
+#: src/output/ascii.c:161
 #, c-format
-msgid "ascii_line_vert: bad vline %d,(%d,%d) out of (%d,%d)\n"
+msgid "ascii: opening output file \"%s\""
 msgstr ""
 
-#: src/output/ascii.c:854
+#: src/output/ascii.c:172
 #, 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 ""
 
-#: src/output/groff-font.c:295
+#: src/output/ascii.c:233
 #, c-format
-msgid "Missing type for character `%s'."
+msgid "ascii: closing output file \"%s\""
 msgstr ""
 
-#: src/output/groff-font.c:304
+#: src/output/ascii.c:285
 #, 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 ""
 
-#: src/output/groff-font.c:432
+#: src/output/ascii.c:292
 #, c-format
-msgid "Bad character \\%3o."
+msgid "ascii: multiple values for %s"
 msgstr ""
 
-#: src/output/groff-font.c:687
+#: src/output/ascii.c:300
 #, c-format
-msgid "Groff font error: Cannot find \"%s\"."
+msgid "ascii: unknown parameter `%s'"
 msgstr ""
 
-#: src/output/groff-font.c:752
+#: src/output/ascii.c:314
 #, 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 ""
 
-#: 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 ""
 
-#: 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
-msgid "%s: Device characteristic already defined."
+msgid "ascii: zero or positive integer required as `%s' value"
 msgstr ""
 
-#: src/output/groff-font.c:869
+#: src/output/ascii.c:384
 #, c-format
-msgid "%s: Invalid numeric format."
+msgid "ascii: boolean value expected for `%s'"
 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
-msgid "HTML driver initializing as `%s'..."
+msgid "ascii: bad line (%d,%d)-(%d,%d) out of (%d,%d)\n"
 msgstr ""
 
-#: src/output/html.c:171
+#: src/output/ascii.c:683 src/output/postscript.c:832
 #, 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/output/html.c:350
+#: src/output/html.c:68
 #, c-format
-msgid "%s: HTML prologue read successfully."
+msgid "opening HTML output file: %s"
 msgstr ""
 
-#: src/output/html.c:354
-#, c-format
-msgid "%s: Error reading HTML prologue."
+#: src/output/html.c:79
+msgid "PSPP Output"
 msgstr ""
 
-#: src/output/html.c:382
+#: src/output/html.c:165
 #, c-format
-msgid "HTML output driver: %s: %s"
+msgid "unknown configuration parameter `%s' for HTML device driver"
 msgstr ""
 
-#: src/output/output.c:160
+#: src/output/output.c:159
 #, 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 ""
 
-#: src/output/output.c:255
+#: src/output/output.c:254
 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: src/output/output.c:330 src/output/output.c:497
+#: src/output/output.c:330 src/output/output.c:496
 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 ""
 
-#: 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 ""
 
-#: src/output/output.c:352
+#: src/output/output.c:351
 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 ""
 
-#: src/output/output.c:598
+#: src/output/output.c:597
 msgid "Syntax error in string constant."
 msgstr ""
 
-#: src/output/output.c:630
+#: src/output/output.c:632
 msgid "Syntax error in options."
 msgstr ""
 
-#: src/output/output.c:640
+#: src/output/output.c:642
 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 ""
 
-#: src/output/output.c:744
+#: src/output/output.c:691
 #, 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 ""
 
-#: 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
-msgid "Can't deinitialize output driver class `%s'."
+msgid "Can't initialize output driver `%s' of class `%s'."
 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 ""
 
-#: src/output/output.c:1066
+#: src/output/output.c:922
 #, 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 ""
 
-#: src/output/output.c:1107
+#: src/output/output.c:963
 #, 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 ""
 
-#: src/output/output.c:1166
+#: src/output/output.c:1022
 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 ""
 
-#: 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 ""
 
-#: 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 ""
 
-#: 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
-msgid "Error opening page on %s device of %s class."
+msgid "opening PostScript output file \"%s\""
 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 ""
-"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 ""
 
-#: src/output/postscript.c:573
+#: src/output/postscript.c:250
 #, c-format
-msgid "Unknown configuration parameter `%s' for PostScript device driver."
+msgid "closing PostScript output file \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:589
+#: src/output/postscript.c:310
 #, c-format
-msgid ""
-"Unknown orientation `%s'.  Valid orientations are `portrait' and `landscape'."
+msgid "unknown configuration parameter `%s' for PostScript device driver"
 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 ""
-"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 ""
 
-#: src/output/postscript.c:904
+#: src/output/postscript.c:338
 #, c-format
-msgid "%s: %s: Opening PostScript font encoding..."
+msgid "boolean value expected for %s"
 msgstr ""
 
-#: src/output/postscript.c:910
+#: src/output/postscript.c:351
 #, 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 ""
 
-#: src/output/postscript.c:957
+#: src/output/postscript.c:356
 #, 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 ""
 
-#: src/output/postscript.c:993
+#: src/output/postscript.c:388
 #, 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 ""
 
-#: src/output/postscript.c:996
+#: src/output/postscript.c:1182
 #, c-format
-msgid "%s: PostScript font encoding read successfully."
+msgid "\"%s\": bad font specification"
 msgstr ""
 
-#: src/output/postscript.c:1090
+#: src/output/postscript.c:1190
 #, c-format
-msgid "%s: %s: Opening PostScript encoding list file."
+msgid "could not find AFM file \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:1123
+#: src/output/postscript.c:1204
 #, c-format
-msgid "%s: PostScript encoding list file read successfully."
+msgid "could not find font \"%s\""
 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
-msgid "%s: %s: Opening PostScript prologue..."
+msgid "could not find encoding \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:1465
+#: src/output/postscript.c:1313
 #, c-format
-msgid "%s: PostScript prologue read successfully."
+msgid "cannot open font file \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:1469
+#: src/output/postscript.c:1354
 #, c-format
-msgid "%s: Error reading PostScript prologue."
+msgid "reading font file \"%s\""
 msgstr ""
 
-#: src/output/postscript.c:1639
+#: src/output/postscript.c:1376
 #, c-format
-msgid "PostScript output driver: %s: %s"
+msgid "cannot open font encoding file \"%s\""
 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 ""
 
-#: 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 ""
 
-#: 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"
@@ -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"
-"  -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"
@@ -4949,7 +4703,7 @@ msgid ""
 "\n"
 msgstr ""
 
-#: src/ui/terminal/command-line.c:249
+#: src/ui/terminal/command-line.c:247
 #, 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
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, 3, i, TAB_LEFT | TAT_FIX,
+      tab_text (t, 3, i, TAB_LEFT | TAB_FIX,
                    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);
 }
@@ -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);
-       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);
 }
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);
-  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.h = text.v = INT_MAX;
   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;
   
-         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++)
-             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);
          }
 
-         fputs ("  <TR>\n", x->file.file);
+         fputs ("  </TR>\n", x->file);
        }
       else
        assert (0);
@@ -380,16 +374,14 @@ clean_up (void)
            free (prc->header);
          }
        free (prc);
-      
-       d->class->text_set_font_by_name (d, "PROP");
       }
     else if (d->class == &html_class)
       {
-       if (d->driver_open && d->page_open)
+       if (d->page_open)
          {
            struct html_driver_ext *x = d->ext;
 
-           fputs ("</TABLE>\n", x->file.file);
+           fputs ("</TABLE>\n", x->file);
          }
       }
     else
@@ -405,12 +397,9 @@ static void
 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)
@@ -418,10 +407,15 @@ write_varname (struct outp_driver *d, char *string, int 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.h = text.v = INT_MAX;
   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
@@ -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. */
-      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.h = text.v = INT_MAX;
       d->class->text_draw (d, &text);
-      d->cp_x = text.h;
+      d->class->text_metrics (d, &text, &d->cp_x, NULL);
 
       goto entry;
       do
@@ -528,8 +524,7 @@ determine_layout (void)
       
       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);
@@ -548,7 +543,6 @@ determine_layout (void)
       if (width <= max_width)
        {
          prc->header_rows = 2;
-         d->class->text_set_font_by_name (d, "FIXED");
          continue;
        }
 
@@ -593,8 +587,6 @@ determine_layout (void)
            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;
        }
 
@@ -605,7 +597,6 @@ determine_layout (void)
       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);
@@ -692,12 +683,13 @@ list_cases (struct ccase *c, void *aux UNUSED)
        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];
-           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));
@@ -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); 
               }
-           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);
index 9d835abe5204f439fbe97b18b7a091a9b8b8e1bd..52828400f9382194b4e3c25f0e3f95f06612b7d2 100644 (file)
@@ -810,12 +810,12 @@ dump_table (const struct file_handle *fh)
        {
          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);
-         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;
        }
@@ -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, 3, nspec, TAB_LEFT | TAT_FIX,
+         tab_text (t, 3, nspec, TAB_LEFT | TAB_FIX,
                        fmt_to_string (&spec->u.v.f));
          break;
        }
@@ -837,12 +837,12 @@ dump_table (const struct file_handle *fh)
       }
 
   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
-    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);
 }
 
@@ -927,7 +927,7 @@ print_trns_proc (void *trns_, struct ccase *c, int case_num UNUSED)
        if (t->writer == NULL)
          {
            buf[len] = 0;
-           tab_output_text (TAT_FIX | TAT_NOWRAP, buf);
+           tab_output_text (TAB_FIX | TAT_NOWRAP, buf);
          }
        else
          {
index 98cc90ddfb9e600114de1b8712ff97b65c08c729..1f9bc7e49d7b7830cd4f9e2db6997cd4c97ce821 100644 (file)
@@ -96,7 +96,7 @@ cmd_sysfile_info (void)
   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:"));
@@ -200,7 +200,7 @@ cmd_display (void)
       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
@@ -311,7 +311,7 @@ display_documents (void)
                 && 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 ())
-    tab_output_text (TAB_LEFT | TAT_FIX, ds_c_str (line));
+    tab_output_text (TAB_LEFT | TAB_FIX, ds_c_str (line));
 
   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);
-  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"));
@@ -1088,7 +1088,7 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
          }
        strcpy (cp, "].");
 
-       tab_title (table, 0, title);
+       tab_title (table, "%s", 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);
 
-      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"));
@@ -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);
-      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"));
@@ -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);
-      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,
@@ -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);
-      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"));
@@ -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, -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);
@@ -1481,14 +1481,20 @@ crosstabs_dim (struct tab_table *t, struct outp_driver *d)
   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)
-    c += outp_string_width (d, "M");
+    c += outp_string_width (d, "M", OUTP_PROPORTIONAL);
 
   /* 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;
index b305deea0f1aa022add52c4b0199daeb5a33c0c6..9a90cc9f119951a26e2e6af57ca7f604e55d86c2 100644 (file)
@@ -540,7 +540,7 @@ dump_z_table (struct dsc_proc *dsc)
   }
   
   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);
@@ -915,7 +915,7 @@ display (struct dsc_proc *dsc)
          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);
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_title (tbl, 0, _("Case Processing Summary"));
+  tab_title (tbl, _("Case Processing Summary"));
   
 
   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_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);
@@ -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_title (tbl, 0, _("Descriptives"));
+  tab_title (tbl, _("Descriptives"));
 
 
   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_title (tbl, 0, _("Percentiles"));
+  tab_title (tbl, _("Percentiles"));
 
 
   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,
-          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);
@@ -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_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);
 
 }
@@ -1234,9 +1234,9 @@ dump_full (struct variable *v)
 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;
 
@@ -1295,10 +1295,10 @@ dump_condensed (struct variable *v)
     }
 
   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);
-  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);
 }
@@ -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 | 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 */
 
@@ -1537,9 +1537,9 @@ dump_statistics (struct variable *v, int show_varname)
   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
-       tab_title (t, 0, v->name);
+       tab_title (t, "%s", v->name);
     }
   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);
 
 
@@ -412,7 +412,7 @@ show_descriptives(void)
   tab_text (t, 9, 1, TAB_CENTER | TAT_TITLE, _("Maximum"));
 
 
-  tab_title (t, 0, _("Descriptives"));
+  tab_title (t, _("Descriptives"));
 
 
   row = 2;
@@ -541,7 +541,7 @@ show_homogeneity(void)
   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 ) 
     {
@@ -611,7 +611,7 @@ show_contrast_coeffs(short *bad_contrast)
 
   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"));
 
@@ -678,7 +678,7 @@ show_contrast_tests(short *bad_contrast)
   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"));
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_title (t, 0, _("Model Summary"));
+  tab_title (t, _("Model Summary"));
   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);
     }
-  tab_title (t, 0, _("Coefficients"));
+  tab_title (t, _("Coefficients"));
   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_title (t, 0, _("ANOVA"));
+  tab_title (t, _("ANOVA"));
   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);
        }
     }
-  tab_title (t, 0, _("Coefficient Correlations"));
+  tab_title (t, _("Coefficient Correlations"));
   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);
-  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"));
@@ -699,8 +699,8 @@ ssbox_independent_samples_init(struct ssbox *this,
   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"));
@@ -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);
-  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"));
@@ -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);
-  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);
@@ -1150,14 +1150,14 @@ trbox_paired_init(struct trbox *self,
   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_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"),
@@ -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);
-  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);
 
@@ -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);
 
-  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"));
@@ -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_title(table, 0, _("Paired Samples Correlations"));
+  tab_title(table, _("Paired Samples Correlations"));
 
   /* 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.
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.
 
-   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
@@ -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,
-             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;
+}
 
-  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. */
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,
-                  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 *);
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.
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>
-#include <libpspp/message.h>
+
 #include <ctype.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
+
+#include <data/filename.h>
 #include <libpspp/alloc.h>
-#include <libpspp/message.h>
-#include "chart.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 "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"
-   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.
-   init=""                      Written at beginning of output.
-   done=""                      Written at end of output.
    
    headers=on|off               Put headers at top of page?
+   emphasis=bold|underline|none Style to use for emphasis.
    length=66
    width=130
-   lpi=6                        Only used to determine font size.
-   cpi=10                       
    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).
-   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 */
 
-/* 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
   {
@@ -115,36 +72,9 @@ enum
     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 
@@ -154,330 +84,195 @@ struct line
     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
   {
+    struct pool *pool;
+
     /* 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 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. */
-    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 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;
-  
-  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_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->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++)
-    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->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;
-  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
   {
-    pos_int_arg = -10,
-    nonneg_int_arg,
+    boolean_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},
-    {"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},
-    {"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},
-    {"", 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;
-  int cat, subcat;
+  int subcat;
   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)
        {
-         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;
-    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:
       {
@@ -545,7 +311,8 @@ ascii_option (struct outp_driver *this, const char *key,
        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)
@@ -554,19 +321,25 @@ ascii_option (struct outp_driver *this, const char *key,
            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:
-           assert (0);
+           abort ();
          }
       }
       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;
@@ -576,79 +349,40 @@ ascii_option (struct outp_driver *this, const char *key,
        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:
-           x->left_margin = arg;
-           break;
-         case 1:
-           x->right_margin = arg;
-           break;
-         case 2:
            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:
-           s = &x->ops[OPS_DONE];
+           x->bottom_margin = arg;
            break;
          case 2:
-           s = &x->ops[OPS_FORMFEED];
-           break;
-         case 3:
-           s = &x->ops[OPS_NEWLINE];
+           x->tab_width = arg;
            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:
       {
-       int setting;
+       bool setting;
        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"))
-         setting = 0;
+         setting = false;
        else
          {
-           msg (SE, _("Boolean value expected for %s."), key);
-           return;
+           error (0, 0, _("ascii: boolean value expected for `%s'"), key);
+           return false;
          }
        switch (subcat)
          {
@@ -662,988 +396,340 @@ ascii_option (struct outp_driver *this, const char *key,
             x->squeeze_blank_lines = setting;
             break;
          default:
-           assert (0);
+           abort ();
          }
       }
       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;
 
-  assert (this->driver_open && !this->page_open);
   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;
         }
-      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;
-
-  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
-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;
-  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
-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;
-  int x1 = r->x1 / this->horiz;
-  int y1 = r->y1 / this->vert;
-  int y2 = r->y2 / this->vert;
   int y;
+  unsigned short value;
 
-  assert (this->driver_open && this->page_open);
-  if (y1 == y2)
-    return;
+  assert (this->page_open);
 #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
-      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
 
-  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
-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:
-      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
-   nonzero.
-
-   You probably don't want to look at this code. */
+   true. */
 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)
-       {
-         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
-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
-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. */
 
-#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;
-  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
-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
-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)
 {
-  static int s_len;
-
   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)
     {
-      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
-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 
-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,
-  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,
@@ -1668,22 +747,7 @@ struct outp_class ascii_class =
 
   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,
 
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 = \
+       src/output/afm.c \
+       src/output/afm.h \
        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 \
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 "error.h"
 #include "getline.h"
 #include "getlogin_r.h"
 #include "output.h"
 #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;
 
-  assert (this->driver_open == 0);
-  msg (VM (1), _("HTML driver initializing as `%s'..."), this->name);
-
   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;
-
-  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);
-  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
-{
-  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[] =
-{
-  /* *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;
-  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:
-      {
-       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:
-      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 *);
@@ -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;
   
-  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) 
     {
@@ -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:
-      link_image( &x->file, ((struct chart *)s->ext)->filename);
+      link_image (x->file, ((struct chart *)s->ext)->filename);
       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
-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)
@@ -473,22 +270,21 @@ output_tab_table (struct outp_driver *this, struct tab_table *t)
   
   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;
     }
 
-  fputs ("<TABLE BORDER=1>\n", x->file.file);
+  fputs ("<TABLE BORDER=1>\n", x->file);
   
   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;
        
-       fputs ("  <TR>\n", x->file.file);
+       fputs ("  <TR>\n", x->file);
        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;
-           if (*ct & TAB_JOIN) 
+           if (*ct & TAB_JOIN)
               {
                 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; 
               }
 
-           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)
-                 cp = spprintf (cp, " COLSPAN=%d", j->x2 - j->x1);
+                 fprintf (x->file, " COLSPAN=%d", j->x2 - j->x1);
                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
@@ -602,45 +368,21 @@ html_finalise_chart(struct outp_driver *d UNUSED, struct chart *ch)
 
 /* 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
   {
-    /* 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;
 
+struct outp_driver;
+void html_put_cell_contents (struct outp_driver *this,
+                             unsigned int opts, struct fixed_string *text);
+
 #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;
 
-  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);
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;
 
+/* 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;
 
@@ -80,8 +87,8 @@ static int disabled_devices;
 
 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
@@ -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;
-  new_list->ref_count = 0;
 
   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 epsf_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);
 
@@ -252,11 +256,15 @@ delete_macros (void)
 static void
 init_default_drivers (void) 
 {
+  struct string s;
+
   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
@@ -290,7 +298,6 @@ outp_read_devices (void)
       goto exit;
     }
 
-  msg (VM (1), _("%s: Opening device description file..."), init_fn);
   f = fopen (init_fn, "r");
   if (f == NULL)
     {
@@ -344,7 +351,6 @@ exit:
 
   if (result) 
     {
-      msg (VM (2), _("Device definition file read successfully."));
       if (outp_driver_list == NULL) 
         msg (MW, _("No output drivers are active.")); 
     }
@@ -612,16 +618,19 @@ tokener (void)
   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);
-  while (tokener ())
+  while (ok && tokener ())
     {
       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;
        }
-      d->class->option (d, key, &op_tokstr);
+      ok = callback (driver, key, &op_tokstr);
     }
   ds_destroy (&op_tokstr);
+
+  return ok;
 }
 
 /* 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
-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)
-    if (!strcmp (c->class->name, class_name))
+    if (!strcmp (c->class->name, ds_c_str (class_name)))
       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)
     {
-      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"))
-           d->device |= OUTP_DEV_LISTING;
+           device |= OUTP_DEV_LISTING;
          else if (!strcmp (type, "screen"))
-           d->device |= OUTP_DEV_SCREEN;
+           device |= OUTP_DEV_SCREEN;
          else if (!strcmp (type, "printer"))
-           d->device |= OUTP_DEV_PRINTER;
+           device |= OUTP_DEV_PRINTER;
          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);
-  if (iter)
+  if (iter != 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;
-  return;
-
-error:
-  if (d)
-    destroy_driver (d);
-  return;
 }
 
 /* String LINE is in format:
@@ -770,12 +763,12 @@ static void
 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);
 
-  save_idx = -1;
+  save_idx = 0;
   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]))
-    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"));
 
@@ -798,27 +790,17 @@ configure_driver_line (struct string *line)
 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->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);
-      
-      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);
 
@@ -831,82 +813,20 @@ destroy_driver (struct outp_driver *d)
     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
-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. */
@@ -1141,7 +1061,6 @@ outp_get_paper_size (char *size, int *h, int *v)
       goto exit;
     }
 
-  msg (VM (1), _("%s: Opening paper size definition file..."), pprsz_fn);
   f = fopen (pprsz_fn, "r");
   if (!f)
     {
@@ -1211,9 +1130,7 @@ exit:
   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;
@@ -1238,9 +1155,7 @@ outp_drivers (struct outp_driver *d)
        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;
     }
 
@@ -1258,40 +1173,57 @@ outp_enable_device (int enable, int 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;
 
-      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
-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;
+  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>
 
 
-/* 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
   {
-    /* 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. */
-
-    /* Internal use only. */
-    int w, l;                  /* Width, length. */
   };
 
 struct som_entity;
@@ -119,61 +67,27 @@ struct chart;
 /* Defines a class of output driver. */
 struct outp_class
   {
-    /* Basic class information. */
     const char *name;          /* Name of this driver class. */
-    int magic;                 /* Driver-specific constant. */
     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 *);
     
-    /* 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 *);
-
   };
 
 /* 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_DISABLED = 010    /* Broken device. */
   };
 
 /* 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. */
-    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 res, horiz, vert;      /* Device resolution. */
-    int width, length;         /* Page size. */
-
     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 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. */
@@ -221,21 +128,6 @@ struct outp_option
     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;
 
@@ -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 *);
 
-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_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 *);
index b26676a92096c441254e9ab67245ad2120792e93..53e81104f87851069ce7d3598876f786bf141001 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
 #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>
-
-#if HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 
 #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/misc.h>
+#include <libpspp/start-date.h>
+#include <libpspp/version.h>
+
 #include <data/filename.h>
-#include "font.h"
+
+#include "afm.h"
+#include "chart.h"
+#include "error.h"
 #include "getline.h"
-#include <libpspp/hash.h>
 #include "intprops.h"
-#include <libpspp/misc.h>
-#include "output.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)
 
-/* 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"
-   color=yes|no
-   data=clean7bit|clean8bit|binary
-   line-ends=lf|crlf
 
    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
 
-   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
 
-   line-style=thick|double
-   line-gutter=0.5pt
-   line-spacing=0.5pt
+   line-gutter=1pt
+   line-spacing=1pt
    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
 
-/* 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
   {
-    /* 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. */
 
-    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_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))
 
-/* 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 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. */
 
-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;
-  
-  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->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->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;
-  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;
-  
-  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);
-  
-  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
 {
-  boolean_arg = -10,
+  output_file_arg,
+  paper_size_arg,
+  orientation_arg,
+  line_style_arg,
+  boolean_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[] =
 {
-  /* *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},
+
+  {"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},
-  {"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},
-  {"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-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;
-  int cat, subcat;
+  int subcat;
   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;
-    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;
-    case 2:
+    case paper_size_arg:
       outp_get_paper_size (value, &this->width, &this->length);
       break;
-    case 3:
+    case orientation_arg:
       if (!strcmp (value, "portrait"))
-       x->orientation = OTN_PORTRAIT;
+       x->portrait = true;
       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
-       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:
-      {
-       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:
       {
@@ -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)
          {
-           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)
          {
-           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)
@@ -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->font_size = arg;
+           this->font_height = arg;
            break;
          default:
-           assert (0);
+           abort ();
          }
       }
       break;
@@ -711,2167 +385,709 @@ ps_option (struct outp_driver *this, const char *key, const struct string *val)
 
        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)
          {
-         case 2:
+         case 0:
            x->line_width = dimension;
            break;
-         case 3:
+         case 1:
            x->line_gutter = dimension;
            break;
-         case 4:
+         case 2:
            x->line_width = dimension;
            break;
-         case 5:
-           x->line_width_thick = dimension;
-           break;
          default:
-           assert (0);
+           abort ();
          }
       }
       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:
-      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. */
-/* PORTME: Filename operations. */
 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
-/* 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
-output_encodings (struct outp_driver *this)
+ps_open_page (struct outp_driver *this)
 {
   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
-add_encoding (struct outp_driver *this, char *filename)
+ps_close_page (struct outp_driver *this)
 {
   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
-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:
-      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;
-    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
-/* 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
-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
-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
-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_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,
-           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;
-  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
-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 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. */
-      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
-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
-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)
 {
@@ -2884,12 +1100,12 @@ ps_chart_initialise (struct outp_driver *this UNUSED, struct chart *ch)
   int x_origin, y_origin;
 
   ch->file = tmpfile ();
-  if (ch->file == NULL) 
+  if (ch->file == NULL)
     {
       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;
@@ -2905,7 +1121,7 @@ ps_chart_initialise (struct outp_driver *this UNUSED, struct chart *ch)
 #endif
 }
 
-static void 
+static void
 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;
 
-  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);
-  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);
 
-  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
 }
+\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,
@@ -3017,26 +1441,10 @@ struct outp_class epsf_class =
 
   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
-
 };
index 7306ee3cfb76d26016e45d640caf46d6bf3b2be9..a9fc3743a6bec1f91e54a4b5aef377ab51286bfb 100644 (file)
@@ -29,6 +29,7 @@
 #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"
 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 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);
@@ -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;
 
-  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);
 
-  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));
 
-  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));
 
-  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));
 
-  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;
-  
+
   return t;
 }
 
@@ -108,7 +96,6 @@ tab_destroy (struct tab_table *t)
 {
   assert (t != NULL);
   pool_destroy (t->container);
-  t=0;
 }
 
 /* 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);
-#if DEBUGGING
-  assert (t->reallocable);
-#endif
   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->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)
        {
-         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)
 {
-  int y;
-
   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 & 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)
 {
-  int x;
-
   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 & 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 & 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 & 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)
@@ -387,11 +357,8 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v,
        {
          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)
@@ -402,11 +369,8 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v,
        {
          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)
 {
-  int len;
+  char *tmp = 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);
   
-  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
-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);
-  text_format (t, format ? TAT_PRINTF : TAT_NONE, title, args, &t->title);
+  text_format (t, TAT_PRINTF, title, args, &t->title);
   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];
+        int w;
                
        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];
+        int h;
 
        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];
-       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
-    
+
   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
+
+  tab_box (table, -1, -1, TAL_0, TAL_0, x1, y1, x2, y2);
   
   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);
+  char *tmp_buf = NULL;
 
-  assert (buf != NULL);
   if (options & TAT_PRINTF)
     {
       va_list args;
-      char *temp_buf = local_alloc (4096);
       
       va_start (args, buf);
-      nvsprintf (temp_buf, buf, args);
-      buf = temp_buf;
+      buf = tmp_buf = xvasprintf (buf, 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);
-  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);
-
-  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. */
@@ -944,20 +871,64 @@ tabi_table (struct som_entity *table)
   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)
 {
+  int c, r;
   int i;
-
+  
   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++)
@@ -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;
-    } else {
+    }
+  else
+    {
       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;
 
-    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;
@@ -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);
 
-/* 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
-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++;
 
@@ -1236,32 +1228,9 @@ tabi_render (int x1, int y1, int x2, int y2)
   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 =
@@ -1290,151 +1259,215 @@ struct som_table_class tab_table_class =
     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
-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,
index 678d6aa3a84b05e57364505c6ae0457485b653d4..51031da23c0e45c11299b8a8393b8f3dd56b032d 100644 (file)
@@ -28,27 +28,28 @@ enum
   {
     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. */
 
-    /* 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. */
-    TAL_3 = 3,                 /* Special line of driver-defined style. */
+    TAL_GAP = 3,                /* Spacing but no line. */
     TAL_COUNT,                 /* Number of line styles. */
-
-    TAL_SPACING = 0200         /* Don't draw the line, just reserve space. */
   };
 
 /* 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]. */
-    unsigned char *trh;                /* Types of horiz rules; [nr+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. */
@@ -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 hr_tot, vr_tot;                /* Hrules total height, vrules total width. */
 
     /* Editing info. */
     int col_ofs, row_ofs;      /* X and Y offsets. */
-#if DEBUGGING
-    int reallocable;           /* Can table be reallocated? */
-#endif
   };
 
 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_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 *);
 
@@ -155,8 +151,7 @@ enum
   {
     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). */
   };
 
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);
-  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"));
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.
index 711d9685e0506597e530dc3c1b4ca336be8b0fdc..31164d9b96dfa7307bf1d0dde07ef8ad459555d4 100755 (executable)
@@ -70,7 +70,7 @@ EOF
 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;
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
-#==========#===========#=====#
-#          #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
 
index 95d91abf4129bbffc3c37b14d3b23be031688934..73d767b8860797d0273fe305584efee8471e2532 100755 (executable)
@@ -110,22 +110,22 @@ diff -b  $TEMPDIR/pspp.list - << EOF
 +--------+------+
 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             #
@@ -137,121 +137,121 @@ Case#  QUALITY        W    BRAND
 #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
-#==========================================================#=========#==========#
-#                                                          #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
-#===========================#=============================#
-#                           #            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
-#===================================#===========#=====#
-#               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
-#======================================================================#=========#==========#
-#               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
 
index 929963e2045e61d945ef9cabffe1ec773dea4cb7..c0d8dc33278e8a8eb8bb1ec53129f50d543fba3f 100755 (executable)
@@ -107,7 +107,7 @@ diff -b  $TEMPDIR/pspp.list - << EOF
 +--------+------+
 2.1 ONEWAY.  Descriptives
 #===============#========#==#====#==============#==========#=======================#=======#=======#
-#               |        #  |    |              |          |    95% Confidence     |       |       #
+#               |        #  |    |              |          |95% Confidence Interval|       |       #
 #               |        #  |    |              |          +-----------+-----------+       |       #
 #               |        # 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
 #==============================#=========#===============================================================================#
-#                              #Levene's |                          t-test for Equality of Means                         #
+#                              # Levene's|                          t-test for Equality of Means                         #
 #                              #----+----+-----+------+---------------+---------------+---------------------+------------#
 #                              #    |    |     |      |               |               |                     |    95%     #
 #                              #    |    |     |      |               |               |                     +------+-----#
index 0deef6dad0424ad04d9fcbcf95a198604013b255..a228cffbdb8c7f3d55a3b046ba49a4b772fd844a 100755 (executable)
@@ -100,7 +100,7 @@ diff  -b $TEMPDIR/pspp.list - <<EOF
 #===========#=====================================================#======#==#===============#
 #           #                  Paired Differences                 |      |  |               #
 #           #-------+--------------+---------------+--------------+      |  |               #
-#           #       |              |               |     95%      |      |  |               #
+#           #       |              |               |95% Confidence|      |  |               #
 #           #       |              |               +-------+------+      |  |               #
 #           #  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
-#============================================#=========#==========#
-#                                            #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