[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pspp-cvs] pspp ./ChangeLog ./NEWS ./Smake config/ChangeLo...
From: |
Ben Pfaff |
Subject: |
[Pspp-cvs] pspp ./ChangeLog ./NEWS ./Smake config/ChangeLo... |
Date: |
Mon, 03 Apr 2006 20:07:55 +0000 |
CVSROOT: /cvsroot/pspp
Module name: pspp
Branch:
Changes by: Ben Pfaff <address@hidden> 06/04/03 20:07:55
Modified files:
. : ChangeLog NEWS Smake
config : ChangeLog automake.mk devices
doc : concept-index.texi configuring.texi
installing.texi pspp.texinfo
po : en_GB.po pspp.pot
src : procedure.c
src/language : ChangeLog line-buffer.c
src/language/data-io: data-list.c list.q print.c
src/language/dictionary: sys-file-info.c
src/language/stats: crosstabs.q descriptives.c examine.q
frequencies.q oneway.q regression.q t-test.q
src/libpspp : ChangeLog str.c str.h
src/output : ChangeLog ascii.c automake.mk html.c htmlP.h
manager.c output.c output.h postscript.c
table.c table.h
tests : ChangeLog
tests/bugs : examine-missing.sh
tests/command : examine-extremes.sh examine.sh oneway.sh
t-test-1-indep-val.sh t-test-pairs.sh
trimmed-mean.sh
Added files:
config/psfonts : Courier-Bold.afm Courier-BoldOblique.afm
Courier-Oblique.afm Courier.afm
Helvetica-Bold.afm Helvetica-BoldOblique.afm
Helvetica-Oblique.afm Helvetica.afm
Times-Bold.afm Times-BoldItalic.afm
Times-Italic.afm Times-Roman.afm
src/output : afm.c afm.h
Removed files:
config : html-prologue ps-prologue
src/output : font.h groff-font.c
Log message:
Clean up output subsystem.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/ChangeLog.diff?tr1=1.48&tr2=1.49&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/NEWS.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/Smake.diff?tr1=1.24&tr2=1.25&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/ChangeLog.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/automake.mk.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/devices.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Courier-Bold.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Courier-BoldOblique.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Courier-Oblique.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Courier.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Helvetica-Bold.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Helvetica-BoldOblique.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Helvetica-Oblique.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Helvetica.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Times-Bold.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Times-BoldItalic.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Times-Italic.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/config/psfonts/Times-Roman.afm?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/doc/concept-index.texi.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/doc/configuring.texi.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/doc/installing.texi.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/doc/pspp.texinfo.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/po/en_GB.po.diff?tr1=1.73&tr2=1.74&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/po/pspp.pot.diff?tr1=1.76&tr2=1.77&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/procedure.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/ChangeLog.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/line-buffer.c.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/data-io/data-list.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/data-io/list.q.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/data-io/print.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/dictionary/sys-file-info.c.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/stats/crosstabs.q.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/stats/descriptives.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/stats/examine.q.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/stats/frequencies.q.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/stats/oneway.q.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/stats/regression.q.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/language/stats/t-test.q.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/libpspp/ChangeLog.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/libpspp/str.c.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/libpspp/str.h.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/ChangeLog.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/afm.c?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/afm.h?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/ascii.c.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/automake.mk.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/html.c.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/htmlP.h.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/manager.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/output.c.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/output.h.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/postscript.c.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/table.c.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/output/table.h.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/ChangeLog.diff?tr1=1.52&tr2=1.53&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/examine-missing.sh.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/examine-extremes.sh.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/examine.sh.diff?tr1=1.14&tr2=1.15&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/oneway.sh.diff?tr1=1.16&tr2=1.17&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/t-test-1-indep-val.sh.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/t-test-pairs.sh.diff?tr1=1.12&tr2=1.13&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/trimmed-mean.sh.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
Patches:
Index: pspp/ChangeLog
diff -u pspp/ChangeLog:1.48 pspp/ChangeLog:1.49
--- pspp/ChangeLog:1.48 Thu Mar 30 23:51:01 2006
+++ pspp/ChangeLog Mon Apr 3 20:07:54 2006
@@ -1,3 +1,7 @@
+Mon Apr 3 11:01:00 2006 Ben Pfaff <address@hidden>
+
+ * Smake: (GNULIB_MODULES) Add strsep.
+
Thu Mar 30 15:50:05 2006 Ben Pfaff <address@hidden>
* Smake: Enable -Wdeclaration-after-statement warning if
Index: pspp/NEWS
diff -u pspp/NEWS:1.13 pspp/NEWS:1.14
--- pspp/NEWS:1.13 Sat Mar 4 00:28:15 2006
+++ pspp/NEWS Mon Apr 3 20:07:54 2006
@@ -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 address@hidden
+
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.
Changes since 0.4.0 to 0.4.1:
@@ -21,10 +38,10 @@
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
Index: pspp/Smake
diff -u pspp/Smake:1.24 pspp/Smake:1.25
--- pspp/Smake:1.24 Thu Mar 30 23:49:21 2006
+++ pspp/Smake Mon Apr 3 20:07:54 2006
@@ -35,6 +35,7 @@
strcspn \
strerror \
strftime \
+ strsep \
strstr \
strtod \
strtok_r \
Index: pspp/config/ChangeLog
diff -u pspp/config/ChangeLog:1.3 pspp/config/ChangeLog:1.4
--- pspp/config/ChangeLog:1.3 Sat Mar 4 00:28:15 2006
+++ pspp/config/ChangeLog Mon Apr 3 20:07:54 2006
@@ -1,3 +1,19 @@
+Mon Apr 3 11:01:16 2006 Ben Pfaff <address@hidden>
+
+ * 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 <address@hidden>
* html-prologue: Don't use ${source-file}, which is no longer
Index: pspp/config/automake.mk
diff -u pspp/config/automake.mk:1.1 pspp/config/automake.mk:1.2
--- pspp/config/automake.mk:1.1 Sat Mar 4 00:53:47 2006
+++ pspp/config/automake.mk Mon Apr 3 20:07:54 2006
@@ -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 @@
# 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: pspp/config/devices
diff -u pspp/config/devices:1.5 pspp/config/devices:1.6
--- pspp/config/devices:1.5 Wed Dec 31 06:40:48 2003
+++ pspp/config/devices Mon Apr 3 20:07:54 2006
@@ -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 @@
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:
Index: pspp/doc/concept-index.texi
diff -u pspp/doc/concept-index.texi:1.1 pspp/doc/concept-index.texi:1.2
--- pspp/doc/concept-index.texi:1.1 Sat Oct 30 10:14:05 2004
+++ pspp/doc/concept-index.texi Mon Apr 3 20:07:54 2006
@@ -1,4 +1,4 @@
address@hidden Concept Index, Installation, Command Index, Top
address@hidden Concept Index, Configuration, Command Index, Top
@chapter Concept Index
@printindex cp
@setfilename ignored
Index: pspp/doc/configuring.texi
diff -u pspp/doc/configuring.texi:1.6 pspp/doc/configuring.texi:1.7
--- pspp/doc/configuring.texi:1.6 Sun Dec 11 02:48:44 2005
+++ pspp/doc/configuring.texi Mon Apr 3 20:07:54 2006
@@ -1,18 +1,13 @@
address@hidden Configuration, Portable File Format, Installation, Top
address@hidden 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 address@hidden
+This chapter describe how to configure PSPP for your system.
@menu
* File locations:: How PSPP finds config files.
-* Configuration techniques:: Many different methods of address@hidden
+* 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 @@
* 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:
-
address@hidden
address@hidden
-The @dfn{base name} of the file being sought is determined.
-
address@hidden
-The path to search is determined.
-
address@hidden
-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.
address@hidden enumerate
-
-The first two steps are elaborated below for the sake of our pedantic
-friends.
-
address@hidden
address@hidden
-A @dfn{base name} is a file name lacking an absolute directory
-reference. Some examples of base names are: @file{ps-encodings},
address@hidden, @file{devps/DESC} (under UNIX), @file{devps\DESC} (under
-M$ environments).
-
-Determining the base name is a two-step process:
-
address@hidden a
address@hidden
-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}.
-
address@hidden
-Otherwise, the compiled-in default is used. For example, when searching
-for the output driver initialization file, the default base name is
address@hidden
address@hidden enumerate
-
address@hidden note:} If a user-specified base name does contain an
-absolute directory reference, as in a file name like
address@hidden/home/pfaff/fonts/TR}, no path is searched---the file name is used
-exactly as given---and the algorithm terminates.
-
address@hidden
-The path is the first of the following that is defined:
-
address@hidden @bullet
address@hidden
-A variable definition for the path given in the user environment. This
-is a PSPP-specific environment variable name; for instance,
address@hidden
-
address@hidden
-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.)
-
address@hidden
-The configuration file path, which is itself determined by the
-following rules:
-
address@hidden a
address@hidden
-If the command line contains an option of the form @samp{-B @var{path}}
-or @address@hidden, then the value given on the
-rightmost occurrence of such an option is used.
-
address@hidden
-Otherwise, if the environment variable @code{STAT_CONFIG_PATH} is
-defined, the value of that variable is used.
-
address@hidden
-Otherwise, the compiled-in fallback default is used. On UNIX machines,
-the default fallback path is
-
address@hidden 1
address@hidden
address@hidden/.pspp}
-
address@hidden
address@hidden/usr/local/lib/pspp}
-
address@hidden
address@hidden/usr/lib/pspp}
address@hidden enumerate
-
-On DOS machines, the default fallback path is:
-
address@hidden 1
address@hidden
-All the paths from the DOS search path in the @samp{PATH} environment
-variable, in left-to-right order.
-
address@hidden
address@hidden:\PSPP}, as a last resort.
address@hidden enumerate
-
-Note that the installer of PSPP can easily change this default
-fallback path; thus the above should not be taken as gospel.
address@hidden enumerate
address@hidden itemize
address@hidden 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
address@hidden/.pspp}, then the package system configuration directory (usually
address@hidden/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
address@hidden@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 @@
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
address@hidden Variable values, Environment substitutions, Environment
variables, Environment variables
address@hidden Values of environment variables
-
-Values for environment variables are obtained by the following means,
-which are arranged in order of decreasing precedence:
-
address@hidden
address@hidden
-Command-line options. @xref{Invocation}.
-
address@hidden
-The @file{environment} configuration file---more on this below.
-
address@hidden
-Actual environment variables (defined in the shell or other parent
-process).
address@hidden 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
address@hidden 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.
-
address@hidden is composed of lines having the form
address@hidden@address@hidden, 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.
-
address@hidden
address@hidden note:} Support for @file{environment} is not yet
-implemented.
address@hidden quotation
-
address@hidden Environment substitutions, Predefined variables, Variable
values, Environment variables
address@hidden 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 @@
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 address@hidden
-Replaced by the value of environment variable @var{var}, determined as
-specified in @ref{Variable values}. @var{var} must be one of the
-following:
-
address@hidden @bullet
address@hidden
-One or more letters.
-
address@hidden
-Exactly one nonalphabetic character. This may not be a left brace
-(@address@hidden).
address@hidden 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 (@address@hidden).
@item address@hidden@address@hidden
Same as above, but @var{var} may contain any character (except
@@ -737,34 +575,9 @@
@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,
address@hidden, 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.
+acceptable to PostScript printers and other interpreters.
-The PostScript driver is described in further detail below.
-
address@hidden
-* 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.
address@hidden menu
-
address@hidden PS output options, PS page options, PostScript driver class,
PostScript driver class
address@hidden PostScript output options
-
-These options deal with the form of the output and the output file
-itself:
+The available options are listed below.
@table @code
@item address@hidden
@@ -773,57 +586,6 @@
(i.e., @code{"pspp.ps"}), a pipe filename (i.e., @code{"|lpr"}), or
stdout (@code{"-"}). Default: @code{"pspp.ps"}.
address@hidden address@hidden
-
-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},
address@hidden, and nonzero integers. Negative boolean values are
address@hidden, @samp{false}, @samp{no}, and zero.
-
address@hidden address@hidden
-
-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}.
-
address@hidden address@hidden
-
-One of @code{cr}, @code{lf}, or @code{crlf}. This controls what is used
-for new-line in the output file. Default: @code{cr}.
-
address@hidden address@hidden
-
-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
address@hidden of @code{0} has the advantage of being better for
-interactive environments. @code{1} is the default unless the
address@hidden flag is set; in that case, the default is @code{0}.
-
address@hidden address@hidden
-
-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}.
address@hidden table
-
address@hidden PS page options, PS file options, PS output options, PostScript
driver class
address@hidden PostScript page options
-
-These options affect page setup:
-
address@hidden @code
@item address@hidden
Controls whether the standard headers showing the time and date and
@@ -849,355 +611,58 @@
included in the margins; they are in addition to the margins. For a
description of dimensions, see @ref{Dimensions}. Default: @code{0.5in}.
address@hidden table
-
address@hidden PS file options, PS font options, PS page options, PostScript
driver class
address@hidden 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 address@hidden
-
-First let's look at the options that are available:
-
address@hidden @code
-
address@hidden address@hidden
-
-Sets the font directory. Default: @code{devps}.
-
address@hidden address@hidden
-
-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}.
-
address@hidden address@hidden
-
-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}.
-
address@hidden address@hidden
-
-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:
address@hidden
-
-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.
-
address@hidden address@hidden
-
-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}.
-
address@hidden 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:
-
address@hidden
-
address@hidden
-Constructs a path by taking the first of the following that is defined:
-
address@hidden a
-
address@hidden
-Environment variable @code{STAT_GROFF_FONT_PATH}. @xref{Environment
-variables}.
-
address@hidden
-Environment variable @code{GROFF_FONT_PATH}.
-
address@hidden
-The compiled-in fallback default.
address@hidden enumerate
-
address@hidden
-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}.
address@hidden address@hidden,@var{font-file}[,@var{encoding-file}]]
address@hidden address@hidden,@var{font-file}[,@var{encoding-file}]]
address@hidden address@hidden,@var{font-file}[,@var{encoding-file}]]
+
+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.
+
+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.
+
+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
address@hidden are also allowed.
+
+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}).
address@hidden
-Searches for the base name in the path constructed above. If the file
-is found, the algorithm terminates.
-
address@hidden
-Searches for the base name in the standard configuration path. See
address@hidden locations}, for more details. If the file is found, the
-algorithm terminates.
-
address@hidden
-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.,
address@hidden
-
address@hidden
-Searches for the base name in the path constructed in the first step.
-If the file is found, the algorithm terminates.
-
address@hidden
-Searches for the base name in the standard configuration path. If the
-file is found, the algorithm terminates.
-
address@hidden
-The algorithm terminates unsuccessfully.
address@hidden 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.
-
address@hidden PS font options, PS line options, PS file options, PostScript
driver class
address@hidden PostScript font options
-
-The list of available font options is short and sweet:
-
address@hidden @code
address@hidden address@hidden
-
-Sets the default proportional font. The name should be that of a
-PostScript font. Default: @code{"Helvetica"}.
-
address@hidden address@hidden
-
-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
address@hidden, fixed-pitch font @code{Courier.afm}.
@item address@hidden
Sets the size of the default fonts, in thousandths of a point. Default:
address@hidden
-
address@hidden table
-
address@hidden PS line options, Prologue, PS font options, PostScript driver
class
address@hidden 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:
-
address@hidden @code
-
address@hidden address@hidden
-
-Sets the style used for lines used to divide tables into sections.
address@hidden must be either @code{thick}, in which case thick lines are
-used, or @var{double}, in which case double lines are used. Default:
address@hidden
+10000 (10 point).
@item address@hidden
-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 address@hidden
-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:
address@hidden
+Sets the spacing between the lines in a double line in a table.
+Default: @code{1pt}.
@item address@hidden
-Sets the width of a typical line used in tables. Default: @code{0.5pt}.
-
address@hidden address@hidden
-
-Sets the width of a thick line used in tables. Not used if
address@hidden is set to @code{thick}. Default: @code{1.5pt}.
-
address@hidden table
-
address@hidden Prologue, Encodings, PS line options, PostScript driver class
address@hidden 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:
-
address@hidden
address@hidden
-All lines that contain three bangs in a row (@code{!!!}).
-
address@hidden
-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
address@hidden is deleted.
-
address@hidden
-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.
address@hidden enumerate
-
-The following are the variables that are substituted. Only the
-variables listed are substituted; environment variables are not.
address@hidden substitutions}.
-
address@hidden @code
address@hidden 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}.
-
address@hidden creator
-
-PSPP version as a string: @samp{GNU PSPP 0.1b}, for example.
-
address@hidden date
-
-Date the file was created. Example: @samp{Tue May 21 13:46:22 1991}.
-
address@hidden data
-
-Value of the @code{data} PostScript driver option, as one of the strings
address@hidden, @samp{Clean8Bit}, or @samp{Binary}.
-
address@hidden orientation
-
-Page orientation, as one of the strings @code{Portrait} or
address@hidden
-
address@hidden 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}.
-
address@hidden host
-
-System hostname as reported by @code{gethostname()}. Defaults to
address@hidden
-
address@hidden prop-font
-
-Name of the default proportional font, prefixed by the word
address@hidden and a space. Example: @samp{font Times-Roman}.
-
address@hidden fixed-font
-
-Name of the default fixed-pitch font, prefixed by the word @samp{font}
-and a space.
-
address@hidden scale-factor
-
-The page scaling factor as a floating-point number. Example:
address@hidden Note that this is also passed as an argument to the BP
-macro.
-
address@hidden paper-length
address@hidden 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.
-
address@hidden left-margin
address@hidden 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.
-
address@hidden 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>)}.
-
address@hidden source-file
-
-PSPP syntax file name. Example: @samp{mary96/first.stat}.
-
+Sets the width of the lines used in tables. Default: @code{0.5pt}.
@end table
-Any other questions about the PostScript prologue can best be answered
-by examining the default prologue or the PSPP source.
-
address@hidden Encodings, , Prologue, PostScript driver class
address@hidden 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
address@hidden an error if an encoding is used but not included by one of
-these mechanisms. In this case, the built-in PostScript encoding
address@hidden 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
address@hidden
address@hidden
-* ASCII output options:: Output file options.
-* ASCII page options:: Page size, margins, more.
-* ASCII font options:: Box character, bold & italics.
address@hidden menu
-
address@hidden ASCII output options, ASCII page options, ASCII driver class,
ASCII driver class
address@hidden ASCII output options
+The available options are listed below.
@table @code
@item address@hidden
@@ -1206,55 +671,16 @@
(e.g., @code{"pspp.txt"}), a pipe filename (e.g., @code{"|lpr"}), or
stdout (@code{"-"}). Default: @code{"pspp.list"}.
address@hidden address@hidden
-
-One of @samp{ascii} or @samp{latin1}. This has no effect on output at
-the present time. Default: @code{ascii}.
-
address@hidden address@hidden
-
-The string written to the output to cause a formfeed. See also
address@hidden, described below, for a related setting. Default:
address@hidden"\f"}.
-
address@hidden address@hidden
-
-The string written to the output to cause a new-line (carriage return
-plus linefeed). The default, which can be specified explicitly with
address@hidden, 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 address@hidden
-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:
address@hidden
@item address@hidden
The distance between tab stops for this device. If set to 0, tabs will
not be used in the output. Default: @code{8}.
address@hidden address@hidden
-
-String written to the device before anything else, at the beginning of
-the output. Default: @code{""} (the empty string).
-
address@hidden address@hidden
-
-String written to the device after everything else, at the end of the
-output. Default: @code{""} (the empty string).
address@hidden table
-
address@hidden ASCII page options, ASCII font options, ASCII output options,
ASCII driver class
address@hidden ASCII page options
-
-These options affect page setup:
-
address@hidden @code
@item address@hidden
If enabled, two lines of header information giving title and subtitle,
@@ -1272,25 +698,6 @@
Physical width of a page, in characters. Margins are subtracted from
this value. Default: @code{130}.
address@hidden address@hidden
-
-Number of lines per vertical inch. Not currently used. Default: @code{6}.
-
address@hidden address@hidden
-
-Number of characters per horizontal inch. Not currently used. Default:
address@hidden
-
address@hidden address@hidden
-
-Width of the left margin, in characters. PSPP subtracts this value
-from the page width. Default: @code{0}.
-
address@hidden address@hidden
-
-Width of the right margin, in characters. PSPP subtracts this value
-from the page width. Default: @code{0}.
-
@item address@hidden
Length of the top margin, in lines. PSPP subtracts this value from
@@ -1301,14 +708,6 @@
Length of the bottom margin, in lines. PSPP subtracts this value from
the page length. Default: @code{2}.
address@hidden table
-
address@hidden ASCII font options, , ASCII page options, ASCII driver class
address@hidden ASCII font options
-
-These are the ASCII font options:
-
address@hidden @code
@item address@hidden@var{box-chars}
The characters used for lines in tables produced by the ASCII driver can
@@ -1316,9 +715,8 @@
type of line to change; @var{box-chars} is the character or string of
characters to use for this type of line.
address@hidden 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:
address@hidden 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 @@
@item 2
Double line.
-
address@hidden 3
-Special device-defined line, if one is available; otherwise, a double
-line.
@end table
Examples:
@@ -1378,112 +772,21 @@
@address@hidden"="}
@item
address@hidden"#"}
address@hidden@code{box[0002]="#"}
address@hidden@code{box[0202]="#"}
-
address@hidden
@code{box[3000]="="}
@address@hidden"="}
@address@hidden"="}
@item
address@hidden"#"}
address@hidden@code{box[0003]="#"}
address@hidden@code{box[0303]="#"}
-
address@hidden
For all others, @samp{+} is used unless there are double lines or
special lines, in which case @samp{#} is used.
@end itemize
address@hidden address@hidden
-
-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
address@hidden Default: @code{overstrike}.
-
address@hidden address@hidden
-
-Character sequence to turn off italics or underline printing. Default:
address@hidden""} (the empty string).
-
address@hidden address@hidden
-
-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
address@hidden and @code{carriage-return-style}. Default:
address@hidden
-
address@hidden address@hidden
-
-Character sequence to turn off bold or emphasized printing. Default:
address@hidden""} (the empty string).
-
address@hidden address@hidden
address@hidden address@hidden
-Character sequence written to turn on bold-italic printing. If set to
address@hidden, 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
address@hidden and @code{carriage-return-style}. Default:
address@hidden
-
address@hidden address@hidden
-
-Character sequence to turn off bold-italic printing. Default: @code{""}
-(the empty string).
-
address@hidden address@hidden
-
-Either @code{single} or @code{line}:
-
address@hidden @bullet
address@hidden
-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.
-
address@hidden
-If @code{line} is selected then the output driver will output an entire
-line, then backspace or emit a carriage return (as indicated by
address@hidden), then overstrike the entire line at once.
address@hidden itemize
-
address@hidden is recommended for use with ttys and programs that
-understand overstriking in text files, such as the pager @code{less}.
address@hidden 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!
-
address@hidden is recommended for use with printer devices. Most programs
-that understand overstriking in text files will not properly deal with
address@hidden mode.
-
-Default: @code{single}.
-
address@hidden address@hidden
-
-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}.
-
address@hidden @bullet
address@hidden
-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).
-
address@hidden
-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).
address@hidden 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 @@
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 address@hidden
@@ -1502,87 +805,9 @@
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"}.
-
address@hidden address@hidden
-
-Sets the name of the PostScript prologue file. You can write your own
-prologue if you want to customize colors or other settings: see
address@hidden Prologue}. Default: @code{html-prologue}.
@end table
address@hidden
-* HTML Prologue:: Format of the HTML prologue file.
address@hidden menu
-
address@hidden HTML Prologue, , HTML driver class, HTML driver class
address@hidden 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:
-
address@hidden
address@hidden
-All lines that contain three bangs in a row (@code{!!!}).
-
address@hidden
-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.
-
address@hidden
-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.
address@hidden enumerate
-
-The following are the variables that are substituted. Only the
-variables listed are substituted; environment variables are not.
address@hidden substitutions}.
-
address@hidden @code
address@hidden generator
-
-PSPP version as a string: @samp{GNU PSPP 0.1b}, for example.
-
address@hidden date
-
-Date the file was created. Example: @samp{Tue May 21 13:46:22 1991}.
-
address@hidden 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}.
-
address@hidden host
-
-System hostname as reported by @code{gethostname()}. Defaults to
address@hidden
-
address@hidden title
-
-Document title as a string. This is the title specified in the PSPP
-syntax file.
-
address@hidden subtitle
-
-Document subtitle as a string.
-
address@hidden source-file
-
-PSPP syntax file name. Example: @samp{mary96/first.stat}.
address@hidden table
-
address@hidden Miscellaneous configuring, Improving output quality, HTML driver
class, Configuration
address@hidden Miscellaneous configuring,, HTML driver class, Configuration
@section Miscellaneous configuration
The following environment variables can be used to further configure
@@ -1670,66 +895,3 @@
Under MS-DOS only, these variables are consulted after TMPDIR, in this
order.
@end table
-
address@hidden Improving output quality, , Miscellaneous configuring,
Configuration
address@hidden 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.
-
address@hidden @bullet
address@hidden
-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:
-
address@hidden @minus
address@hidden
-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.
-
address@hidden
-With the PostScript driver, try these ideas:
-
address@hidden +
address@hidden
-Landscape mode.
-
address@hidden
-Legal-size (8.5" x 14") paper in landscape mode.
-
address@hidden
-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.
address@hidden itemize
address@hidden itemize
-
-Try to strike a balance between character size and page width.
-
address@hidden
-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.
-
address@hidden
-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.
-
address@hidden
-Make sure that you're using good ink/ribbon/toner. Darker print is
-easier to read.
-
address@hidden
-Use plain fonts with serifs, such as Times-Roman or Palatino. Avoid
-choosing italic or bold fonts as document base fonts.
address@hidden itemize
address@hidden ignored
Index: pspp/doc/installing.texi
diff -u pspp/doc/installing.texi:1.1 pspp/doc/installing.texi:1.2
--- pspp/doc/installing.texi:1.1 Sat Oct 30 10:14:05 2004
+++ pspp/doc/installing.texi Mon Apr 3 20:07:54 2006
@@ -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:
-
address@hidden @bullet
address@hidden
-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.
-
address@hidden
-The @code{int} type must be 32 bits or wider.
-
address@hidden
-The recommended compiler is gcc 2.7.2.1 or later, but any ANSI compiler
-will do if it fits the above criteria.
address@hidden 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.
-
address@hidden
-* UNIX installation:: Installing on UNIX-like environments.
address@hidden menu
-
address@hidden UNIX installation, , Installation, Installation
address@hidden UNIX installation
address@hidden UNIX, installing PSPP under
address@hidden installation, under UNIX
address@hidden
-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 @@
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
address@hidden, 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.
-
address@hidden @file{Makefile}
address@hidden @file{config.h}
address@hidden @file{pref.h}
address@hidden makefile
address@hidden
-(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.
-
address@hidden 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: pspp/doc/pspp.texinfo
diff -u pspp/doc/pspp.texinfo:1.5 pspp/doc/pspp.texinfo:1.6
--- pspp/doc/pspp.texinfo:1.5 Sat Apr 16 01:39:25 2005
+++ pspp/doc/pspp.texinfo Mon Apr 3 20:07:54 2006
@@ -86,7 +86,6 @@
* 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 @@
@include command-index.texi
@include concept-index.texi
address@hidden installing.texi
@include configuring.texi
@include portable-file-format.texi
Index: pspp/po/en_GB.po
diff -u pspp/po/en_GB.po:1.73 pspp/po/en_GB.po:1.74
--- pspp/po/en_GB.po:1.73 Tue Mar 28 06:05:05 2006
+++ pspp/po/en_GB.po Mon Apr 3 20:07:54 2006
@@ -7,7 +7,7 @@
msgstr ""
"Project-Id-Version: PSPP 0.3.1\n"
"Report-Msgid-Bugs-To: address@hidden"
-"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 <address@hidden>\n"
"Language-Team: John Darrington <address@hidden>\n"
@@ -1038,7 +1038,7 @@
#: 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 @@
"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 @@
"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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
" -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 @@
"\n"
msgstr ""
-#: src/ui/terminal/command-line.c:249
+#: src/ui/terminal/command-line.c:247
#, c-format
msgid ""
"\n"
Index: pspp/po/pspp.pot
diff -u pspp/po/pspp.pot:1.76 pspp/po/pspp.pot:1.77
--- pspp/po/pspp.pot:1.76 Tue Mar 28 06:05:06 2006
+++ pspp/po/pspp.pot Mon Apr 3 20:07:54 2006
@@ -8,7 +8,7 @@
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: address@hidden"
-"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 <address@hidden>\n"
"Language-Team: LANGUAGE <address@hidden>\n"
@@ -1039,7 +1039,7 @@
#: 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 @@
"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 @@
"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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
" -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 @@
"\n"
msgstr ""
-#: src/ui/terminal/command-line.c:249
+#: src/ui/terminal/command-line.c:247
#, c-format
msgid ""
"\n"
Index: pspp/src/language/ChangeLog
diff -u pspp/src/language/ChangeLog:1.1 pspp/src/language/ChangeLog:1.2
--- pspp/src/language/ChangeLog:1.1 Sat Mar 4 01:11:57 2006
+++ pspp/src/language/ChangeLog Mon Apr 3 20:07:54 2006
@@ -1,3 +1,14 @@
+Mon Apr 3 11:03:36 2006 Ben Pfaff <address@hidden>
+
+ * 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 <address@hidden>
* Moved files from src directory
Index: pspp/src/language/data-io/data-list.c
diff -u pspp/src/language/data-io/data-list.c:1.3
pspp/src/language/data-io/data-list.c:1.4
--- pspp/src/language/data-io/data-list.c:1.3 Wed Mar 15 03:29:10 2006
+++ pspp/src/language/data-io/data-list.c Mon Apr 3 20:07:54 2006
@@ -792,12 +792,12 @@
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 @@
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: pspp/src/language/data-io/list.q
diff -u pspp/src/language/data-io/list.q:1.4
pspp/src/language/data-io/list.q:1.5
--- pspp/src/language/data-io/list.q:1.4 Wed Mar 15 03:29:10 2006
+++ pspp/src/language/data-io/list.q Mon Apr 3 20:07:54 2006
@@ -115,10 +115,12 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
if (width <= max_width)
{
prc->header_rows = 2;
- d->class->text_set_font_by_name (d, "FIXED");
continue;
}
@@ -593,8 +587,6 @@
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 @@
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 @@
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 @@
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: pspp/src/language/data-io/print.c
diff -u pspp/src/language/data-io/print.c:1.3
pspp/src/language/data-io/print.c:1.4
--- pspp/src/language/data-io/print.c:1.3 Wed Mar 15 03:29:10 2006
+++ pspp/src/language/data-io/print.c Mon Apr 3 20:07:54 2006
@@ -810,12 +810,12 @@
{
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 @@
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 @@
}
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 @@
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: pspp/src/language/dictionary/sys-file-info.c
diff -u pspp/src/language/dictionary/sys-file-info.c:1.2
pspp/src/language/dictionary/sys-file-info.c:1.3
--- pspp/src/language/dictionary/sys-file-info.c:1.2 Wed Mar 15 03:29:10 2006
+++ pspp/src/language/dictionary/sys-file-info.c Mon Apr 3 20:07:54 2006
@@ -96,7 +96,7 @@
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 @@
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 @@
&& 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: pspp/src/language/line-buffer.c
diff -u pspp/src/language/line-buffer.c:1.2 pspp/src/language/line-buffer.c:1.3
--- pspp/src/language/line-buffer.c:1.2 Wed Mar 15 03:29:10 2006
+++ pspp/src/language/line-buffer.c Mon Apr 3 20:07:54 2006
@@ -465,7 +465,7 @@
/* 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: pspp/src/language/stats/crosstabs.q
diff -u pspp/src/language/stats/crosstabs.q:1.4
pspp/src/language/stats/crosstabs.q:1.5
--- pspp/src/language/stats/crosstabs.q:1.4 Tue Mar 28 00:02:28 2006
+++ pspp/src/language/stats/crosstabs.q Mon Apr 3 20:07:54 2006
@@ -809,7 +809,7 @@
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 @@
}
strcpy (cp, "].");
- tab_title (table, 0, title);
+ tab_title (table, "%s", title);
local_free (title);
}
@@ -1104,7 +1104,7 @@
(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 @@
{
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 @@
{
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 @@
{
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 @@
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 @@
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: pspp/src/language/stats/descriptives.c
diff -u pspp/src/language/stats/descriptives.c:1.3
pspp/src/language/stats/descriptives.c:1.4
--- pspp/src/language/stats/descriptives.c:1.3 Wed Mar 15 03:29:11 2006
+++ pspp/src/language/stats/descriptives.c Mon Apr 3 20:07:54 2006
@@ -540,7 +540,7 @@
}
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 @@
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: pspp/src/language/stats/examine.q
diff -u pspp/src/language/stats/examine.q:1.3
pspp/src/language/stats/examine.q:1.4
--- pspp/src/language/stats/examine.q:1.3 Wed Mar 15 03:29:11 2006
+++ pspp/src/language/stats/examine.q Mon Apr 3 20:07:54 2006
@@ -914,7 +914,7 @@
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 @@
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 @@
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 @@
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: pspp/src/language/stats/frequencies.q
diff -u pspp/src/language/stats/frequencies.q:1.3
pspp/src/language/stats/frequencies.q:1.4
--- pspp/src/language/stats/frequencies.q:1.3 Wed Mar 15 03:29:11 2006
+++ pspp/src/language/stats/frequencies.q Mon Apr 3 20:07:54 2006
@@ -1214,7 +1214,7 @@
}
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 @@
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 @@
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 @@
}
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 @@
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 @@
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: pspp/src/language/stats/oneway.q
diff -u pspp/src/language/stats/oneway.q:1.3
pspp/src/language/stats/oneway.q:1.4
--- pspp/src/language/stats/oneway.q:1.3 Wed Mar 15 03:29:11 2006
+++ pspp/src/language/stats/oneway.q Mon Apr 3 20:07:54 2006
@@ -355,7 +355,7 @@
}
- tab_title (t, 0, _("ANOVA"));
+ tab_title (t, _("ANOVA"));
tab_submit (t);
@@ -412,7 +412,7 @@
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 @@
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 @@
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 @@
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: pspp/src/language/stats/regression.q
diff -u pspp/src/language/stats/regression.q:1.5
pspp/src/language/stats/regression.q:1.6
--- pspp/src/language/stats/regression.q:1.5 Thu Mar 16 15:07:04 2006
+++ pspp/src/language/stats/regression.q Mon Apr 3 20:07:54 2006
@@ -150,7 +150,7 @@
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 @@
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 @@
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 @@
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: pspp/src/language/stats/t-test.q
diff -u pspp/src/language/stats/t-test.q:1.3
pspp/src/language/stats/t-test.q:1.4
--- pspp/src/language/stats/t-test.q:1.3 Wed Mar 15 03:29:11 2006
+++ pspp/src/language/stats/t-test.q Mon Apr 3 20:07:54 2006
@@ -677,7 +677,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
_("%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 @@
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: pspp/src/libpspp/ChangeLog
diff -u pspp/src/libpspp/ChangeLog:1.6 pspp/src/libpspp/ChangeLog:1.7
--- pspp/src/libpspp/ChangeLog:1.6 Fri Mar 31 18:38:59 2006
+++ pspp/src/libpspp/ChangeLog Mon Apr 3 20:07:54 2006
@@ -1,3 +1,10 @@
+Mon Apr 3 11:10:21 2006 Ben Pfaff <address@hidden>
+
+ * 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 <address@hidden>
Add freaderror() analogous to fwriteerror() in gnulib.
Index: pspp/src/libpspp/str.c
diff -u pspp/src/libpspp/str.c:1.4 pspp/src/libpspp/str.c:1.5
--- pspp/src/libpspp/str.c:1.4 Fri Mar 31 00:30:22 2006
+++ pspp/src/libpspp/str.c Mon Apr 3 20:07:54 2006
@@ -431,7 +431,7 @@
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 @@
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: pspp/src/libpspp/str.h
diff -u pspp/src/libpspp/str.h:1.5 pspp/src/libpspp/str.h:1.6
--- pspp/src/libpspp/str.h:1.5 Fri Mar 31 00:30:22 2006
+++ pspp/src/libpspp/str.h Mon Apr 3 20:07:54 2006
@@ -144,7 +144,9 @@
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: pspp/src/output/ChangeLog
diff -u pspp/src/output/ChangeLog:1.5 pspp/src/output/ChangeLog:1.6
--- pspp/src/output/ChangeLog:1.5 Fri Mar 31 00:30:22 2006
+++ pspp/src/output/ChangeLog Mon Apr 3 20:07:54 2006
@@ -1,3 +1,120 @@
+Mon Apr 3 11:14:38 2006 Ben Pfaff <address@hidden>
+
+ 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 <address@hidden>
* output.c: (colon_tokenize) Removed.
Index: pspp/src/output/ascii.c
diff -u pspp/src/output/ascii.c:1.4 pspp/src/output/ascii.c:1.5
--- pspp/src/output/ascii.c:1.4 Wed Mar 15 03:29:11 2006
+++ pspp/src/output/ascii.c Mon Apr 3 20:07:54 2006
@@ -18,92 +18,49 @@
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 @@
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 @@
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};
+static int get_default_box_char (size_t idx);
+static bool handle_option (struct outp_driver *this, const char *key,
+ const struct string *val);
- assert (n_valid_sizes);
- *n_valid_sizes = 1;
- return valid_sizes;
-}
-
-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++)
- {
- 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;
-
- case TAYSTE2BYTE (0, 1, 0, 0):
- case TAYSTE2BYTE (0, 1, 0, 1):
- case TAYSTE2BYTE (0, 0, 0, 1):
- c[0] = '-';
- break;
- case TAYSTE2BYTE (1, 0, 0, 0):
- case TAYSTE2BYTE (1, 0, 1, 0):
- case TAYSTE2BYTE (0, 0, 1, 0):
- c[0] = '|';
- break;
-
- 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;
-
- 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;
-
- 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++)
+ for (i = 0; i < LNS_COUNT; i++)
+ if (x->box[i] == NULL)
{
- this->horiz_line_spacing[i] = (i & ~1) ? this->vert : 0;
- this->vert_line_spacing[i] = (i & ~1) ? this->horiz : 0;
+ char s[2];
+ s[0] = get_default_box_char (i);
+ s[1] = '\0';
+ x->box[i] = pool_strdup (x->pool, s);
}
- }
- this->driver_open = 1;
- msg (VM (2), _("%s: Initialization complete."), this->name);
+ return true;
- return 1;
+ error:
+ pool_destroy (x->pool);
+ return false;
}
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;
+
+ /* 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 0x0100: case 0x0101: case 0x0001:
+ return '-';
+
+ case 0x1000: case 0x1010: case 0x0010:
+ return '|';
+
+ case 0x0300: case 0x0303: case 0x0003:
+ case 0x0200: case 0x0202: case 0x0002:
+ return '=';
+
+ default:
+ return left > 1 || top > 1 || right > 1 || bottom > 1 ? '#' : '+';
+ }
+}
+
+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);
+ 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);
- 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);
-
- 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 @@
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);
- 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);
+ case -1:
+ error (0, 0, _("ascii: unknown parameter `%s'"), key);
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 @@
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 @@
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 @@
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 @@
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);
-}
+ int x;
-/* 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);
-}
-
-/* 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;
-
- /* Maximum `y' position we can write to. */
- int max_y;
+ int max_width;
+ int height_left;
- /* Current position in string, character following end of string. */
- const char *s = ls_c_str (&t->s);
- const char *end = ls_end (&t->s);
+ const char *cp = ls_c_str (&text->string);
- /* Temporary struct outp_text to pass to low-level function. */
- struct outp_text temp;
+ max_width = 0;
+ height_left = text->v;
-#if DEBUGGING && 0
- if (!ext->debug)
+ while (height_left > 0)
{
- ext->debug = 1;
- printf (_("%s: horiz=%d, vert=%d\n"), this->name, this->horiz,
this->vert);
- }
-#endif
-
- if (!width)
- {
- 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;
- }
-}
/* 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++)
+ 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++)
{
- memcpy (cp, ls_c_str (&x->ops[OPS_NEWLINE]), nl_len);
- cp += nl_len;
+
+ /* 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 @@
{
"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 @@
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: pspp/src/output/automake.mk
diff -u pspp/src/output/automake.mk:1.2 pspp/src/output/automake.mk:1.3
--- pspp/src/output/automake.mk:1.2 Wed Mar 15 03:29:11 2006
+++ pspp/src/output/automake.mk Mon Apr 3 20:07:54 2006
@@ -6,9 +6,9 @@
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 \
Index: pspp/src/output/html.c
diff -u pspp/src/output/html.c:1.6 pspp/src/output/html.c:1.7
--- pspp/src/output/html.c:1.6 Tue Mar 28 06:05:07 2006
+++ pspp/src/output/html.c Mon Apr 3 20:07:54 2006
@@ -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"
@@ -42,361 +43,137 @@
#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_name = xstrdup ("pspp.html");
+ x->file = 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;
+ outp_parse_options (options, handle_option, this);
- x->sequence_no = 0;
-
- 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 @@
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 @@
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 " ". */
static void
-escape_string (FILE *f, char *s, int len)
+escape_string (FILE *file,
+ const char *text, size_t length,
+ const char *space)
+{
+ while (length-- > 0)
+ {
+ char c = *text++;
+ switch (c)
+ {
+ case '&':
+ fputs ("&", file);
+ break;
+ case '<':
+ fputs ("<", file);
+ break;
+ case '>':
+ fputs (">", 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)
{
- char *ep = &s[len];
- char *bp, *cp;
+ struct html_driver_ext *x = this->ext;
- for (bp = cp = s; bp < ep; bp = cp)
+ if (!(opts & TAB_EMPTY))
{
- while (cp < ep && *cp != '&' && *cp != '<' && *cp != '>' && *cp)
- cp++;
- if (cp > bp)
- fwrite (bp, 1, cp - bp, f);
- if (cp < ep)
- switch (*cp++)
- {
- case '&':
- fputs ("&", f);
- break;
- case '<':
- fputs ("<", f);
- break;
- case '>':
- fputs (">", f);
- break;
- case 0:
- break;
- default:
- assert (0);
- }
+ 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), " ");
+ 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 @@
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 @@
{
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 @@
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;
+ fprintf (x->file, " ROWSPAN=%d", j->y2 - j->y1);
}
-
- strcpy (cp, ">");
- fputs (header, x->file.file);
-
- if ( ! (*ct & TAB_EMPTY) )
- {
- char *s = ls_c_str (cc);
- size_t l = ls_length (cc);
+ putc ('>', x->file);
- while (l && isspace ((unsigned char) *s))
- {
- l--;
- s++;
- }
-
- escape_string (x->file.file, s, l);
- }
+ /* 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 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",
+ 1,
- html_initialise_chart,
- html_finalise_chart
+ html_open_driver,
+ html_close_driver,
-};
+ NULL,
+ NULL,
+
+ html_submit,
+
+ NULL,
+ NULL,
+ NULL,
+ html_initialise_chart,
+ html_finalise_chart
+ };
Index: pspp/src/output/htmlP.h
diff -u pspp/src/output/htmlP.h:1.2 pspp/src/output/htmlP.h:1.3
--- pspp/src/output/htmlP.h:1.2 Wed Mar 15 03:29:11 2006
+++ pspp/src/output/htmlP.h Mon Apr 3 20:07:54 2006
@@ -25,14 +25,14 @@
/* 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: pspp/src/output/manager.c
diff -u pspp/src/output/manager.c:1.3 pspp/src/output/manager.c:1.4
--- pspp/src/output/manager.c:1.3 Wed Mar 15 03:29:11 2006
+++ pspp/src/output/manager.c Mon Apr 3 20:07:54 2006
@@ -147,13 +147,7 @@
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: pspp/src/output/output.c
diff -u pspp/src/output/output.c:1.7 pspp/src/output/output.c:1.8
--- pspp/src/output/output.c:1.7 Fri Mar 31 00:30:22 2006
+++ pspp/src/output/output.c Mon Apr 3 20:07:54 2006
@@ -68,6 +68,13 @@
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 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 @@
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 @@
{
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 @@
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 @@
goto exit;
}
- msg (VM (1), _("%s: Opening device description file..."), init_fn);
f = fopen (init_fn, "r");
if (f == NULL)
{
@@ -344,7 +351,6 @@
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 @@
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 @@
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 @@
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))
- {
- msg (IS, _("Can't complete initialization of output driver `%s' of "
- "class `%s'."), d->name, d->class->name);
- goto error;
+
+ /* 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 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 @@
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 @@
}
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 @@
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 @@
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 @@
goto exit;
}
- msg (VM (1), _("%s: Opening paper size definition file..."), pprsz_fn);
f = fopen (pprsz_fn, "r");
if (!f)
{
@@ -1211,9 +1130,7 @@
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 @@
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 @@
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: pspp/src/output/output.h
diff -u pspp/src/output/output.h:1.2 pspp/src/output/output.h:1.3
--- pspp/src/output/output.h:1.2 Wed Mar 15 03:29:11 2006
+++ pspp/src/output/output.h Mon Apr 3 20:07:54 2006
@@ -25,91 +25,39 @@
#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
- {
- 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
+enum outp_font
{
- 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 @@
/* 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 @@
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 @@
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_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: pspp/src/output/postscript.c
diff -u pspp/src/output/postscript.c:1.8 pspp/src/output/postscript.c:1.9
--- pspp/src/output/postscript.c:1.8 Fri Mar 31 00:30:22 2006
+++ pspp/src/output/postscript.c Mon Apr 3 20:07:54 2006
@@ -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 <address@hidden>.
This program is free software; you can redistribute it and/or
@@ -20,502 +20,250 @@
#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
+/* A PostScript font. */
+struct font
{
- struct font_entry *font; /* Font. */
- int size; /* Font size. */
- int index; /* PostScript index. */
- };
-
-/* A font encoding. */
-struct ps_encoding
- {
- 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 dump_lines (struct outp_driver *this);
-
-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 void write_ps_prologue (struct outp_driver *);
-static char *quote_ps_name (char *dest, const char *string);
-static char *quote_ps_string (char *dest, const char *string);
+static char *quote_ps_name (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);
/* 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");
-
- if (x->prop_family == NULL)
- x->prop_family = xstrdup ("H");
- if (x->fixed_family == NULL)
- x->fixed_family = xstrdup ("C");
-
- read_ps_encodings (this);
- x->family = NULL;
- x->size = PSUS / 6;
+ 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 (this->length / x->font_size < 15)
+ if (this->length / this->font_height < 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;
+ 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;
}
- this->driver_open = 1;
- msg (VM (2), _("%s: Initialization complete."), this->name);
-
- return 1;
+ 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;
+
+ 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);
+
+ write_ps_prologue (this);
+
+ return true;
+
+ 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;
+ bool ok;
+ size_t 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);
+ 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 @@
/* 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 output_file_arg:
+ free (x->file_name);
+ x->file_name = xstrdup (value);
break;
- case 1:
- free (x->file.filename);
- x->file.filename = 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 @@
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 @@
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 @@
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;
+ }
}
-/* 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);
-}
-
-/* Hash table hash function for ps_encoding's. */
-static unsigned
-hash_ps_encoding (const void *pa, void *foo UNUSED)
-{
- const struct ps_encoding *a = pa;
-
- return hsh_hash_string (a->filename);
-}
-
-/* Hash table free function for ps_encoding's. */
-static void
-free_ps_encoding (void *pa, void *foo UNUSED)
-{
- struct ps_encoding *a = pa;
-
- free (a->filename);
- free (a);
-}
+/* Basic file operations. */
-/* 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. */
+/* Writes the PostScript prologue to file F. */
static void
-output_encodings (struct outp_driver *this)
+write_ps_prologue (struct outp_driver *this)
{
struct ps_driver_ext *x = this->ext;
+ size_t embedded_cnt, preloaded_cnt;
+ size_t i;
- struct hsh_iterator iter;
- struct ps_encoding *pe;
+ fputs ("%!PS-Adobe-3.0\n", x->file);
+ fputs ("%%Pages: (atend)\n", x->file);
- struct string line, buf;
-
- 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;
-
- 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);
+ 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)
+{
+ const char *cp;
- msg (VM (2), _("%s: PostScript font encoding read successfully."),
- this->name);
- }
+ 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);
+ }
}
- ds_destroy (&line);
- ds_destroy (&buf);
+ return xasprintf ("/%s", string);
}
-/* 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)
+static void
+ps_open_page (struct outp_driver *this)
{
struct ps_driver_ext *x = this->ext;
- struct ps_encoding *pe;
- pe = (struct ps_encoding *) hsh_find (x->encodings, (void *) &norm_filename);
- return pe;
-}
-
-/* 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;
+ /* Assure page independence. */
+ x->last_font = -1;
- 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;
+ x->page_number++;
- temp = find_ps_file (this, filename);
- if (temp == NULL)
- return NULL;
+ fprintf (x->file,
+ "%%%%Page: %d %d\n"
+ "%%%%BeginPageSetup\n"
+ "/pg save def 0.001 dup scale\n",
+ x->page_number, x->page_number);
+
+ if (!x->portrait)
+ fprintf (x->file,
+ "%d 0 translate 90 rotate\n",
+ x->paper_width);
- filename = fn_normalize (temp);
- assert (filename != NULL);
- free (temp);
+ if (x->bottom_margin != 0 || x->left_margin != 0)
+ fprintf (x->file,
+ "%d %d translate\n",
+ x->left_margin, x->bottom_margin);
+
+ fprintf (x->file,
+ "/LW %d def %d setlinewidth\n"
+ "%%%%EndPageSetup\n",
+ x->line_width, x->line_width);
- 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++;
-}
-
-/* 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)
-{
- 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;
-}
-
-/* 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);
+ fputs ("%%PageTrailer\n"
+ "EP\n",
+ x->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;
- }
-}
-
-/* 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;
-}
-
-/* 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;
-}
-
-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);
-}
-
+/* Draws a line from (x0,y0) to (x1,y1). */
static void
-ps_text_set_font_family (struct outp_driver *this, const char *s)
+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);
-
- free(x->family);
- x->family = xstrdup (s);
+ struct ps_driver_ext *ext = this->ext;
+ fprintf (ext->file, "%d %d %d %d L\n", x0, YT (y0), x1, YT (y1));
}
-static const char *
-ps_text_get_font_name (struct outp_driver *this)
+/* 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);
- return x->current->font->name;
+ 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 const char *
-ps_text_get_font_family (struct outp_driver *this)
+/* 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);
- return x->family;
+ 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);
+ }
}
-static int
-ps_text_set_size (struct outp_driver *this, int size)
-{
- struct ps_driver_ext *x = this->ext;
+/* 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;
- assert (this->driver_open && this->page_open);
- x->size = PSUS / 72000 * size;
- return 1;
-}
+ /* Offset from center of each line in a pair of double lines. */
+ int double_line_ofs = (ext->line_space + ext->line_width) / 2;
-static int
-ps_text_get_size (struct outp_driver *this, int *em_width)
-{
- struct ps_driver_ext *x = this->ext;
+ /* 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;
- 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 (!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);
+ }
-/* 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. */
- };
+ 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 comparison function for ps_combo structs. */
+/* Writes STRING at location (X,Y) trimmed to the given MAX_WIDTH
+ and with the given JUSTIFICATION for THIS driver. */
static int
-compare_ps_combo (const void *pa, const void *pb, void *foo UNUSED)
+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;
- const struct ps_font_combo *b = pb;
+ struct outp_text text;
+ int width;
- return !((a->font == b->font) && (a->size == b->size));
+ 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 hash function for ps_combo structs. */
-static unsigned
-hash_ps_combo (const void *pa, void *foo UNUSED)
-{
- 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);
+/* Writes LEFT left-justified and RIGHT right-justified within
+ (X0...X1) at Y. LEFT or RIGHT or both may be null. */
+static void
+draw_header_line (struct outp_driver *this,
+ const char *left, const char *right,
+ int x0, int x1, int y)
+{
+ 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);
}
-/* Hash table free function for ps_combo structs. */
+/* Draw top of page headers for THIS driver. */
static void
-free_ps_combo (void *a, void *foo UNUSED)
+draw_headers (struct outp_driver *this)
{
- free (a);
-}
+ struct ps_driver_ext *ext = this->ext;
+ 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;
-/* 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. */
+ 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);
+}
+
+/* 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
-switch_font (struct outp_driver *this, const struct output_char *cp)
+write_text (struct outp_driver *this,
+ int x0, int y0,
+ enum outp_font font,
+ enum outp_justification justification,
+ const struct afm_character **chars, int *kerns, size_t char_cnt,
+ int width_left)
{
struct ps_driver_ext *ext = this->ext;
- struct ps_font_combo srch, **fc;
+ struct afm *afm = ext->fonts[font]->metrics;
+ struct string out;
+ size_t i, j;
+
+ 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;
- srch.font = cp->font;
- srch.size = cp->size;
+ fprintf (ext->file, "\n%d %d moveto\n", x0, YT (y0));
- fc = (struct ps_font_combo **) hsh_probe (ext->combos, &srch);
- if (*fc)
+ if (ext->last_font != font)
{
- fprintf (ext->file.file, "F%x%s", (*fc)->index, ext->eol);
+ ext->last_font = font;
+ fprintf (ext->file, "F%d setfont\n", font);
}
- else
+
+ ds_init (&out, 0);
+ for (i = 0; i < char_cnt; i = j)
{
- 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++;
+ for (j = i + 1; j < char_cnt; j++)
+ if (kerns[j] != 0)
+ break;
- 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 (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++;
+ }
+ }
+ }
+ ds_destroy (&out);
+}
+
+/* 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. */
- 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;
+ /* Statistics. */
+ int max_width; /* Widest line so far. */
+ };
- 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;
-}
-
-/* (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). */
+/* Adjusts S to complete a line of text,
+ and draws the current line if appropriate. */
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)
+finish_line (struct outp_driver *this, struct text_state *s)
{
- struct ps_driver_ext *ext = this->ext;
- int ofs;
-
- int last_y;
-
- char number[INT_STRLEN_BOUND (int) + 1];
- char line[80];
- char *lp;
+ int width;
- switch (t->options & OUTP_T_JUST_MASK)
+ if (s->draw)
{
- 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 ();
+ 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;
}
- lp = line;
- last_y = INT_MIN;
- while (cp < end)
- {
- 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);
+ /* Update maximum width. */
+ width = s->text->h - s->width_left;
+ if (width > s->max_width)
+ s->max_width = width;
- if (y != last_y)
- {
- *lp++ = ' ';
- put_number (YT (y));
- *lp++ = ' ';
- *lp++ = 'S';
- last_y = y;
- }
- else
- {
- *lp++ = ' ';
- *lp++ = 'T';
- }
+ /* Move to next line. */
+ s->width_left = s->text->h;
+ s->height_left -= this->font_height;
- if (lp >= &line[70])
- output_line ();
- }
- if (lp != line)
- output_line ();
+ /* No spaces on this line yet. */
+ s->space_char = NULL;
}
-#undef output_line
-#undef put_number
-
-/* Displays the text in outp_text T, if DRAW is nonzero; or, merely
- determine the text metrics, if DRAW is zero. */
+/* 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, struct outp_text *t, int draw)
+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;
- /* 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. */
-
- /* 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;
-
- /* Current location. */
- int x, y;
-
- /* 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. */
-
- /* Previous character. */
- int prev_char;
-
- /* 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. */
-
- /* Name of the current character. */
- const char *char_name;
- char local_char_name[2] = {0, 0};
-
- local_char_name[0] = local_char_name[1] = 0;
-
- buf = local_alloc (sizeof *buf * 128);
- buf_end = &buf[128];
- buf_loc = buf;
-
- 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.text = text;
+ s.draw = draw;
- if (!width || !height_left)
- goto exit;
+ s.glyphs = NULL;
+ s.glyph_kerns = NULL;
+ glyph_cap = 0;
- while (cp < end)
- {
- struct char_metrics *metric;
- int cur_char;
- int kern_amt;
- int char_width;
- int separate = 0;
+ s.glyph_cnt = 0;
+ s.width_left = s.text->h;
+ s.height_left = s.text->v;
- /* 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;
+ s.space_char = 0;
- 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);
+ s.max_width = 0;
- /* 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;
+ cp = ls_c_str (&s.text->string);
+ while (s.height_left >= this->font_height && cp < ls_end (&s.text->string))
+ {
+ const struct afm_character *cur;
+ int char_width;
+ int kern_adjust;
+
+ 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)
+ if (cur->code == ' ' && cp > ls_c_str (&s.text->string))
{
- space_char = cp;
- space_buf_loc = buf_loc;
- space_width_left = width_left;
+ s.space_char = cp;
+ s.space_glyph_cnt = s.glyph_cnt;
+ s.space_width_left = s.width_left;
+ }
+
+ /* Enough room on this line? */
+ if (char_width + kern_adjust > s.width_left)
+ {
+ 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;
+ }
}
- /* Drop down to a new line if there's no room left on this
- line. */
- if (char_width + kern_amt > width_left)
- {
- /* 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;
- }
- if (ext->size > max_height)
- max_height = ext->size;
- if (max_height > height_left)
- goto exit;
+ 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++;
- /* Actually draw the character. */
- if (draw)
- {
- 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;
- }
+ s.width_left -= char_width + kern_adjust;
+ }
+ if (s.height_left >= this->font_height && s.glyph_cnt > 0)
+ finish_line (this, &s);
- /* Prepare for next iteration. */
- width_left -= char_width + kern_amt;
- prev_char = cur_char;
- }
- 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;
+ if (width != NULL)
+ *width = s.max_width;
+ if (height != NULL)
+ *height = text->v - s.height_left;
+ free (s.glyphs);
+ free (s.glyph_kerns);
}
static void
-ps_text_metrics (struct outp_driver *this, struct outp_text *t)
+ps_text_metrics (struct outp_driver *this, const struct outp_text *t,
+ int *width, int *height)
{
- assert (this->driver_open && this->page_open);
- text (this, t, 0);
+ text (this, t, false, width, height);
}
static void
-ps_text_draw (struct outp_driver *this, struct outp_text *t)
+ps_text_draw (struct outp_driver *this, const struct outp_text *t)
{
- assert (this->driver_open && this->page_open);
- text (this, t, 1);
+ assert (this->page_open);
+ text (this, t, true, NULL, NULL);
}
-/* 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);
-}
-
-/* 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);
-}
-
-/* Initializes the global font list by creating the hash table for
- translation of filenames to font_desc structs. */
-static void
-init_fonts (void)
-{
- ps_fonts = hsh_create (31, compare_filename2font, hash_filename2font,
- NULL, NULL);
-}
-
-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)
-{
- 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;
-}
-
static void
ps_chart_initialise (struct outp_driver *this UNUSED, struct chart *ch)
{
@@ -2884,12 +1100,12 @@
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 @@
#endif
}
-static void
+static void
ps_chart_finalise (struct outp_driver *this UNUSED, struct chart *ch UNUSED)
{
#ifndef NO_CHARTS
@@ -2913,103 +1129,311 @@
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
}
+
+static void embed_font (struct outp_driver *this, struct font *font);
+static void reencode_font (struct outp_driver *this, struct font *font);
-/* PostScript driver class. */
-struct outp_class postscript_class =
+/* 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;
+ }
+
+ /* 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,
-
- ps_preopen_driver,
- ps_option,
- ps_postopen_driver,
- ps_close_driver,
+/* 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_open_page,
- ps_close_page,
+ if (font->embed_fn != NULL)
+ embed_font (this, font);
+ else
+ fprintf (x->file, "%%%%IncludeResource: font %s\n",
+ afm_get_findfont_name (font->metrics));
- ps_submit,
+ 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_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,
+ if (font->encoding_fn != NULL)
+ reencode_font (this, font);
- ps_chart_initialise,
- ps_chart_finalise
-};
+ fprintf (x->file, "/F%d ED\n", index);
+}
+
+/* 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;
+ }
+}
+
+/* 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)
+{
+ 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;
-/* EPSF driver class. FIXME: Probably doesn't work right. */
-struct outp_class epsf_class =
+ struct string line;
+
+ int line_number;
+ FILE *file;
+
+ 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 =
{
- "epsf",
- MAGIC_EPSF,
+ "postscript",
0,
- ps_open_global,
- ps_close_global,
- ps_font_sizes,
-
- ps_preopen_driver,
- ps_option,
- ps_postopen_driver,
+ ps_open_driver,
ps_close_driver,
ps_open_page,
@@ -3017,26 +1441,10 @@
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: pspp/src/output/table.c
diff -u pspp/src/output/table.c:1.4 pspp/src/output/table.c:1.5
--- pspp/src/output/table.c:1.4 Wed Mar 15 03:29:11 2006
+++ pspp/src/output/table.c Mon Apr 3 20:07:54 2006
@@ -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"
@@ -42,23 +43,22 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
{
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 @@
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 @@
{
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;
-
- d->class->text_metrics (d, &text);
- if (text.h > width)
- width = text.h;
+ 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, &w, NULL);
+ if (w > width)
+ width = w;
}
}
@@ -525,19 +484,22 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
tabi_render,
};
-/* Render contiguous strip consisting of columns C1...C2, exclusive,
- on row R, at location (X,Y). Return width of the strip thus
- rendered.
-
- Renders joined cells, even those outside the strip, within the
- rendering region (C1,R1)-(C2,R2).
-
- For the purposes of counting rows and columns in this function
- only, horizontal rules are considered rows and vertical rules are
- considered columns.
+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];
+}
- FIXME: Doesn't use r1? Huh? */
+/* Returns the vertical rule at the given column and row. */
static int
-render_strip (int x, int y, int r, int c1, int c2, int r1 UNUSED, int r2)
+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)
{
- int x_origin = x;
+ 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);
+}
- /* Horizontal rules. */
- if ((r & 1) == 0)
+/* 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 (c = c1; c < c2; c++)
+ width += t->w[c] + t->wrv[c + 1];
+ if (c1 < c2)
+ width -= t->wrv[c2];
+ return width;
+}
+
+/* Returns the height of rows R1...R2 exclusive,
+ including interior but not exterior rules. */
+static int
+strip_height (int r1, int r2)
+{
+ int height = 0;
+ int r;
+
+ 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))
{
- int hrh = t->hrh[r / 2];
- int c;
+ 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
+ {
+ 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: pspp/src/output/table.h
diff -u pspp/src/output/table.h:1.3 pspp/src/output/table.h:1.4
--- pspp/src/output/table.h:1.3 Wed Mar 15 03:29:11 2006
+++ pspp/src/output/table.h Mon Apr 3 20:07:54 2006
@@ -28,27 +28,28 @@
{
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 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 @@
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_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 @@
{
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: pspp/src/procedure.c
diff -u pspp/src/procedure.c:1.3 pspp/src/procedure.c:1.4
--- pspp/src/procedure.c:1.3 Tue Mar 21 00:33:05 2006
+++ pspp/src/procedure.c Mon Apr 3 20:07:54 2006
@@ -881,8 +881,8 @@
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: pspp/tests/ChangeLog
diff -u pspp/tests/ChangeLog:1.52 pspp/tests/ChangeLog:1.53
--- pspp/tests/ChangeLog:1.52 Thu Mar 23 17:15:17 2006
+++ pspp/tests/ChangeLog Mon Apr 3 20:07:54 2006
@@ -1,3 +1,7 @@
+Mon Apr 3 12:32:36 2006 Ben Pfaff <address@hidden>
+
+ * Updated tests to match changes in output formatting.
+
2006-03-23 Jason Stover <address@hidden>
* command/regression.sh: New test.
Index: pspp/tests/bugs/examine-missing.sh
diff -u pspp/tests/bugs/examine-missing.sh:1.3
pspp/tests/bugs/examine-missing.sh:1.4
--- pspp/tests/bugs/examine-missing.sh:1.3 Sat Mar 11 07:16:40 2006
+++ pspp/tests/bugs/examine-missing.sh Mon Apr 3 20:07:54 2006
@@ -70,7 +70,7 @@
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: pspp/tests/command/examine-extremes.sh
diff -u pspp/tests/command/examine-extremes.sh:1.10
pspp/tests/command/examine-extremes.sh:1.11
--- pspp/tests/command/examine-extremes.sh:1.10 Sat Mar 11 07:16:40 2006
+++ pspp/tests/command/examine-extremes.sh Mon Apr 3 20:07:54 2006
@@ -106,23 +106,23 @@
#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: pspp/tests/command/examine.sh
diff -u pspp/tests/command/examine.sh:1.14 pspp/tests/command/examine.sh:1.15
--- pspp/tests/command/examine.sh:1.14 Sat Mar 11 07:16:40 2006
+++ pspp/tests/command/examine.sh Mon Apr 3 20:07:55 2006
@@ -110,22 +110,22 @@
+--------+------+
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 @@
#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: pspp/tests/command/oneway.sh
diff -u pspp/tests/command/oneway.sh:1.16 pspp/tests/command/oneway.sh:1.17
--- pspp/tests/command/oneway.sh:1.16 Sat Mar 11 07:16:40 2006
+++ pspp/tests/command/oneway.sh Mon Apr 3 20:07:55 2006
@@ -107,7 +107,7 @@
+--------+------+
2.1 ONEWAY. Descriptives
#===============#========#==#====#==============#==========#=======================#=======#=======#
-# | # | | | | 95% Confidence
| | #
+# | # | | | |95% Confidence
Interval| | #
# | # | | |
+-----------+-----------+ | #
# | # N|Mean|Std. Deviation|Std. Error|Lower Bound|Upper
Bound|Minimum|Maximum#
#===============#========#==#====#==============#==========#===========#===========#=======#=======#
Index: pspp/tests/command/t-test-1-indep-val.sh
diff -u pspp/tests/command/t-test-1-indep-val.sh:1.11
pspp/tests/command/t-test-1-indep-val.sh:1.12
--- pspp/tests/command/t-test-1-indep-val.sh:1.11 Sat Mar 11 07:16:40 2006
+++ pspp/tests/command/t-test-1-indep-val.sh Mon Apr 3 20:07:55 2006
@@ -109,7 +109,7 @@
#===========#==#====#==============#========#
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: pspp/tests/command/t-test-pairs.sh
diff -u pspp/tests/command/t-test-pairs.sh:1.12
pspp/tests/command/t-test-pairs.sh:1.13
--- pspp/tests/command/t-test-pairs.sh:1.12 Sat Mar 11 07:16:40 2006
+++ pspp/tests/command/t-test-pairs.sh Mon Apr 3 20:07:55 2006
@@ -100,7 +100,7 @@
#===========#=====================================================#======#==#===============#
# # Paired Differences | | |
#
# #-------+--------------+---------------+--------------+ | |
#
-# # | | | 95% | | |
#
+# # | | |95% Confidence| | |
#
# # | | +-------+------+ | |
#
# # Mean |Std. Deviation|Std. Error Mean| Lower | Upper| t
|df|Sig. (2-tailed)#
#===========#=======#==============#===============#=======#======#======#==#===============#
Index: pspp/tests/command/trimmed-mean.sh
diff -u pspp/tests/command/trimmed-mean.sh:1.13
pspp/tests/command/trimmed-mean.sh:1.14
--- pspp/tests/command/trimmed-mean.sh:1.13 Sat Mar 11 07:16:40 2006
+++ pspp/tests/command/trimmed-mean.sh Mon Apr 3 20:07:55 2006
@@ -99,23 +99,23 @@
#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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Pspp-cvs] pspp ./ChangeLog ./NEWS ./Smake config/ChangeLo...,
Ben Pfaff <=