summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorRoger Leigh <rleigh@debian.org>2008-10-26 16:10:50 +0000
committerRoger Leigh <rleigh@debian.org>2008-10-26 16:10:50 +0000
commiteb5718390731a9746c556317e641320b671f2091 (patch)
tree762876b4adf298c1281142328e2ae87007330904 /doc
Imported Upstream version 4.2.0
Diffstat (limited to 'doc')
-rw-r--r--doc/.cvsignore33
-rw-r--r--doc/FAQ.html286
-rw-r--r--doc/Makefile.am190
-rw-r--r--doc/README.maintaining561
-rw-r--r--doc/appendices.texi15
-rw-r--r--doc/copying.texi28
-rw-r--r--doc/dither.texi504
-rw-r--r--doc/escp2.texi919
-rw-r--r--doc/functions.texi744
-rw-r--r--doc/gimpprint.texi130
-rw-r--r--doc/gpl.texi396
-rw-r--r--doc/indices.texi14
-rw-r--r--doc/integrating.texi192
-rw-r--r--doc/introduction.texi38
-rw-r--r--doc/new-printer.texi696
-rw-r--r--doc/overview.texi19
-rw-r--r--doc/print-color.pngbin0 -> 11217 bytes
-rw-r--r--doc/print-main.pngbin0 -> 17787 bytes
-rw-r--r--doc/print-setup.pngbin0 -> 3539 bytes
-rw-r--r--doc/problems.texi17
-rw-r--r--doc/programs.texi278
-rw-r--r--doc/users_guide/.cvsignore12
-rw-r--r--doc/users_guide/Makefile.am268
-rw-r--r--doc/users_guide/README39
-rw-r--r--doc/users_guide/figures/.cvsignore1
-rw-r--r--doc/users_guide/figures/README24
-rw-r--r--doc/users_guide/figures/cups_admin.pngbin0 -> 11105 bytes
-rw-r--r--doc/users_guide/figures/cups_admin_device.pngbin0 -> 10515 bytes
-rw-r--r--doc/users_guide/figures/cups_admin_make.pngbin0 -> 11540 bytes
-rw-r--r--doc/users_guide/figures/cups_admin_model.pngbin0 -> 12445 bytes
-rw-r--r--doc/users_guide/figures/cups_admin_success.pngbin0 -> 10441 bytes
-rw-r--r--doc/users_guide/figures/cups_config_printer.pngbin0 -> 15395 bytes
-rw-r--r--doc/users_guide/figures/cups_my_printer.pngbin0 -> 14544 bytes
-rw-r--r--doc/users_guide/figures/cups_printers.pngbin0 -> 10008 bytes
-rw-r--r--doc/users_guide/figures/cups_startup.pngbin0 -> 11252 bytes
-rw-r--r--doc/users_guide/figures/gimp-print-gui-1.pngbin0 -> 24241 bytes
-rw-r--r--doc/users_guide/figures/gimp-print-gui.pngbin0 -> 26080 bytes
-rw-r--r--doc/users_guide/figures/gimp-print-new-printer.pngbin0 -> 1438 bytes
-rw-r--r--doc/users_guide/figures/gimp-print-print-color-adjust.pngbin0 -> 11402 bytes
-rw-r--r--doc/users_guide/figures/gimp-print-setup.pngbin0 -> 2973 bytes
-rw-r--r--doc/users_guide/figures/gimp_image.pngbin0 -> 35648 bytes
-rw-r--r--doc/users_guide/figures/gimp_startup.pngbin0 -> 3890 bytes
-rw-r--r--doc/users_guide/users-guide.sgml1873
-rw-r--r--doc/using.texi46
-rw-r--r--doc/weave.texi1290
45 files changed, 8613 insertions, 0 deletions
diff --git a/doc/.cvsignore b/doc/.cvsignore
new file mode 100644
index 0000000..00d9220
--- /dev/null
+++ b/doc/.cvsignore
@@ -0,0 +1,33 @@
+manual-html
+html-stamp
+gimpprint.pgs
+version.texi
+gimpprint.info
+gimpprint.info-1
+gimpprint.info-2
+gimpprint.info-3
+gimpprint.info-4
+gimpprint.info-5
+texinfo.tex
+print-color.eps
+print-main.eps
+print-setup.eps
+gimpprint.tocs
+Makefile.in
+Makefile
+stamp-vti
+gimpprint.pg
+gimpprint.pdf
+gimpprint.fn
+gimpprint.vr
+gimpprint.toc
+gimpprint.dvi
+gimpprint.ky
+gimpprint.tp
+gimpprint.ps
+gimpprint.fns
+gimpprint.cp
+gimpprint.log
+gimpprint.cps
+gimpprint.aux
+gimpprint.vrs
diff --git a/doc/FAQ.html b/doc/FAQ.html
new file mode 100644
index 0000000..8d49e23
--- /dev/null
+++ b/doc/FAQ.html
@@ -0,0 +1,286 @@
+<html>
+<head>
+<title>The Gimp-Print FAQ</title>
+</head>
+
+<body>
+<h2>Gimp-Print FAQ</h2>
+
+<ol>
+
+<p><li><h3>Is it only for Gimp?</h3>
+
+<p>No, it can be used for many printing needs. Gimp-print started out
+as a driver for The Gimp, the well known image manipulation program.
+Early in development versions for Ghostscript and later CUPS were
+added. The emphasis is still on quality color printing, though
+performance gets a lot of attention these days.
+
+<p><li><h3>I cannot install it, it complains about missing Gimp files</h3>
+
+<ul>
+
+<p><li>If you have the Gimp installed on your system, you probably
+have the user package, but not the development package, installed.
+You will need to install the latter from your installation media; it's
+usually named gimp-devel.
+
+<p><li>If you do have the Gimp installed, and you've installed the
+gimp-devel package, you may also need to install the gtk-devel and
+glib-devel packages.
+
+<p><li>If you've installed the Gimp from source, you may need to run
+<tt>ldconfig</tt> as root. The installation procedure for the Gimp
+doesn't run ldconfig, which is needed on many systems to tell the
+system about the shared libraries that are installed. If you don't
+understand this, don't worry; just do it. If you're nervous about
+doing that, reboot.
+
+<p><li>If you don't have the Gimp installed on your system, and just
+want to compile Gimp-Print for CUPS (for example), you need to pass
+<tt>configure</tt> the option <tt>--with-gimp=no</tt>, so it won't try
+to look for the Gimp and fail.
+
+</ul>
+
+<p><li><h3>What is the difference between B/W, Line art, solid color and
+Photo mode (or ImageType in Ghostscript)?</h3>
+
+<p>Photo mode does a lot of work to make colors as similar to screen
+presentation as possible. This takes time. Line art is faster, but
+colors may be off. Solid Colors is somewhere in between. B/W mode
+does not use color ink when printing, and is much faster.
+
+<p><li><h3>I selected my printer and it doesn't work at all!</h3>
+
+<p>Please check your printing system (lpd, CUPS, LPRng, etc.)
+configuration. You may also have a problem with your parallel port
+or USB connection, so take a look at <tt>/var/log/messages</tt> (or
+wherever your system logs are kept).
+
+<p><li><h3>I selected my printer and it simply feeds paper without
+printing</h3>
+
+<p>Many Epson printers (in particular) do this if they encounter an
+error in the command stream. This usually indicates a bug in
+Gimp-Print; please report it to <a
+mailto="gimp-print-devel@sourceforge.net">gimp-print-devel@sourceforge.net</a>
+or via the bug tracking system at <a
+href="http://gimp-print.sourceforge.net">http://gimp-print.sourceforge.net</a>.
+Make sure you report the printer you have and all of the settings that
+you used. But first, triple check that you're using the right printer
+model!
+
+<p><li><h3>I selected my printer, and it prints the image badly
+distorted, or at completely the wrong place on the page</h3>
+
+<p>This usually indicates a bug in the package. Please report it as
+described above. Also as described above, make sure you've set the
+right printer.
+
+<p><li><h3>I selected the right printer and nonsense, or only part of
+the page, gets printed</h3>
+
+<p>Printers for which support just has been added may not have been
+tested, as the developers do not have access to the printer. It is
+worth trying different settings. For example, change the resolution to
+a mainstream value as used on that printer. Also photo mode is better
+tested than the optimized versions. When you find out what works and
+what doesn't, file a bug report.
+
+<p>One common cause of this is not using "raw" mode when printing from
+the Gimp plugin. Depending upon your printing system, you will need
+to use either <tt>-l</tt> (traditional BSD lpd), <tt>-oraw</tt> (CUPS
+lpr), or <tt>-d</tt> (most versions of System V lp, including CUPS).
+Otherwise the printing system attempts to interpret the output as
+something else, and tries to apply a filter to it to convert it to
+something else (usually PostScript).
+
+<p>Another less common cause of this (it usually causes other
+symptoms, like printing only part of a page) is lack of space
+somewhere. This is most commonly an issue when using the Gimp Print
+plugin. The plugin creates a huge temporary file that gets sent to
+the printing system. The size of the file varies; it's proportional
+to the page size and the resolution setting chosen. Full-page, high
+resolution photographs can result in 100 MB of output. The system may
+need to have 2 or 3 copies of this file for short periods of time. If
+your /tmp, /var, or wherever your spooler keeps its temporary files is
+too small, you'll have problems.
+
+<p>Finally, problems with your parallel or USB port may be the cause
+of problems here. Certain Epson printers in particular are known to
+be very sensitive to the quality of connecting cables, and may have
+trouble with long or low quality cables, or USB hubs. If nothing else
+works, and you're certain you've tried everything else, try a better
+cable or a direct USB connection.
+
+<p><li><h3>What's up with the HP Deskjet 1200?</h3>
+
+<p>HP had sold two printers with the 1200 model designation. The old
+version is 300 DPI and has a heating element to dry the ink. It was
+manufactured around 1990. The new version is of 2000 vintage and has
+higher resolution. The one supported by this package is the new
+one???
+
+<p><li><h3>I selected the right printer and the quality is lousy</h3>
+
+<p>Try selecting a different resolution or quality setting. Especially
+lower resolutions have a problem putting enough ink on paper. Also,
+use Photo mode. If you find settings that do not work at all (you get
+garbage or no output, but other settings work), report these as bugs.
+High resolutions should produce a similar (but smoother) result than
+medium resolutions. Resolutions under a certain printer dependent
+figure are seen as draft-only - for example lower than 360 DPI on
+Epsons with standard paper or lower than 300 DPI on HP.
+
+<p>Also make sure that you have the right kind of paper selected.
+Selecting plain paper when you're printing on high quality photo paper
+is certain to result in a light, grainy image. Selecting photo paper
+when you're printing on plain paper will result in a dark, muddy image
+that bleeds through the paper. There are differences between
+different kinds of paper; you may need to tweak the density and color
+settings slightly.
+
+<p>In addition, certain printers don't work well on certain kinds of
+paper. Epson printers work well on Epson printers, but don't work
+well on many third party papers (particularly the high quality photo
+papers made by other vendors). This isn't a conspiracy to lock you
+into their paper, it's because they've formulated the paper and ink to
+work well together.
+
+<p>If you use Ghostscript, make sure the Ghostscript resolution is not
+set higher than the driver resolution. If it is higher, the driver has
+to throw away part of the pixels, leading to uneven strokes in text
+and slanted lines with interruptions.
+
+<p><li><h3>How do I start setting options for Ghostscript?</h3>
+
+<p>Please see src/ghost/README for more information.
+
+<p><li><h3><tt>escputil -i</tt> or <tt>escputil -d</tt> fails as follows:</h3>
+
+<p><pre>
+% escputil -r /dev/lp0 -i
+
+[ ... license info omitted ... ]
+
+Cannot read from /dev/lp0: Invalid argument
+</pre>
+
+<p>You need to rebuild your kernel with CONFIG_PRINTER_READBACK
+enabled.
+
+<p><li><h3>I tried to test my Epson printer by 'cat .cshrc > /dev/lp0'
+and nothing prints!!!???</h3>
+
+<p>The classic test of printer connectivity -- sending an ASCII file
+to it -- doesn't work on many Epson printers out of the box (or after
+printing from Windows or Macintosh). Epson printers from the Stylus
+Color 740 and newer use a special "packet mode" in which they do not
+recognize standard commands or ASCII text. They must be sent a
+special sequence that takes them out of packet mode. The command
+
+<p><pre>escputil -u -s -r /dev/lp0</pre>
+
+<p>will take the printer out of packet mode and enable you to print to
+it. Of course, as soon as you've read back status from the printer,
+you know it's working (although if you're unable to read status out of
+the printer, you might have a different problem; see above).
+
+<p>Printing to your printer from Gimp-Print, whether you use the Print
+plugin, the CUPS driver, or the Ghostscript driver, will also take the
+printer out of packet mode. But then again, if you successfully print
+to your printer, you know it's working, so why worry? If you're
+trying to test your spooler, though, the escputil trick above will do
+it. Just make sure that /dev/lp0 is the right device; if it isn't,
+substitute whatever is.
+
+<p><em>Note:</em> this does not apply to printers prior to the 740
+(such as the Stylus Photo EX, Stylus Color 850, or anything even
+older). Those printers are always capable of printing ASCII text, and
+don't have packet mode. You can read status from them, but you must
+leave off the '-u' option.
+
+<p><li><h3>My USB-connected Epson Stylus printer won't work with
+{Free,Net,Open}BSD!</h3>
+
+<p>By default, the BSD device driver for the USB printer device (usually
+ulpt0) does a prime, or USB bus reset, when the device is opened. This
+causes the printer to reset itself (one can hear the print head moving back
+and forth when this happens) and lose sync. After this the printer
+won't go into graphics mode and instead spews characters all over you
+expensive photo paper. This has been observed on the Stylus Photo
+870; it likely exists with other USB-connected Epson Stylus printers.
+
+<p>The fix is to use the "unlpt0" device instead of "ulpt0". The driver
+doesn't perform the USB prime when unlpt is opened. If this device
+doesn't exist on your system you can create it with
+
+<p><pre>mknod unlpt0 c 113 64 root wheel</pre>
+
+<p>in the /dev directory.
+
+<p><li><h3>I try to print with StarOffice and it doesn't print
+correctly!</h3>
+
+<p>If you use CUPS, and your prints from StarOffice come out
+incorrectly (particularly at low resolution), try the following. This
+assumes a network installation of StarOffice 5.2.
+
+<ol>
+
+<p><li>Ensure that <tt>root</tt> does not have a .Xpdefaults file (if
+it does, the procedure below will edit root's version rather than the
+system-wide version in <tt>.../office52/share/xp3/Xpdefaults</tt>).
+
+<p><li>As root, start <tt>.../office52/program/spadmin</tt>. This is
+the StarOffice printer administration program.
+
+<p><li>Click on <b>Install New Driver</b>. For the <b>Driver
+directory</b>, select your CUPS PPD directory. This is usually
+<tt>/etc/cups/ppd</tt>. This should list the names of all of the
+drivers you have installed.
+
+<p><li>If there are no drivers visible, you may need to give the .ppd
+files names ending in .PS. The following script will accomplish this:
+
+<p><pre>
+# cd /etc/cups/ppd
+# for f in * ; do
+> ln -s $f `echo $f | sed 's/ppd$/PS/'`
+> done
+</pre>
+
+<p>Following this, restart <tt>spadmin</tt> and click on <b>Install
+New Driver</b>. When you select your CUPS PPD directory, you will
+find the necessary drivers listed.
+
+<p><li>Select the drivers you want StarOffice to know about and click
+OK.
+
+<p><li>If you have been using the generic Postscript printer, remove
+all of your old queues.
+
+<p><li>Select the appropriate new driver(s) and click <b>Add New
+Printer</b>.
+
+<p><li>Select the appropriate printer queue and click <b>Connect</b>
+to connect it to the printer queue of your choice.
+
+</ol>
+
+<p>You can now set up appropriate options for this printer. Note that
+you can create multiple queues with different settings, for example
+one for draft mode and one for high quality.
+
+<p><li><h3>I'm printing through Samba, and my printer prints
+garbage!</h3>
+
+<p>There are a number of Samba configuration issues that cause
+problems; a common problem is translation from UNIX newlines (\n) to
+Windows newlines (\r\n). It's important to ensure that sending raw
+data, with no translation, to the printer.
+
+</ol>
+
+</body></html>
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..9e5e88c
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,190 @@
+## $Id: Makefile.am,v 1.27 2001/11/08 13:15:18 rlk Exp $
+## Copyright (C) 2000 Roger Leigh
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = 1.4 gnu
+
+@SET_MAKE@
+
+MAINT_CHARSET = latin1
+
+SUBDIRS = users_guide
+
+
+## Variables
+
+MANUAL = gimpprint
+HTMLDIR = manual-html
+DOCS = $(MANUAL).dvi $(MANUAL).ps html
+
+IMAGES = \
+ print-color.png \
+ print-main.png \
+ print-setup.png
+
+EPS_IMAGES = $(addsuffix .eps,$(basename $(IMAGES)))
+
+if MAINTAINER_MODE
+MAINT_MODE = true
+else
+MAINT_MODE = false
+endif
+
+USER_GUIDE = $(MANUAL).ps html
+
+STANDARD_TARGETS=@USER_GUIDE@
+
+
+if MAINTAINER_MODE
+ALL_LOCAL_TARGETS = docs
+else
+ALL_LOCAL_TARGETS = $(STANDARD_TARGETS)
+endif
+
+
+## Data
+
+info_TEXINFOS = gimpprint.texi
+
+gimpprint_TEXINFOS = overview.texi copying.texi gpl.texi introduction.texi using.texi functions.texi programs.texi problems.texi appendices.texi dither.texi weave.texi escp2.texi new-printer.texi indices.texi integrating.texi version.texi
+
+
+## Rules
+
+all-local: $(DOCS)
+
+docs: $(DOCS)
+ cd users_guide; $(MAKE) docs
+
+ps: $(MANUAL).ps
+ cd users_guide; $(MAKE) ps
+
+pdf: $(MANUAL).pdf
+ cd users_guide; $(MAKE) pdf
+
+
+TEXI2DVIFLAGS = -I $(srcdir)
+gimpprint.dvi: $(EPS_IMAGES) $(addprefix $(srcdir)/,$(gimpprint_TEXINFOS) $(info_TEXINFOS))
+ $(TEXI2DVI) $(TEXI2DVIFLAGS) $(srcdir)/gimpprint.texi
+
+%.eps: %.png
+ $(CONVERT) $< EPS2:$@
+
+html: html-stamp
+ cd users_guide; $(MAKE) html
+
+## Note the rather weird way of setting the exit status; this is because
+## texi2html doesn't set the exit status.
+html-stamp: $(addprefix $(srcdir)/,$(gimpprint_TEXINFOS) $(info_TEXINFOS))
+ $(RM) -rf $(HTMLDIR)-tmp
+ mkdir $(HTMLDIR)-tmp
+ for image in $(addprefix $(srcdir)/, $(IMAGES)) ; do \
+ cp -p $$image $(HTMLDIR)-tmp ; \
+ done
+ cd $(HTMLDIR)-tmp ; \
+ $(TEXI2HTML) -menu -split_node -number -expandinfo \
+ -I ../$(srcdir) ../$(srcdir)/$(MANUAL).texi 2>&1
+ $(RM) -rf $(HTMLDIR)
+ mv $(HTMLDIR)-tmp $(HTMLDIR)
+ touch html-stamp
+
+$(MANUAL).ps: $(MANUAL).dvi
+ TEXPICTS=$(srcdir):. $(DVIPS) $< -o $@
+
+$(MANUAL).pdf: $(MANUAL).dvi
+ TEXPICTS=$(srcdir):. $(DVIPDF) $< $@
+
+install-data-local: $(STANDARD_TARGETS)
+ if test -n '$(STANDARD_TARGETS)' ; then \
+ $(mkinstalldirs) $(DESTDIR)$(datadir)/$(PACKAGE)/doc ; \
+ $(mkinstalldirs) $(DESTDIR)$(datadir)/$(PACKAGE)/doc/manual-html ; \
+ if test -f $(MANUAL).ps ; then \
+ $(INSTALL_DATA) $(MANUAL).ps $(DESTDIR)$(datadir)/$(PACKAGE)/doc ; \
+ elif test -f $(srcdir)/$(MANUAL).ps ; then \
+ $(INSTALL_DATA) $(srcdir)/$(MANUAL).ps $(DESTDIR)$(datadir)/$(PACKAGE)/doc ; \
+ fi ; \
+ if test -d $(HTMLDIR) ; then \
+ cd $(HTMLDIR) ; \
+ elif test -d $(srcdir)/$(HTMLDIR) ; then \
+ cd $(srcdir)/$(HTMLDIR) ; \
+ fi ; \
+ for file in * ; do \
+ if test -f $$file ; then \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(datadir)/$(PACKAGE)/doc/manual-html ; \
+ fi ; \
+ done ; \
+ fi
+
+dist-hook: html
+ for dir in manual-html ; do \
+ if test -d $(srcdir)/$$dir ; then \
+ mkdir $(distdir)/$$dir; \
+ for dirfile in $(srcdir)/$$dir/*; do \
+ if test -f $$dirfile ; then \
+ cp -p $$dirfile $(distdir)/$$dir; \
+ fi \
+ done \
+ fi \
+ done
+
+CLEAN_MANUALS = \
+ $(RM) -rf html-stamp manual-html ; \
+ $(RM) -f $(MANUAL).pdf $(MANUAL).ps $(MANUAL).dvi ; \
+ $(RM) -f $(EPS_IMAGES)
+
+clean-local:
+ if test $(srcdir) = '.' -a $(MAINT_MODE) = false ; then \
+ echo 'clean-local: Not removing manual-html' ; \
+ echo 'clean-local: Not removing $(MANUAL).pdf' ; \
+ echo 'clean-local: Not removing $(MANUAL).ps' ; \
+ echo 'clean-local: Not removing $(MANUAL).dvi' ; \
+ echo 'clean-local: Not removing EPS figures' ; \
+ else \
+ $(CLEAN_MANUALS) ; \
+ fi
+ -$(RM) -rf *.tex *.log *.aux *.gz *.out *.junk *.fot
+ -$(RM) -rf *.ky *.pg *.toc *.tp *.vr *.vrs
+ -$(RM) -rf manual-html-tmp
+
+veryclean:
+ $(MAKE) MAINT_MODE=true clean
+
+maintainer-clean-local:
+ $(CLEAN_MANUALS)
+
+# We duplicate mostlyclean-aminfo here because we do not want to remove
+# the .dvi and .ps files that mostlyclean-aminfo wants to remove. The
+# reason why is that we do not want make clean to force a rebuild of the
+# doc, since users may not have the texinfo tools required to do so.
+# Unfortunately, this generates a warning about overriding commands for
+# mostlyclean-aminfo.
+mostlyclean-aminfo:
+ -$(RM) -f gimpprint.aux gimpprint.cp gimpprint.cps \
+ gimpprint.fn gimpprint.fns gimpprint.ky gimpprint.kys \
+ gimpprint.log gimpprint.pg gimpprint.toc \
+ gimpprint.tp gimpprint.tps gimpprint.vr gimpprint.vrs \
+ gimpprint.op gimpprint.tr gimpprint.cv gimpprint.cn
+
+
+## Clean
+
+MAINTAINERCLEANFILES = Makefile.in html-stamp
+
+EXTRA_DIST = $(DOCS) $(IMAGES) $(EPS_IMAGES) html-stamp FAQ.html README.maintaining
+
+.PHONY: html ps pdf docs clean-manuals
diff --git a/doc/README.maintaining b/doc/README.maintaining
new file mode 100644
index 0000000..b8fa393
--- /dev/null
+++ b/doc/README.maintaining
@@ -0,0 +1,561 @@
+BUILD SCRIPTS: how they work and how to modify them
+===================================================
+
+A guide to the GIMP-Print build system.
+
+
+Introduction
+------------
+
+GIMP-Print uses GNU autoconf and automake to generate the scripts that build
+the software. It also uses libtool to create shared libraries. This file
+describes how they work together. It also discusses the thinking behind how
+they are used in GIMP-Print, and how to modify the GIMP-Print build scripts
+without breaking other things. If you have used autoconf and automake before,
+there will be little that is new in this file, but you should note the
+conventions used in GIMP-Print.
+
+This file is split into the following sections:
+
+ o Integration of the autotools
+ o Normal use of the tools
+ - Using CVS
+ - Setting up the build scripts from CVS
+ - Building the package
+ o configure.in.in
+ - Layout
+ - AC_SUBST
+ - AC_DEFINE and AC_DEFINE_UNQUOTED
+ - AM_CONDITIONAL
+ o Makefile.am
+ - Automake basics
+ - Make and subdirectories
+ - Conditional compilation
+ - When automake is not enough...
+ + Rule syntax
+ + Correctly referencing files
+ o aclocal
+ o config.h
+ o libgimpprint and libprintut
+ o automake subtleties
+ o libtool tricks
+ o Testing changes to the build scripts
+ o Further information
+ o Known problems
+
+I hope you find this useful. If any part was not clear, or there was something
+that you would like covering, please let me know!
+
+ -- Roger Leigh <roger@whinlatter.uklinux.net>
+
+ $Id: README.maintaining,v 1.8 2001/10/27 17:16:37 rlk Exp $
+
+
+1. Integration of the autotools
+-------------------------------
+
+Each directory has a Makefile.am file which is processed by automake to produce
+a Makefile.in. In the root directory there is a configure.in.in which is
+processed by autogen.sh to produce configure.in. configure.in is processed by
+autoconf to make a script called configure. When run, configure does various
+tests and checks, and then reads each Makefile.in to make a Makefile, and also
+generates a header called config.h from config.h.in. config.h.in is produced
+with autoheader from configure.in and acconfig.h. autoconf also requires a
+file aclocal.m4 which is generated by aclocal.
+
+All these files are generated simply by running `./autogen.sh' in the top
+directory. If you are using a distributed version of GIMP-Print, as opposed to
+CVS, then they will already be present and the following will not be necessary.
+
+This is probably best demonstrated graphically. The relationships between the
+files are as follows:
+
+During package setup (from CVS), running autogen.sh:
+
+ autogen.sh
+ configure.in.in ------------> configure.in
+
+ gettext files added
+ libtool files added
+ aclocal
+ configure.in ------------> aclocal.m4
+
+ autoheader
+ acconfig.h + configure.in ------------> config.h.in
+
+ automake
+ Makefile.am ------------> Makefile.in
+
+ autoconf
+ aclocal.m4 + configure.in ------------> configure
+
+Running configure:
+ configure
+ Makefile.in ------------> Makefile
+ config.h.in ------------> config.h
+ headers.h.in ------------> headers.h
+ manpage.n.in ------------> manpage.n
+
+
+2. Normal use of the tools
+--------------------------
+
+This section describes how to use the scripts for basic day-to-day working.
+
+2.1 Using CVS
+-------------
+The latest working copy of GIMP-Print (HEAD) and all prior releases are
+available from CVS either anonymously (read-only with CVS pserver) or
+authenticated (read-write with SSH). The modulename for GIMP-Print is 'print'.
+
+Anonymous CVS access:
+The module you wish to check out must be specified as the modulename. When
+prompted for a password for anonymous, simply press the Enter key.
+
+ $ cvs -d:pserver:anonymous@cvs.gimp-print.sourceforge.net:/cvsroot/gimp-
+ print login
+ $ cvs -z3
+ -d:pserver:anonymous@cvs.gimp-print.sourceforge.net:/cvsroot/gimp-print
+ co modulename
+
+Developer CVS access via SSH:
+Only project developers can access the CVS tree via this method. SSH1 must be
+installed on your client machine. Substitute modulename and developername with
+the proper values. Enter your site password when prompted. See the sourceforge
+documentation for more details, including how to use RSA keys for
+authentication.
+
+ $ export CVS_RSH=ssh
+ $ cvs -z3
+ -ddevelopername@cvs.gimp-print.sourceforge.net:/cvsroot/gimp-print
+ co modulename
+
+The CVS info documentation has very detailed explanations of everything that
+can be done with CVS.
+
+2.2 Setting up the build scripts from CVS
+-----------------------------------------
+After initially getting a copy of GIMP-Print from CVS, or if any of the scripts
+have changed, simply run autogen.sh:
+
+ $ ./autogen.sh [options]
+
+Note that one can pass any options to autogen.sh that one would normally pass
+to configure. './configure --help' will give a complete list of options one
+can use.
+
+2.3 Building the package
+------------------------
+The normal method is to run the `configure' script, and then `make'. The
+package can then be installed with 'make install':
+
+ $ ./configure
+ $ make
+ $ make [DESTDIR=... VAR1=val1 VARn=valn] install
+
+If the build scripts have been modified, it will not normally be necessary to
+re-run autogen.sh: the Makefiles will notice and regenerate themselves, running
+autoconf, automake, aclocal and configure again if needed. If configure.in.in
+has been modified, re-run autogen.sh manually to regenerate configure.in.
+
+The build is only guaranteed to work if make is run from the top level. It
+should be possible to make individual subdirectories, but sometimes this will
+cause problems e.g. if it depends on some other directory that should have
+been built first.
+
+A common problem is getting errors about a non-existent file called
+`doc/version.texi'. This file is automatically generated. It will
+be generated if you run make after running './autogen.sh' or
+'./configure --enable-maintainer-mode'. It is only generated if
+`maintainer-mode' is enabled.
+
+Other packages (including the extra development packages on some systems) must
+be installed on your system to build correctly. These include: autoconf,
+automake, libtool, gtk, gdk, gimp 1.2, cups, foomatic, makeinfo, readline
+texi2html. Not all these need to be installed, depending on the configure
+options used. It might be necessary to get the latest releases of some of
+these packages, as critical bugs present in easrlier releases have been fixed.
+The latest gettext and texi2html are strongly suggested.
+
+2.4 Extra make targets
+----------------------
+The Makefiles can do much more than build the package. `targets' can be
+given to make, which do various things. They are used as follows:
+
+ $ make target1 target2 ...
+
+Some of the targets available are:
+
+ all same as make with no targets
+ clean remove everything generated by 'make all'
+ distclean as clean, and everything generated by configure
+ maintainer-clean as distclean, and everything generated by
+ autogen.sh
+ install install the package
+ uninstall uninstall the package
+ tags make tags tables
+ dist make a distribution
+ distcheck as dist, but test it as well
+ gimp-dist package the for inclusion in the GIMP tree
+
+Other targets are available. See Makefile.in for details.
+
+
+3. configure.in.in
+------------------
+
+This file is a Bourne shell script with m4 macros embedded in it. It is parsed
+with sed to produce configure.in, which has hard-coded release dates in it.
+autoconf expands the m4 macros to produce configure.
+
+3.1 Layout
+----------
+The file is split into mostly discrete sections:
+i. Versioning details (including library versioning)
+ii. autoconf and automake initialisation
+iii. libtool setup
+iv. Default settings
+v. configure --with and --enable options
+vi. Checks for programs
+vii. Compiler flags
+viii. Checks for libraries
+ix. Checks for headers
+x. Checks for typedefs, structures, and compiler characteristics
+xi. Define what has to be built (conditional compilation of things)
+xii. CUPS path settings
+xiii. Definitions and substitutions
+xiv. Parse and output files
+
+The ordering of sections is based solely on that some checks depend on checks
+being performed previously. There is sometimes some overlap between sections,
+but any additions should go into the appropriate section, if at all possible.
+A new section may be created if there is no suitable section.
+
+3.2 AC_SUBST
+------------
+The main use of the configure script is to produce customised Makefiles, and
+other files too. This is done through the use of AC_SUBST, which makes a
+variable get substituted in a file:
+
+ ESCPUTIL_BIN="escputil"
+ AC_SUBST(ESCPUTIL_BIN)
+
+will replace any instance of @ESCPUTIL_BIN@ in a template file (ending in
+.in'). E.g.
+
+ bin_PROGRAMS = @ESCPUTIL_BIN@
+
+3.3 AC_DEFINE and AC_DEFINE_UNQUOTED
+------------------------------------
+These macros are used to insert a #define in config.h.
+
+ AC_DEFINE(MACRO)
+
+will cause '#define MACRO 1' to appear in config.h (this will be of the form
+'#undef MACRO' in config.h.in)
+
+AC_DEFINE_UNQUOTED is the same as AC_DEFINE, except that a second option
+can be used to define a string literal.
+
+3.4 AM_CONDITIONAL
+------------------
+This is used to make certain parts of a Makefile conditional depending on
+what happens in configure. It is used in the form:
+
+ AM_CONDITIONAL(NAME, test)
+ where name is the name of the conditional you define, and test
+ is a check that must return true for the conditional to be
+ defined.
+
+This is used in a Makefile.am as follows:
+
+ if NAME
+ [do stuff]
+ endif
+
+Not that only one line can be made conditional, and that you cannot also use
+normal make conditionals. Its main use is to define macros, or to make a
+rule conditional.
+
+
+4. Makefile.am
+--------------
+
+There is a Makefile.am in each directory, apart from a few where the Makefile
+the next level up handles things. Each Makefile.am is split into several
+sections:
+i. Macros common to every Makefile.am
+ii. Path macros
+iii. Compiler macros
+iv. Build dependencies. This is further split into a) binaries and b) data.
+ Each of these sections has
+ 1. list of objects to build (if applicable)
+ 2. EXTRA_ objects (if applicable)
+ 3. Dependencies for each object (e.g. sources)
+v. Rules
+vi. Cleaning macros
+vii. EXTRA_DIST
+
+Keeping everything in this logical order keeps them neat and readable. Not
+every Makefile.am will have all these sections, but those that are present
+should be ordered in this way.
+
+4.1 Automake basics
+-------------------
+Automake parses Makefile.am, and generates rules in Makefile.in depending on
+what it finds. There are `primary' variables, such as PROGRAMS, SCRIPTS,
+MANS, HEADERS and DATA that describe the type of source one is defining. These
+are coupled with a location to install into. For example, these are a few
+standard locations: bindir, sbindir, mandir, datadir, pkgdatadir. You can
+define your own quite easily. They are used together as follows:
+
+ bin_PROGRAMS = myprog [where bindir=$(prefix)/bin]
+ pkgdata_DATA = datafile1 datafile2
+ [where pkgdatadir=$(prefix)/share/$(PACKAGE)]
+
+Note! the 'dir' postfix is stripped off the location. I.e. bindir -> bin.
+That is all there is to it! You can use these simple variables to describe
+everything in your source, and where is gets installed to.
+ In the case of PROGRAMS, one also has to specify the SOURCES as well.
+E.g. in the example above, a binary called `myprog' was defined. The sources
+for this program are defined as follows:
+
+ myprog_SOURCES = myprog.c myprog.h
+
+automake will create all of the rules needed to build and install everything.
+An extra point is that suppose one doesn't want to install something? For this
+there is a 'noinst' macro, so that noinst_PROGRAMS will not ever be installed.
+One might also want noinst_HEADERS. If one wanted to install headers, one would
+define
+
+ includedir=$(prefix)/include
+and then
+ pkgincludedir=$(includedir)/$(PACKAGE).
+Now
+ pkginclude_HEADERS = myheader.h
+
+will install the header into the correct location. Some of the locations in the
+above examples are defined by default. The others must be defined by hand.
+ There are also some macros with specific functions. Any file that is not
+mentioned in a macro, and also and MANS, will have to be put in an EXTRA_DIST
+macro, so that automake knows to distribute them.
+ Also, some files might not be automatically cleaned. There are CLEANFILES,
+DISTCLEANFILES and MAINTAINERCLEANFILES macros for use with the 'clean',
+'distclean' and 'maintainer-clean' make targets respectively. Use with caution!
+One does not want to clean things that cannot be recreated! CLEANFILES should
+be regenerated with 'make' as part of the build process, DISTCLEANFILES by
+configure (e.g. Makefiles) and MAINTAINERCLEANFILES should be created by
+'autogen.sh' and the programs it calls (e.g. Makefile.in's which are created by
+automake).
+
+4.2 Make and subdirectories
+---------------------------
+If a Makefile.am has a SUBDIRS macro, make will recurse through these
+subdirectories, running make in each one. e.g. in the top-level Makefile.am:
+
+ SUBDIRS = intl lib man src test po
+
+In this case the order of directories is critical: lib, src and test depend on
+intl being built and src and test depend on lib being built. Also, test depends
+on libgimpprint in src and po must be run after all the source has been built
+(as it parses all C source, possibly including dynamically generated code). The
+same applies in src/Makefile.am: most directories require libgimpprint for
+linking with, and libgimpprint requires printdef.
+ Therefore the order of building is critical! It should be technically
+possible to run make in any subdirectory and have all the dependencies
+satisfied by rules in that Makefile. Unfortunately, this requires complex rules
+in each directory, and this cannot be done as the source tree gets bigger and
+more complex. As a result, one should only run make from the top level, as
+only this is certain to satisfy all dependencies.
+
+4.3 Conditional compilation
+---------------------------
+Most of the source is conditionally compiled according to the defaults in
+configure.in.in, which may be overridden by passing options to configure,
+or possibly by the results of configure checks. Depending on the result,
+configure may substitute what to build into the generated Makefile, e.g.:
+
+ bin_PROGRAMS = @ESCPUTIL_BIN@
+ EXTRA_PROGRAMS = escputil
+
+It is important to have the EXTRA_ macro, as otherwise the source will
+not get distributed.
+
+4.4 When automake is not enough...
+----------------------------------
+When one wants to do something that is not within the scope of the facilities
+automake provides, one can write one's own rules, just like in any other
+Makefile.
+
+4.4.1 Rule syntax
+Make rules take the following form:
+
+ target ... : prerequisites ...
+ commands
+ ...
+ ...
+where
+ target is the name of a file (or files) to create
+ prerequisites are files that are needed to make the target
+ commands are commands to make the target
+
+The target will only be made if it does not exist or the timestamp on any of the
+prerequisites is newer, indicating that it is out of date.
+ make is a complex program, and this is just the bare basic operation. See
+the GNU make info documentation for a detailed explanation.
+
+4.4.2 Correctly referencing files
+A file may be present either in the _source_ or _build_ directory, which may or
+may not be the same. The source directory contains the unchanging source files,
+whereas the build directory contains all the generated files, such as
+Makefiles, object code, libraries and executables and also generated headers, C
+source and manual pages. The macros to use are:
+
+ $(srcdir) The equivalent directory in the source tree
+ . The build directory (which is the current directory)
+ $(top_srcdir) The highest level of the source tree
+ $(top_builddir) The highest level of the build tree
+
+
+5. aclocal
+----------
+
+aclocal contains all the macros that are needed by autoconf to generate
+configure from configure.in. It is created by running 'aclocal'. If any of the
+macros are not present on your system, you can point out where the macros
+distributed with GIMP-Print are by using '-I macrodir' with aclocal. E.g. if
+AM_PATH_GIMPPRINT is missing, you can make it use src/main/gimpprint.m4 with
+'aclocal -I src/main'.
+
+
+6. config.h
+-----------
+
+config.h is created by configure and included by all of the C source files in
+the distribution. It is created from config.h.in by 'configure'. config.h.in
+is created from configure.in and acconfig.h by 'autoheader'. If you add any
+AC_DEFINE, or AC_DEFINE_UNQUOTED macros to configure.in.in, you may be required
+to add entries to acconfig.h. If you defined 'HAVE_FOO_H' you would add
+something like:
+ /* Define if foo.h is present */
+ #undef HAVE_FOO_H
+to acconfig.h
+
+
+7. libgimpprint and libprintut
+
+Any source that is to link with libgimpprint should include the gimp-print.h
+header. The right way to do this is as follows:
+
+ #ifdef INCLUDE_GIMP_PRINT_H
+ # include INCLUDE_GIMP_PRINT_H
+ #else
+ # include <gimp-print.h>
+ #endif
+
+This is so that an installed version of libgimpprint can be linked against.
+ To ensure proper linking, the Makefile.am should have the following:
+
+ program_LDADD = $(LIBGIMPPRINT_LIBS)
+
+The Makefile.am should also include any necessary CFLAGS with:
+
+ INCLUDES = @INCLUDES@ $(LIBGIMPPRINT_CFLAGS)
+
+It is used with INCLUDES and not CFLAGS because is usually is used to specify
+header locations.
+ If a program uses the utility library libprintut, it must include
+libprintut.h:
+
+ #include "../../lib/libprintut.h"
+
+To link, the library must be specified in the same way as for libgimpprint:
+
+ program_LDADD = ../../lib/libprintut.la $(INTLLIBS) ../../lib/libprintut.la
+
+Note that if it is using gettext, then you have to specify it _twice_. If every
+binary is to link with it, then use LIBS instead:
+
+ LIBS = @LIBS@ ../../lib/libprintut.la $(INTLLIBS) ../../lib/libprintut.la
+
+
+8. automake subtleties
+----------------------
+
+Automake parses Makefile.am to produce Makefile.in. Makefile.am looks much like
+a normal Makefile, e.g. you can write your own rules in it. However, it is not
+entirely like a normal Makefile. In particular, automake conditionals are not
+the same as make conditionals in that they only work for single lines, not
+whole blocks of lines. Therefore if you want to make a rule conditional, just
+surround the 'target: dependencies' line:
+
+ if BUILD_CUPS
+ install-data-local: ppd
+ endif
+ $(mkinstalldirs) $(DESTDIR)$(cups_modeldir)
+ cd ppd ; \
+ for ppdfile in * ; do \
+ $(INSTALL_DATA) $$ppdfile $(DESTDIR)$(cups_modeldir) ; \
+ done
+
+Another gotcha is that automake adds rules of its own, so you must make sure
+that the names do not clash, or you may get obscure problems occurring.
+
+
+9. libtool tricks
+-----------------
+
+libtool is used to create shared libraries. One gotcha with libtool is that if
+a program is linked with a libtool shared library in the build tree, then it is
+actually created in '.libs/program', and not 'program'. However, if it is
+statically linked (e.g. the platform does not support shared libraries, or you
+used --disable-shared with configure, perhaps to make the build faster), then
+it will be created as 'program'. This is so that you can run the program
+before you install it. If it is linked with shared libraries, a wrapper script
+does some magic with LD_LIBRARY_PATH. However, this means that your install
+rules must take this into account by checking that '.libs/program exists', and
+installing it if it is present, but otherwise installing 'program'. Automake
+install rules do this automatically, but it you write your own, you must take
+this into consideration.
+
+
+10. Testing changes to the build scripts
+---------------------------------------
+
+If you make a change to one of the scripts, simply running autogen.sh and
+seeing if 'make' and 'make install' work is not enough. In particular, you
+must check that it does not break 'VPATH' builds where the source and build
+directories are not the same.
+To do this:
+
+ $ mkdir /var/tmp/tmp-build
+ $ cd /var/tmp/tmp-build
+ $ ~roger/gimp-print/current/configure --with-cups
+ $ make
+ $ make DESTDIR=/var/tmp/tmp-inst install
+
+You should also test that 'make install' works with and without DESTDIR set.
+Note that the current stable gettext release does not support DESTDIR, but the
+CVS version does. The current gettext also breaks in VPATH due to
+MKINSTALLDIRS being wrongly defined. This is also fixed in CVS.
+
+
+11. Further information
+-----------------------
+
+autoconf: autoconf.info
+automake: automake.info
+CVS: cvs.info
+gettext: gettext.info (but it's not very comprehensive)
+libtool: libtool.info
+make: make.info
+
+
+12. Known problems
+------------------
+
+If you have a version of the Gimp older than about 1.1.27, your
+gimp.m4 (in /usr/share/aclocal or equivalent) will be incorrect. You
+should install the version of gimp.m4 from scripts/ prior to use.
+This should only be a problem when building from CVS; the configure
+script included in released versions will not have this problem.
diff --git a/doc/appendices.texi b/doc/appendices.texi
new file mode 100644
index 0000000..0170e74
--- /dev/null
+++ b/doc/appendices.texi
@@ -0,0 +1,15 @@
+@node Appendices, Data Type and Variable Index, Problems, Top
+@chapter Appendices
+@cindex Appendices
+
+@menu
+* Dithering:: Dither algorithms.
+* Weaving:: Weaving algorithms.
+* ESC/P2:: Epson ESC/P2 printer control language.
+* New Printer:: Adding a new printer to libgimpprint.
+@end menu
+
+@include dither.texi
+@include weave.texi
+@include escp2.texi
+@include new-printer.texi
diff --git a/doc/copying.texi b/doc/copying.texi
new file mode 100644
index 0000000..2422223
--- /dev/null
+++ b/doc/copying.texi
@@ -0,0 +1,28 @@
+@node Copying, Overview, Instructions, Top
+@include gpl.texi
+
+@unnumbered Copying summary
+GIMP-Print is @dfn{free}; this means that everyone is free to use it and
+free to redistribute it on a free basis. GIMP-Print is not in the public
+domain; it is copyrighted and there are restrictions on its
+distribution, but these restrictions are designed to permit everything
+that a good cooperating citizen would want to do. What is not allowed is
+to try to prevent others from further sharing any version of GIMP-Print
+that they might get from you.
+
+Specifically, we want to make sure that you have the right to give away
+copies of GIMP-Print, that you receive source code or else can get it if
+you want it, that you can change GIMP-Print or use pieces of it in new
+free programs, and that you know you can do these things.
+
+To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights. For example, if you distribute
+copies of GIMP-Print, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must tell them their rights.
+
+Also, for our own protection, we must make certain that everyone finds
+out that there is no warranty for GIMP-Print. If GIMP-Print is modified
+by someone else and passed on, we want their recipients to know that
+what they have is not what we distributed, so that any problems
+introduced by others will no reflect on our reputation.
diff --git a/doc/dither.texi b/doc/dither.texi
new file mode 100644
index 0000000..f0b363e
--- /dev/null
+++ b/doc/dither.texi
@@ -0,0 +1,504 @@
+@node Dithering, Weaving, Appendices, Appendices
+@appendix Dithering
+@cindex dithering
+
+The dithering code in @file{print-dither.c} attempts to reproduce
+various shades of gray (or all colors) from only a few different inks
+(black, cyan, magenta, yellow, and sometimes light cyan and light
+magenta). The dots can't vary in darkness or size (except for certain
+special printers), and so we need to lay down a certain fraction of dots
+to represent each distinct level.
+
+This sounds straightforward; in practice, it isn't. Completely random
+distribution of dots (simple probabilistic dithering) would create
+grainy clumps and light spots. The smoothest pattern results from an
+equidistant spacing of dots. Approximating this requires sophisticated
+algorithms. We have two dithering algorithms, an ordered dither
+algorithm that uses a grid (matrix) to decide whether to print, and a
+modified Floyd-Steinberg error diffusion algorithm that uses a grid in a
+slightly different way.
+
+
+We currently have three dithering functions:
+
+@enumerate
+@item
+@code{dither_fastblack} produces pure black or white from a pre-dithered
+input. This is used for two purposes: for printing pure black and white
+very quickly (e. g. text), and for printing pre-screened monochrome
+output that was rasterized externally.
+
+@item
+@code{dither_black} produces black from grayscale input. The new
+dither_black can produce either a single or multiple levels of black,
+for printers supporting variable dot size.
+
+@item
+@code{dither_cmyk} produces 3, 4, 5, 6, or 7 color output (CMY, CMYK,
+CcMmYK, CcMmYy, CcMmYyK, or any variants). The new routine can handle
+single or multiple levels of each color.
+@end enumerate
+
+There is a choice of dithering algorithms. Four of them are based on a
+basic error diffusion, with a few tweaks of my own. The other one is
+`ordered'. However, they all share the basic operation in common.
+First, the algorithm picks what kind of dot (if there are multiple dot
+sizes and/or tones that may be picked) is the candidate to be printed.
+This decision is made based on the darkness at the point being dithered.
+Then, it decides whether the dot will be printed at all. What this is
+based on depends upon which algorithm family we use. This is all
+described in more detail below.
+
+
+Ordered dithering works by comparing the value at a given point with the
+value of a tiled matrix. If the value at the point is greater than the
+value in the matrix, the dot is printed. The matrix should consist of a
+set of evenly spaced points between 0 and the upper limit. The choice
+of matrix is very important for print quality. A good dither matrix
+will emphasize high frequency components, which distributes dots evenly
+with a minimum of clumping. The matrices used here are all simple
+matrices that are expanded recursively to create larger matrices with
+the same kind of even point distribution. This is described below.
+
+Note that it is important to use different matrices for the two
+sub-operations, because otherwise the choice about whether to print and
+the choice of dot size will be correlated. The usual result is that the
+print is either too dark or too light, but there can be other problems.
+
+Ordered dithering works quite well on single dot size, four color
+printers. It has not been well tested on four color, variable dot size
+printers. It should be avoided on six color printers.
+
+
+Error diffusion works by taking the output error at a given pixel and
+``diffusing'' it into surrounding pixels. Output error is the
+difference between the amount of ink output and the input level at each
+pixel. For simple printers, with one or four ink colors and only one
+dot size, the amount of ink output is either 65536 (i. e. full output)
+or 0 (no output). The difference between this and the input level is
+the error. Normal error diffusion adds part of this error to the
+adjoining pixels in the next column and the next row (the algorithm
+simply scans each row in turn, never backing up). The error adds up
+until it reaches a threshold (half of the full output level, or 32768),
+at which point a dot is output, the output is subtracted from the
+current value, and the (now negative) error is diffused similarly.
+
+Error diffusion works quite well in general, but it tends to generate
+artifacts which usually appear as worm-like lines or areas of anomalous
+density. I have devised some ways, as described below, of ameliorating
+these artifacts.
+
+There are two sub-classes of error diffusion that we use here, `random'
+and `hybrid'. One of the techniques that we use to ameliorate the
+artifacts is to use a fuzzy threshold rather than the hard threshold of
+half of the output level. Random error diffusion uses a pseudo-random
+number to perturb the threshold, while hybrid error diffusion uses a
+matrix. Hybrid error diffusion worked very poorly in 3.1.3, and I
+couldn't figure out why until I found a bug. It now works very well.
+
+There is one additional variant (on both sub-classes), called `adaptive
+hybrid' and `adaptive random'. The adaptive variant takes advantage of
+the fact that the patterns that ordered dithering create are less
+visible at very low densities, while the artifacts created by error
+diffusion are more objectionable at low densities. At low densities,
+therefore, it uses ordered dithering; at higher densities it uses error
+diffusion.
+
+
+Handling multiple output levels makes life a bit more complicated. In
+principle, it shouldn't be much harder: simply figure out what the ratio
+between the available output levels is and have multiple thresholds. In
+practice, getting these right involves a lot of trial and error. The
+other thing that's important is to maximize the number of dots that have
+some ink. This will reduce the amount of speckling. More on this
+later.
+
+The next question: how do we handle black when printing in color? Black
+ink is much darker than colored inks. It's possible to produce black by
+adding some mixture of cyan, magenta, and yellow---in principle. In
+practice, the black really isn't very black, and different inks and
+different papers will produce different color casts. However, by using
+CMY to produce gray, we can output a lot more dots! This makes for a much
+smoother image. What's more, one cyan, one magenta, and one yellow dot
+produce less darkness than one black dot, so we're outputting that many
+more dots. Better yet, with 6 or 7 color printers, we have to output even
+more light ink dots. So Epson Stylus Photo printers can produce really
+smooth grays---if we do everything right. The right idea is to use
+CMY at lower black levels, and gradually mix in black as the overall
+amount of ink increases, so the black dots don't really become visible
+within the ink mass.
+
+Variable dot sizes are handled by dividing the range between 0 and
+65536 into segments. Each segment can either represent a range in
+which all of one kind of ink (color and/or dot size) is used, with
+varying amounts of ink, or a transition region between inks, in which
+equal numbers of dots are printed but the amount of each ink will be
+adjusted throughout the range. Each range is represented by four
+numbers:
+
+@enumerate
+@item
+bottom of the range
+@item
+top of the range
+@item
+value of the lighter ink
+@item
+value of the darker ink
+@end enumerate
+
+In addition, the bit patterns and which type of ink are also
+represented, but they don't affect the actual algorithm.
+
+
+As mentioned above, the basic algorithm is the same whether we use
+ordered dither or error diffusion. We perform the following steps on
+each color of each pixel:
+
+@enumerate
+@item
+Compute the value of the particular color we're printing. This isn't
+usually the pure CMY value; it's adjusted to improve saturation and to
+limit the use of black in light toned regions (to avoid speckling).
+
+@item
+Find the range containing this value.
+
+@item
+Compute where this value lies within the range. We scale the endpoints
+between 0 and 65536 for this purpose. So for example, if the bottom of
+the range is 10,000 and the top of the range is 20,000, and the value is
+12,500, we're 1/4 of the way between the bottom and the top of the
+range, so our scale point is 16384.
+
+@item
+Compute the ``virtual value''. The virtual value is the distance between
+the value of the lighter and the value of the darker ink. So if the
+value of the light ink is 32768 and the dark ink is 65536, we compute a
+virtual value scaled appropriately between these two values, which is
+40960 in this case.
+
+@item
+Using either error diffusion or ordered dither, the standard threshold
+is 1/2 of the value (20480 in this case). Using ordered dither, we want
+to compute a value between 0 and 40960 that we will compare the input
+value against to decide whether to print. Using pure error diffusion,
+we would compare the accumulated error against 20480 to decide whether
+to print. In practice, we use the same matrix method to decide whether
+to print. The correct amount of ink will be printed this way, but we
+minimize the squiggly lines characteristic of error diffusion by
+dithering the threshold in this fashion. A future enhancement will
+allow us to control the amount of dithering applied to the threshold.
+@end enumerate
+
+The matrices were generated by Thomas Tonino
+@email{<ttonino@@bio.vu.nl>} with an algorithm of his devising. The
+algorithm is designed to maximize the spacing between dots at any given
+density by searching the matrix for holes and placing a dot in the
+largest available hole. It requires careful selection of initial points
+to achieve good results, and is very time consuming. For best results,
+a different matrix must be used for modes with 2:1 aspect ratio
+(e.g. 1440x720) than for 1:1 (e. g. 720x720). It is essential with any
+of these matrices that every point be used. Skipping points generates
+low-frequency noise.
+
+It's essential to use different matrices for deciding whether to print
+and for deciding what color (dark or light) to print. This should be
+obvious; the decision about whether to print at all should be as
+independent as possible from the decision about what color to print,
+because any bias will result in excess light or dark ink being
+printed, shifting the tonal balance. We actually use the same
+matrices, but we shift them vertically and horizontally. Assuming
+that the matrices are not self-correlated, this will yield good
+results.
+
+The ranges are computed from a list of ink values (between 0 and 1 for
+each possible combination of dot size and ink tone, where the value
+represents the darkness of the ink) and the desired maximum density of
+the ink. This is done in dither_set_ranges, and needs more
+documentation.
+
+
+I stated earlier that I've tweaked the basic error diffusion algorithm.
+Here's what I've done to improve it:
+
+@enumerate
+@item
+We use a variable threshold to decide when to print, as discussed above.
+This does two things for us: it reduces the slightly squiggly diagonal
+lines that are the mark of error diffusion; and it allows us to lay down
+some ink even in very light areas near the edge of the image. The
+squiggly lines that error diffusion algorithms tend to generate are
+caused by the gradual accumulation of error. This error is partially
+added horizontally and partially vertically. The horizontal
+accumulation results in a dot eventually being printed. The vertical
+accumulation results in a dot getting laid down in roughly the same
+horizontal position in the next row. The diagonal squigglies result
+from the error being added to pixels one forward and one below the
+current pixel; these lines slope from the top right to the bottom left
+of the image.
+
+Error diffusion also results in pale areas being completely white near
+the top left of the image (the origin of the printing coordinates).
+This is because enough error has to accumulate for anything at all to
+get printed. In very pale areas it takes quite a long time to build up
+anything printable at all; this results in the bare spots.
+
+Randomizing the threshold somewhat breaks up the diagonals to some
+degree by randomizing the exact location that the accumulated output
+crosses the threshold. It reduces the false white areas by allowing
+some dots to be printed even when the accumulated output level is very
+low. It doesn't result in excess ink because the full output level is
+still subtracted and diffused.
+
+Excessive randomization leads to blobs at high densities. Therefore, as
+the density increases, the degree of randomization decreases.
+
+@item
+Alternating scan direction between rows (first row is scanned left to
+right, second is scanned right to left, and so on). This also helps
+break up white areas, and it also seems to break up squigglies a bit.
+Furthermore, it eliminates directional biases in the horizontal
+direction. This isn't necessary for ordered dither, but it doesn't hurt
+either.
+
+@item
+Diffusing the error into more pixels. Instead of diffusing the entire
+error into @math{(X+1, Y)} and @math{(X, Y+1)}, we diffuse it into
+@math{(X+1, Y)}, @math{(X+K, Y+1)}, @math{(X, Y+1)}, @math{(X-K, Y+1)}
+where @math{K} depends upon the output level (it never exceeds about 10
+dots, and is greater at higher output levels). This really reduces
+squigglies and graininess. The amount of this spread can be controlled;
+for line art, it should be less than for photographs (of course, line
+art doesn't usually contain much light color, but the @strong{error}
+value can be small in places!) In addition to requiring more
+computation, a wide ink spread results in patterning at high dot
+densities (note that the dot density can be high even in fairly pale
+regions if multiple dot sizes are in use).
+
+@item
+Don't lay down any colored ink if we're laying down black ink. There's
+no point; the colored ink won't show. We still pretend that we did for
+purposes of error diffusion (otherwise excessive error will build up,
+and will take a long time to clear, resulting in heavy bleeding of ink
+into surrounding areas, which is very ugly indeed), but we don't bother
+wasting the ink. How well this will do with variable dot size remains
+to be seen.
+
+@item
+Oversampling. This is how to print 1440x720 with Epson Stylus printers.
+Printing full density at 1440x720 will result in excess ink being laid
+down. The trick is to print only every other dot. We still compute the
+error as though we printed every dot. It turns out that randomizing
+which dots are printed results in very speckled output. This can be
+taken too far; oversampling at 1440x1440 or 1440x2880 virtual resolution
+results in other problems. However, at present 1440x1440 (which is more
+accurately called "1440x720 enhanced", as the Epson printers cannot
+print 1440 rows per inch) does quite well, although it's slow.
+@end enumerate
+
+What about multiple output levels? For 6 and 7 color printers, simply
+using different threshold levels has a problem: the pale inks have trouble
+being seen when a lot of darker ink is being printed. So rather than
+just using the output level of the particular color to decide which ink
+to print, we look at the total density (sum of all output levels).
+If the density's high enough, we prefer to use the dark ink. Speckling
+is less visible when there's a lot of ink, anyway. I haven't yet figured
+out what to do for multiple levels of one color.
+
+You'll note that I haven't quoted a single source on color or printing
+theory. I simply did all of this empirically.
+
+There are various other tricks to reduce speckling. One that I've seen
+is to reduce the amount of ink printed in regions where one color
+(particularly cyan, which is perceived as the darkest) is very pale.
+This does reduce speckling all right, but it also results in strange
+tonal curves and weird (to my eye) colors.
+
+
+
+Before any dither routine is used, @code{init_dither()} must be called.
+This takes three arguments: the input width (number of pixels in the
+input), the output width (number of pixels in the output), and a
+@code{vars_t} structure containing the parameters for the print job.
+
+@code{init_dither()} returns a pointer to an opaque object representing
+the dither. This object is passed as the first argument to all of the
+dither-related routines.
+
+After a page is fully dithered, @code{free_dither()} must be called to
+free the dither object and perform any cleanup. In the future, this may
+do more (such as flush output). This arrangement permits using these
+routines with programs that create multiple output pages, such as
+GhostScript.
+
+The dithering routines themselves have a number of control knobs that
+control internal aspects of the dithering process. These knobs are
+accessible via a number of functions that can be called after
+@code{init_dither()}.
+
+@itemize @bullet
+@item
+@code{dither_set_density()} takes a double between 0 and 1 representing
+the desired ink density for printing solid colors. This is used in a
+number of places in the dithering routine to make decisions.
+
+@item
+@code{dither_set_black_density()} takes a double between 0 and 1
+representing the desired ink density for printing black ink in color
+printing. This is used to balance black against color ink. By default,
+this is equal to the density set by @code{dither_set_density()}. By
+setting it higher, more black ink will be printed. For example, if the
+base density is .4 and the black density is .8, twice as much black ink
+will be printed as would otherwise be called for.
+
+This is not used when printing in monochrome. When printing monochrome,
+the base density (@code{dither_set_density}) should be adjusted
+appropriately.
+
+@item
+@code{dither_set_ink_budget()} takes an unsigned number representing the
+most ink that may be deposited at a given point. This number is
+arbitrary; the limit is computed by summing the size of each ink dot,
+which is supplied as a parameter in @code{dither_set_@var{X}_ranges}.
+By default, there is no limit.
+
+@item
+@code{dither_set_black_lower()} takes a double that should be between 0
+and 1 that represents the lowest density level at which black ink will
+start to mix in with colored ink to generate grays. The lower this is,
+the less density is required to use black ink. Setting this too low
+will result in speckling from black dots, particularly on 6 and 7 color
+printers. Setting this too high will make it hard to get satisfactory
+black or may result in sharp transition between blended colors and
+black. Default: 0.0468.
+
+It is important to note that since the density scale is never linear
+(and since this value is adjusted via other things happening during the
+dithering process) that this does not mean that 95% gray will use any
+black ink. At this setting, there will be no black ink used until about
+50% gray.
+
+This only applies to color mode.
+
+This value should be set lower for printers capable of variable dot
+size, since more dots can be laid down close to each other.
+
+@item
+@code{dither_set_black_upper()} takes a double that should be between 0
+and 1 that represents the highest density level at which colored inks
+will be mixed to create gray. Setting this too low will result in
+speckly dark grays because there is not enough ink to fill all the
+holes, or sharp transition between blended colors and black if it is too
+close to the value of dither_set_black_upper(). Setting this too high
+will result in poor black and dark tone quality. Default: 0.5. This
+results in 10% and darker grays being printed with essentially all
+black.
+
+This only applies to color mode.
+
+@item
+@code{dither_set_black_levels()} takes three doubles that represent the
+amount of cyan, magenta, and yellow respectively that are blended to
+create gray. The defaults are 1.0 for each, which is probably too low
+for most printers. These values are adjusted to create a good gray
+balance. Setting these too low will result in pale light and midtone
+grays, with a sharp transition to darker tones as black mixes in.
+Setting them too high will result in overly dark grays and use of too
+much ink, possibly creating bleed-through.
+
+This only applies to color mode.
+
+@item
+@code{dither_set_randomizers()} takes four integer values representing
+the degree of randomness used for cyan, magenta, yellow, and black.
+This is used to allow some printing to take place in pale areas. Zero
+is the most random; greater than 8 or so gives very little randomness at
+all. Defaults are 0 for cyan, magenta, and yellow, and 4 for black.
+Setting the value for black too low will result in black speckling in
+pale areas. Setting values too high will result in pale areas getting
+no ink at all.
+
+This currently only applies to single dot size in color and black. It
+should be extended to operate in variable dot size mode, although
+actually applying it correctly will be tricky.
+
+@item
+@code{dither_set_ink_darkness()} takes three doubles representing the
+contribution to perceived darkness of cyan, magenta, and yellow. This
+is used to help decide when to switch between light and dark inks in 6
+and 7 color printers (with light cyan, light magenta, and possibly light
+yellow). Setting these too low will result in too much light ink being
+laid down, creating flat spots in the darkness curves and bleed-through.
+Setting them too high will result in dark ink being used in pale areas,
+creating speckle. The defaults are .4 for cyan, .3 for magenta, and .2
+for yellow. Dark cyan will show against yellow much more than dark
+magenta will show against cyan, since the cyan appears much darker than
+the yellow.
+
+@item
+@code{dither_set_light_inks()} takes three doubles between 0 and 1
+representing the ratio in darkness between the light and dark versions
+of the inks. Setting these too low will result in too much dark ink
+being used in pale areas, creating speckling, while setting them too
+high will result in very smooth texture but too much use of light ink,
+resulting in flat spots in the density curves and ink bleed-through.
+There are no defaults. Any light ink specified as zero indicates that
+there is no light ink for that color.
+
+This only applies to 6 and 7 color printers in single dot size color
+mode, and only to those inks which have light versions (usually cyan and
+magenta).
+
+@item
+@code{dither_set_ink_spread()} takes a small integer representing the
+amount of ink spread in the dither. Larger numbers mean less spread.
+Larger values are appropriate for line art and solid tones; they will
+yield sharper transitions but more dither artifacts. Smaller values are
+more appropriate for photos. They will reduce resolution and sharpness
+but reduce dither artifacts up to a point. A value of 16 or higher
+implies minimum ink spread at any resolution no matter what the
+overdensity. A value of 14 is typical for photos on single dot size, 6
+color printers. For 4 color printers, subtract 1 (more spread; the dots
+are farther apart). For variable dot size printers, add 1 (more small
+dots are printed; less spread is desirable).
+
+@item
+@code{dither_set_adaptive_divisor()} takes a float representing the
+transition point between error diffusion and ordered dither if adaptive
+dithering is used. The float is a fraction of the printing density.
+For example, if you wish the transition to be at 1/4 of the maximum
+density (which works well on simple 4-color printers), you would pass
+.25 here. With six colors and/or with multiple dot sizes, the values
+should be set lower.
+
+@item
+@code{dither_set_transition()} takes a float representing the exponent
+of the transition curve between light and dark inks/dot sizes. A value
+less than 1 (typical when using error diffusion) mixes in less dark
+ink/small dots at lower ends of the range, to reduce speckling. When
+using ordered dithering, this must be set to 1.
+
+@item
+@code{dither_set_@var{X}_ranges_simple} (@var{X}=@samp{c}, @samp{m},
+@samp{y}, or @samp{k}) describes the ink choices available for each
+color. This is useful in typical cases where a four color printer with
+variable dot sizes is in use. It is passed an array of doubles between
+(0, 1] representing the relative darkness of each dot size. The dot
+sizes are assigned bit patterns (and ink quantities, see
+@code{dither_set_ink_budget()} above) from 1 to the number of levels.
+This also requires a density, which is the desired density for this
+color. This density need not equal the density specified in
+@code{dither_set_density()}. Setting it lower will tend to print more
+dark ink (because the curves are calculated for this color assuming a
+lower density than is actually supplied).
+
+@item
+@code{dither_set_@var{X}_ranges} (@var{X}=@samp{c}, @samp{m}, @samp{y},
+or @samp{k}) describes in a more general way the ink choices available
+for each color. For each possible ink choice, a bit pattern, dot size,
+value (i. e. relative darkness), and whether the ink is the dark or
+light variant ink is specified.
+@end itemize
+
+---Robert Krawitz @email{<rlk@@alum.mit.edu>} May 8, 2000
diff --git a/doc/escp2.texi b/doc/escp2.texi
new file mode 100644
index 0000000..db6f057
--- /dev/null
+++ b/doc/escp2.texi
@@ -0,0 +1,919 @@
+@node ESC/P2, New Printer, Weaving, Appendices
+@appendix ESC/P2
+@cindex ESC/P2
+
+@menu
+* ESC/P2 Introduction:: What is ESC/P2
+* ESC/P2 Standard Commands:: Normal ESC/P2 commands
+* ESC/P2 Remote Mode Commands:: Exotic ESC/P2 commands
+* ESC/P2 Appropriate Remote Commands:: Useful remote command sequences
+@end menu
+
+@node ESC/P2 Introduction, ESC/P2 Standard Commands, , ESC/P2
+@appendixsection Introduction to ESC/P2
+@cindex ESC/P2 introduction
+
+This is a description of the ESC/P2 raster commands used by the
+gimp-print plugin and Ghostscript driver, which is a subset of the
+complete command set. The full documents are found on
+@url{http://www.ercipd.com/isv/edr_docs.htm}. Note that these are
+@strong{not} always correct, and are certainly not complete.
+
+All ESCP/2 raster commands begin with the @samp{ESC} character (1b hex),
+followed by either one or two command characters and arguments where
+applicable. Older commands generally have one command character. Newer
+commands usually have a @samp{(} (left parenthesis) followed by a
+command character and a byte count for the arguments that follow. The
+byte count is a 16-bit (2 byte) binary integer, in little endian order.
+
+All arguments listed here are of the form @samp{name[bytes]} where
+@samp{[bytes]} is the number of bytes that comprise the argument. The
+arguments themselves are usually one, two, or four byte integers, always
+little endian (the least significant bits come first). Presumably this
+is to match Intel processors.
+
+In some cases, the same command sequence identifies different versions
+of the same command, depending upon the number of bytes of arguments.
+
+
+@node ESC/P2 Standard Commands, ESC/P2 Remote Mode Commands, ESC/P2 Introduction, ESC/P2
+@appendixsection Standard commands
+
+@deffn {ESC/P2 command} @code{ESC @@}
+Reset the printer. Discards any output, ejects the existing page,
+returns all settings to their default. Always use this before printing
+a page.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (G @var{BC}=1 @var{ON1}}
+Turn on graphics mode. @var{ON} should be @samp{1} (turn on graphics
+mode).
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (U @var{BC}=1 @var{UNIT1}}
+Set basic unit of measurement used by printer. This is expressed in
+multiples of 1/3600". At 720 DPI, @var{UNIT} is @samp{5}; at 360 DPI,
+@var{UNIT} is @samp{10}.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (U @var{BC}=5 @var{PAGEUNITS1} @var{VUNIT1} @var{HUNIT1} @var{BASEUNIT2}}
+Set basic units of measurement used by the printer. @var{PAGEUNIT} is
+the unit of page measurement (for commands that set page dimensions and
+the like). @var{VUNIT} is the unit of vertical measurement (for
+vertical movement commands). @var{HUNIT} is the unit of horizontal
+movement (for horizontal positioning commands). All of these units are
+expressed in @var{BASEUNIT}, which is in reciprocal inches. Typically,
+@var{BASEUNIT} is @samp{1440}. In 720 DPI mode, @var{PAGEUNIT},
+@var{VUNIT}, and @var{HUNIT} are all @samp{2}; in 1440x720 DPI mode,
+@var{PAGEUNIT} and @var{VUNIT} are normally set to @samp{2}; @var{HUNIT}
+is set to @samp{1}.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (K @var{BC}=2 @var{ZERO1} @var{GRAYMODE1}}
+Set color or grayscale mode, on printers supporting an explicit
+grayscale mode. These printers can be identified because they are
+advertised as having more black nozzles than nozzles of individual
+colors. Setting grayscale mode allows use of these extra nozzles for
+faster printing. @var{GRAYMODE} should be @samp{0} or @samp{2} for
+color, @samp{1} for grayscale. @var{ZERO} should always be @samp{0}.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (i @var{BC}=1 @var{MICROWEAVE1}}
+If @var{MICROWEAVE} is @samp{1}, use microweave mode. On older
+printers, this is used to turn on microweave; on newer printers, it
+prints one row at a time. All printers support this mode. It should
+only be used at 720 (or 1440x720) DPI. The Epson Stylus Pro series
+indicates additional modes:
+
+@table @samp
+@item 2
+``Full-overlap''
+@item 3
+``Four-pass''
+@item 4
+``Full-overlap 2''
+@end table
+
+Any of these commands can be used with the high four bits set to either
+@samp{3} or @samp{0}.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC U @var{DIRECTION1}}
+If @var{DIRECTION} is @samp{1}, print unidirectionally; if @samp{0},
+print bidirectionally.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (s @var{BC}=1 @var{SPEED1}}
+On some older printers, this controls the print head speed. @var{SPEED}
+of @samp{2} is 10 inches/sec; SPEED of @samp{0} or 1 is 20.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (e @var{BC}=2 @var{ZERO1} @var{DOTSIZE1}}
+Choose print dotsize. @var{DOTSIZE} can take on various values,
+depending upon the printer. Almost all printers support @samp{0} and
+@samp{2}. Variable dot size printers allow a value of @var{16}. Other
+than the value of @var{16}, this appears to be ignored at resolutions of
+720 DPI and above.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (C @var{BC}=2 @var{PAGELENGTH2}}
+@deffnx {ESC/P2 command} @code{ESC (C @var{BC}=4 @var{PAGELENGTH4}}
+Set the length of the page in "pageunits" (see @samp{ESC (U} above).
+The second form of the command allows setting of longer page lengths on
+new printers (these happen to be the printers that support variable dot
+size).
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (c @var{BC}=4 @var{TOP2} @var{LENGTH2}}
+@deffnx {ESC/P2 command} @code{ESC (c @var{BC}=8 @var{TOP4} @var{LENGTH4}}
+Set the vertical page margins of the page in "pageunits" (see @samp{ESC
+(U} above). The margins are specified as the top of the page and the
+length of the page. The second form of the command allows setting of
+longer page lengths on new printers (these happen to be the printers
+that support variable dot size).
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (S @var{BC}=8 @var{WIDTH4} @var{LENGTH4}}
+Set the width and length of the printed page region in "pageunits" (see
+@samp{ESC (U} above).
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (v @var{BC}=2 @var{ADVANCE2}}
+@deffnx {ESC/P2 command} @code{ESC (v @var{BC}=4 @var{ADVANCE4}}
+Feed vertically @var{ADVANCE} "vertical units" (see @samp{ESC (U} above)
+from the current print head position.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (V @var{BC}=2 @var{ADVANCE2}}
+@deffnx {ESC/P2 command} @code{ESC (V @var{BC}=4 @var{ADVANCE4}}
+Feed vertically @var{ADVANCE} "vertical units" (see @samp{ESC (U} above)
+from the top margin.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC ($ @var{BC}=4 @var{OFFSET4}}
+Set horizontal position to @var{OFFSET} from the left margin. This
+command operates on printers of the 740 class and newer (all printers
+with variable dot size).
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC $ @var{OFFSET2}}
+Set horizontal position to @var{OFFSET} from the left margin. This
+command operates on printers of the 740 class and newer (all printers
+with variable dot size).
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (\ @var{BC}=4 @var{UNITS2} @var{OFFSET2}}
+Set horizontal position to @var{OFFSET} from the previous print head
+position, measured in @var{UNITS}. @var{UNITS} is measured in inverse
+inches, and should be set to 1440 in all cases. This operates on all
+1440 dpi printers that do not support variable dot size.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (/ @var{BC}=4 @var{OFFSET4}}
+Set horizontal position to @var{OFFSET} from the previous print head
+position, measured in "horizontal units" (see @samp{ESC (U} above).
+This operates on all variable dot size printers.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC \ @var{OFFSET2}}
+Set horizontal position to @var{OFFSET} from the previous print head
+position, measured in basic unit of measurement (see @samp{ESC (U}
+above). This is used on all 720 dpi printers, and can also be used on
+1440 dpi printers in lower resolutions to save a few bytes. Note that
+@var{OFFSET} may be negative. The range of values for this command is
+between @samp{-16384} and @samp{16383}.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC r @var{COLOR1}}
+@deffnx {ESC/P2 command} @code{ESC (r @var{BC}=2 @var{DENSITY1} @var{COLOR1}}
+Set the ink color. The first form is used on four-color printers; the
+second on six-color printers. @var{DENSITY} is @samp{0} for dark inks,
+@samp{1} for light. @var{COLOR} is
+
+@table @samp
+@item 0
+black
+@item 1
+magenta
+@item 2
+cyan
+@item 4
+yellow
+@end table
+
+This command is not used on variable dot size printers in softweave
+mode.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC . @var{COMPRESS1} @var{VSEP1} @var{HSEP1} @var{LINES1} @var{WIDTH2} @var{data...}}
+ Print data. @var{COMPRESS} signifies the compression mode:
+
+@table @samp
+@item 0
+no compression
+@item 1
+TIFF compression (incorrectly documented as "run length encoded")
+@item 2
+TIFF compression with a special command set.
+@end table
+
+@var{VSEP} depends upon resolution and printer type. At 360 DPI, it is
+always @samp{10}. At 720 DPI, it is normally @samp{5}5. On the ESC
+600, it is @samp{40} (@math{8 * 5}). On some other printers, it varies.
+
+@var{HSEP1} is @samp{10} at 360 DPI and @samp{5} at 720 or 1440 DPI
+(1440 DPI cannot be printed in one pass; it is printed in two passes,
+with the dots separated in each pass by 1/720").
+
+@var{LINES} is the number of lines to be printed. It should be @samp{1}
+in microweave and 360 DPI. At 720 DPI softweave, it should be the
+number of lines to be actually printed.
+
+@var{WIDTH} is the number of pixels to be printed in each row.
+Following this command, a carriage return (@samp{13} decimal, @samp{0A}
+hex) should be output to return the print head position to the left
+margin.
+
+The basic data format is a string of bytes, with data from left to right
+on the page. Within each byte, the highest bit is first.
+
+The TIFF compression is implemented as one count byte followed by one or
+more data bytes. There are two cases:
+
+@enumerate
+@item
+If the count byte is @samp{128} or less, it is followed by @math{[count]
++ 1} data bytes. So if the count byte is @samp{0}, it is followed by 1
+data byte; if it is @samp{128}, it is followed by 129 data bytes.
+
+@item
+If the count byte is greater than 128, it is followed by one byte. This
+byte is repeated (257 - [count]) times. So if [count] is 129, the next
+byte is treated as though it were repeated 128 times; if [count] is 255,
+it is treated as though it were repeated twice.
+@end enumerate
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC i @var{COLOR1} @var{COMPRESS1} @var{BITS1} @var{BYTES2} @var{LINES2} @var{data...}}
+Print data in the newer printers (that support variable dot size), and
+Stylus Pro models.
+
+@var{COLOR} is the color:
+
+@table @samp
+@item 0
+black
+@item 1
+magenta
+@item 2
+cyan
+@item 4
+yellow
+@item 17
+light magenta
+@item 18
+light cyan
+@end table
+
+@var{COMPRESS} signifies the
+compression mode:
+
+@table @samp
+@item 0
+no compression
+@item 1
+TIFF compression (incorrectly documented as "run length encoded")
+@item 2
+TIFF compression with a special command set.
+@end table
+
+@var{BITS} is the number of bits per pixel.
+
+@var{BYTES} is the number of bytes wide for each row (@math{ceiling(BITS
+* width_of_row, 8)}). Note that this is different from the @samp{ESC .}
+command above.
+
+@var{LINES} is the number of lines to be printed. This command is the
+only way to get variable dot size printing. In variable dot mode, the
+size of the dots increases as the value (@samp{1}, @samp{2}, or
+@samp{3}) increases.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (D @var{BC}=4 @var{BASE2} @var{VERTICAL1} @var{HORIZONTAL1}}
+Set printer horizontal and vertical spacing. It only applies to
+variable dot size printers in softweave mode (and possibly other high
+end printers).
+
+@var{BASE} is the base unit for this command; it must be @samp{14400}.
+
+@var{VERTICAL} is the distance in these units between printed rows; it
+should be (@math{separation_in_nozzles * BASE / 720}).
+
+@var{HORIZONTAL} is the horizontal separation between dots in a row.
+Depending upon the printer, this should be either (@math{14400 / 720})
+or (@math{14400 / 360}). The Stylus Pro 9000 manual suggests that the
+settings should match the chosen resolution, but that is apparently not
+the case (or not always the case) on other printers.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC (R @var{BC}=8 00 R E M O T E 1}
+Enters ``remote mode''. This is a special, undocumented command set that
+is used to set up various printer options, such as paper feed tray, and
+perform utility functions such as head cleaning and alignment. It does
+not appear that anything here is actually required to make the printer
+print. Our best understanding of what is in a remote command sequence
+is described in a separate section below.
+@end deffn
+
+@deffn {ESC/P2 command} @code{ESC 01 @@EJL [sp] ID\r\n}
+Return the printer ID. This is considered a remote mode command,
+although the syntax is that of a conventional command. This returns the
+following information:
+
+@example
+@@EJL ID\r
+MFG:EPSON;
+CMD:ESCPL2,BDC;
+MDL:[printer model];
+CLS:PRINTER;
+DES:EPSON [printer model];
+\f
+@end example
+@end deffn
+
+After all data has been sent, a form feed byte should be sent.
+
+All newer Epson printers (STC 440, STP 750) require the following
+command to be sent at least once to enable printing at all. This
+command specifically takes the printer out of the Epson packet mode
+communication protocol (whatever that is) and enables normal data
+transfer. Sending it multiple times is is not harmful, so it is
+normally sent at the beginning of each job:
+
+@example
+ESC 01@@EJL[space]1284.4[newline]@@EJL[space][space][space][space]
+[space][newline]ESC@@
+@end example
+
+The proper sequence of initialization commands is:
+
+@example
+magic command
+ESC @
+remote mode if needed
+ESC (G
+ESC (U
+ESC (K (if appropriate)
+ESC (i
+ESC U (if needed)
+ESC (s (if appropriate)
+ESC (e
+ESC (C
+ESC (c
+ESC (S
+ESC (D (if needed)
+ESC (V (optional -- this can be accomplished with ESC (v)
+@end example
+
+For printing, the proper sequence is:
+
+@example
+ESC (v
+@end example
+
+@noindent
+and repeat for each color:
+
+@example
+ESC ($ @r{or} ESC (\ @r{or} ESC \
+ESC (r @r{or} ESC r @r{(if needed---not used with @samp{ESC i} and not needed if the color
+has not changed from the previous printed line)}
+ESC . @r{or} ESC i ...data... [return] (0A hex)
+@end example
+
+To terminate a page:
+
+@example
+[formfeed] (0C hex)
+ESC @@
+@end example
+
+
+@node ESC/P2 Remote Mode Commands, ESC/P2 Appropriate Remote Commands, ESC/P2 Standard Commands, ESC/P2
+@appendixsection Remote Mode Commands
+
+The following description of remote commands comes out of an
+examination of the sequences used by the printer utilities bundled
+with the Windows drivers for the ESC740, and from other sources (some
+Epson manuals, experimentation, analysis of print files). It is
+largely speculative as these commands are not all documented in the
+Epson documentation we have access to. Generally, newer manuals
+provide more thorough documentation.
+
+Remote command mode is entered when the printer is sent the following
+sequence:
+
+@example
+ESC (R BC=8 00 R E M O T E 1
+@end example
+
+Remote mode commands are then sent, and terminated with the following
+sequence:
+
+@example
+ESC 00 00 00
+@end example
+
+All remote mode commands must be sent before the initial @samp{ESC (G}
+command is sent.
+
+This introductory sequence is then followed by a sequence of commands.
+Each command is constructed as follows:
+
+@itemize
+@item Two ASCII bytes indicating the function
+@item A byte count (two bytes, little-endian) for the parameters
+@item Binary parameters, if any
+@end itemize
+
+This is a list of all remote commands we have seen:
+
+@deffn {ESC/P2 remote command} @code{NC @var{BC}=2 00 00}
+Print a nozzle check pattern
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{VI @var{BC}=2 00 00}
+on my 740, prints the following:
+
+@example
+W01286 I02382\r\n
+@end example
+
+@noindent
+probably ``version information''
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* AI @var{BC}=3 00 00 00}
+Prints a ``printer ID''. On one 870, prints the following:
+@example
+51-51-50-51-49-48\r\n
+@end example
+
+The Windows driver has a text entry field where this number can be
+entered, but its purpose is unknown.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* LD @var{BC}=0}
+Load printer defaults from NVRAM, DIP switches, and/or ROM. This
+apparently does not load factory defaults per se, but any settings that
+are saved. This is commonly used right at the end of each print job
+after the @samp{ESC @@} printer reset command.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* CH @var{BC}=2 00 @var{xx}}
+Perform a head cleaning cycle. The heads to clean are determined by
+parameter @var{xx}:
+
+@table @samp
+@item 00
+clean all heads
+@item 01
+clean black head
+@item 02
+clean color heads
+@end table
+
+While @var{xx} = @samp{00} is probably supported by all printers, @var{xx} =
+@samp{01} and @samp{02} may well not be.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* DT @var{BC}=3 00 @var{xx} 00}
+Print an alignment pattern. There are three patterns, which are picked
+via the choice of @var{xx}. Pattern @samp{0} is coarse, pattern
+@samp{1} is medium, and pattern @samp{2} is fine.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* DU @var{BC}=6 00 @var{xx} 00 09 00 @var{yy}}
+Print another alignment pattern. It isn't entirely clear what @var{xx}
+and @var{yy} are, but it appears that @var{xx} takes on the values
+@samp{1} and @samp{2} , and @var{yy} takes on the values @samp{0} and
+@var{1}. This may only work on the 580 and/or 480.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* DA @var{BC}=4 00 @var{xx} 00 @var{yy}}
+Set results for the first alignment pattern. @var{xx} is the pattern
+(@samp{1}--@samp{3}); @var{yy} is the best choice from the set
+(@samp{1}--@samp{7} or @samp{1}--@samp{15}). This does not save to
+NVRAM, so when the printer is powered off, the setting will be lost.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* DA @var{BC}=6 00 @var{xx} 00 @var{yy} 09 00}
+Set results for alternate alignment pattern. @var{xx} appears to be the
+pass, and @var{yy} appears to be the optimum pattern. This does not
+save to NVRAM, so when the printer is powered off, the setting will be
+lost.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* SV @var{BC}=0}
+Save the current settings to NVRAM.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* RS @var{BC}=1 01}
+Reset the printer.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* IQ @var{BC}=1 01}
+Get ink quantity. This requires direct access to the printer port. The
+return looks like
+
+@example
+IQ:KKCCMMYY
+@end example
+
+@noindent
+or
+
+@example
+IQ:KKCCMMYYccmm
+@end example
+
+@noindent
+(for 4-color and 6-color printers respectively), where each pair of
+digits are hexadecimal representations of percent.
+@end deffn
+
+The following two commands have been observed on an STP 870.
+
+@deffn {ESC/P2 remote command} @code{* IR @var{BC}=2 00 @var{xx}}
+@strong{Function unknown}. This command has been observed on an STP 870
+with @var{xx}=@samp{03} at the start of a job and @var{xx}=@samp{02} at
+the end of a job (where it is followed by an @samp{LD} command). When
+in roll mode, the values change to @var{xx}=@samp{01} at the start of a
+job and @var{xx}=@samp{00} at the end of a job.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* FP @var{BC}=3 00 @var{xx} @var{yy}}
+@var{xx}=@samp{00} and @var{yy}=@samp{00} selects the printer's normal
+left margin (about 3mm). @var{xx}=@samp{0xb0} and @var{yy}=@samp{0xff}
+selects zero-margin mode, where the left-most print position is shifted
+to a point about 0.1" to the left of the left-hand edge of the paper,
+allowing printing up to (and off) the left-hand edge of the paper.
+@end deffn
+
+The commands below are partially documented in the Stylus Pro 9000
+manual. Much of this information is interpreted; none is tested.
+
+@deffn {ESC/P2 remote command} @code{* SN @var{BC}=3 00 @var{xx} @var{yy}}
+Select Mechanism Sequence. @var{xx} controls which sub-operation is
+performed. @var{xx}=@samp{00} selects the ``Feed paper sequence
+setting''. @var{yy} can take on the following values (on the STP 870,
+at any rate):
+
+@table @samp
+@item 0
+default
+@item 1
+plain paper
+@item 2
+postcards
+@item 3
+film (photo quality glossy film, transparencies)
+@item 4
+envelopes
+@item 5
+plain paper (fast load)
+@item 6
+back light film (although this has been observed with heavyweight matte
+paper)
+@item 7
+matte paper (observed with 360 dpi inkjet paper, and photo quality
+inkjet paper)
+@item 8
+photo paper
+@end table
+
+Experimentation suggests that this setting changes details of how the
+printers' cut sheet feeder works, presumably to tune it for different
+types of paper.
+
+@var{xx}=@samp{01} controls the platen gap setting; @var{yy}=@samp{00}
+is the default, @var{yy}=@samp{1} or @samp{2} are higher settings.
+
+@var{xx}=@samp{02} controls paper loading speed (@var{yy}=@samp{0} is
+normal, @samp{1} is fast, @samp{2} is slow). It appears that @samp{1}
+is used when printing on ``plain paper'', ``360dpi ink jet paper'' or
+``ink jet transparencies'', and @var{yy}=@samp{00} for all other paper
+type settings.
+
+@var{xx}=@samp{07} controls duplex printing for printers with that
+capability (@var{yy}=@var{0} is default, for non-duplex printing;
+@samp{1} is front side of the paper, and @var{2} is back side).
+
+@var{xx}=@samp{09} controls zero margin printing on the printers with
+the capability of printing zero-margin on all sides (Stylus Photo
+780/790, 890, and 1280/1290). @var{yy}=@samp{0} is the default;
+@samp{1} enables zero margin printing.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* PP @var{BC}=3 00 @var{xx} @var{yy}}
+Set Paper Path. @var{xx}=@samp{2} indicates manual feed,
+@var{xx}=@samp{3} is for roll paper. @var{yy} selects ``paper path
+number''.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* AC @var{BC}=2 00 @var{xx}}
+Set Auto Cutting State. @var{xx}=@samp{0} selects auto cutting off,
+@var{xx}=@samp{1} selects auto cutting on, and @var{xx}=@samp{2}
+indicates horizontal print page line on. It appears that with auto
+cutting on, roll paper is cut automatically at the point a formfeed
+character is sent. The formfeed character is normally used to eject a
+page; with this turned on, it also cuts the roll paper. Horizontal
+print page line on prints a narrow line of black dots at the position
+the paper should be cut manually.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* DR @var{BC}=4 00 xx @var{DT2}}
+Set Drying Time. @var{xx}=@samp{00} sets the drying time ``per scan''
+(per pass?); @var{xx}=@samp{01} sets the drying time per page. @var{DT}
+indicates the drying time, which is in seconds if page mode is used and
+in milliseconds if scan mode is used. @var{DT} must not exceed 3600
+seconds in per-page mode and 10000 milliseconds in per-scan mode.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* IK @var{BC}=2 00 @var{xx}}
+Select Ink Type. @var{xx}=@samp{00} selects dye ink. Pigment ink is
+apparently selected by @var{xx}=@samp{01}. This probably does not apply
+to the consumer-grade printers.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* PZ BC=2 00 xx}
+Set Pause After Printing. @var{xx}=@samp{00} selects no pause after
+printing; @var{xx}=@samp{01} selects pause after printing. If turned
+on, the printer is paused after the page is ejected (by the FF
+byte). If cutting is turned on, the printer is paused @strong{after}
+the cutting or printing of the horizontal cut line.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* EX @var{BC}=6 00 00 00 00 0x14 @var{xx}}
+Set Vertical Print Page Line Mode. @var{xx}=@samp{00} is off,
+@var{xx}=@samp{01} is on. If turned on, this prints vertical trim lines
+at the left and right margins.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* EX @var{BC}=6 00 00 00 00 0x05 @var{xx}}
+Set Roll Paper Mode. If @var{xx} is @samp{0}, roll paper mode is off;
+if @var{xx} is @samp{1}, roll paper mode is on.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* EX @var{BC}=3 00 @var{xx} @var{yy}}
+Appears to be a synonym for the @samp{SN} command described above.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* PH @var{BC}=2 00 @var{xx}}
+Select Paper Thickness. Set the paper thickness @var{xx} in .1 mm
+units. This must not exceed 0x10 (1.6 mm). If the thickness is set
+"more than" .6 mm (which probably means "at least" .6 mm, since the
+other case reads "less than 0.5 mm"), the platen gap is set high
+irrespective of the @samp{SN} command.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* PM @var{BC}=2 00 00}
+@strong{Function unknown}. Used on the STC 3000 at least when using roll
+feed, and on the STP 870 in all print files analysed to date.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* ST @var{BC}=2 00 @var{xx}}
+Epson's STP 750/1200 programming guide refers to the @samp{ST} command
+as ``Set printer state reply''. If @var{xx} is @samp{0} or @samp{2},
+the printer will not send status replies. If @var{xx} is @samp{1} or
+@samp{3}, the printer will send status replies. The status replies
+consist of state, error codes, ink leve, firmware version, and warning
+status.
+
+The actual reply is documented as
+
+@example
+@@BDC ST\r
+ST: xx;
+[ER: yy;]
+IQ: n1n2n3n4;
+[WR: w1,w2...;]
+RV: zz;
+AI:CW:02kkccmmyy, MI:mm
+[TC:tttt;]
+INK:...;
+\f
+@end example
+
+@noindent
+(@samp{\r} is carriage return; @samp{\n} is newline; @samp{\f} is
+formfeed.)
+
+@samp{ST} is the printer status:
+
+@table @samp
+@item 00
+Error
+@item 01
+Self-test
+@item 02
+Busy
+@item 03
+Waiting while printing
+@item 04
+Idle
+@item 07
+Cleaning/filling ink heads
+@item 08
+Not yet initialized/filling heads
+@end table
+
+@samp{ER}, if provided, is the error status:
+
+@table @samp
+@item 00
+Fatal error
+@item 01
+Interface not selected
+@item 04
+Paper jam
+@item 05
+Out of ink
+@item 06
+Paper out
+@end table
+
+@samp{IQ} is the amount of ink left, as a (decimal!) percentage
+expressed in hexadecimal. The values are black, cyan, magenta, and
+yellow (presumably 6-color printers supply light cyan and light magenta
+inks as additional parameters).
+
+@samp{WR}, if provided, is the warning status:
+
+@table @samp
+@item 10
+Black ink low
+@item 11
+Cyan
+@item 12
+Magenta
+@item 13
+Yellow
+@item 14
+Light cyan (presumably)
+@item 15
+Light magenta (presumably)
+@end table
+
+@samp{RV} is the firmware revision (one byte ASCII).
+
+@samp{AI} is actuator information. These are two byte ASCII codes that
+indicate ``ink weight rank ID'' of KCMY, respectively.
+
+@samp{TC}, if provided, is the total time of cleaning or ink filling (?).
+
+@samp{INK:} and @samp{MI} are @strong{not documented}.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* SM @var{BC}=2 00 @var{xx}}
+Set Status Reply Rate. @var{xx} is the repeat interval in seconds. If
+@var{xx} is @samp{0}, the status is returned only when the printer's
+state changes.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* ST @var{BC}=1 01}
+Reply Printer Status. The reply is formatted as
+
+@example
+@@BDC PS\r\nST:@var{xx};\f
+@end example
+
+(@samp{\r} is carriage return; @samp{\n} is newline; @samp{\f} is
+formfeed). If @var{xx} (the reply value) is @samp{0} or @samp{2},
+automatic status update is disabled; if @samp{1} or @samp{3}, it is
+enabled.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* SM @var{BC}=1 01}
+Reply Printer Status Rate. The reply is formatted as
+
+@example
+@@BDC PS\r\nST:xx;\f
+@end example
+
+(@samp{\r} is carriage return; @samp{\n} is newline; @samp{\f} is
+formfeed). See @samp{SM @var{BC}=2} above for the meaning of the return
+value.
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* ?? @var{BC}=@var{xx} @var{y}[1] @dots{} @var{y}[xx]}
+Echo Parameters (perhaps better described as Echo Commands). The
+command string is executed (it would appear from the documentation), and
+the string sent is returned using a sequence similar to that described
+in the @samp{ST @var{BC}=1} and @samp{SM @var{BC}=1} commands. Note
+that in this case the number of bytes is variable!
+@end deffn
+
+@deffn {ESC/P2 remote command} @code{* SM @var{BC}=2 00 02}
+@strong{Function unknown}. Used on the STC 3000 at least when using
+roll feed.
+@end deffn
+
+
+@node ESC/P2 Appropriate Remote Commands, , ESC/P2 Remote Mode Commands, ESC/P2
+@appendixsection Appropriate Remote Commands
+
+All of the remote commands described above are wrapped up with the usual
+boilerplate. The files always start with @samp{00 00 00} and the
+``magic'' command described above, then two @samp{ESC @@}s to reset the
+printer. The remote command sequences come next; if they print anything
+that is usually followed by a @samp{FF} (0C hex) character to feed the
+page, then the file ends with another two @samp{ESC @@}s to get back to
+the ground state.
+
+An alignment sequence goes like this:
+
+@enumerate
+@item Host uses @samp{DT} to print an alignment sheet
+@item User eyeballs the sheet to see which is the best aligned pattern.
+@item Host sends a @samp{DA} command indicating which pattern the user chose
+@item If the user said "realign", meaning he isn't done yet, go to step 1
+@item We are done: host sends a @samp{SV} command and exits
+@end enumerate
+
+The sequence used (by the STC 3000, at least) to print from the roll
+feed is (with byte count omitted)
+
+@example
+ PM 00 00
+ SN 00 00 00
+ EX 00 00 00 00 05 01
+ ST 00 01
+ SM 00 02
+@end example
+
+The sequence used by the STP 870 to print on plain paper is
+
+@example
+ PM 00 00
+ IR 00 03
+ SN 00 00 01
+ SN 00 01 00
+ SN 00 02 01
+ EX 00 00 00 00 05 00
+ FP 00 00 00
+@end example
+
+@noindent
+and the job finishes with
+
+@example
+ IR 00 02
+ LD
+@end example
+
+For different paper type settings on the STP 870, the arguments to
+@samp{SN} vary. The arguments to the first and third @samp{SN} commands
+are as outlined in the description of the @samp{SN} command above; the
+arguments to the second (``platen gap'') are @samp{00 01 01} for thick
+papers (``matte paper---heavyweight'', ``photo paper'' and ``premium
+glossy photo paper'') and @samp{00 01 00} for all others.
+
+For roll-mode printing, the STP 870's sequence changes as follows.
+@samp{IR}'s arguments become @samp{00 01} in the header, and @samp{00
+00} after the job, and @samp{EX}'s last argument changes from @samp{00}
+to @samp{01}.
+
+For zero-margin printing on the STP 870, the arguments to @samp{FP} become
+@samp{00 0xb0 0xff}. This moves the origin about 5.5mm to the left, to a
+point one tenth of an inch to the left of the left-hand edge of the
+paper, allowing printing right up to (and beyond) the edge of the
+paper. Some printers (at least the STP 870) include white absorbent
+pads at the left margin position and other positions (89mm and 100mm
+on the STP 870) to soak up ink which misses the edge of the paper.
+Printing off the edge of paper of a width not aligned with a pad could
+result in making a mess of the inside of the printer and ink getting
+on the reverse of the paper.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/functions.texi b/doc/functions.texi
new file mode 100644
index 0000000..773d4fd
--- /dev/null
+++ b/doc/functions.texi
@@ -0,0 +1,744 @@
+@node Functions, Programs, Integrating libgimpprint, Top
+@chapter Functions
+@cindex functions
+
+This section of the manual is a complete reference to all of the functions
+comprising libgimpprint, with examples.
+
+All of the libgimpprint functions can be declared by including the master
+libgimpprint header, @file{<gimp-print/gimp-print.h>}. This should be done in
+every source file that uses gimpprint functions by putting
+
+@example
+#include <gimp-print/gimp-print.h>
+@end example
+
+@noindent
+at the top of each file.
+
+@menu
+* Main functions:: Essential functions every program must call.
+* stp_vars_t functions:: Using stp_vars_t.
+* Dither functions:: Dither algorithms.
+* Options functions:: Options.
+* Paper functions:: Paper size and orientation.
+* Printer functions:: Printer selection.
+* Settings functions:: Getting and changing settings.
+* Version functions:: Getting libgimpprint version information.
+@end menu
+
+@node Main functions, stp_vars_t functions, , Functions
+@section Main functions
+@cindex main functions
+
+These functions are essential to the correct functioning of
+libgimpprint. All or most other functions in the library depend
+absolutely upon them. In the case of @code{stp_init}, this function
+@emph{must} be called before any of the other functions in the library.
+
+
+@cindex initialising libgimpprint
+@deftypefun int stp_init (void)
+
+This function initialises the libgimpprint library. It must be called before
+any of the other libgimpprint functions are called. It is responsible for
+setting up message catalogues (for internationalisation). This function
+may be called more than once, at any stage during the execution of a
+program.
+
+It returns zero on success, nonzero on failure.
+@end deftypefun
+
+@code{stp_init} might be used as follows:
+
+@example
+int
+main (int argc, char **argv)
+@{
+ stp_init();
+
+ @dots{}
+
+@}
+@end example
+
+@cindex memory allocation
+@deftypefun {void *} stp_malloc (size_t @var{size})
+
+Where @var{size} is the amount of memory to allocate (in bytes).
+
+This function allocates memory. It will always return a pointer to the
+allocated memory. It will not return on failure.
+
+It returns a pointer to the allocated memory.
+@end deftypefun
+
+@node stp_vars_t functions, Dither functions, Main functions, Functions
+@section @code{stp_vars_t} functions
+@cindex @code{stp_vars_t} functions
+
+@deftypevr {Data type} {void *} stp_vars_t
+This is an opaque data type, whose structure is not visible to the
+user. This object contains all of the information about settings for
+a given printer, such as color (contrast, brightness), the type of
+printer, the dithering algorithm in use, and so forth. Please see the
+@code{stp_set_*} and @code{stp_get_*} functions below for the
+accessors and mutators for this data type.
+@end deftypevr
+
+
+@deftypefun stp_vars_t stp_allocate_vars (void)
+Allocate a new @code{stp_vars_t} with default settings for all members.
+@end deftypefun
+
+@deftypefun void stp_copy_vars (stp_vars_t @var{vd}, const stp_vars_t @var{vs})
+Copy the settings from @var{vs} to @var{vd}.
+@end deftypefun
+
+@deftypefun stp_vars_t stp_allocate_copy (const stp_vars_t @var{vs})
+Allocate a new @code{stp_vars_t}, copying settings from @var{vs}.
+@end deftypefun
+
+@deftypefun void stp_free_vars (stp_vars_t @var{vv})
+Free all resources associated with @var{vv}. @var{vv} must not be
+used in any way following this call.
+@end deftypefun
+
+@deftypefun {const char *} stp_get_output_to (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_output_to (stp_vars_t @var{vv}, const char *@var{val})
+@deftypefunx void stp_set_output_to_n (stp_vars_t @var{vv}, const char *@var{val}, int @var{bytes})
+Get or set the name of the command that this job will be printed to.
+This is used by front ends; the driver library always prints to a
+stream provided by the front end and never uses this directly.
+@end deftypefun
+
+@deftypefun {const char *} stp_get_driver (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_driver (stp_vars_t @var{vv}, const char *@var{val})
+@deftypefunx void stp_set_driver_n (stp_vars_t @var{vv}, const char *@var{val}, int @var{bytes})
+Get or set the name of the driver (the type of printer).
+@end deftypefun
+
+@deftypefun {const char *} stp_get_ppd_file (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_ppd_file (stp_vars_t @var{vv}, const char *@var{val})
+@deftypefunx void stp_set_ppd_file_n (stp_vars_t @var{vv}, const char *@var{val}, int @var{bytes})
+Get or set the name of the PPD file used by this print job. Normally,
+only PostScript printers use PPD files.
+@end deftypefun
+
+@deftypefun {const char *} stp_get_resolution (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_resolution (stp_vars_t @var{vv}, const char *@var{val})
+@deftypefunx void stp_set_resolution_n (stp_vars_t @var{vv}, const char *@var{val}, int @var{bytes})
+Get or set the resolution to be used in this print job. Different
+drivers support different resolutions, and many drivers support
+multiple quality settings for a given DPI resolution.
+@end deftypefun
+
+@deftypefun {const char *} stp_get_media_size (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_media_size (stp_vars_t @var{vv}, const char *@var{val})
+@deftypefunx void stp_set_media_size_n (stp_vars_t @var{vv}, const char *@var{val}, int @var{bytes})
+Get or set the name of the media size (e. g. A3, letter, legal) to be
+used in this print job.
+@end deftypefun
+
+@deftypefun {const char *} stp_get_media_type (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_media_type (stp_vars_t @var{vv}, const char *@var{val})
+@deftypefunx void stp_set_media_type_n (stp_vars_t @var{vv}, const char *@var{val}, int @var{bytes})
+Get or set the name of the media type (e. g. plain paper, photo
+quality inkjet paper) to be used in this print job.
+@end deftypefun
+
+@deftypefun {const char *} stp_get_media_source (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_media_source (stp_vars_t @var{vv}, const char *@var{val})
+@deftypefunx void stp_set_media_source_n (stp_vars_t @var{vv}, const char *@var{val}, int @var{bytes})
+Get or set the name of the media source (e. g. manual feed, tray A) to
+be used in this print job.
+@end deftypefun
+
+@deftypefun {const char *} stp_get_ink_type (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_ink_type (stp_vars_t @var{vv}, const char *@var{val})
+@deftypefunx void stp_set_ink_type_n (stp_vars_t @var{vv}, const char *@var{val}, int @var{bytes})
+Get or set the name of the ink type (e. g. four color standard, six
+color photo) to be used in this print job.
+@end deftypefun
+
+@deftypefun {const char *} stp_get_dither_algorithm (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_dither_algorithm (stp_vars_t @var{vv}, const char *@var{val})
+@deftypefunx void stp_set_dither_algorithm_n (stp_vars_t @var{vv}, const char *@var{val}, int @var{bytes})
+Get or set the dither algorithm to be used in this print job.
+@end deftypefun
+
+@deftypefun int stp_get_output_type (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_output_type (stp_vars_t @var{vv}, int @var{val})
+Get or set the output type (color, grayscale, black and white) for
+this print job.
+@end deftypefun
+
+@deftypefun int stp_get_orientation (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_orientation (stp_vars_t @var{vv}, int @var{val})
+Get or set the paper orientation for this print job.
+@end deftypefun
+
+@deftypefun int stp_get_left (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_left (stp_vars_t @var{vv}, int @var{val})
+Get or set the left margin (in 1/72 inch units, or "points") for this
+print job.
+@end deftypefun
+
+@deftypefun int stp_get_top (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_top (stp_vars_t @var{vv}, int @var{val})
+Get or set the top margin (in 1/72 inch units, or "points") for this
+print job.
+@end deftypefun
+
+@deftypefun int stp_get_image_type (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_image_type (stp_vars_t @var{vv}, int @var{val})
+Get or set the image type (line art, continuous tone, solid colors)
+for this print job.
+@end deftypefun
+
+@deftypefun int stp_get_unit (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_unit (stp_vars_t @var{vv}, int @var{val})
+Get or set the base unit (inches or centimeters) for this print job.
+This is provided for front ends; the package itself uses points as its
+unit of measurement.
+@end deftypefun
+
+@deftypefun int stp_get_page_width (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_page_width (stp_vars_t @var{vv}, int @var{val})
+Get or set the width of the printed region of the page.
+@end deftypefun
+
+@deftypefun int stp_get_page_height (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_page_height (stp_vars_t @var{vv}, int @var{val})
+Get or set the height of the printed region of the page.
+@end deftypefun
+
+@deftypefun int stp_get_input_color_model (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_input_color_model (stp_vars_t @var{vv}, int @var{val})
+Get or set the color model (currently RGB or CMY) of the input to the
+driver. Most front ends will use RGB input.
+@end deftypefun
+
+@deftypefun int stp_get_output_color_model (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_output_color_model (stp_vars_t @var{vv}, int @var{val})
+Get or set the color model (currently RGB or CMY) of the output of the
+driver. Most printers will use CMY.
+@end deftypefun
+
+@deftypefun float stp_get_scaling (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_scaling (stp_vars_t @var{vv}, float @var{val})
+Get or set the scaling factor of the image. If the scaling factor is
+greater than 0, it is interpreted as a percent (5.0-100.0 is the valid
+range) of the printable page region, using the more restrictive axis.
+For example, if the image to be printed should be 3" (wide) x 2"
+(high), and the printable page region is 8"x10.5", the scale factor
+should be 37.5 (3"/8").
+
+If the scaling is less than zero, it is interpreted as pixels per
+inch.
+
+It is likely that in the future this will be migrated into the front
+end. There is no particular reason why the driver needs to know about
+this.
+@end deftypefun
+
+@deftypefun float stp_get_gamma (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_gamma (stp_vars_t @var{vv}, float @var{val})
+Get or set the gamma of the print job (valid range: 0.1-4.0; default
+1.0). Note that this is not the absolute gamma used by the print job;
+it is scaled by the gamma appropriate for the printer. This is true
+for all of the numerical parameters.
+@end deftypefun
+
+@deftypefun float stp_get_brightness (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_brightness (stp_vars_t @var{vv}, float @var{val})
+Get or set the brightness of the print job (valid range: 0.0-2.0;
+default: 1.0). Any value other than 1.0 will result in some possible
+values not being used; if brightness is less than 1.0, no output point
+will be pure white, and if brightness is greater than 1.0, no output
+point will be pure black (or cyan, or magenta, or yellow).
+@end deftypefun
+
+@deftypefun float stp_get_contrast (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_contrast (stp_vars_t @var{vv}, float @var{val})
+Get or set the contrast of the print job (valid range: 0.0-4.0;
+default: 1.0). Values less than 1.0 will result in pure white or
+black not being used (0.0 will make the entire image 50% gray).
+Values greater than 1.0 do not hard clip; while the contrast in the
+midtones increases, it only asymptotically approaches the limits.
+@end deftypefun
+
+@deftypefun float stp_get_cyan (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_cyan (stp_vars_t @var{vv}, float @var{val})
+Get or set the cyan adjustment of the print job (range: 0.0-4.0; default:
+1.0). This currently adjusts the gamma of the cyan curve. It is
+scaled by the cyan adjustment for the printer model in question.
+@end deftypefun
+
+@deftypefun float stp_get_magenta (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_magenta (stp_vars_t @var{vv}, float @var{val})
+Get or set the magenta adjustment of the print job (range: 0.0-4.0; default:
+1.0). This currently adjusts the gamma of the magenta curve. It is
+scaled by the magenta adjustment for the printer model in question.
+@end deftypefun
+
+@deftypefun float stp_get_yellow (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_yellow (stp_vars_t @var{vv}, float @var{val})
+Get or set the yellow adjustment of the print job (range: 0.0-4.0; default:
+1.0). This currently adjusts the gamma of the yellow curve. It is
+scaled by the yellow adjustment for the printer model in question.
+@end deftypefun
+
+@deftypefun float stp_get_saturation (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_saturation (stp_vars_t @var{vv}, float @var{val})
+Get or set the saturation of the print job (range: 0.0-9.0; default: 1.0).
+Saturation of 0.0 produces grayscale output using composite (CMY or
+CMYK, as appropriate for the printer) color.
+@end deftypefun
+
+@deftypefun float stp_get_density (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_density (stp_vars_t @var{vv}, float @var{val})
+Get or set the density of the print job (range: 0.0-2.0; default:
+1.0). This adjusts the amount of ink deposited in a linear fashion
+for all channels. It is scaled by the density appropriate for the
+choice of printer, resolution, paper type, and other factors that the
+driver may deem appropriate.
+@end deftypefun
+
+@deftypefun float stp_get_app_gamma (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_app_gamma (stp_vars_t @var{vv}, float @var{val})
+Get or set the gamma of the input (i. e. what the driving application
+uses).
+@end deftypefun
+
+@deftypefun {void *} stp_get_lut (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_lut (stp_vars_t @var{vv}, void *@var{val})
+Get or set the color lookup table for the print job. This is useful
+outside of the library for computing a preview of the printed result.
+The lookup table itself should be treated as an opaque handle.
+@end deftypefun
+
+@deftypefun {unsigned char *} stp_get_cmap (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_cmap (stp_vars_t @var{vv}, unsigned char *@var{val})
+Get or set the color map for the print job. This is a table of R,G,B
+values for 8-bit indexed input. This may be moved outside of the
+library in the future; in this case, the front end would be required
+to do its own mapping and supply true-color RGB to the driver.
+@end deftypefun
+
+The following methods are used to perform output and error reporting
+by the driver. The driver supplies a stream of output bytes; the
+front end is responsible for providing methods that accept this output
+and handle it appropriately.
+
+@deftypefun stp_outfunc_t stp_get_outfunc (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_outfunc (const stp_vars_t @var{vv}, stp_outfunc_t @var{val})
+@deftypefunx {void *} stp_get_outdata (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_outdata (stp_vars_t @var{vv}, void *@var{val})
+
+@deftypevr {Data type} {} stp_outfunc_t
+@example
+typedef void (*stp_outfunc_t) (void *data,
+ const char *buffer, size_t bytes);
+@end example
+@end deftypevr
+Get or set the output function the driver will use. The front end
+must supply a suitable function for accepting the output data. The
+@code{stp_set_outdata} method provides a way of passing an appropriate
+object to the output function.
+@end deftypefun
+
+@deftypefun stp_outfunc_t stp_get_errfunc (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_errfunc (const stp_vars_t @var{vv}, stp_outfunc_t @var{val})
+@deftypefunx {void *} stp_get_errdata (const stp_vars_t @var{vv})
+@deftypefunx void stp_set_errdata (stp_vars_t @var{vv}, void *@var{val})
+Get or set the error reporting function that the driver will use.
+This is used to report errors or debugging information, and must be
+supplied. A typical errfunc will simply print whatever it's passed to
+stderr.
+@end deftypefun
+
+/*
+ * hue_map is an array of 49 doubles representing the mapping of hue
+ * from (0..6) to (0..6) in increments of .125. The hue_map is in CMY space,
+ * so hue=0 is cyan.
+ */
+typedef void (*stp_convert_t)(const stp_vars_t vars, const unsigned char *in,
+ unsigned short *out, int *zero_mask,
+ int width, int bpp, const unsigned char *cmap,
+ const double *hue_map, const double *lum_map,
+ const double *sat_map);
+
+@deftypefun void stp_merge_printvars (stp_vars_t @var{user}, const stp_vars_t @var{print})
+
+@end deftypefun
+
+@deftypefun void stp_allocate_lut (stp_vars_t @var{v}, size_t @var{steps})
+
+@end deftypefun
+
+@deftypefun void stp_free_lut (stp_vars_t @var{v})
+
+@end deftypefun
+
+@deftypefun void stp_compute_lut (stp_vars_t @var{v}, size_t @var{steps})
+
+@end deftypefun
+
+
+@node Dither functions, Options functions, stp_vars_t functions, Functions
+@section Dither functions
+@cindex dither functions
+
+@deftypefun size_t stp_dither_algorithm_count (void)
+
+@end deftypefun
+
+@deftypefun {const char *} stp_dither_algorithm_name (int @var{id})
+
+@end deftypefun
+
+@deftypefun {const char *} stp_default_dither_algorithm (void)
+
+@end deftypefun
+
+
+
+@node Options functions, Paper functions, Dither functions, Functions
+@section Options functions
+@cindex options functions
+
+@deftypevr {Data type} {void *} stp_option_t
+This is an opaque data type, whose structure is not visible to the
+user.
+@end deftypevr
+
+@deftypefun void stp_set_option(stp_vars_t @var{v}, const char *@var{name}, const char *@var{data}, int @var{bytes})
+
+@end deftypefun
+
+@deftypefun void stp_clear_option (stp_vars_t @var{v}, const char *@var{name})
+
+@end deftypefun
+
+@deftypefun void stp_clear_all_options (stp_vars_t @var{v})
+
+@end deftypefun
+
+@deftypefun size_t stp_option_count (const stp_vars_t @var{v})
+
+@end deftypefun
+
+@deftypefun {const stp_option_t} stp_get_option_by_index (const stp_vars_t @var{v}, size_t @var{idx})
+
+@end deftypefun
+
+@deftypefun {const stp_option_t} stp_get_option_by_name (const stp_vars_t @var{v}, const char *@var{name})
+
+@end deftypefun
+
+@deftypefun {const char *} stp_option_data (const stp_option_t @var{option})
+@strong{Note}: not null delimited!
+@end deftypefun
+
+@deftypefun {const char *} stp_option_name (const stp_option_t @var{option})
+
+@end deftypefun
+
+@deftypefun size_t stp_option_length (const stp_option_t @var{option})
+
+@end deftypefun
+
+
+@node Paper functions, Printer functions, Options functions, Functions
+@section Paper functions
+@cindex paper functions
+
+@deftypevr {Data type} {void *} stp_papersize_t
+This is an opaque data type, whose structure is not visible to the
+user.
+@end deftypevr
+
+@deftypevr {Data type} {} stp_papersize_unit_t
+@example
+typedef enum papersize_unit
+@{
+ PAPERSIZE_ENGLISH,
+ PAPERSIZE_METRIC
+@} stp_papersize_unit_t;
+@end example
+@end deftypevr
+
+@deftypefun int stp_known_papersizes (void)
+
+@end deftypefun
+
+@deftypefun {const stp_papersize_t} stp_get_papersize_by_name (const char *@var{name})
+
+@end deftypefun
+
+@deftypefun {const stp_papersize_t} stp_get_papersize_by_size (int @var{l}, int @var{w})
+
+@end deftypefun
+
+@deftypefun {const stp_papersize_t} stp_get_papersize_by_index (int @var{index})
+
+@end deftypefun
+
+@deftypefun {const char *} stp_papersize_get_name (const stp_papersize_t @var{pt})
+
+@end deftypefun
+
+@deftypefun unsigned stp_papersize_get_width (const stp_papersize_t @var{pt})
+
+@end deftypefun
+
+@deftypefun unsigned stp_papersize_get_height (const stp_papersize_t @var{pt})
+
+@end deftypefun
+
+@deftypefun unsigned stp_papersize_get_top (const stp_papersize_t @var{pt})
+
+@end deftypefun
+
+@deftypefun unsigned stp_papersize_get_left (const stp_papersize_t @var{pt})
+
+@end deftypefun
+
+@deftypefun unsigned stp_papersize_get_bottom (const stp_papersize_t @var{pt})
+
+@end deftypefun
+
+@deftypefun unsigned stp_papersize_get_right (const stp_papersize_t @var{pt})
+
+@end deftypefun
+
+
+@deftypefun stp_papersize_unit_t stp_papersize_get_unit (const stp_papersize_t @var{pt})
+
+@end deftypefun
+
+
+@node Printer functions, Settings functions, Paper functions, Functions
+@section Printer functions
+@cindex printer functions
+
+@deftypevr {Data type} {void *} stp_printer_t
+This is an opaque data type, whose structure is not visible to the
+user.
+@end deftypevr
+
+@deftypefun int stp_known_printers (void)
+
+@end deftypefun
+
+
+@deftypefun {const stp_printer_t} stp_get_printer_by_index (int @var{idx})
+
+@end deftypefun
+
+
+@deftypefun {const char *} stp_printer_get_long_name (const stp_printer_t @var{p})
+
+@end deftypefun
+
+
+@deftypefun {const stp_printer_t} stp_get_printer_by_long_name (const char *@var{long_name})
+
+@end deftypefun
+
+
+@deftypefun {const stp_printer_t} stp_get_printer_by_driver (const char *@var{driver})
+
+@end deftypefun
+
+
+@deftypefun int stp_get_printer_index_by_driver (const char *@var{driver})
+
+@end deftypefun
+
+
+@deftypefun {const char *} stp_printer_get_driver (const stp_printer_t @var{p})
+
+@end deftypefun
+
+
+@deftypefun int stp_printer_get_model (const stp_printer_t @var{p})
+
+@end deftypefun
+
+
+@deftypefun {const stp_printfuncs_t *} stp_printer_get_printfuncs (const stp_printer_t @var{p})
+
+@end deftypefun
+
+@deftypevr {Data type} {} stp_printfuncs_t
+@example
+typedef struct
+@{
+ char **(*parameters)(const stp_printer_t printer,
+ const char *ppd_file,
+ const char *name, int *count);
+ void (*media_size)(const stp_printer_t printer,
+ const stp_vars_t v, int *width,
+ int *height);
+ void (*imageable_area)(const stp_printer_t printer,
+ const stp_vars_t v,
+ int *left, int *right,
+ int *bottom, int *top);
+ void (*limit)(const stp_printer_t printer,
+ const stp_vars_t v,
+ int *width, int *height);
+ void (*print)(const stp_printer_t printer,
+ stp_image_t *image, const stp_vars_t v);
+ const char *(*default_parameters)(const stp_printer_t printer,
+ const char *ppd_file,
+ const char *name);
+ void (*describe_resolution)(const stp_printer_t printer,
+ const char *resolution,
+ int *x, int *y);
+ int (*verify)(const stp_printer_t p, const stp_vars_t v);
+@} stp_printfuncs_t;
+@end example
+@end deftypevr
+
+@deftypevr {Data type} {} stp_image_t
+@example
+typedef struct stp_image
+@{
+ void (*init)(struct stp_image *image);
+ void (*reset)(struct stp_image *image);
+ void (*transpose)(struct stp_image *image);
+ void (*hflip)(struct stp_image *image);
+ void (*vflip)(struct stp_image *image);
+ void (*crop)(struct stp_image *image,
+ int left, int top, int right,
+ int bottom);
+ void (*rotate_ccw)(struct stp_image *image);
+ void (*rotate_cw)(struct stp_image *image);
+ void (*rotate_180)(struct stp_image *image);
+ int (*bpp)(struct stp_image *image);
+ int (*width)(struct stp_image *image);
+ int (*height)(struct stp_image *image);
+ void (*get_row)(struct stp_image *image,
+ unsigned char *data, int row);
+ const char *(*get_appname)(struct stp_image *image);
+ void (*progress_init)(struct stp_image *image);
+ void (*note_progress)(struct stp_image *image,
+ double current, double total);
+ void (*progress_conclude)(struct stp_image *image);
+ void *rep;
+@} stp_image_t;
+@end example
+This is an abstract data type for interfacing with the program which
+created the image.
+@end deftypevr
+
+@deftypefun {const stp_vars_t} stp_printer_get_printvars (const stp_printer_t @var{p})
+
+@end deftypefun
+
+
+@node Settings functions, Version functions, Printer functions, Functions
+@section Settings functions
+@cindex settings functions
+
+@deftypefun stp_convert_t stp_choose_colorfunc (int @var{output_type}, int @var{image_bpp}, const unsigned char *@var{cmap}, int *@var{out_bpp}, const stp_vars_t @var{v})
+
+@end deftypefun
+
+
+@deftypefun void stp_compute_page_parameters (int @var{page_right}, int @var{page_left}, int @var{page_top}, int @var{page_bottom}, double @var{scaling}, int @var{image_width}, int @var{image_height}, stp_image_t *@var{image}, int *@var{orientation}, int *{page_width}, int *@var{page_height}, int *@var{out_width}, int *@var{out_height}, int *@var{left}, int *@var{top})
+
+@end deftypefun
+
+
+@deftypefun {const stp_vars_t} stp_default_settings (void)
+
+@end deftypefun
+
+
+@deftypefun {const stp_vars_t} stp_maximum_settings (void)
+
+@end deftypefun
+
+
+@deftypefun {const stp_vars_t} stp_minimum_settings (void)
+
+@end deftypefun
+
+
+
+
+@node Version functions, , Settings functions, Functions
+@section Version functions
+@cindex version functions
+
+@deftypefun {const char *} stp_check_version (unsigned int @var{required_major},
+unsigned int @var{required_minor}, unsigned int @var{required_micro})
+
+This function checks whether the version of libgimpprint that the program
+is linked with is equal to the version number passed to it. If the version
+is the same, the function returns @code{NULL}. If any of the version
+numbers do not match (i.e. the library version is too old or too new), a string containing a desription of the difference is
+returned. The first error found is returned. The function checks in the order
+major, minor, micro.
+@end deftypefun
+
+@subsection Version macros
+
+@defmac GIMPPRINT_CHECK_VERSION (major,minor,micro)
+
+This macro returns zero if the version of the libgimpprint headers are
+greater or equal to the version given as an argument. It returns nonzero
+if the version of the libgimpprint headers are less than the argument.
+@end defmac
+
+@defmac GIMPPRINT_MAJOR_VERSION
+@end defmac
+
+@defmac GIMPPRINT_MINOR_VERSION
+@end defmac
+
+@defmac GIMPPRINT_MICRO_VERSION
+@end defmac
+
+@defmac GIMPPRINT_CURRENT_INTERFACE
+@end defmac
+
+@defmac GIMPPRINT_BINARY_AGE
+@end defmac
+
+@defmac GIMPPRINT_INTERFACE_AGE
+@end defmac
+
+These macros are integers holding the version numbers. They should be
+used for compile-time checking only. To check version numbers at
+run-time, use the equivalent variables. Note that at present (4.1.x
+development branch) the library interface version numbers are not used.
+
+@subsection Version variables
+
+@deftypevar {const unsigned int} gimpprint_major_version
+@end deftypevar
+
+@deftypevar {const unsigned int} gimpprint_minor_version
+@end deftypevar
+
+@deftypevar {const unsigned int} gimpprint_micro_version
+@end deftypevar
+
+@deftypevar {const unsigned int} gimpprint_current_interface
+@end deftypevar
+
+@deftypevar {const unsigned int} gimpprint_binary_age
+@end deftypevar
+
+@deftypevar {const unsigned int} gimpprint_interface_age
+@end deftypevar
+
+These variables hold the library version numbers. Because the version of
+the library may change on a system using shared libraries, these should
+be used instead of the equivalent macros when checking the library
+version at run-time. Note that library interface version numbers are not
+used in the development branch, but are in the stable branch.
diff --git a/doc/gimpprint.texi b/doc/gimpprint.texi
new file mode 100644
index 0000000..92a27d7
--- /dev/null
+++ b/doc/gimpprint.texi
@@ -0,0 +1,130 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@c $Id: gimpprint.texi,v 1.6 2001/10/27 17:16:37 rlk Exp $
+@setfilename gimpprint.info
+@settitle GIMP-Print
+@finalout
+@c @exampleindent 0
+@c For double-sided printing, uncomment:
+@c @setchapternewpage odd
+@c %**end of header
+
+@c Combine several related indices
+@syncodeindex pg cp
+@syncodeindex tp vr
+
+@c Include version numbers
+@include version.texi
+
+@c Macro definitions
+@set BUGADDR @email{gimp-print-devel@@lists.sourceforge.net}
+@set MAILLIST @email{gimp-print-devel@@lists.sourceforge.net}
+
+@dircategory Libraries
+@direntry
+* GIMP-Print: (gimpprint). print plugin for the GIMP, and printing library
+@end direntry
+
+@ifinfo
+This file documents the gimpprint library and associated programs
+used for high quality printing.
+
+Copyright (C) 2001 Michael Sweet (@email{mike@@easysw.com}) and Robert
+Krawitz (@email{rlk@@alum.mit.edu})
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end ifinfo
+
+@titlepage
+@title GIMP-Print
+@subtitle The print plugin for the GIMP
+@subtitle Version @value{VERSION}, @value{UPDATED}
+@author The GIMP-Print Project
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 2001 Michael Sweet
+(@email{mike@@easysw.com}) and Robert Krawitz (@email{rlk@@alum.mit.edu})
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Free Software Foundation.
+@end titlepage
+
+
+@c Print tables of contents
+@shortcontents
+@contents
+
+@ifnottex
+@c All the nodes can be updated using the EMACS command
+@c texinfo-every-node-update, which is normally bound to C-c C-u C-e.
+@node Top, , (dir), (dir)
+@comment node-name, next, previous, up
+@top The print plugin for the GIMP and printing library
+
+This file documents the libgimpprint library and associated programs used
+for high quality printing. This edition documents version @value{VERSION}.
+
+@xref{Problems}, for information on how to report problems with
+GIMP-Print.
+@end ifnottex
+
+@c All the menus can be updated with the EMACS command
+@c texinfo-all-menus-update, which is normally bound to C-c C-u C-a.
+@menu
+* Instructions:: How to read this manual.
+* Copying:: Your rights.
+* Overview:: Preliminary information.
+* Using libgimpprint:: Examples of how to use libgimpprint.
+* Integrating libgimpprint:: Using libgimpprint in your own packages.
+* Functions:: libgimpprint function reference.
+* Programs:: Using GIMP-Print programs.
+* Problems:: Reporting bugs.
+* Appendices:: Additional information.
+* Data Type and Variable Index:: Index of data types and variables.
+* Function and Macro Index:: Index of functions and macros.
+* Concept Index:: Index of concepts.
+@end menu
+
+@include introduction.texi
+@include copying.texi
+@include overview.texi
+@include using.texi
+@include integrating.texi
+@include functions.texi
+@include programs.texi
+@include problems.texi
+@include appendices.texi
+@include indices.texi
+
+@bye
diff --git a/doc/gpl.texi b/doc/gpl.texi
new file mode 100644
index 0000000..1aeb8f3
--- /dev/null
+++ b/doc/gpl.texi
@@ -0,0 +1,396 @@
+@setfilename gpl.info
+
+@unnumbered GNU GENERAL PUBLIC LICENSE
+@center Version 2, June 1991
+
+@display
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+675 Mass Ave, Cambridge, MA 02139, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@unnumberedsec Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software---to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+@iftex
+@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate
+@item
+This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The ``Program'', below,
+refers to any such program or work, and a ``work based on the Program''
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term ``modification''.) Each licensee is addressed as ``you''.
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+@item
+You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+@item
+You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+@enumerate a
+@item
+You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+@item
+If the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
+@end enumerate
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+@item
+You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+@enumerate a
+@item
+Accompany it with the complete corresponding machine-readable
+source code, which must be distributed under the terms of Sections
+1 and 2 above on a medium customarily used for software interchange; or,
+
+@item
+Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+@item
+Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
+@end enumerate
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+@item
+You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+@item
+Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+@item
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+@item
+If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+@item
+The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and ``any
+later version'', you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+@item
+If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+@iftex
+@heading NO WARRANTY
+@end iftex
+@ifinfo
+@center NO WARRANTY
+@end ifinfo
+
+@item
+BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+@item
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+@end enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@unnumberedsec How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the ``copyright'' line and a pointer to where the full notice is found.
+
+@smallexample
+@var{one line to give the program's name and an idea of what it does.}
+Copyright (C) 19@var{yy} @var{name of author}
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+@smallexample
+Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'. This is free software, and you are welcome
+to redistribute it under certain conditions; type `show c'
+for details.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than @samp{show w} and
+@samp{show c}; they could even be mouse-clicks or menu items---whatever
+suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a ``copyright disclaimer'' for the program, if
+necessary. Here is a sample; alter the names:
+
+@smallexample
+@group
+Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written
+by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end group
+@end smallexample
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/doc/indices.texi b/doc/indices.texi
new file mode 100644
index 0000000..fdabf0a
--- /dev/null
+++ b/doc/indices.texi
@@ -0,0 +1,14 @@
+@node Data Type and Variable Index, Function and Macro Index, Appendices, Top
+@unnumbered Data Type and Variable Index
+
+@printindex vr
+
+@node Function and Macro Index, Concept Index, Data Type and Variable Index, Top
+@unnumbered Function and Macro Index
+
+@printindex fn
+
+@node Concept Index, , Function and Macro Index, Top
+@unnumbered Concept Index
+
+@printindex cp
diff --git a/doc/integrating.texi b/doc/integrating.texi
new file mode 100644
index 0000000..75e150b
--- /dev/null
+++ b/doc/integrating.texi
@@ -0,0 +1,192 @@
+@node Integrating libgimpprint, Functions, Using libgimpprint, Top
+@chapter Integrating libgimpprint
+@cindex integrating
+
+This chapter describes how to integrate the compiling and linking of
+programs using libgimpprint with build scripts. Commonly used systems include
+@command{make}, but more commonly @file{Makefile} files are generated by using
+tools such as @command{autoconf} and @command{automake}.
+
+@menu
+* gimpprint-config:: Getting the correct compiler and linker flags
+* make:: Normal makefiles
+* autoconf:: Macro to automatically check for libgimpprint
+* automake:: Automatically defined variables to use
+@end menu
+
+
+@node gimpprint-config, make, , Integrating libgimpprint
+@section @command{gimpprint-config}
+@pindex gimpprint-config
+
+Depending on the setup of the computer system GIMP-Print was installed on, as
+well as the options passed to @command{configure} when configuring the
+package when it was built, the @env{CFLAGS} and @env{LIBS} parameters
+needed to compile and link programs with libgimpprint may vary. To make it
+simple to determine what these are on any given system, the script
+@command{gimpprint-config} was created. It's job is to output the
+correct parameters for the setup on your system. The following options
+are available:
+
+@example
+roger@@whinlatter:~/gimpprint/devel$ gimpprint-config --help
+Usage: gimpprint-config [OPTIONS] [LIBRARIES]
+Options:
+ [--prefix[=DIR]]
+ [--exec-prefix[=DIR]]
+ [--version]
+ [--libs]
+ [--cflags]
+Libraries:
+ gimpprint
+@end example
+
+The @option{--prefix} and @option{--exec-prefix} options are only needed if the
+installed locations of parts of GIMP-Print are different from the configured
+locations. These should never be needed if GIMP-Print was properly configured
+and installed.
+
+The installed version of GIMP-Print can be obtained with the
+@option{--version} option:
+
+@example
+roger@@whinlatter:~/gimpprint/devel$ gimpprint-config --version
+@value{VERSION}
+@end example
+
+The correct @env{CFLAGS} to use can be obtained with the @option{--cflags}
+option:
+
+@example
+roger@@whinlatter:~/gimpprint/devel$ gimpprint-config --cflags
+
+@end example
+
+In this case, there are no special @env{CFLAGS} required to compile programs.
+
+The correct @env{LIBS} to use can the obtained with the @option{--libs} option:
+
+@example
+roger@@whinlatter:~/gimpprint/devel$ gimpprint-config --libs
+-L/usr/lib -lgimpprint -lm
+@end example
+
+The command can be used from the shell by enclosing it in backquotes @samp{`}:
+
+@example
+gcc `gimpprint-config --cflags` -c prog.c
+gcc `gimpprint-config --libs` -o prog prog.o
+@end example
+
+However, this is not the way it it typically used. Normally it is used in a
+@file{Makefile} (@pxref{make}) or by an @command{m4} macro in a @command{configure}
+script (@pxref{autoconf}).
+
+
+@node make, autoconf, gimpprint-config, Integrating libgimpprint
+@section @command{make}
+@pindex make
+
+If you use @command{make} with your own @file{Makefile} files, then you are on
+your own. This manual offers no assistance with doing this. Only the following
+suggestion is offered:
+
+@example
+GIMPPRINT_VERSION = $(shell gimpprint-config --version)
+GIMPPRINT_CFLAGS = $(shell gimpprint-config --cflags)
+GIMPPRINT_LIBS = $(shell gimpprint-config --libs)
+@end example
+
+How you choose to use these variables is entirely up to you. @inforef{Top, GNU
+make, make}, for more information.
+
+
+@node autoconf, automake, make, Integrating libgimpprint
+@section @command{autoconf}
+@pindex autoconf
+@cindex m4 macros
+
+The @command{autoconf} program produces a Bourne shell script called
+@file{configure} from a template file called @file{configure.in}.
+@file{configure.in} contains both Bourne shell script, and @command{m4} macros.
+@command{autoconf} expands the @command{m4} macros into `real' shell script.
+The resulting @file{configure} script performs various checks for installed
+programs, compiler characteristics and other system information such as
+available headers and libraries. @inforef{Top, GNU autoconf, autoconf}, for
+more information.
+
+GIMP-Print provides an @command{m4} macro, @code{AM_PATH_GIMPPRINT}, suitable for
+use in a @file{configure.in}. It defines the environment variables
+@env{GIMPPRINT_CFLAGS}, @env{GIMPPRINT_LIBS} and @env{GIMPPRINT_CONFIG}. You can
+optionally specify a minimum version of the library to use, and shell script to
+run if the test suceeds or fails.
+
+@defmac AM_PATH_GIMPPRINT (@r{[}@var{minimum-version} @r{[}, @var{action-if-found} @r{[}, @var{action-if-not-found}@r{]]]})
+Check for an installed version of GIMP-Print greater than or equal to
+@var{minimum-version}.
+
+@var{action-if-found} is a list of shell commands to run if the check
+for the library succeeds; @var{action-if-not-found} is a list of
+shell commands to run if the check fails.
+
+The macro sets the following environment variables: @env{GIMPPRINT_CFLAGS},
+@env{GIMPPRINT_LIBS} and @env{GIMPPRINT_CONFIG}. It also will substitute them
+into any @file{Makefile.in} you specify in @code{AC_OUTPUT} because it calls
+@code{AC_SUBST} for each of them. However, you will probably be using
+@command{automake} to generate your @file{Makefile.in} files
+(@pxref{automake}).
+
+@end defmac
+
+@node automake, , autoconf, Integrating libgimpprint
+@section @command{automake}
+@pindex automake
+
+The @command{automake} program can be used to generate @file{Makefile.in} files
+suitable for use with a @file{configure} script generated by
+@command{autoconf}. As @command{automake} @emph{requires} @command{autoconf},
+this section will assume the use of a @file{configure} script which uses the
+@code{AM_PATH_GIMPPRINT} macro (there is little point in @emph{not} using it!).
+
+It is highly recommeded that you use GNU @command{autoconf} and
+@command{automake}. They will allow you to make your software build on most
+platforms with most compilers. @command{automake} makes writing complex
+@file{Makefile} files very easy, by expressing how to build your packages
+in terms of what files are required to build a project and the installation
+locations of the files. It imposes a few limitations over using plain
+@file{Makefile} files, such as in the use of conditionals, but these problems
+are vastly outweighed by the benefits it brings. It also creates many extra
+targets in the generated @file{Makefile.in} files such as @command{dist},
+@command{distcheck}, @command{clean}, @command{distclean},
+@command{maintainer-clean} and @command{tags}, and there are many more more
+available. @inforef{Top, GNU automake, automake}, for more information.
+
+Because @code{AM_PATH_GIMPPRINT} calls @code{AC_SUBST} to substitute
+@env{GIMPPRINT_CFLAGS}, @env{GIMPPRINT_LIBS} and @env{GIMPPRINT_CONFIG},
+@command{automake} will automatically set these variables in the
+@file{Makefile.in} files it generates, requiring no additional effort on
+your part!
+
+As in previous examples, we will make a program @command{prog} from a file @file{prog.c}. This is how one might build write a @file{Makefile.am} to do this:
+
+@example
+AUTOMAKE_OPTIONS = 1.4 gnu
+MAINT_CHARSET = latin1
+
+@@SET_MAKE@@
+
+CFLAGS = @@CFLAGS@@
+
+INCLUDES = @@INCLUDES@@ $(GIMPPRINT_CFLAGS)
+
+bin_PROGRAMS = prog
+prog_SOURCES = prog.c
+prog_LDADD = $(GIMPPRINT_LIBS)
+
+MAINTAINERCLEANFILES = Makefile.in
+@end example
+
+That's all there is to it! Please note that this example also requires the
+macro @code{AC_PROG_MAKE_SET} to be used in @file{configure.in} and the use of
+@code{AC_SUBST} to substitute @env{CFLAGS} and @env{INCLUDES} where
+@code{@@CFLAGS@@} and @code{@@INCLUDES@@} are found in the file, respectively.
diff --git a/doc/introduction.texi b/doc/introduction.texi
new file mode 100644
index 0000000..3dab48e
--- /dev/null
+++ b/doc/introduction.texi
@@ -0,0 +1,38 @@
+@node Instructions, Copying, Top, Top
+@unnumbered Preface
+
+@cindex reading
+@cindex manual, how to read
+@cindex how to read
+This manual documents the use of the GIMP-Print package, focusing mainly on the
+libgimpprint library that is the core of GIMP-Print. Parts of the manual which
+describe the use of libgimpprint are aimed primarily at programmers, and do
+assume that the reader is familiar with C programming, and using standard
+programming tools on GNU or UNIX systems. Other parts of the manual document
+the use of the programs that make up the GIMP-Print package, and assume no
+knowledge other than the basics of using a shell and editor.
+
+The best way to learn how to use libgimpprint in your own programs is to read
+the manual from start to finish, using the examples given in the text to learn
+how it works. The bulk of the manual can be used as a reference once one
+understands the basics.
+
+The manual is split into several parts for the programmer. It starts
+with a simple usage example of how to link a program with libgimpprint,
+then how to integrate this into package build scripts, using
+@command{make}, @command{autoconf} and @command{automake}. This is
+followed by a detailed function reference, including descriptions of all
+the data types used.
+
+For the end-user, there is a section on all of the programs that come
+with GIMP-Print, including the GIMP @command{print} plugin, and the CUPS
+and Ghostscript drivers.
+
+The appendices at the end of the manual detail the dither and weave
+algorithms used in libgimpprint, the ESC/P2 printer control language
+used in Epson printers and how to add support for a new printer to
+libgimpprint.
+
+@sp 2
+@center We hope you enjoy using GIMP-Print!
+@center ---The GIMP-Print project
diff --git a/doc/new-printer.texi b/doc/new-printer.texi
new file mode 100644
index 0000000..672d92c
--- /dev/null
+++ b/doc/new-printer.texi
@@ -0,0 +1,696 @@
+@node New Printer, ,ESC/P2, Appendices
+@appendix Adding a new printer
+@cindex adding a printer
+@cindex printer, adding
+@cindex new printer
+
+
+This appendix covers adding a new ESCP/2, PCL, or Canon printer.
+Writing a new driver module is not covered.
+
+The three steps to adding a printer are:
+
+@enumerate
+@item Add an entry to @file{printers.xml}
+@item Add the appropriate code and data to the appropriate driver module
+@item Tune the printer
+@end enumerate
+
+Printer information is stored in two places: in @file{printers.xml}
+(which contains the list of printer models available to the the
+upper-level application), and in the appropriate driver file
+(@file{print-escp2.c}, @file{print-pcl.c}, or @file{print-canon.c}).
+
+@menu
+* printers.xml:: File format description.
+* Driver file:: Data structures to use.
+* Epson inkjet printers:: Adding an Epson printer.
+* Tuning Epson printers:: Tweaking settings.
+* Canon inkjet printers:: Adding a Canon printer.
+@end menu
+
+@node printers.xml, Driver file, , New Printer
+@appendixsection @file{printers.xml}
+
+@file{printers.xml} is an XML-like file (there's no formal DTD) that
+contains very simple printer definitions. A typical definition follows:
+
+@example
+<printer name="EPSON Stylus Color 1500" driver="escp2-1500">
+<color>
+<model value=2>
+<gamma value=0.597>
+<density value=1.0>
+<language value=escp2>
+</printer>
+@end example
+
+There are other tags that may be present. The only ones that are
+mandatory are @samp{<printer>}, @samp{<color>}, @samp{<model>}, and
+@samp{<language>}. The other optional parameters (gamma and density in
+this case) can be used to adjust control settings. This is probably not
+the right place for them; the printer drivers themselves should contain
+this information. There's probably no good reason for anything but
+gamma and density to be in here. Gamma refers to the printer's gamma
+factor; density is the desired base ink density for the printer. The
+Epson driver contains the density information for each printer at each
+resolution internally. An even better driver would adjust density and
+possibly even gamma for paper type. All the more reason not to have
+that information here.
+
+If you really are curious about what tags are permitted, please see
+@file{printdefl.l}. I deliberately want to make this obscure.
+
+Anyway, here's the definition of the tags that do matter:
+
+@deffn {@file{printers.xml} tag} @code{<printer name="@var{longname}" driver="@var{drivername}">}
+This starts the definition of a printer. The @var{longname} should be
+something human readable; the @var{drivername} should consist of
+alphanumerics and hyphens, and be fairly short. The @var{longname} is
+what will appear in the GUI listing of printers; the @var{drivername} is
+what is actually used to key into the list of printers. It is legal to
+have multiple printers with the same driver name.
+@end deffn
+
+@deffn {@file{printers.xml} tag} @code{<color>}
+@deffnx {@file{printers.xml} tag} @code{<nocolor>}
+Indicates that this printer is capable of color, or is not capable of
+color respectively
+@end deffn
+
+@deffn {@file{printers.xml} tag} @code{<model value=@var{int}>}
+This defines a model number. This is passed into the driver, which may
+do whatever it cares to with it---index into a table, compute on, or
+whatever. This need not be unique.
+@end deffn
+
+@deffn {@file{printers.xml} tag} @code{<language value=@var{type}>}
+This defines what driver module this printer uses. @var{type} should be
+@samp{escp2}, @samp{pcl}, @samp{canon}, or @samp{ps}.
+@end deffn
+
+@deffn {@file{printers.xml} tag} @code{</printer>}
+This, of course, closes off a printer definition.
+@end deffn
+
+This is handled very ad-hoc. It's ugly. But it's reasonably easy to
+extend, and it's buzzword-compliant.
+
+
+@node Driver file, Epson inkjet printers, printers.xml, New Printer
+@appendixsection The driver file
+@cindex driver file
+
+Adding a new printer to a driver module (@file{print-escp2.c},
+@file{print-pcl.c}, or @file{print-canon.c}---@file{print-ps.c} is
+really ad hoc) requires a bit more planning. Each driver is somewhat
+different, but they all generally have a vector of printer definitions,
+and the code does some special casing based on particular printer
+capabilities. The PCL and Canon drivers are quite similar; the Canon
+driver was actually cribbed from the PCL driver, but it then returned
+the favor.
+
+The Epson driver is a little bit different. Canon and PCL printers
+have some amount of intelligence; a lot of them have specific ink
+options, and know about specific paper sizes and types, and must be
+told the right thing. Epson printers have somewhat less intelligence
+and will more or less do exactly what the host tells it to do in a
+fairly regular fashion. I actually prefer this; it isn't materially
+more work for the host to compute things like exact paper sizes and
+such, it allows a lot more tweaking, and it may be why Epson has been
+more open with information -- the communication protocol doesn't
+really contain very much IP, so they have less reason to keep it
+secret.
+
+Someone else will have to fill in the sections about PCL and Canon
+printers.
+
+
+@node Epson inkjet printers, Tuning Epson printers, Driver file, New Printer
+@appendixsection Epson inkjet printers
+@cindex Epson inkjet printers
+
+The @samp{model_capabilities} vector in @file{print-escp2.c} contains
+one entry for each defined printer model. The @samp{model} parameter in
+@file{printers.xml} is an index into this table.
+
+In general, the new printers have fewer eccentricities than the older
+printers. That doesn't mean they're simpler, just that they're more
+consistent.
+
+An @code{escp2_printer_t} is a C struct defined as follows:
+
+@deftypevr {Data type} {} escp2_printer_t
+@example
+typedef struct escp2_printer
+@{
+ model_cap_t flags; /* Bitmask of flags, see below */
+/*****************************************************************************/
+ int nozzles; /* Number of nozzles per color */
+ int min_nozzles; /* Minimum number of nozzles per color */
+ int nozzle_separation; /* Separation between rows, in 1/360" */
+ int black_nozzles; /* Number of black nozzles (may be extra) */
+ int min_black_nozzles; /* # of black nozzles (may be extra) */
+ int black_nozzle_separation; /* Separation between rows */
+/*****************************************************************************/
+ int xres; /* Normal distance between dots in */
+ /* softweave mode (inverse inches) */
+ int enhanced_xres; /* Distance between dots in highest */
+ /* quality modes */
+ int base_separation; /* Basic unit of row separation */
+ int base_resolution; /* Base hardware spacing (above this */
+ /* always requires multiple passes) */
+ int enhanced_resolution;/* Above this we use the */
+ /* enhanced_xres rather than xres */
+ int resolution_scale; /* Scaling factor for ESC(D command */
+ int max_black_resolution; /* Above this resolution, we */
+ /* must use color parameters */
+ /* rather than (faster) black */
+ /* only parameters*/
+ int max_hres;
+ int max_vres;
+ int min_hres;
+ int min_vres;
+/*****************************************************************************/
+ int max_paper_width; /* Maximum paper width, in points */
+ int max_paper_height; /* Maximum paper height, in points */
+ int min_paper_width; /* Maximum paper width, in points */
+ int min_paper_height; /* Maximum paper height, in points */
+ /* Softweave: */
+ int left_margin; /* Left margin, points */
+ int right_margin; /* Right margin, points */
+ int top_margin; /* Absolute top margin, points */
+ int bottom_margin; /* Absolute bottom margin, points */
+ /* "Micro"weave: */
+ int m_left_margin; /* Left margin, points */
+ int m_right_margin; /* Right margin, points */
+ int m_top_margin; /* Absolute top margin, points */
+ int m_bottom_margin; /* Absolute bottom margin, points */
+/*****************************************************************************/
+ int extra_feed; /* Extra distance the paper can be spaced */
+ /* beyond the bottom margin, in 1/360". */
+ /* (maximum useful value is */
+ /* nozzles * nozzle_separation) */
+ int separation_rows; /* Some printers require funky spacing */
+ /* arguments in microweave mode. */
+ int pseudo_separation_rows;/* Some printers require funky */
+ /* spacing arguments in softweave mode */
+
+ int zero_margin_offset; /* Offset to use to achieve */
+ /* zero-margin printing */
+/*****************************************************************************/
+ /* The stylus 480 and 580 have an unusual arrangement of
+ color jets that need special handling */
+ const int *head_offset;
+ int initial_vertical_offset;
+ int black_initial_vertical_offset;
+
+/*****************************************************************************/
+ const int *dot_sizes; /* Vector of dot sizes for resolutions */
+ const double *densities; /* List of densities for each printer */
+ const escp2_variable_inklist_t *inks; /* Choices of inks for this printer */
+/*****************************************************************************/
+ const double *lum_adjustment;
+ const double *hue_adjustment;
+ const double *sat_adjustment;
+ const paperlist_t *paperlist;
+@} escp2_printer_t;
+@end example
+@end deftypevr
+
+The printer definition block is divided into 8 sections. The first
+section is a set of miscellaneous printer options. These are
+described in the code, and will not be discussed further here.
+
+
+The second section describes the number of nozzles and the separation
+between nozzles in base units. The base unit is 1/360" for all
+currently supported printers, but future printers may support a
+smaller base unit.
+
+Many printers have more black nozzles than nozzles of other colors,
+and when used in black and white mode, it's possible to use these
+extra nozzles, which speeds up printing. As an example, a printer
+that is specified to have 48 cyan, magenta, and yellow nozzles, and
+144 black nozzles, can use all 144 black nozzles when printing black
+ink only. When printing in color, only 48 nozzles of each color
+(including black) can be used.
+
+Most printers can print using either the number of nozzles available
+or any smaller number. Some printers require that all of the nozzles
+be used. Those printers will set @code{min_nozzles} and/or
+@code{min_black_nozzles} to the same value as @code{nozzles} and/or
+@code{black_nozzles}.
+
+
+The third section defines basic units of measure for the printer,
+including the standard separation between dots, the base nozzle
+separation, and the minimum and maximum printing resolutions the
+printer supports. Most of these are fairly self-explanatory, but some
+are not obvious.
+
+Most Epson printers, other than the high-end Stylus Pro models, cannot
+print dots spaced more closely than 1/360" or 1/720" apart (this is
+the setting for @code{xres}. This is true even for printers that
+support resolutions of 1440 or 2880 DPI. In these cases, the data
+must be printed in 2, 4, or 8 passes. While the printer can position
+the head to a resolution of 1/1440" or 1/2880", the head cannot
+deposit ink that frequently.
+
+Some printers can only print in their very best quality (using the
+smallest dots available) printing at a lower resolution. For example,
+the Stylus Photo EX can normally print with a dot spacing of 1/720".
+The smallest dot size cannot be printed with a dot spacing of less
+than 1/360", however. In this case, we use @code{enhanced_xres}
+to specify the resolution to be used in this enhanced mode, and
+@code{enhanced_resolution} to specify the printing resolution above
+which we use the @code{enhanced_xres}.
+
+The @code{resolution_scale} command is used to specify scaling factors
+for the dot separation on newer printers. It should always be 14400
+with current printers.
+
+
+The fourth section specifies the minimum and maximum paper sizes, and
+the margins. Some printers allow use of narrower margins when
+softweave is used; both sets of margins are specified.
+
+There is a convenient @samp{INCH} macro defined to make specification of
+the @code{max_paper_width} and @code{max_paper_height} more legible. It
+multiplies 72 by the provided expression to get the appropriate number
+of points. For example, to specify 8.5", @samp{INCH(17/2)} expands to
+@samp{(72 * 17/2)}, which is evaluated left to right, and hence
+generates the correct value.
+
+
+The fifth section specifies some miscellaneous values that are
+required for certain printers. For most printers, the correct values
+are 1 for @code{separation_rows} and 0 for the others. Very, very few
+printers require (or allow) @code{separation_rows} to be anything but
+1 and @code{pseudo_separation_rows} other than zero. The Stylus Color
+1520, Stylus Color 800, Stylus Color 850, and (strangely enough to my
+mind, since it's a new printer) Stylus Color 660 seem to be the only
+exceptions.
+
+The @code{zero_margin_offset} is used to specify an additional
+negative horizontal offset required to print to the edges of the paper
+on newer Stylus Photo printers. These must be determined empirically;
+good starting values are 100 for 1440 DPI and 50 for 2880 DPI
+printers. The goal is to print to the edge of the page, but not over
+it.
+
+
+The sixth section specifies head offsets for printers that do not have
+the color jets aligned. Certain printers, such as the Stylus Color
+480, have an unusual head arrangement whereby instead of all of the
+colors being aligned vertically, the nozzles are configured in
+groups. These printers are easy to determine; if the normal head
+offset of zero for each color is used, the printing will be vertically
+out of alignment. Most of these printers require specification of a
+negative offset for printing to the top edge of the paper; typically
+these printers do not require such an offset when printing black only.
+
+The seventh section specifies the most difficult values to tune, the
+dot sizes, printing densities, and ink values (for variable dot size
+enabled printers). These will be described in detail below.
+
+
+The last section specifies luminosity, hue, and saturation adjustment
+vectors for the printer, and the paper definitions. These are used to
+adjust the color in Photograph and Solid Colors output modes. These are
+each vectors of 48 (actually 49, as the first value must be duplicated)
+doubles that remap the luminosity, hue, and saturation respectively.
+The hue is calculated, and the value used to interpolate between the two
+closest points in each vector.
+
+The paper definitions is a set of paper definitions. The paper
+definition contains the name of the paper type, special settings that
+are required for printers to process the paper correctly, and a set of
+adjustment values. These are not currently discussed here.
+
+
+The lists of dot sizes and densities contain values for 13 printing
+modes: 120/180 DPI using printer weaving (single row; incorrectly
+referred to as ``microweave'') and ``soft'' weaving (the driver
+determines the exact pattern of dot layout), 360 DPI microweave and
+softweave, 720x360 DPI microweave and softweave, 720 DPI microweave
+and softweave, 1440x720 microweave and softweave, 2880x720 microweave
+and softweave, and 2880x1440 softweave only. Printer weaving is
+referred to as ``microweave'' for historical reasons.
+
+For the dot sizes, the value for each element in the vector selects
+the dot size to be used when printing at this (or similar)
+resolution. The dot sizes are determined by consulting the
+programming manual for the printer and experimenting as described
+below. Current Epson printers always use dot sizes less than
+@samp{16}, or @samp{0x10}, to indicate single dot size (each dot is
+represented by 1 bit, and it's either printed or not), and dot sizes
+of @samp{16} or greater to indicate variable dot size (each dot is
+represented by 2 bits, and it can either be not printed or take on 2
+or 3 values, representing the relative size of the printed dot).
+Variable dot sizes permit the use of very small dots (which would be
+too small to fill the page and produce solid black) in light areas,
+while allowing the page to be filled with larger dots in darker areas.
+
+Even single dot size printers can usually produce dots of different
+sizes; it's just illegal to actually try to switch dot size during a
+page. These dots are also much bigger than those used in true
+variable dot size printing.
+
+A dot size of @samp{-1} indicates that this resolution is illegal for
+the printer in question. Any resolutions that would use this dot size
+will not be presented to the user. A dot size of @samp{-2} indicates
+that this resolution is legal, but that the driver is not to attempt
+to set any dot size. Some very old printers do not support the
+command to set the dot size.
+
+Most printers support a dot size of @samp{0} as a mode-specific default,
+but it's often a bigger dot than necessary. Printers usually also
+support some dot sizes between @samp{1} and @samp{3}. Usually @samp{1}
+is the right dot size for 720 and 1440 dpi printing, and @samp{3} works
+best at 360 dpi.
+
+Variable dot size printers usually support 2 or 3 sets of variable dot
+sizes. Older printers based on a 6 picolitre drop (the 480, 720, 740,
+750, 900, and 1200) support two: mode 16 (0x10 in hexadecimal) for
+normal variable dots at 1440 or 720 dpi, and mode 17 (0x10) for
+special larger dots at 360 dpi. Newer printers based on 4 picolitre
+drops normally support three sizes: @samp{0x10} for 4 pl base drops,
+@samp{0x11} for 6 pl base drops, and @samp{0x12} for special large
+drops. On these printers, @samp{0x10} usually works best at 1440x720
+and @samp{0x11} works best at 720x720. Unfortunately, @samp{0x10}
+doesn't seem to generate quite enough density at 720x720, because if
+it did the output would be very smooth. Perhaps it's possible to
+tweak things@enddots{}
+
+
+The list of densities is a list of base density values for all of the
+above listed modes. ``Density'' refers to the amount of ink deposited
+when a solid color (or solid black) is printed. So if the density is
+@samp{.5}, solid black actually prints only half the possible dots.
+``Base density'' refers to the fact that the density value can be
+scaled in the GUI or on the Ghostscript command line. The density
+value specified (which is not made visible to the user) is multiplied
+by the base density to obtain the effective density value. All other
+things (such as ink drop size) remaining the same, doubling the
+resolution requires halving the base density. The base density in the
+density vector may exceed @samp{1}, as many paper types require lower
+density than the base driver. The driver ensures that the actual
+density never exceeds 1.
+
+Tuning the density should be done on high quality paper (usually
+glossy photo paper). The goal is to find the lowest density value
+that results in solid black (no visible gaps under a fairly high power
+magnifying glass or loupe). If an appropriate density value is found
+for 720 DPI, it could be divided by 2 for 1440x720, by 4 for 2880x720,
+and by 8 for 2880x1440.
+
+However, for printers that offer a choice of dot size, this may not be
+the best strategy. The best choice for dot size is the smallest dot
+size that allows choosing a density value not greater than 1 that
+gives full coverage. This dot size may be different for different
+resolutions. Tuning variable dot size printers is more complicated;
+the process is described below.
+
+The last member is a pointer to a structure containing a list of ink
+values for variable dot size (or 6 color) inks. We model variable dot
+size inks as producing a certain "value" of ink for each available dot
+size, where the largest dot size has a value of 1. 6-color inks are
+handled similarly; the light cyan and light magenta inks are treated
+as a fractional ink value. The combination of variable dot size and 6
+color inks, of course, just creates that many more different ink
+choices.
+
+This structure is actually rather complicated; it contains entries for
+each combination of physical printer resolution (180, 360, 720, and
+1440 dpi), ink colors (4, 6, and 7), and single and variable dot sizes
+(since some printer modes can't handle variable dot size inks). Since
+there's so much data, it's actually a somewhat deeply nested
+structure:
+
+An @code{escp2_printer_t} contains a pointer (essentially, a reference
+rather than a copy) to an @code{escp2_variable_inklist_t}.
+
+An @code{escp2_variable_inklist_t} contains pointers to
+@code{escp2_variable_inkset_t} structures. There is one such pointer
+for each combination of resolution, dot type, and ink colors as
+described above. Yes, this is rather inflexible.
+
+An @code{escp2_variable_inkset_t} contains pointers to
+@code{escp2_variable_ink_t} structures. There is one such pointer for
+each of the four colors (C, M, Y, and K).
+
+An @code{escp2_variable_ink_t} contains a pointer to the actual list of
+ink values (@code{simple_dither_range_t}), the number of ink values, and
+a density value to be used for computing the transitions. This density
+value is actually a scaling value; it is multiplied by the effective
+density to compute the density to be used for computing the transitions.
+Normally, this value is @samp{1}, but in some cases it may be possible
+to get smoother results with a different value (in particular, the
+single dot size 6-color inks work best with the effective density scaled
+to @samp{.75} for this purpose). A lower density lowers the transition
+points, which results in more ink being deposited.
+
+A @code{simple_dither_range_t} is a structure containing four values:
+
+@enumerate
+@item The value of the particular ink
+@item The bit pattern used to represent the ink
+@item Whether the ink is light (0) or dark (1), for inks with light and dark variants
+@item The relative amount of ink actually deposited by this dot (not
+currently used for much; it can be used for ink reduction purposes, to
+reduce the amount of ink deposited on the paper).
+@end enumerate
+
+These things are interesting as arrays. From an array of
+@code{simple_dither_range_t}'s, the dither code computes transition
+values that it looks up at run time to decide what ink to print, as well
+as whether to print at all.
+
+@strong{Really} confused now? Yup. You'll probably find it easier to
+simply read the code.
+
+
+@node Tuning Epson printers, Canon inkjet printers, Epson inkjet printers, New Printer
+@appendixsection Tuning the printer
+@cindex tuning the printer
+@cindex printer, tuning
+
+Now, how do you use all this to tune a printer? There are a number of
+ways to do it; this one is my personal favorite.
+
+There's a file named @file{cyan-sweep.tif}. This consists of a thin bar
+of cyan sweeping from white to almost pure cyan, and from pure cyan to
+black. The first thing to do is to pick the appropriate
+@code{simple_dither_range_t} (or create a whole new
+@code{escp2_variable_inklist_t}) and comment out all but the darkest ink
+(this means you'll be using the largest dots of dark ink). At 8.5"
+width (the width of a letter-size piece of paper), the bar will be 1/8"
+high. Printing it on wider or narrower paper will change the height
+accordingly. Print it width-wise across a piece of photo quality paper
+in line art mode using ordered or adaptive hybrid dither. Do not use
+photographic mode; the colors in photographic mode vary non-linearly
+depending upon the presence of the three color components, while in line
+art mode the colors are much purer. Make sure that all the color
+adjustments are set to defaults (1.0). Use the highest quality version
+of the print mode you're testing to reduce banding and other artifacts.
+This is much easier to do with the Gimp than with Ghostscript.
+
+At this stage, you want to look for four things:
+
+@enumerate
+@item
+The black near the center of the line is solid, but not more so than
+that.
+
+@item
+The cyan immediately to the left of the black is @emph{almost} solid.
+
+@item
+The dark cyan at the far right of the page is solid, but not more so.
+You can try tuning the density so that it isn't quite solid, then
+nudging up the density until it is.
+
+@item
+Both sweeps sweep smoothly from light to dark. In particular, the dark
+half of the bar shouldn't visibly change color; it should go smoothly
+from cyan to black.
+@end enumerate
+
+Repeat this stage until you have everything just right. Use the
+positioning entry boxes in the dialog to position each bar exactly
+1/8" further down the page. Adjacent bars will be touching.
+
+The next step is to uncomment out the second darkest dot size. If
+you're using variable dots, use the second largest dot size of the
+dark ink rather than the largest dot size of the light ink. This will
+give you two inks.
+
+When you recompile the plugin, you simply need to copy the new
+executable into the correct place. You do not need to exit and
+restart the Gimp.
+
+Print another bar adjacent to the first one. Your goal is to match
+the bar using a single dot size as closely as possible. You'll find
+that the dark region of the bar shouldn't change to any great degree,
+but the light half probably will. If the lighter part of the light
+half is too dark, you need to increase the value of the smaller dot;
+if it's too light, you need to decrease the value. The reasoning is
+that if the value is too low, the ink isn't being given enough credit
+for its contribution to the darkness of the ink, and vice versa.
+Repeat until you have a good match. Make sure you let the ink dry
+fully, which will take a few minutes. Wet ink will look too dark.
+Don't look at the paper too closely; hold it at a distance. The extra
+graininess of the largest dot size will probably make it look lighter
+than it should; if you hold it far enough away so that you can't see
+the dots, you'll get a more accurate picture of what's going on.
+
+After you have what looks like a good match, print another bar using
+only the largest dot size (or dark ink, for single dot size 6-color
+printers). You want to ensure that the bars touching each other look
+identical, or as close as possible to it; your eye won't give you a
+good reading if the bars are separated from each other. You'll
+probably have to repeat the procedure.
+
+The next step is to comment out all but the largest and third-largest
+dot size, and repeat the procedure. When they match, use all three
+dot sizes of dark ink. Again, the goal is to match the single dot
+size.
+
+You'll probably find the match is imperfect. Now you have to figure
+out what region isn't right, which takes some experimentation. Even
+small adjustments can make a noticeable difference in what you see.
+At this stage, it's very important to hold the page far enough from
+your eye; when you use all three dot sizes, the texture will be much
+more even, which sometimes makes it look darker and sometimes lighter.
+
+After this is calibrated, it's time to calibrate the light ink against
+the dark ink. To do this, comment out all but the large dot version
+of the two inks, and repeat the procedure. This is trickier, because
+the hues of the inks might not be quite identical. Look at the dark
+half of the bar as well as the light half to see that the hue really
+doesn't change as you sweep from cyan to black. Sometimes it's easier
+to judge that way. You may find that it looks blotchy, in which case
+you should switch from ordered dither to adaptive hybrid.
+
+After you have the light and dark inks calibrated against each other,
+it's time to add everything back in. Usually you don't want to use
+the largest dot size of light ink. These dots will be much larger
+than the small dots of dark ink, but they'll still be lighter. This
+will cause problems when printing mixed colors, since you'll be
+depositing more ink on lighter regions of the page, and you'll
+probably get strange color casts that you can't get rid of in neutral
+tones. I normally use only the smallest one or two dot sizes of light
+ink.
+
+After you've tweaked everything, print the color bar with saturation
+set to zero. This will print neutral tones using color inks. Your
+goal here is to look for neutral tonality. If you're using a 6-color
+printer and get a yellow cast, it means that the values for your light
+inks are too high (remember, that means they're getting too much
+credit, so you're not depositing enough cyan and magenta ink, and the
+yellow dominates). If you get a bluish or bluish-purple cast, your
+light inks are too low (you're not giving them enough credit, so too
+much cyan and magenta is deposited, which overwhelms the yellow).
+Make sure you do this on very white, very high grade inkjet paper
+that's designed for 1440x720 dpi or higher; otherwise the ink will
+spread on contact and you'll get values that aren't really true for
+high grade paper. You can, of course, calibrate for low grade paper
+if that's what you're going to use, but that shouldn't be put into the
+distribution.
+
+You can also fully desaturate this bar inside the Gimp and print it as
+monochrome (don't print the cyan as monochrome; the driver does funny
+things with luminance), for comparison. You'll find it very hard to
+get rid of all color casts.
+
+There are other ways of tuning printers, but this one works pretty
+well for me.
+
+
+@node Canon inkjet printers, , Tuning Epson printers, New Printer
+@appendixsection Canon inkjet printers
+
+Basically, a new Canon printer can be added to @file{print-canon.c} in a
+similar way as described above for the epson inkjet printers. The main
+differences are noted here:
+
+In general, Canon printers have more ``built-in intelligence'' than Epson
+printers which results in the fact that the driver only has to tell the
+printing conditions like resolutions, dot sizes, etc. to the printer and
+afterwards transfer the raster data line by line for each color used.
+
+@code{canon_cap_t} is a C struct defined as follows:
+
+@deftypevr {Data type} {} canon_cap_t
+@example
+typedef struct canon_caps @{
+ int model; /* model number as used in printers.xml */
+ int max_width; /* maximum printable paper size */
+ int max_height;
+ int base_res; /* base resolution - shall be 150 or 180 */
+ int max_xdpi; /* maximum horizontal resolution */
+ int max_ydpi; /* maximum vertical resolution */
+ int max_quality;
+ int border_left; /* left margin, points */
+ int border_right; /* right margin, points */
+ int border_top; /* absolute top margin, points */
+ int border_bottom; /* absolute bottom margin, points */
+ int inks; /* installable cartridges (CANON_INK_*) */
+ int slots; /* available paperslots */
+ int features; /* special bjl settings */
+ canon_dot_size_t dot_sizes; /* Vector of dot sizes for resolutions */
+ canon_densities_t densities; /* List of densities for each printer */
+ canon_variable_inklist_t *inxs; /* Choices of inks for this printer */
+@} canon_cap_t;
+@end example
+@end deftypevr
+
+Since there are Canon printers which print in resolutions of
+@math{2^n*150} dpi (e.g. 300, 600, 1200) and others which support
+resolutions of @math{2^n*180} dpi (e.g. 360, 720, 1440), there's a base
+resolution (150 or 180, respectively) given in the
+@code{canon_cap_t}. The structs @code{canon_dot_size_t},
+@code{canon_densities_t} and @code{canon_variable_inklist_t} refer to
+resolutions being multiples of the base resolution.
+
+For the Canon driver, the struct @code{canon_dot_size_t} holds values
+for a model's capabilities at a given resolution: @samp{-1} if the
+resolution is not supported. @samp{0} if it can be used and @samp{1} if
+the resolution can be used for variable dot size printing.
+
+In @code{canon_densities_t} the base densities for each resolution can
+be specified like for an epson printer, the same holds true for
+@code{canon_variable_inklist_t}. See the descriptions above to learn
+about how to adjust your model's output to yield nice results.
+
+There's a slight difference though in the way the Canon driver and the escp2
+driver define their variable inklists: In the Canon driver, you need to define
+an inklist like this:
+
+@example
+static const canon_variable_inklist_t canon_ink_myinks[] =
+@{
+ @{
+ 1,4, /* 1bit/pixel, 4 colors */
+ &ci_CMYK_1, &ci_CMYK_1, &ci_CMYK_1,
+ &ci_CMYK_1, &ci_CMYK_1, &ci_CMYK_1,
+ @},
+ @{
+ 3,4, /* 3bit/pixel, 4 colors */
+ &ci_CMYK_3, &ci_CMYK_3, &ci_CMYK_3,
+ &ci_CMYK_3, &ci_CMYK_3, &ci_CMYK_3,
+ @},
+@};
+@end example
+
+@noindent
+where the @samp{&ci_CMYK_1} and @samp{&ci_CMYK_3} entries are references
+to a previously defined const of type @code{canon_variable_inkset_t}.
+
+
+
+
+
+
+
diff --git a/doc/overview.texi b/doc/overview.texi
new file mode 100644
index 0000000..64d3409
--- /dev/null
+++ b/doc/overview.texi
@@ -0,0 +1,19 @@
+@node Overview, Using libgimpprint, Copying, Top
+@chapter Overview
+@cindex overview
+
+The GIMP-Print package is a collection of programs and a library for
+high quality printing on modern inkjets, including `photographic
+quality' models which offer very high resolutions and several inks.
+
+
+META: Short history of the project
+
+GIMP-Print is the print facility of the @dfn{GNU Image Manipulation Program}
+(GIMP). It is in addition
+a suite of drivers that may be used with common UNIX spooling systems
+using GhostScript or CUPS. These drivers provide printing quality for
+UNIX/Linux on a par with proprietary vendor-supplied drivers in many
+cases, and can be used for many of the most demanding printing tasks.
+The core of GIMP-Print is a shared library (libgimpprint) which may be
+used by any program that wishes to produce high-qulaity printed output.
diff --git a/doc/print-color.png b/doc/print-color.png
new file mode 100644
index 0000000..db1af3f
--- /dev/null
+++ b/doc/print-color.png
Binary files differ
diff --git a/doc/print-main.png b/doc/print-main.png
new file mode 100644
index 0000000..2d78222
--- /dev/null
+++ b/doc/print-main.png
Binary files differ
diff --git a/doc/print-setup.png b/doc/print-setup.png
new file mode 100644
index 0000000..904e03b
--- /dev/null
+++ b/doc/print-setup.png
Binary files differ
diff --git a/doc/problems.texi b/doc/problems.texi
new file mode 100644
index 0000000..0e59e03
--- /dev/null
+++ b/doc/problems.texi
@@ -0,0 +1,17 @@
+@node Problems, Appendices, Programs, Top
+@chapter Reporting Bugs
+@cindex bugs
+@cindex problems
+
+If you find a bug in GIMP-Print or have any suggestions for modification
+or improvement, please send electronic mail to the GIMP-Print bug
+reporting address @footnote{@value{BUGADDR}}. Include the version
+number, which you can find by running @w{@samp{gimpprint-config
+--version}}. Also include in your message the output that the program
+produced and the output you expected, if applicable, otherwise the best
+description of the problem that you can provide.
+
+If you have other questions, comments or suggestions about GIMP-Print,
+contact the developers via electronic mail to the GIMP-Print mailing
+list @footnote{@value{MAILLIST}}. They will try to help you out,
+although they may not have time to fix your problems.
diff --git a/doc/programs.texi b/doc/programs.texi
new file mode 100644
index 0000000..4db47ee
--- /dev/null
+++ b/doc/programs.texi
@@ -0,0 +1,278 @@
+@node Programs, Problems, Functions, Top
+@chapter Programs
+@cindex programs
+
+This chapter of the manual describes the use of some of the programs
+which use the GIMP-Print library (libgimpprint). Note that there is now
+a user manual in DocBook/SGML format, currently provided in HTML,
+PostScript and PDF formats which is distributed with GIMP-Print. This
+manual currently covers the use of the GIMP Print plugin and CUPS
+drivers.
+
+
+@menu
+* The GIMP plugin:: The print plugin for the GIMP
+* Ghostscript:: Printer driver
+* CUPS:: Printer driver
+@end menu
+
+@node The GIMP plugin, Ghostscript, Programs, Programs
+@section The GIMP Print plugin
+@cindex GIMP Print plugin
+@cindex Print plugin
+
+The GIMP Print plugin is the printing facility for the GNU Image
+Manipulation Program@footnote{@uref{http://www.gimp.org}}. This section
+examines the features offered by the Print plugin.
+
+The main window is divided into five panes:
+
+
+@subsection Preview
+
+The Preview pane contains a positioning widget that allows interactively
+positioning the output on the page. It contains an outer border,
+representing the sheet of paper; an inner border, representing the
+printable area of the printer; an arrow, pointing to the top of the page
+(the end that's fed into the printer); and a black rectangle,
+representing the position of the image on the page. The image can be
+moved around on the paper. When the first (left) button is used, the
+image is moved in screen pixels; when any other button is used, the
+image is moved in points@footnote{The output resolution of the plugin.}.
+The arrow resizes depending upon the media size chosen; the shaft of the
+arrow is always equal to one inch on the output.
+
+@image{print-main,,4in}
+
+
+@subsection Printer Settings
+
+The Printer Settings pane contains a dropdown menu for selecting a
+printer to print to. There is a special `printer' named @samp{File}
+that allows you to choose a file to print to, rather than a printer
+queue. The Setup box to the right allows specification of a printer
+type, a PPD file@footnote{For Postscript printers.}, and the command to
+be used to print. Each distinct printer in the Printer list can have
+different settings applied to it. Below that is a combo box allowing
+choice of media size. The choices are constrained to those that the
+printer supports. Below that are dropdown menus for choosing media type
+(what kind of paper), media source (what input tray), ink type, and
+resolution. All of these settings are printer-specific.
+
+@image{print-setup,,2in}
+
+
+@subsection Position
+
+The Position pane contains various widgets to place the image on the
+paper. These widgets work in conjunction with the Preview pane. At the
+top of the pane is a button to center the image on the paper (not on the
+printable area), and on either side buttons to center vertically and
+horizontally. Below these are four boxes that allow entry of the left,
+top, right, and bottom of the image. These positions are relative to
+the top left of the paper@footnote{Again, that's relative to the paper
+corner, not the printable area, which is usually smaller.}. There are
+two additional boxes that allow specification of the right margin and
+bottom margin if you prefer; these are relative to the bottom right
+corner of the paper. Any of these may have values entered into them;
+the preview image will be moved appropriately.
+
+@strong{Note}: These entries do not resize the image.
+
+Finally, there is a pick box for orientation (landscape or portrait).
+There is an @samp{Auto} mode that picks the orientation that yields the
+orientation that best matches that of the image to be printed.
+
+@subsection Scaling
+
+The Scaling pane contains a slider that allows scaling of the image.
+The image can be scaled in either percent of the printable area
+(@strong{not} the page in this case) or pixels per inch (PPI) via a
+radio button below the slider. PPI allows matching image resolution to
+printer resolution. The image may be scaled using either method to
+between 5 and 100% of the imageable area. It is not possible to crop
+with the Print plugin. In Percent mode, the image is scaled so that
+neither axis will be longer than the percent of the printable area
+specified. For example, if you print an image at 20%, it will be
+possible to tile the image 5 times on one axis and at least 5 times on
+the other. To the right of the radio button is a button called Set
+Image Scale. This sets the scaling to PPI, and sets the resolution as
+closely as possible to the resolution stored in the image. To the right
+of the Set Image Scale button are two boxes that allow entry of width
+and height of the image. These set the scaling mode to PPI. Specifying
+one automatically sets the other, and the image is repositioned as
+needed to prevent it from falling off the edge of the page.
+
+To its right is a button group that allows choosing English (inch)
+units or metric (centimeter) units.
+
+@subsection Image Settings
+
+The Image Settings pane allows choice of Line Art, Solid Colors, or
+Photograph image type. Line art or Solid Colors should be used for
+graphics containing mostly solid areas of color. They're very similar
+to each other. Photograph mode dithers more slowly, but produces more
+accurate colors. To the right of these three radio buttons is a button
+called Adjust Color. This pops up a new window that controls various
+output quality settings. That will be described separately. Finally,
+there is a choice of Black and White, Color and Monochrome output.
+Monochrome output can be used to print absolute black and white very
+quickly.
+
+
+@subsubsection Adjust Output
+
+The Adjust Output button button pops up a non-modal dialog that allows
+adjustment of various parameters related to the print quality. These
+are independent of the controls within the GIMP itself and only affect
+the print.
+
+@image{print-color,,2in}
+
+At the top of the window is a thumbnail of the image that changes to
+reflect the color settings of the image. This enables you to get an
+idea of how the image will print out as you adjust settings.
+
+Below that there are eight sliders:
+
+@table @emph
+@item Brightness
+(0--2.0, default 1.0) Adjust the brightness of the image.
+
+@item Contrast
+(0--4.0, default 1.0) Adjust the output contrast.
+
+@item Cyan, Magenta, Yellow
+(0--4.0, default 1.0) Adjust the cyan, magenta, and yellow in the
+output. These should not normally need to be adjusted very much; even
+very small adjustments can go quite a long way to restoring color
+balance.
+
+@item Saturation
+(0--9.0, default 1.0) Adjust the color brilliance (saturation) of the
+output. Saturation of 0 means pure gray scale, with no color.
+Saturation of 9.0 will make just about anything but pure grays
+brilliantly colored.
+
+@item Density
+(0.1--2.0, default 1.0) Adjust the density (amount of ink) in the print.
+The density is automatically corrected for the particular printer,
+resolution, and in some cases paper choices. If solid black in the
+input is not solid in the print, the density needs to be increased; if
+there is excessive ink bleed-through and muddy dark colors, the density
+should be decreased.
+
+@strong{Note}: the density will not increase beyond a certain amount no
+matter what the slider is set to.
+
+@item Gamma
+(0.1--4.0, default 1.0) Adjust the output gamma. The gamma value is
+automatically corrected for the choice of printer; this is used if you
+believe the automatic setting is incorrect.
+@end table
+
+
+@subsubsection Dither Algorithm
+There is also a selection box for the dither algorithm to be used in the
+pop-up dialog. There are currently seven choices:
+
+@table @emph
+@item Adaptive Hybrid
+Adaptive Hybrid usually yields the best output quality; it chooses a
+modified Floyd-Steinberg error diffusion algorithm or ordered dithering
+depending upon the image characteristics.
+
+@item Ordered
+Ordered uses a pure ordered dither. It generally yields excellent
+quality for simple black and white or four color printers without
+variable drop size or drop modulation; it is not recommended if high
+quality is desired on six color printers. It is considerably faster
+than Adaptive Hybrid.
+
+@item Fast
+Fast also uses a pure ordered dither, but uses a very simple black model
+and makes no attempt to handle multi-level (6-color, variable drop size,
+or drop modulation) at all cleanly. It is substantially faster than
+Ordered dither. The quality tends to be quite poor except on simple
+four color printers. On three color printers, quality is probably
+competitive with anything else.
+
+@item Very Fast
+Very Fast is similar to Fast, except that it uses a very simple dither
+matrix that can be looked up much more quickly than the matrix used in
+the Fast dither. For simple pure black and white images dominated by
+horizontal and vertical lines, this may actually yield the best results;
+for other types of image, the quality will be poor.
+
+@item Adaptive Random
+Adaptive Random is similar to Adaptive Hybrid, except that the
+modifications to the Floyd-Steinberg algorithm are slightly different.
+This is slower than Adaptive Hybrid on most systems. For some images
+the quality may be better than Adaptive Hybrid, but generally Adaptive
+Hybrid should yield slightly superior images.
+
+@item Hybrid Floyd-Steinberg
+Hybrid Floyd-Steinberg uses the modified Floyd-Steinberg algorithm of
+Adaptive Hybrid on the entire image. Generally, the results are poor in
+pale regions.
+
+@item Random Floyd-Steinberg
+Random Floyd-Steinberg uses the modified Floyd-Steinberg algorithm of
+Adaptive Random on the entire image. Generally, the results are poor in
+pale regions.
+@end table
+
+
+@subsection Action Buttons
+
+The last pane contains four action buttons:
+
+@table @emph
+@item Print and Save Settings
+Immediately print the image (or, if the File printer is chosen, display
+a file selection window to pick the output file), and save all current
+settings for all printers.
+
+@item Save Settings
+Immediately save the settings, and continue working in the Print plugin.
+
+@item Print
+Immediately print the image (or, if the @samp{File} printer is chosen,
+display a file selection window to pick the output file), but do not
+save settings.
+
+@item Cancel
+Immediately quit without saving settings or printing.
+@end table
+
+
+@node Ghostscript, CUPS, The GIMP plugin, Programs
+@section Ghostscript driver
+@cindex ghostscript driver
+
+
+@node CUPS, , Ghostscript, Programs
+@section CUPS driver
+@cindex CUPS driver
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/users_guide/.cvsignore b/doc/users_guide/.cvsignore
new file mode 100644
index 0000000..ba5c952
--- /dev/null
+++ b/doc/users_guide/.cvsignore
@@ -0,0 +1,12 @@
+Makefile.in
+Makefile
+users-guide.tex
+users-guide.log
+users-guide
+users-guide.aux
+users-guide.dvi
+users-guide.ps
+users-guide.pdf
+users-guide.out
+html-stamp
+html
diff --git a/doc/users_guide/Makefile.am b/doc/users_guide/Makefile.am
new file mode 100644
index 0000000..a91b1d6
--- /dev/null
+++ b/doc/users_guide/Makefile.am
@@ -0,0 +1,268 @@
+## $Id: Makefile.am,v 1.28 2001/11/08 13:15:18 rlk Exp $
+## Copyright (C) 2001 Andy Stewart and Roger Leigh
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = 1.4 gnu
+
+@SET_MAKE@
+
+MAINT_CHARSET = latin1
+
+
+## Variables
+
+MANUAL = users-guide
+HTMLDIR = html
+
+OUTPUTS = \
+ $(MANUAL).pdf \
+ $(MANUAL).ps \
+ html
+
+USER_GUIDE = $(MANUAL).pdf html $(MANUAL).ps
+
+STANDARD_TARGETS=@USER_GUIDE@
+
+DISTHOOKDIRS = figures $(HTMLDIR)
+DISTHOOKFILES = $(STANDARD_TARGETS)
+
+PNG_IMAGES = figures/cups_admin.png \
+ figures/cups_admin_device.png \
+ figures/cups_admin_make.png \
+ figures/cups_admin_model.png \
+ figures/cups_admin_success.png \
+ figures/cups_config_printer.png \
+ figures/cups_my_printer.png \
+ figures/cups_printers.png \
+ figures/cups_startup.png \
+ figures/gimp-print-gui-1.png \
+ figures/gimp-print-gui.png \
+ figures/gimp-print-new-printer.png \
+ figures/gimp-print-print-color-adjust.png \
+ figures/gimp-print-setup.png \
+ figures/gimp_image.png \
+ figures/gimp_startup.png
+
+EPS_IMAGES = $(addsuffix .eps,$(basename $(PNG_IMAGES)))
+
+if MAINTAINER_MODE
+MAINT_MODE = true
+else
+MAINT_MODE = false
+endif
+
+if MAINTAINER_MODE
+ALL_LOCAL_TARGETS = docs
+else
+ALL_LOCAL_TARGETS = $(STANDARD_TARGETS)
+endif
+
+## Rules
+
+dist-hook: $(USER_GUIDE)
+ for dir in $(DISTHOOKDIRS) ; do \
+ if test -d $(srcdir)/$$dir ; then \
+ mkdir $(distdir)/$$dir; \
+ for dirfile in $(srcdir)/$$dir/*; do \
+ if test -f $$dirfile ; then \
+ cp -p $$dirfile $(distdir)/$$dir ; \
+ fi ; \
+ if test -d $$dirfile ; then \
+ cp -pR $$dirfile $(distdir)/$$dir ; \
+ fi ; \
+ done \
+ fi \
+ done
+ for file in $(DISTHOOKFILES) ; do \
+ if test -f $$file ; then \
+ cp -p $$file $(distdir) ; \
+ fi ; \
+ done
+
+$(MANUAL).pdf: ./$(MANUAL).sgml
+ if test $(srcdir) = '.' ; then \
+ : ; \
+ else \
+ if test -L $(notdir $<) ; then \
+ $(RM) $(notdir $<) ; \
+ fi ; \
+ $(LN_S) $< $(notdir $<) ; \
+ if test -d figures ; then \
+ : ; \
+ else \
+ mkdir figures ; \
+ fi ; \
+ for image in $(addprefix $(srcdir)/, $(PNG_IMAGES)) ; do \
+ cp -p $$image figures/`basename $$image` ; \
+ done ; \
+ fi ; \
+ $(DB2PDF) $(MANUAL).sgml
+
+docs: html ps pdf
+
+all-local: $(ALL_LOCAL_TARGETS)
+
+pdf: $(MANUAL).pdf
+
+ps: $(MANUAL).ps
+
+$(MANUAL).ps: $(MANUAL).sgml $(EPS_IMAGES)
+ sed -e 's/\.png"/.eps"/g' -e 's/FORMAT="PNG"/FORMAT="EPS"/g' $< > $(MANUAL)-eps.sgml
+ $(DB2PS) $(MANUAL)-eps.sgml
+ mv $(MANUAL)-eps.ps $(MANUAL).ps
+ -$(RM) -f $(MANUAL)-eps.*
+
+%.eps:
+ if test ! -d figures ; then mkdir figures ; fi
+ $(CONVERT) $(srcdir)/$(basename $@).png EPS2:$@
+
+html: html-stamp
+
+# This ugly workaround with SOURCE is because db2html doesn't seem to like
+# "./users-guide.sgml". Note that db2ps does not have the same limitation.
+# html-stamp should *only* be called by html--it's just a timestamp!
+html-stamp: $(MANUAL).sgml $(PNG_IMAGES)
+ if test $(srcdir) = '.' ; then \
+ : ; \
+ else \
+ if test -L $(notdir $<) ; then \
+ $(RM) $(notdir $<) ; \
+ fi ; \
+ $(LN_S) $< $(notdir $<) ; \
+ fi
+ $(DB2HTML) $(MANUAL).sgml
+ -mkdir $(MANUAL)/figures
+ for image in $(addprefix $(srcdir)/, $(PNG_IMAGES)) ; do \
+ cp -p $$image $(MANUAL)/figures/`basename $$image` ; \
+ done
+ -$(RM) -rf $(HTMLDIR)
+ mv $(MANUAL) $(HTMLDIR)
+ chmod a+rx $(HTMLDIR)
+ touch html-stamp
+
+install-data-local: $(STANDARD_TARGETS)
+ if test -n '$(STANDARD_TARGETS)' ; then \
+ $(mkinstalldirs) $(DESTDIR)$(datadir)/$(PACKAGE)/doc/html/figures ; \
+ $(mkinstalldirs) $(DESTDIR)$(datadir)/$(PACKAGE)/doc/html/stylesheet-images ; \
+ if test -f $(MANUAL).pdf ; then \
+ $(INSTALL_DATA) $(MANUAL).pdf $(DESTDIR)$(datadir)/$(PACKAGE)/doc ; \
+ elif test -f $(srcdir)/$(MANUAL).pdf ; then \
+ $(INSTALL_DATA) $(srcdir)/$(MANUAL).pdf $(DESTDIR)$(datadir)/$(PACKAGE)/doc ; \
+ fi ; \
+ if test -d $(HTMLDIR) ; then \
+ cd $(HTMLDIR) ; \
+ elif test -d $(srcdir)/$(HTMLDIR) ; then \
+ cd $(srcdir)/$(HTMLDIR) ; \
+ else \
+ exit 1 ; \
+ fi ; \
+ for file in *.html *.css ; do \
+ if test -f $$file ; then \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(datadir)/$(PACKAGE)/doc/html ; \
+ fi ; \
+ done ; \
+ cd figures ; \
+ for file in *.png ; do \
+ if test -f $$file ; then \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(datadir)/$(PACKAGE)/doc/html/figures ; \
+ fi ; \
+ done ; \
+ cd ../stylesheet-images ; \
+ for file in * ; do \
+ if test -f $$file ; then \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(datadir)/$(PACKAGE)/doc/html/stylesheet-images ; \
+ fi ; \
+ done ; \
+ fi
+
+uninstall-local:
+ -$(RM) -r $(DESTDIR)$(datadir)/$(PACKAGE)/doc
+
+CLEAN_MANUALS = \
+ $(RM) -f $(MANUAL).pdf $(MANUAL).ps ; \
+ $(RM) -rf html-stamp $(HTMLDIR) ; \
+ $(RM) -f $(EPS_IMAGES)
+
+clean-local:
+ if test $(srcdir) = "." -a $(MAINT_MODE) = false ; then \
+ echo "clean-local: Not removing $(HTMLDIR)" ; \
+ echo 'clean-local: Not removing $(MANUAL).pdf' ; \
+ echo 'clean-local: Not removing $(MANUAL).ps' ; \
+ echo 'clean-local: Not removing EPS figures' ; \
+ else \
+ $(CLEAN_MANUALS) ; \
+ fi
+ if test $(srcdir) = "." ; then \
+ : ; \
+ else \
+ $(RM) -f $(MANUAL).sgml ; \
+ $(RM) -rf figures ; \
+ fi
+ -$(RM) -rf *.tex *.log *.aux *.dvi *.gz *.out *.junk *.out *.fot
+ -$(RM) -rf db2html* DB2HTML*
+
+veryclean:
+ $(MAKE) MAINT_MODE=true clean
+
+maintainer-clean-local:
+ $(CLEAN_MANUALS)
+
+#
+# This is my (so far failed) attempt to create an index for this documentation.
+#
+#
+#index.sgml:
+# $(PERL) /usr/share/sgml/docbook/docbook-dsssl-stylesheets-1.64/bin/collateindex.pl -N -o index.sgml
+#
+# $(JADE) -V html-index \
+# -t sgml \
+# -c /usr/share/sgml/CATALOG.jade_dsl \
+# -c /usr/share/sgml/CATALOG.docbook-dsssl-stylesheets \
+# -c /usr/share/sgml/CATALOG.gnome \
+# -c /usr/share/sgml/CATALOG.docbook_4 \
+# -c /usr/share/sgml/CATALOG.docbook_3 \
+# -D /usr/share/sgml/docbook/docbook-dsssl-stylesheets-1.64 \
+# -d /usr/share/sgml/docbook-toys/suse-both.dsl \
+# -o index.sgml \
+# gimp-print-users-guide-4.1.99-b3.sgml
+#
+#
+# END failed attempt at index creation.
+#
+
+help:
+ @echo " "
+ @echo "Supported targets in this Makefile:"
+ @echo " docs - creates PS, PDF, and HTML documentation files"
+ @echo " ps - creates PostScript documentation"
+ @echo " pdf - creates PDF documentation"
+ @echo " html - creates HTML documentation"
+ @echo " clean - deletes machine generated files, but not outputs"
+ @echo " veryclean - deletes output files in addition"
+ @echo " help - prints this help text"
+ @echo " "
+
+
+## Clean
+
+MAINTAINERCLEANFILES = Makefile.in html-stamp
+
+
+EXTRA_DIST = README $(MANUAL).sgml html-stamp
+
+.PHONY: docs html ps pdf help
diff --git a/doc/users_guide/README b/doc/users_guide/README
new file mode 100644
index 0000000..9dc1b90
--- /dev/null
+++ b/doc/users_guide/README
@@ -0,0 +1,39 @@
+
+The files contained in this directory are all of the source files necessary
+to build "The User's Guide to the Gimp-Print Top Quality Printer Drivers".
+
+Type: make pdf - to build the PDF documentation file
+ make ps - to build the Postscript documentation file
+ make html - to build the HTML documentation files
+ make docs - to build all of the documentation files
+
+This is what will be generated:
+
+ users_guide.ps
+ users_guide.pdf
+ html/book1.html
+
+While building the documentation, you will see messages from LaTeX regarding
+undefined references. These can also be safely ignored.
+
+The documentation contains many color screenshots. My goal was to have the
+documentation print acceptably at 360 DPI. However, I realize that not everybody
+has a color printer. For those people, such as the owners of laser printers,
+I'd like to suggest printing the documentation in greyscale. Printing the
+documentation in black and white will results in unacceptable quality for many
+of the screenshots.
+
+All of the figures are contained in the "figures" subdirectory. Read the
+figures/README file if you are interested in how I created the
+screenshots used throughout the documentation.
+
+All of the HTML files are contained in the "html" subdirectory.
+
+Your constructive feedback is most welcome.
+
+Andy Stewart
+13-oct-2001
+
+
+
+
diff --git a/doc/users_guide/figures/.cvsignore b/doc/users_guide/figures/.cvsignore
new file mode 100644
index 0000000..f7b5423
--- /dev/null
+++ b/doc/users_guide/figures/.cvsignore
@@ -0,0 +1 @@
+*.eps
diff --git a/doc/users_guide/figures/README b/doc/users_guide/figures/README
new file mode 100644
index 0000000..4d37e87
--- /dev/null
+++ b/doc/users_guide/figures/README
@@ -0,0 +1,24 @@
+
+Here's how I created the screen dumps shown in the documentation
+================================================================
+
+0) Bring up the interesting window to be dumped
+
+1) Bring up the GIMP
+
+2) In the GIMP, select File...Acquire...ScreenShot
+
+3) Click on the interesting window to be dumped
+
+4) Select File...SaveAs, PNG, and the file name
+
+The encapsulated postscript files are needed for generating the
+final .ps file. These are created from the PNG files using the
+convert utility. The PNG file is needed for the HTML output.
+
+The image scaling is done in the DocBook source code contained in
+users-guide.sgml
+
+AMS 3-oct-2001
+
+
diff --git a/doc/users_guide/figures/cups_admin.png b/doc/users_guide/figures/cups_admin.png
new file mode 100644
index 0000000..464fcc4
--- /dev/null
+++ b/doc/users_guide/figures/cups_admin.png
Binary files differ
diff --git a/doc/users_guide/figures/cups_admin_device.png b/doc/users_guide/figures/cups_admin_device.png
new file mode 100644
index 0000000..b258263
--- /dev/null
+++ b/doc/users_guide/figures/cups_admin_device.png
Binary files differ
diff --git a/doc/users_guide/figures/cups_admin_make.png b/doc/users_guide/figures/cups_admin_make.png
new file mode 100644
index 0000000..1948ba7
--- /dev/null
+++ b/doc/users_guide/figures/cups_admin_make.png
Binary files differ
diff --git a/doc/users_guide/figures/cups_admin_model.png b/doc/users_guide/figures/cups_admin_model.png
new file mode 100644
index 0000000..b476a75
--- /dev/null
+++ b/doc/users_guide/figures/cups_admin_model.png
Binary files differ
diff --git a/doc/users_guide/figures/cups_admin_success.png b/doc/users_guide/figures/cups_admin_success.png
new file mode 100644
index 0000000..edebafe
--- /dev/null
+++ b/doc/users_guide/figures/cups_admin_success.png
Binary files differ
diff --git a/doc/users_guide/figures/cups_config_printer.png b/doc/users_guide/figures/cups_config_printer.png
new file mode 100644
index 0000000..1f980dc
--- /dev/null
+++ b/doc/users_guide/figures/cups_config_printer.png
Binary files differ
diff --git a/doc/users_guide/figures/cups_my_printer.png b/doc/users_guide/figures/cups_my_printer.png
new file mode 100644
index 0000000..d8441c8
--- /dev/null
+++ b/doc/users_guide/figures/cups_my_printer.png
Binary files differ
diff --git a/doc/users_guide/figures/cups_printers.png b/doc/users_guide/figures/cups_printers.png
new file mode 100644
index 0000000..4d45d1c
--- /dev/null
+++ b/doc/users_guide/figures/cups_printers.png
Binary files differ
diff --git a/doc/users_guide/figures/cups_startup.png b/doc/users_guide/figures/cups_startup.png
new file mode 100644
index 0000000..22d01d0
--- /dev/null
+++ b/doc/users_guide/figures/cups_startup.png
Binary files differ
diff --git a/doc/users_guide/figures/gimp-print-gui-1.png b/doc/users_guide/figures/gimp-print-gui-1.png
new file mode 100644
index 0000000..1c083bb
--- /dev/null
+++ b/doc/users_guide/figures/gimp-print-gui-1.png
Binary files differ
diff --git a/doc/users_guide/figures/gimp-print-gui.png b/doc/users_guide/figures/gimp-print-gui.png
new file mode 100644
index 0000000..a9739fb
--- /dev/null
+++ b/doc/users_guide/figures/gimp-print-gui.png
Binary files differ
diff --git a/doc/users_guide/figures/gimp-print-new-printer.png b/doc/users_guide/figures/gimp-print-new-printer.png
new file mode 100644
index 0000000..39dd681
--- /dev/null
+++ b/doc/users_guide/figures/gimp-print-new-printer.png
Binary files differ
diff --git a/doc/users_guide/figures/gimp-print-print-color-adjust.png b/doc/users_guide/figures/gimp-print-print-color-adjust.png
new file mode 100644
index 0000000..5ab1a33
--- /dev/null
+++ b/doc/users_guide/figures/gimp-print-print-color-adjust.png
Binary files differ
diff --git a/doc/users_guide/figures/gimp-print-setup.png b/doc/users_guide/figures/gimp-print-setup.png
new file mode 100644
index 0000000..e406c0b
--- /dev/null
+++ b/doc/users_guide/figures/gimp-print-setup.png
Binary files differ
diff --git a/doc/users_guide/figures/gimp_image.png b/doc/users_guide/figures/gimp_image.png
new file mode 100644
index 0000000..9193558
--- /dev/null
+++ b/doc/users_guide/figures/gimp_image.png
Binary files differ
diff --git a/doc/users_guide/figures/gimp_startup.png b/doc/users_guide/figures/gimp_startup.png
new file mode 100644
index 0000000..b6335e1
--- /dev/null
+++ b/doc/users_guide/figures/gimp_startup.png
Binary files differ
diff --git a/doc/users_guide/users-guide.sgml b/doc/users_guide/users-guide.sgml
new file mode 100644
index 0000000..f4fef19
--- /dev/null
+++ b/doc/users_guide/users-guide.sgml
@@ -0,0 +1,1873 @@
+<!doctype book public "-//OASIS//DTD DocBook V4.1//EN">
+<book>
+
+ <bookinfo>
+ <title>The User's Guide to the Gimp-Print Top Quality Printer Drivers</title>
+ <date>November 23, 2001</date>
+ <pubdate>November 23, 2001</pubdate>
+ <author>
+ <firstname>Andy</firstname>
+ <surname>Stewart</surname>
+ </author>
+ <copyright>
+ <year>2001</year>
+ <holder>Andy Stewart</holder>
+ </copyright>
+ <legalnotice>
+ <para>The User's Guide to the Gimp-Print Top Quality Printer
+Drivers, Copyright 2001, Andy Stewart.
+ </para>
+ <para>
+ Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation License,
+Version 1.1 or any later version published by the Free Software
+Foundation. A copy of the license is included in <xref linkend="gfdl">.
+ </para>
+
+ </legalnotice>
+
+ <abstract>
+ <para>
+ The Gimp-Print Top Quality Printer Drivers (hereafter
+called Gimp-Print) are a set of printer drivers written to
+take advantage of the full capabilities of a wide range of
+printers. These drivers should work on any POSIX compliant operating
+system (e.g. Linux, Solaris, IRIX, etc). This document will explain how to
+use the Gimp-Print software to achieve high quality printouts from the
+<ulink url="http://www.gimp.org">GIMP</ulink> (GNU Image
+Manipulation Program) and
+<ulink url="http://www.cups.org">CUPS</ulink> (Common Unix Printing
+System).
+ </para>
+ <para>
+ Please note that in addition to using the Gimp-Print software as a
+print plugin for the GIMP, and as a set of printer drivers for CUPS, this
+software can also be compiled and used with the
+<ulink url="http://www.ghostscript.com">Ghostscript</ulink> software
+and with the
+<ulink
+url="http://www.linuxprinting.org/foomatic.html">Foomatic</ulink>
+software.
+ </para>
+ <para>
+Regardless of whether the Gimp-Print software is used with the GIMP,
+CUPS, Ghostscript, or Foomatic, the print quality and printer settings
+remain the same. However, use of the Gimp-Print with Ghostscript and
+Foomatic is not covered in this document. These topics may be covered
+in a future revision of this document.
+ </para>
+ <para>
+ This document corresponds to version 4.2.0 of the Gimp-Print
+software. This document will serve as a guide to the user, and as such
+will not explain how to install Gimp-Print, CUPS, GIMP, Ghostscript,
+Foomatic, or any other related software.
+ </para>
+
+ <para>
+ Andy Stewart, the author, is the founder of the
+<ulink url="http://www.wlug.org">Worcester Linux Users' Group</ulink> in
+Worcester, Massachusetts, USA. The group was founded in July 1997 and has
+approximately 140 people on its mailing list. Monthly meetings are
+held and all are invited.
+ </para>
+
+ <para>
+ In terms of "code", this is the author's first contribution to the
+open source community, and definitely his first experience with DocBook.
+Constructive comments, praise, words of encouragement, and the like
+will be most appreciated if e-mailed to the
+<ulink url="mailto:andystewart@mediaone.net">author</ulink>.
+ </para>
+ </abstract>
+ </bookinfo>
+
+ <chapter><title>Project History</title>
+ <para>
+This software package was first written by Michael Sweet of
+<ulink url="http://www.easysw.com">Easy Software Products</ulink> and
+initially worked only as a print plugin to the GIMP (GNU Image
+Manipulation Program). In the summer of 1999,
+Robert Krawitz (the current
+Gimp-Print project leader) purchased an Epson Stylus Photo EX printer
+to feed his photography hobby. Finding no existing printer drivers, Robert
+adapted Mike's Gimp-Print plugin to his six-color printer, and by the end
+of the year released version 3.0 of the Gimp-Print software, which was
+included in version 1.1 of the GIMP. The intention was for this to be
+the stable plugin in version 1.2 of the GIMP while development of the
+Gimp-Print plugin continued for later release.
+ </para>
+ <para>
+Robert put the Gimp-Print development tree on SourceForge starting
+with version 3.1, and quickly found a group of like-minded people who wanted to print
+high quality output on inexpensive inkjet printers. One of the main
+goals, which was not expected to be met until late in the version 3.1
+cycle, was to write a Ghostscript driver so that printing would not be
+restricted to the GIMP. Imagine Robert's surprise when Henryk "Buggs"
+Richter wrote one within days!
+ </para>
+ <para>
+In July 2000, not more than a year after Robert bought his Epson
+Stylus Photo EX, he was invited to the Linux Printing
+Summit hosted by VA Linux Systems. In preparation for that, he spent
+long hours printing out test images. Robert went back to the
+Gimp-Print version 3.0.9 release, which seemed like such an advance
+at the time, and was floored at how far the project had come in four
+months! Output that had been considered impressive with using six
+colors was put to shame by four color output. That should give you
+an idea what six color and variable dot size printers can do. It also
+illustrates what a group of committed people can do.
+ </para>
+ <para>
+Robert came away from the Printing Summit with a lot of new ideas, and in
+November 2000, Gimp-Print version 4.0 was released, the culmination of 9 months
+of work by the team. The quality was already tremendously improved
+over what the software could do at the Printing Summit.
+ </para>
+ <para>
+The team started serious work on version 4.1 in December
+2000, and version 4.2.0 was released in November 2001. Despite the fact
+that version 4.2.0 is a "minor" release over version 4.0, there are vast
+improvements:
+ <itemizedlist>
+ <listitem>
+ <para>
+ The driver is built as a shared library, making it much easier
+to use by higher layers of software
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The packaging system now follows GNU standards
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The print quality (in particular, color accuracy, a well-known weakness in 4.0) is even better
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Improved performance
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Many more options
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ More supported printers
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <para>
+Releases of Gimp-Print have been historically numbered in
+a fashion similar to that of the Linux kernel, where major releases
+are denoted by the first digit (in this case '4'), while minor
+releases are denoted by subsequent digits (such as '4.2.0'). Even
+numbered minor releases are considered stable, while odd numbered
+minor releases are considered development releases (whose stability
+may vary for any given release).
+ </para>
+ <para>
+This project is by no means finished. In future releases, the development
+team hopes to include the following:
+ <itemizedlist>
+ <listitem><para>implementation of proper color management</para></listitem>
+ <listitem><para>improved dithering</para></listitem>
+ <listitem><para>improvements in performance</para></listitem>
+ </itemizedlist>
+ </para>
+ <para>
+The entire Gimp-Print team hopes you will really enjoy using this
+software! For more information, please consult the GIMP-Print project
+<ulink url="http://gimp-print.sourceforge.net">web page</ulink>.
+ </para>
+ </chapter>
+
+ <chapter id="ch-gimp-and-gimp-print"><title>GIMP and Gimp-Print</title>
+
+ <sect1>
+ <title>Running the GIMP</title>
+ <para>
+ This section assumes that you have the GIMP version 1.2 installed
+and working properly on your computer, and that you have an image of
+some type that you desire to print. To get started quickly, log into
+your system, start the X window system, and bring up your favorite terminal
+window. At the $ prompt, type:
+
+ <programlisting>
+ <![ CDATA [
+ $ gimp &
+ ]]>
+ </programlisting>
+
+ This should start the GIMP for you. If it does not, check that
+you have installed the GIMP properly, and that its binary is located
+in one of the directories listed in your &dollar;PATH environment
+variable. On the assumption that this worked, the screen should now
+look something like this:
+
+ <figure><title>The Startup Window for The GIMP</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="figures/gimp_startup.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>Startup window for The GIMP</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ </para>
+ <para>
+ At this point, you should use the
+
+ <menuchoice>
+ <guimenu>File</guimenu>
+ <guimenuitem>Open</guimenuitem>
+ </menuchoice>
+
+menu option to open your favorite picture. We will print this picture
+shortly. Your picture should be displayed next to the GIMP startup
+window, perhaps looking similar to the following (sssh! Don't tell
+anybody the secret!):
+
+ <figure><title>A Sample Image Displayed by The GIMP</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="50" fileref="figures/gimp_image.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>A Sample Image displayed by The Gimp</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ </para>
+
+ </sect1>
+
+ <sect1><title>The Gimp-Print Graphical User Interface</title>
+ <para>
+ Now that the GIMP is displaying your picture, put your mouse over
+the picture and click the right mouse button. A menu will appear.
+Choose the
+ <menuchoice>
+ <guimenu>File</guimenu>
+ <guimenuitem>Print</guimenuitem>
+ </menuchoice>
+menu option. This will cause the Gimp-Print GUI window to appear (see
+<xref linkend="fig-gimp-print-gui">). Move the mouse cursor
+over the various parts of the Gimp-Print GUI window, and notice that
+if you leave your mouse in one place for a short time without clicking
+any buttons, a small box appears. This box contains helpful text.
+These small boxes are called "tooltips" and are intended to remind you
+about the function of each part of the graphical interface.
+ </para>
+ <para>
+The next several sections will continuously refer to
+<xref linkend="fig-gimp-print-gui"> and
+<xref linkend="fig-gimp-print-gui-1">. The difference between
+the two figures can be seen in the top right corner of the window.
+Notice that there are two tabs, one which reads
+<guilabel>Printer Settings</guilabel> and another which reads
+<guilabel>Image/Output Settings</guilabel>. Notice also that the
+window is divided into several major sections which directly map to
+the major sections of this document:
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="sec-preview">Preview</link></para>
+ </listitem>
+ <listitem>
+ <para><link linkend="sec-printer-settings">Printer Settings</link></para>
+ </listitem>
+ <listitem>
+ <para><link linkend="sec-printer-settings">Image/Output Settings</link></para>
+ </listitem>
+ <listitem>
+ <para><link linkend="sec-position">Position</link></para>
+ </listitem>
+ <listitem>
+ <para><link linkend="sec-scaling">Size</link></para>
+ </listitem>
+ <listitem>
+ <para><link linkend="sec-printing-and-saving-settings">Printing and Saving Settings</link></para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <figure id="fig-gimp-print-gui"><title>The Gimp-Print Graphical User Interface 1 (GUI)</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="40" fileref="figures/gimp-print-gui.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The GIMP Print GUI showing printer settings</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <figure id="fig-gimp-print-gui-1"><title>The Gimp-Print Graphical User Interface 2 (GUI)</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="40" fileref="figures/gimp-print-gui-1.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The GIMP Print GUI showing image/output settings</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <sect2><title id="sec-printer-settings">Printer Settings</title>
+ <indexterm id="idx-printer-settings"><primary>Printer Settings</primary></indexterm>
+
+ <sect3><title>Printer</title>
+ <para>
+ Click on the <guilabel>Printer Settings</guilabel> tab near the
+top right hand corner of the window (see
+<xref linkend="fig-gimp-print-gui">). Then, click on the downward
+facing arrow to the right of the <guilabel>Printer</guilabel> combo
+box to see a list of the system printer queues. Select the queue to which
+you would like the printed image to be sent. One may also print the
+image directly to a file by selecting <guimenuitem>File</guimenuitem>.
+In this event, the user will be prompted for the filename when either the
+<guibutton>Print</guibutton> button or the <guibutton>Print and Save
+Settings</guibutton> button is clicked.
+ </para>
+ <para>
+When either the <guibutton>Print and Save Settings</guibutton> button
+or the <guibutton>Save Settings</guibutton> button is clicked,
+the settings are saved in a file called
+<filename>~/.gimp-1.2/printrc</filename>. The user is cautioned about
+hand editing this file since it is generated by Gimp-Print (although
+it was the only way that the author found for removing bogus entries
+created while playing with the <guibutton>New Printer</guibutton> button).
+ </para>
+ </sect3>
+
+ <sect3><title>Setup Printer</title>
+ <para>
+ Before any useful printing can occur, the user needs to associate
+the named printer with the
+actual make and model of the printer. Click the
+<guibutton>Setup Printer</guibutton> button in
+the <guilabel>Printer</guilabel> section of the window (the upper
+right, and just below the Printer display box). When this is done, the
+following window appears:
+
+ <figure><title>The Setup Printer Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="60" fileref="figures/gimp-print-setup.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The Setup Printer Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+ </para>
+
+ <para>
+ Scroll through the Printer Model section of the window until you
+find a printer which matches yours. If you cannot find the precise
+model, pick something close and hope for the best. There are selections
+for a wide array of Postscript, inkjet, and laser printers. After you
+have selected a printer, you will see the printer command displayed.
+ </para>
+ <para>
+The Gimp-Print software does all of the necessary conversion of the
+image to be printed into the language of your printer. It is
+unnecessary and undesirable for any other sofware to manipulate this
+data. (This is why the command contains the "-l" switch or the "-o
+raw" switch). Please use care if you feel the need to edit this
+command. Once you are satisfied with your selection, click the
+<guibutton>OK</guibutton> button.
+ </para>
+
+ </sect3>
+
+ <sect3><title>New Printer</title>
+
+ <para>
+ In the previous sections, the user selected an existing printer
+queue and associated a particular type of printer to that queue. For
+most cases, this is probably all that is required. However, some
+situations might require more detailed control over the handling of
+the printer data.
+ </para>
+ <para>
+ Click the <guibutton>New Printer</guibutton> button to tell the
+software that you wish to create a new name. In this case, the new
+name may actually be an existing printer with different settings that
+you wish to save, or it may simply be a name associated with a
+particular command for handling the printer data. A window will
+appear thus:
+
+ <figure><title>The New Printer Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="figures/gimp-print-new-printer.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The New Printer Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ Type a name into the window and click <guibutton>OK</guibutton>
+(or <guibutton>Cancel</guibutton> if you wish not to do this).
+Notice that the new name now appears as the selected <guilabel>Printer</guilabel>.
+As you change settings in the rest of the Gimp-Print GUI, they will be
+associated with this printer name. When the settings are saved,
+they can be recovered easily by simply selecting this named printer
+from the Printer combo box.
+ </para>
+ <para>
+ One example where this feature might be used is as follows. The
+author frequently prints photos on Epson 4x6 photo paper. Note that
+this paper is physically larger than 4x6 and it has perforations on
+all four sides. The author dislikes printing part of the image on the
+perforated parts of the paper which will be removed after
+printing the photo. By selecting the proper scaling percentage,
+printing can be constrained to the 4x6 part of the paper which will
+remain after the perforated sections are removed. The author has
+saved this setting using this feature of the Gimp-Print software.
+ </para>
+
+ </sect3>
+
+ <sect3><title>Media Size</title>
+ <para>
+ The term <emphasis>media</emphasis> refers to paper, card stock,
+envelopes, or whatever you have put into your printer onto which
+something will be printed. Click the arrow to the right of the
+<guilabel>Media Size</guilabel> box to see a long list of different
+sizes of media. Choose the size that matches the media which you have
+loaded into your printer. Once you have made your choice, the drop
+down menu will disappear, and your choice will be shown in the
+<guilabel>Media Size</guilabel> box. The available paper sizes will
+vary depending upon the printer model you have selected.
+ </para>
+ <para>
+ Some printers support arbitrary (within limits!) paper sizes.
+ These printers will let you select <emphasis>Custom</emphasis>
+ or <emphasis>Roll</emphasis> paper sizes. When you select such a
+ printer, one or both of the <guilabel>Dimensions</guilabel> boxes
+ will let you enter your paper size (in inches or centimetres). The
+ boxes will not let you enter sizes that your printer cannot handle.
+ </para>
+ </sect3>
+
+ <sect3><title>Media Type</title>
+ <para>
+ The type of media onto which your image will be printed should be
+selected here. Click on the arrow to the right of the <guilabel>Media
+Type</guilabel> box to see a long list of the different types of media
+onto which you may print your image. Media types include such things
+as plain paper, postcards, photo quality paper, transparencies, and
+more! Once you have made your choice, the drop down menu will
+disappear, and your choice will be shown in the <guilabel>Media
+Type</guilabel> box. The choices available will vary depending upon
+the printer model you have selected.
+ </para>
+ </sect3>
+
+ <sect3><title>Media Source</title>
+ <para>
+ The <guilabel>Media Source</guilabel> box allows the user to
+ choose the paper source, sometimes called <emphasis>Input
+ Slot</emphasis>, that the paper will be fed from. Many printers
+ only have one available input source (such as the standard paper
+ tray), in which case this entry will be grayed out. If your printer
+ does support multiple input sources, you may specify the source of
+ your choice here. Some Epson printers offer a roll feed option in
+ addition to the standard paper tray, and many HP LaserJet printers
+ have multiple paper trays.
+ </para>
+ </sect3>
+
+ <sect3><title>Ink Type</title>
+ <para>
+ Some printers offer a choice of different types of ink or ink
+ cartridges. Many Canon and Lexmark printers support various
+ combinations of cartridges, such as black only, black and color,
+ photo color, and so forth. Most Epson printers let you choose
+ between three and four color printing (three color uses only color
+ ink, while four color uses black ink as well). Epson printers that
+ support six color photo printing allow you to choose five and six
+ color printing as well.
+ </para>
+ </sect3>
+
+ <sect3><title>Resolution</title>
+ <para>
+ Click on the arrow to the right of the
+<guilabel>Resolution</guilabel> box to see a long list of resolutions
+at which you can print your image. The list is written with the
+lowest resolution at the top, with increasing resolution (and
+generally improved printing quality) as you approach the bottom of the
+list. Different printers support different resolution options, and
+many printers support different quality choices using the same basic
+resolution. In this menu are a few terms which may be unfamiliar to
+you, and they will now be explained.
+ </para>
+ <sect4><title>DPI</title>
+ <para>
+ DPI is an acronym which stands for <emphasis>D</emphasis>ots
+<emphasis>P</emphasis>er <emphasis>I</emphasis>nch. This term refers
+to the number of dots that your printer will print in a space of one
+inch (approximately 2.54 cm). This is highly dependent upon the
+capability of your printer. Resolutions below 300 DPI are
+used for draft quality. For general purpose printing, select
+300 - 360 DPI. Higher quality printing can be achieved by
+selecting 600 - 720 DPI. Settings higher than this are used for the
+highest possible quality for printing photographs and other high
+quality graphics. Experiment with your printer and these settings
+with different types of graphics and photographs to see what
+results you can obtain with your printer. High resolutions (large
+numbers of dots per inch) require substantial image processing time,
+and the print files can be very large; it's not uncommon for a full
+page, 1440x720 DPI image to require 100 MB of temporary storage!
+ </para>
+ </sect4>
+ <sect4><title>Draft or Fast Economy Draft</title>
+ <para>
+ When this text appears next to the resolution, it refers to the
+fact that the quality will be relatively low, but suitable for rough
+drafts. Draft quality is higher than fast economy draft. These
+options will give you the fastest printing speed. Economy Draft uses
+less ink, and as a result the image will be pale. These modes are
+generally not very useful for printing photographs.
+ </para>
+ </sect4>
+
+ <sect4><title>Unidirectional</title>
+ <para>
+ When printing an image, you have probably noticed the print
+head inside the printer moving back and forth across the print media.
+Many printers are capable of putting ink on the page regardless of
+which direction the print head is moving. However, quality can
+sometimes be improved by only putting ink on the page when the printer
+head is moving in one direction. The
+<guimenuitem>Unidirectional</guimenuitem> setting instructs the
+software to only place ink on the page when the print head is moving
+one way. When the print head returns, it will not place ink on the
+page. On many printers, the print quality is better, at the expense
+of printing speed.
+ </para>
+ </sect4>
+ <sect4><title>High(est) Quality</title>
+ <para>
+ With lower quality print modes, one may see an effect where
+the printed image looks like it has rows of stripes with a small
+separation between the stripes. This effect is called "banding" and
+is undesirable. In the <emphasis>high</emphasis> and
+<emphasis>highest</emphasis> quality modes, the printer will make more
+passes over the same part of the page in order to improve quality and
+(reduce or) eliminate banding. This requires more temporary disk
+space and prints more slowly, but does not require significantly more
+processing time.
+ </para>
+ </sect4>
+ <sect4><title>Microweave</title>
+ <para>
+ Certain Epson printers (older models mostly) support a printing
+ mode called <emphasis>Microweave</emphasis>. This mode uses
+ special software within the printer to improve the print quality.
+ Microweave print modes will usually produce better quality
+ output than non-Microweave modes, with only a small performance
+ penalty. If Microweave is not listed at your chosen
+ resolution, fear not. In those cases, the non-Microweave print
+ modes offer similar printing quality improvements.
+ </para>
+ </sect4>
+ <sect4><title>DMT</title>
+ <para>
+ DMT is an acronym which stands for <emphasis>D</emphasis>ot
+ <emphasis>M</emphasis>odulation
+ <emphasis>T</emphasis>echnology.
+ This term refers to a print mode used by certain Canon printers
+ to improve the quality of the printed output. Unfortunately,
+ at this time, all of the available DMT modes do not work
+ correctly. The cases which do work correctly will offer
+ significantly improved printing quality.
+ </para>
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2><title id="sec-preview">Preview</title>
+ <para>
+ Notice in the upper left of the window is a preview of your image.
+This preview is a representation of where your picture will print on
+the selected media, and approximately what it will look like. This
+preview will be updated as you modify selections in the
+<guilabel>Position</guilabel>, <guilabel>Size</guilabel>,
+<guilabel>Media Size</guilabel>, and <guilabel>Output Type</guilabel>
+portions of the window. You may also select the image with your mouse
+and move it manually if you wish. In doing so, you will note that the
+<guilabel>Position</guilabel> settings are updated accordingly. Take
+note of the arrow, which points toward the top of the media, where top
+is the first part of the media to enter the printer.
+ </para>
+ <para>
+ The preview may be moved around the page as follows:
+ </para>
+ <itemizedlist>
+ <listitem><para> Clicking and dragging the <emphasis>left</emphasis>
+ (primary) mouse button moves the image around the page as you would
+ expect; the image moves with the mouse. </para></listitem>
+ <listitem><para> Clicking and dragging the
+ <emphasis>middle</emphasis> mouse button moves the image around the
+ page in a finer fashion, such that each pixel of mouse movement
+ moves the image by one point (1/72 inch). This allows very fine
+ placement of the image on the page. </para></listitem>
+ <listitem><para> Clicking and dragging the
+ <emphasis>right</emphasis> (secondary) mouse button moves the image
+ around the page much the same as with the left button, but the image
+ will only move in units of the image size. Thus, if the image is
+ one inch wide and two inches tall, the image will not move at all
+ until you have moved the mouse far enough so that the image would be
+ moved one inch vertically and two inches horizontally. This is
+ handy if you wish to print multiple images of the same size on one
+ piece of paper.</para></listitem>
+ <listitem><para> If you hold down the <emphasis>shift</emphasis> key
+ on the keyboard when you click and drag the mouse, the image will
+ only move in the horizontal or vertical direction (depending upon
+ which way you first move the mouse). This allows you to constrain
+ motion to the horizontal or vertical. </para></listitem>
+ <listitem><para> If you click another button while dragging the
+ mouse, the image will immediately return to the position it was in
+ before you clicked the mouse the first time. This allows you to
+ not move the image if you have started moving it and have decided
+ that you don't want to move it. The preview will not respond to the
+ mouse until you release all of the mouse buttons and click and drag
+ afresh. </para></listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2><title id="sec-position">Position</title>
+
+ <sect3><title>Orientation</title>
+ <para>
+ The Orientation menu allows the user to choose the orientation
+of the paper. The menu selections are
+<guimenuitem>Auto</guimenuitem>, <guimenuitem>Portrait</guimenuitem>,
+<guimenuitem>Landscape</guimenuitem>, <guimenuitem>Upside
+down</guimenuitem>, and <guimenuitem>Seascape</guimenuitem>. Click on
+the rectangular tab to see these choices
+and make your selection. When you have done so, the pulldown menu
+will have disappeared, and your choice will appear. Also, note that
+the preview image will have changed accordingly.
+ </para>
+ <para>
+ When set to <guimenuitem>Auto</guimenuitem>, the software will make an
+intelligent choice of orientation based on the dimensions of the image
+to be printed. <guimenuitem>Portrait</guimenuitem> orients the print media
+with the longest edge going from top to bottom, while
+<guimenuitem>Landscape</guimenuitem> orients the paper with the longest edge
+going from side to side. <guimenuitem>Upside down</guimenuitem> and
+<guimenuitem>Seascape</guimenuitem> orient the paper the same as
+<guimenuitem>Portrait</guimenuitem> and <guimenuitem>Landscape</guimenuitem>
+respectively, with the difference being that the image is rotated 180 degrees.
+ </para>
+ </sect3>
+
+ <sect3><title>Automatic Centering</title>
+ <para>
+ There are three buttons that deal with centering an image. The
+leftmost button is the <guibutton>Vertically</guibutton> button, the
+middle button is the <guibutton>Both</guibutton> button, and
+the rightmost button is the <guibutton>Horizontally</guibutton>
+button. Use the <guibutton>Both</guibutton> button to center your
+image both horizontally and vertically. This will cause the top and
+bottom borders to be equal, and the left and right borders to be
+equal. If you have placed your image manually by using the mouse
+button, then you may center the image in the horizontal direction only
+by clicking on the <guibutton>Horizontally</guibutton> button.
+Likewise, to adjust the image only in the vertical direction, click on
+the <guibutton>Vertically</guibutton> button. Note that in
+each case, the image is centered with regard to the edges of the
+media, and without regard to the printable portion of the media. Many
+printers are incapable of printing to each edge of the media. Some
+media may have edges which detach. Consult your printer documentation
+for more details regarding your printer's capabilities in this regard.
+ </para>
+ </sect3>
+
+ <sect3><title>Manual Settings</title>
+ <para>
+ You will notice that there are six boxes that contain numbers
+just below the Orientation menu and just above the GUI buttons related
+to centering an image. When you move the preview image manually with
+the mouse, or when you click on one of the centering buttons, the
+preview image moves and these six boxes get updated.
+ </para>
+ <sect4><title>Left</title>
+ <para>
+ The number appearing in the <guimenuitem>Left</guimenuitem> box denotes
+the number of units (cm or inches) that the left side of the image
+will be printed away from the left edge of the media. You may select
+the units by clicking the <guibutton>Inch</guibutton> or
+<guibutton>cm</guibutton> buttons in the <guilabel>Units</guilabel> section just below
+these GUI boxes.
+ </para>
+ </sect4>
+ <sect4><title>Right</title>
+ <para>
+ The number appearing in the <guimenuitem>Right</guimenuitem> box denotes
+the number of units (cm or inches) that the right side of the image
+will be printed away from the left edge of the media. You may select
+the units by clicking the <guibutton>Inch</guibutton> or
+<guibutton>cm</guibutton> buttons in the <guilabel>Units</guilabel> section just below
+these GUI boxes.
+ </para>
+ </sect4>
+ <sect4><title>Right Border</title>
+ <para>
+ The number appearing in the <guimenuitem>Right Border</guimenuitem> box denotes
+the number of units (cm or inches) that the right side of the image
+will be printed away from the right edge of the media. You may select
+the units by clicking the <guibutton>Inch</guibutton> or
+<guibutton>cm</guibutton> buttons in the <guilabel>Units</guilabel> section just below
+these GUI boxes.
+ </para>
+ </sect4>
+ <sect4><title>Top</title>
+ <para>
+ The number appearing in the <guimenuitem>Top</guimenuitem> box denotes
+the number of units (cm or inches) that the top side of the image
+will be printed away from the top edge of the media. You may select
+the units by clicking the <guibutton>Inch</guibutton> or
+<guibutton>cm</guibutton> buttons in the <guilabel>Units</guilabel> section just below
+these GUI boxes.
+ </para>
+ </sect4>
+ <sect4><title>Bottom</title>
+ <para>
+ The number appearing in the <guimenuitem>Bottom</guimenuitem> box denotes
+the number of units (cm or inches) that the bottom side of the image
+will be printed away from the top edge of the media. You may select
+the units by clicking the <guibutton>Inch</guibutton> or
+<guibutton>cm</guibutton> buttons in the <guilabel>Units</guilabel> section just below
+these GUI boxes.
+ </para>
+ </sect4>
+
+ <sect4><title>Bottom Border</title>
+ <para>
+ The number appearing in the <guimenuitem>Bottom Border</guimenuitem> box denotes
+the number of units (cm or inches) that the bottom side of the image
+will be printed away from the bottom edge of the media. You may select
+the units by clicking the <guibutton>Inch</guibutton> or
+<guibutton>cm</guibutton> buttons in the <guilabel>Units</guilabel> section just below
+these GUI boxes.
+ </para>
+ </sect4>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2><title id="sec-scaling">Size</title>
+
+ <sect3><title>Slider Bar and Spin Box</title>
+ <para>
+ The slider bar can be moved as desired by the user. Notice
+that while sliding this bar, the preview image changes accordingly.
+One will also note that several boxes in the Gimp-Print GUI change values when this bar is moved.
+These boxes are the six position boxes (left, right, right border,
+top, bottom, bottom border), the two size boxes (width and height),
+and the spin box to the right of the slider bar.
+ </para>
+ <para>
+ This slider bar is used to scale the image to a desirable size, but the same effect can
+be obtained by either clicking an arrow on the spin box to the right of this
+slider bar, or by manually typing a number into this spin box. Notice
+that by setting the spin box in this way, the slider bar is also
+moved. All of the described methods will cause the image to be
+scaled accordingly.
+ </para>
+ </sect3>
+
+ <sect3><title>Scale by Percent or PPI</title>
+ <para>
+ One may choose to scale the image by a percentage, or by PPI,
+which means "<emphasis>p</emphasis>ixels <emphasis>p</emphasis>er
+<emphasis>i</emphasis>nch". Click the radio button
+next to the word to set the desired scaling factor.
+ </para>
+ <para>
+ When scaling by a percentage, the number reflected in the spin
+box next to the slider bar represents the percentage relative
+to the full size of the selected print medium. For example, with this spin box
+set to 50, the image will be scaled to 50% of the size of the print
+medium. When set to 100, the image will attempt to fill the print
+medium, within the constraints of maintaining the proper aspect ratio
+and the margins of the selected print medium. This effect can be seen
+in the preview window.
+ </para>
+ <para>
+ When scaling by PPI, the number reflected in the spin box next to
+the slider bar represents the number of pixels that will be
+printed per inch. For example, if the user is printing a 640x480
+image at a size of 6.4x4.8 inches (as measured by the size boxes), the
+image will be printed at 100 DPI.
+ </para>
+ </sect3>
+
+ <sect3><title>Use Original Image Size</title>
+ <para>
+ By clicking this button, the image will be scaled to as close
+to the native size of the image as possible. This effect can
+immediately be seen in the preview image.
+ </para>
+ <para>
+ The native image size may be found or set in the GIMP by
+ selecting <guimenuitem>Image/Scale Image</guimenuitem> in the
+ GIMP. Under the <guilabel>Print Size and Display Unit</guilabel>
+ group in the <guilabel>Scale Image</guilabel> dialog, you can
+ determine (or change) the width and height of the image, or
+ choose the resolution.
+ </para>
+ </sect3>
+
+ <sect3><title>Width and Height</title>
+ <para>
+ These boxes show the size of the printed image in either inches
+or centimeters (depending on which unit is selected). The user may
+choose to manually modify these values. When one value is modified,
+the other value is automatically modified in order to maintain the
+aspect ratio (the ratio of width to height). This effect can be
+immediately seen in the preview image.
+ </para>
+ </sect3>
+
+ <sect3><title>Units</title>
+ <para>
+ The units can be set to inches or centimeters by clicking the appropriate
+radio button next to the desired unit. This setting effects the
+values printed in the six position boxes (left, right, right border,
+top, bottom, bottom border) and the two size boxes (width and height).
+ </para>
+ </sect3>
+
+ </sect2>
+
+ <sect2><title id="sec-image-settings">Image/Output Settings</title>
+ <para>
+ By clicking on the tab labeled <guilabel>Image/Output
+Settings</guilabel>, the Gimp-Print window will appear as shown in
+<xref linkend="fig-gimp-print-gui-1">. Notice that there are
+two sections to this portion of the window, namely,
+<guilabel>Image Type</guilabel> and
+<guilabel>Output Type</guilabel>.
+
+ </para>
+
+ <sect3><title>Image Type</title>
+
+ <sect4><title>Line Art</title>
+ <para>
+ This setting tells the printer driver to generate color
+quickly. The color is bold and bright, but color accuracy is not very
+good. There may also be some unexpectedly sharp transitions in
+colors. This mode is acceptable for printing text with small amounts
+of color, and may be acceptable for presentation graphics.
+ </para>
+ </sect4>
+
+ <sect4><title>Solid Colors</title>
+ <para>
+ This mode produces color which is considerably more accurate
+than the <guilabel>Line Art</guilabel> mode, but with a reduction in performance. In
+general, hues will be accurate but tonalities may not be accurate.
+There should be no sharp transitions in colors. This mode is good for
+printing presentation graphics in most cases.
+ </para>
+ </sect4>
+
+ <sect4><title>Photograph</title>
+ <para>
+ This mode produces the most accurate colors and tonalities at a
+greater cost in performance. This is the mode to use when printing
+high quality photographs or other high quality images.
+ </para>
+ </sect4>
+
+ </sect3>
+
+ <sect3><title>Output Type</title>
+ <para>
+ The user is given the choice of color, black and white, and
+grayscale. Color is selected when the desired output is to be in
+color. Greyscale will result in the printed image having various
+shades of grey. Black and white is just that. The effect of this
+setting can be seen in the preview window.
+ </para>
+ </sect3>
+
+ <sect3><title>Adjust Output</title>
+ <para>
+ Clicking on this button causes the <guilabel>Print Color Adjust</guilabel> window to
+appear (see <xref linkend="fig-gimp-print-color-adjust">). In
+this window, one will see a representation of the image to be printed
+as well as several slider bars. These slider bars collectively adjust
+many different aspects of the image. The values can also be adjusted
+by clicking the arrows or by typing a value into the appropriate spin
+box on the right side of each slider bar.
+ </para>
+
+ <figure id="fig-gimp-print-color-adjust"><title>The Print Color Adjust Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="50" fileref="figures/gimp-print-print-color-adjust.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>>The Print Color Adjust Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <sect4><title>Brightness</title>
+ <para>
+ Adjust the brightness of the image. A setting of 0.0 gives a fully black
+image, while a 2.0 setting gives a fully white image. Values greater than 1.0 will result in
+ black not being solid and highlights turning white; values less than
+ 1.0 will result in white not being perfectly clear and shadows turning
+ black.
+ </para>
+ </sect4>
+
+ <sect4><title>Contrast</title>
+ <para>
+ Adjust the contrast of the image. A setting of 0.0 gives a solid gray for the
+entire image, the exact gray depending upon the brightness chosen.
+ </para>
+ </sect4>
+
+ <sect4><title>Cyan, Magenta, Yellow</title>
+ <para>
+These three options allow specification of the cyan, magenta, and
+yellow levels independently, for rebalancing the levels. Normally,
+these should be adjusted to yield neutral gray, but they can be used
+for other effects.
+ </para>
+ </sect4>
+
+ <sect4><title>Saturation</title>
+ <para>
+Adjust the brilliance of colors. A setting of 0.0 results in pure grayscale.
+A saturation setting of less than 1.0 results in more muted colors. A
+saturation setting of greater than 1.0 results in more vibrant colors. Very high
+saturation often results in very strange effects, including
+posterization and banding that might not be expected. For normal
+purposes, the saturation should generally be set to a value less than 1.5.
+ </para>
+ </sect4>
+
+ <sect4><title>Density</title>
+ <para>
+Adjust the amount of ink deposited on the paper. If you have chosen the
+correct paper type and are getting ink bleeding through the paper
+or puddling, try reducing the density to the lowest value you
+can while still achieving solid black. If black is not solid
+black, even with the contrast and brightness at 1.0, try increasing
+the density. Note that changes to this setting will not be visible in
+the image preview.
+ </para>
+ <para>
+All of the supported printers actually need less than 100% ink
+density in most cases, so the actual density is something other than
+the nominal density setting. The effective density setting cannot go
+above 100%, so if a value specified will result in an excessively high
+density level, it will be silently limited to a setting of 1.0.
+ </para>
+ </sect4>
+
+ <sect4><title>Gamma</title>
+ <para>
+Adjust the gamma of the image, over and above the printer-specific
+correction. Gamma less than 1.0 will result in a darker image; gamma
+greater than 1.0 will result in a lighter image. Unlike brightness,
+gamma adjustment does not change the endpoints; it merely changes the
+shape of the input->output curve.
+ </para>
+ </sect4>
+
+ <sect4><title>Dither Algorithm</title>
+ <para>
+The recommended dither algorithm is <guimenuitem>Adaptive
+Hybrid</guimenuitem> (which is the default) for text or other fine
+black detail, or if this is mixed with continuous tone images. The
+<guimenuitem>Ordered</guimenuitem> dithering algorithm is just as good
+(and somewhat faster) for pure continuous-tone images and photographs,
+but may yield poor results with text or other fine detail,
+particularly at high printing resolutions.
+ </para>
+ <para> The <guimenuitem>Fast</guimenuitem> algorithm gives the
+fastest results at the expense of color accuracy. It is a simplified
+ordered dither. On simple four color printers (or other printers used
+in four color mode), the quality is similar to
+<guimenuitem>Ordered</guimenuitem>, although dark gray rendition is
+not as good due to a simpler transfer between black and colored ink.
+With six-color printers, color rendition is somewhat worse, but it
+should be quite usable in cases where optimum quality is not critical.
+In black and white, it is an efficient way to render grayscale, but it
+may not give best results when used with variable dot size printers
+(modern Epson printers, or Canon printers using DMT). On rare three
+color printers (CMY only) the results should be identical to ordered
+dither.
+ </para>
+ <para> <guimenuitem>Very Fast</guimenuitem> is even faster than
+<guimenuitem>Fast</guimenuitem>, with even more loss of quality.
+Color and grayscale output will show strong patterning that resembles
+screening, although it isn't. On laser printers, and possibly on
+certain kinds of text and line art, <guimenuitem>Very
+Fast</guimenuitem> dithering may actually yield the best quality.
+ </para>
+ <para>
+Error diffusion algorithms (<guimenuitem>Hybrid
+Floyd-Steinberg</guimenuitem> is such an algorithm) perform very well
+at high densities, and are capable of
+rendering very fine detail rather well, but they tend to exhibit artifacts in
+the form of "waves" or "worms" of dots which results in noticeable
+texturing in pale areas. Furthermore, pale areas immediately adjacent
+to white take a while to "build up" sufficient error to print at all.
+This is sometimes called "tearing" or "waterfalling".
+ </para>
+
+ </sect4>
+
+ <sect4><title>Set Defaults and Close</title>
+ <para>
+ When the <guibutton>Set Defaults</guibutton> button is clicked,
+the slider bar settings will return to their default values. The
+dither algorithm setting is uneffected. The <guilabel>Print Color
+Adjust</guilabel> window will close when the
+<guibutton>Close</guibutton> button is clicked.
+ </para>
+ </sect4>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2><title id="sec-printing-and-saving-settings">Printing and Saving Settings</title>
+ <para>
+ At the bottom of the Gimp-Print window, there are five buttons labeled
+<guibutton>About</guibutton>,
+<guibutton>Print and Save Settings</guibutton>,
+<guibutton>Save Settings</guibutton>,
+<guibutton>Print</guibutton>,
+and <guibutton>Cancel</guibutton>. The <guibutton>About</guibutton>
+button will show information about the Gimp-Print software, such as
+the version number, authors names, project web site, and software
+licensing. After clicking on the <guibutton>About</guibutton>, read
+the information, and then close the window by pressing the
+<guibutton>OK</guibutton> button.
+ </para>
+ <para>
+ The <guibutton>Print and Save Settings</guibutton> button will
+save the current settings and then print the desired image. Recall
+that these settings are saved in <filename>~/.gimp-1.2/printrc</filename>. The
+<guibutton>Save Settings</guibutton> button will only save the
+settings. The <guibutton>Print</guibutton> button will print the
+image only. The <guibutton>Cancel</guibutton> will close the
+Gimp-Print GUI window.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ </chapter>
+
+ <chapter><title>CUPS and Gimp-Print</title>
+ <sect1><title>Introduction</title>
+ <para>
+ CUPS is an acronym which stands for <emphasis>C</emphasis>ommon
+<emphasis>U</emphasis>nix <emphasis>P</emphasis>rinting
+<emphasis>S</emphasis>ystem. It is assumed that the reader has
+properly installed the CUPS software and the Gimp-Print software.
+This section will discuss adding a printer to CUPS that uses a
+Gimp-Print printer driver, as well as how to modify the various
+settings supplied by Gimp-Print. This will be a rather quick
+explanation, as the CUPS software is quite well documented, and it is
+not my intention to attempt to duplicate the CUPS documentation here.
+ </para>
+ </sect1>
+
+ <sect1><title>CUPS Printer Installation</title>
+ <para>
+This explanation will use the web interface provided by CUPS. First,
+aim your favorite web browser at
+<ulink url="http://localhost:631">the CUPS server</ulink>. The
+following screen should appear within your browser.
+ </para>
+
+ <figure><title>The CUPS Startup Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="45" fileref="figures/cups_startup.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The CUPS Startup Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+Now, you may click on either the word <guilabel>Printers</guilabel> in the bar at the top
+of the page, or you may click on the <guilabel>Manage Printers</guilabel> text. In
+either case, the next screen you see will look like this one if you
+have not yet configured any printers.
+ </para>
+
+ <figure><title>The CUPS Printers Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="45" fileref="figures/cups_printers.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The CUPS Printers Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+At this time, click on the <guibutton>Add Printer</guibutton> button.
+You will then see the Admin screen (shown below).
+ </para>
+
+ <figure><title>The CUPS Admin Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="45" fileref="figures/cups_admin.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The CUPS Admin Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+Notice in the screenshot that the three boxes are shown after the
+author filled them in for his printer at home. You will need to fill
+in an appropriate name of your printer, its location, and a
+description which meets your own needs. Once this is done, click on
+the <guibutton>Continue</guibutton> button, and then this screen will appear.
+ </para>
+
+ <figure id="fig-cups-admin-device"><title>The CUPS Admin Device Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="35" fileref="figures/cups_admin_device.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The CUPS Admin Device Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+Click on the drop down menu next to the word
+<guilabel>Device</guilabel> and a list of possible printer devices
+appears. Select the device appropriate for your printer. Note that
+there are a range of serial, parallel, USB, and other devices from
+which to choose. Once the selection is made, click the
+<guibutton>Continue</guibutton> button. Now, this screen appears.
+ </para>
+
+ <figure><title>The CUPS Admin Model/Driver Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="35" fileref="figures/cups_admin_make.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The CUPS Admin Model/Driver Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <caution>
+ <title>Caution Regarding USB Printers</title>
+
+ <para>
+CUPS versions 1.1.11 and later <emphasis>REQUIRE</emphasis>
+the user to insure that the desired USB printer is powered on
+<emphasis>AND</emphasis> physically connected to the USB bus
+<emphasis>BEFORE</emphasis> starting the CUPS software.
+ </para>
+ <para>
+CUPS must see the USB printer when the software starts. The CUPS software
+is typically started when the computer boots. Note that one cannot
+simply plug in the USB printer and power it on after CUPS has started.
+(Note that this does not apply to parallel port printers).
+ </para>
+ <para>
+If the USB printer was not connected and powered on at the time CUPS was
+started, there will not be a USB printer shown in the
+list of devices on the CUPS Admin Device Window (see
+<xref linkend="fig-cups-admin-device">). In this event, stop the CUPS
+software, properly connect and power on the USB printer, and restart
+the CUPS software.
+ </para>
+ <para>
+From the list of devices shown in the CUPS Admin Device Window
+(see <xref linkend="fig-cups-admin-device">), a clever user might
+attempt to avoid this issue by selecting
+<guimenuitem>Internet Printing Protocol</guimenuitem>
+and then enter something similar to 'usb:/dev/usblp0' in the next
+screen. However, this fails later in the configuration process with a
+"client_error_not_possible" error message with no other explanation.
+Note that entering 'file:/dev/usblp0' will not work either. While CUPS
+will allow this, printing will not actually work in some situations.
+ </para>
+ <para>
+CUPS versions 1.1.10 and earlier exhibit similar behavior with regard
+to not displaying the USB printer if it was not connected to the USB
+bus and powered up prior to starting the CUPS software. However,
+these versions of CUPS will indeed allow the user to enter the name of
+the USB connection, unlike versions 1.1.11 and later.
+ </para>
+ </caution>
+
+ <para>
+Select the manufacturer of your printer and click the
+<guibutton>Continue</guibutton> button. A window will appear which
+asks you to select the specific model number for your printer.
+ </para>
+
+ <para>
+Scroll through the long list and find the model number for your
+printer. Notice carefully that there are many different languages
+supported for each printer, as denoted by the initials in parenthesis.
+(en) would be for English, (da) for Danish, (sv) for Swedish, (fr) for
+French, (no) for Norwegian, (pl) for Polish, and (en_GB) for British
+English (see <xref linkend="fig-cups-admin-model">). Also take note
+of the Gimp-Print revision for the driver, and ensure that it is
+indeed the version of Gimp-Print which you have most recently
+installed. Once you have made the proper selection, click on the
+<guibutton>Continue</guibutton> button.
+ </para>
+
+ <figure id="fig-cups-admin-model"><title>The 2nd CUPS Admin Model/Driver Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="55" fileref="figures/cups_admin_model.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The 2nd CUPS Admin Model/Driver Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <figure><title>The CUPS Admin Success Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="39" fileref="figures/cups_admin_success.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The CUPS Admin Success Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+Congratulations! You should now see the CUPS window indicating that
+your printer was successfully installed. Notice the sentence which
+reads "Printer your_printer has been added successfully". Click on
+your_printer, which will be the underlined name for your printer.
+ </para>
+
+ <figure id="fig-cups-my-printer"><title>The CUPS Window for Your Printer</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="65" fileref="figures/cups_my_printer.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The CUPS Window for Your Printer</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+After clicking on your_printer (epson_870 in this example), a window
+will appear similar to that shown in <xref linkend="fig-cups-my-printer">.
+It would probably be a good idea at this point to click on the
+<guibutton>Print Test Page</guibutton> button to ensure that
+everything is working properly. Take note of the Gimp-Print revision
+printed on this screen and confirm once again that it is the expected
+revision.
+ </para>
+
+ </sect1>
+
+ <sect1><title>Configuring your Printer in CUPS</title>
+
+ <para>
+With reference to <xref linkend="fig-cups-my-printer">, click
+on the <guibutton>Configure Printer</guibutton> button. A partial
+screenshot of the printer configuration window appears in
+<xref linkend="fig-cups-printer-config-window">.
+The contents of this window will vary depending on precisely which
+printer you selected when you configured CUPS for your printer. The
+screenshot shows the selections made by the author for his printer.
+The individual selections will not be explained in detail here, as
+they are the same selections which are available when using the
+Gimp-Print plugin to the GIMP. These selections are explained in
+detail in various sections of <xref linkend="ch-gimp-and-gimp-print">.
+ </para>
+
+ <figure id="fig-cups-printer-config-window"><title>The CUPS Printer Cofiguration Window</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata scale="30" fileref="figures/cups_config_printer.png" FORMAT="PNG">
+ </imageobject>
+ <textobject>
+ <phrase>The CUPS Printer Configuration Window</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+
+ </sect1>
+
+ <sect1><title>Using CUPS from the Command Line</title>
+
+ <para>
+ It is possible to use the CUPS printing system from the command
+line. While this document will not delve into all of the specifics of
+the CUPS command line interface, there are portions of this interface
+which are specific to the Gimp-Print software.
+ </para>
+
+ <para>
+The command line is in some cases a more convenient way to generate
+printed output (e.g. when printing from a script). However, most
+people (including the author) cannot easily predict what a command
+line option of "-o stpCyan=1350" will do to the output. It is
+therefore a good idea to use the GIMP to view the image and the
+Gimp-Print plugin to preview these settings before relying on the
+command line.
+ </para>
+
+ <para>
+When using CUPS from the command line, the command will have this
+general format:
+
+ <programlisting>
+ <![ CDATA [
+ lpr -P my_printer_name \
+ -o option1=<choice1> \
+ -o option2=<choice2> \
+ /path/to/printfile
+ ]]>
+ </programlisting>
+
+When typing the command directly onto the command line, put all of the
+command line options on one line, and do not type the "\" characters.
+The list of possible options which are specific to Gimp-Print,
+followed by some of the supported choices, are shown below:
+
+ <programlisting>
+ <![ CDATA [
+ -o PageSize=<...| A3 | A4 | A4 | ...>
+ -o InputSlot=<Roll | Standard>
+ -o MediaType=< ..| Inkjet | Plain | GlossyPaper | ...>
+ -o Resolution=<360sw | 360swuni ...| 1440x720 >
+ -o ColorModel=<Black | RGB | Gray | CMYK>
+ -o stpBrightness=<0...2000>
+ -o stpContrast=<0...2000>
+ -o stpCyan=<0...4000>
+ -o stpDensity=<0...2000>
+ -o stpDither=<0...4000>
+ -o stpGamma=<0...4000>
+ -o stpImageType=<LineArt | Continuous | SolidTone>
+ -o stpInkType=<PhotoCMY | CMYK | PhotoCMYK | RGB>
+ -o stpMagenta=<0...4000>
+ -o stpSaturation=<0...9000>
+ -o stpYellow=<0...4000>
+ ]]>
+ </programlisting>
+
+For more detailed information, consult the appropriate sections of <xref linkend="ch-gimp-and-gimp-print">.
+ </para>
+
+ </sect1>
+
+ </chapter>
+
+<appendix id="gfdl">
+<title>GNU Free Documentation License</title>
+<!-- - GNU Project - Free Software Foundation (FSF) -->
+<!-- LINK REV="made" HREF="mailto:webmasters@gnu.org" -->
+
+
+ <!-- sect1>
+ <title>GNU Free Documentation License</title -->
+
+ <para>Version 1.1, March 2000</para>
+
+ <blockquote>
+ <para>Copyright (C) 2000 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.</para>
+ </blockquote>
+
+ <sect1 label="0">
+ <title>PREAMBLE</title>
+
+ <para>The purpose of this License is to make a manual, textbook,
+ or other written document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by
+ others.</para>
+
+ <para>This License is a kind of "copyleft", which means that
+ derivative works of the document must themselves be free in the
+ same sense. It complements the GNU General Public License, which
+ is a copyleft license designed for free software.</para>
+
+ <para>We have designed this License in order to use it for manuals
+ for free software, because free software needs free documentation:
+ a free program should come with manuals providing the same
+ freedoms that the software does. But this License is not limited
+ to software manuals; it can be used for any textual work,
+ regardless of subject matter or whether it is published as a
+ printed book. We recommend this License principally for works
+ whose purpose is instruction or reference.</para>
+ </sect1>
+
+ <sect1 label="1">
+ <title>APPLICABILITY AND DEFINITIONS</title>
+
+ <para>This License applies to any manual or other work that
+ contains a notice placed by the copyright holder saying it can be
+ distributed under the terms of this License. The "Document",
+ below, refers to any such manual or work. Any member of the
+ public is a licensee, and is addressed as "you".</para>
+
+ <para>A "Modified Version" of the Document means any work
+ containing the Document or a portion of it, either copied
+ verbatim, or with modifications and/or translated into another
+ language.</para>
+
+ <para>A "Secondary Section" is a named appendix or a front-matter
+ section of the Document that deals exclusively with the
+ relationship of the publishers or authors of the Document to the
+ Document's overall subject (or to related matters) and contains
+ nothing that could fall directly within that overall subject.
+ (For example, if the Document is in part a textbook of
+ mathematics, a Secondary Section may not explain any mathematics.)
+ The relationship could be a matter of historical connection with
+ the subject or with related matters, or of legal, commercial,
+ philosophical, ethical or political position regarding
+ them.</para>
+
+ <para>The "Invariant Sections" are certain Secondary Sections
+ whose titles are designated, as being those of Invariant Sections,
+ in the notice that says that the Document is released under this
+ License.</para>
+
+ <para>The "Cover Texts" are certain short passages of text that
+ are listed, as Front-Cover Texts or Back-Cover Texts, in the
+ notice that says that the Document is released under this
+ License.</para>
+
+ <para>A "Transparent" copy of the Document means a
+ machine-readable copy, represented in a format whose specification
+ is available to the general public, whose contents can be viewed
+ and edited directly and straightforwardly with generic text
+ editors or (for images composed of pixels) generic paint programs
+ or (for drawings) some widely available drawing editor, and that
+ is suitable for input to text formatters or for automatic
+ translation to a variety of formats suitable for input to text
+ formatters. A copy made in an otherwise Transparent file format
+ whose markup has been designed to thwart or discourage subsequent
+ modification by readers is not Transparent. A copy that is not
+ "Transparent" is called "Opaque".</para>
+
+ <para>Examples of suitable formats for Transparent copies include
+ plain ASCII without markup, Texinfo input format, LaTeX input
+ format, SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML designed for human modification.
+ Opaque formats include PostScript, PDF, proprietary formats that
+ can be read and edited only by proprietary word processors, SGML
+ or XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML produced by some word
+ processors for output purposes only.</para>
+
+ <para>The "Title Page" means, for a printed book, the title page
+ itself, plus such following pages as are needed to hold, legibly,
+ the material this License requires to appear in the title page.
+ For works in formats which do not have any title page as such,
+ "Title Page" means the text near the most prominent appearance of
+ the work's title, preceding the beginning of the body of the
+ text.</para>
+ </sect1>
+
+ <sect1 label="2">
+ <title>VERBATIM COPYING</title>
+
+ <para>You may copy and distribute the Document in any medium,
+ either commercially or noncommercially, provided that this
+ License, the copyright notices, and the license notice saying this
+ License applies to the Document are reproduced in all copies, and
+ that you add no other conditions whatsoever to those of this
+ License. You may not use technical measures to obstruct or
+ control the reading or further copying of the copies you make or
+ distribute. However, you may accept compensation in exchange for
+ copies. If you distribute a large enough number of copies you
+ must also follow the conditions in section 3.</para>
+
+ <para>You may also lend copies, under the same conditions stated
+ above, and you may publicly display copies.</para>
+ </sect1>
+
+ <sect1 label="3">
+ <title>COPYING IN QUANTITY</title>
+
+ <para>If you publish printed copies of the Document numbering more
+ than 100, and the Document's license notice requires Cover Texts,
+ you must enclose the copies in covers that carry, clearly and
+ legibly, all these Cover Texts: Front-Cover Texts on the front
+ cover, and Back-Cover Texts on the back cover. Both covers must
+ also clearly and legibly identify you as the publisher of these
+ copies. The front cover must present the full title with all
+ words of the title equally prominent and visible. You may add
+ other material on the covers in addition. Copying with changes
+ limited to the covers, as long as they preserve the title of the
+ Document and satisfy these conditions, can be treated as verbatim
+ copying in other respects.</para>
+
+ <para>If the required texts for either cover are too voluminous to
+ fit legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.</para>
+
+ <para>If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a publicly-accessible
+ computer-network location containing a complete Transparent copy
+ of the Document, free of added material, which the general
+ network-using public has access to download anonymously at no
+ charge using public-standard network protocols. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.</para>
+
+ <para>It is requested, but not required, that you contact the
+ authors of the Document well before redistributing any large
+ number of copies, to give them a chance to provide you with an
+ updated version of the Document.</para>
+ </sect1>
+
+ <sect1 label="4">
+ <title>MODIFICATIONS</title>
+
+ <para>You may copy and distribute a Modified Version of the
+ Document under the conditions of sections 2 and 3 above, provided
+ that you release the Modified Version under precisely this
+ License, with the Modified Version filling the role of the
+ Document, thus licensing distribution and modification of the
+ Modified Version to whoever possesses a copy of it. In addition,
+ you must do these things in the Modified Version:</para>
+
+ <orderedlist numeration="upperalpha">
+ <listitem><para>Use in the Title Page
+ (and on the covers, if any) a title distinct from that of the
+ Document, and from those of previous versions (which should, if
+ there were any, be listed in the History section of the
+ Document). You may use the same title as a previous version if
+ the original publisher of that version gives permission.</para>
+ </listitem>
+
+ <listitem><para>List on the Title Page,
+ as authors, one or more persons or entities responsible for
+ authorship of the modifications in the Modified Version,
+ together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has less than
+ five).</para>
+ </listitem>
+
+ <listitem><para>State on the Title page
+ the name of the publisher of the Modified Version, as the
+ publisher.</para>
+ </listitem>
+
+ <listitem><para>Preserve all the
+ copyright notices of the Document.</para>
+ </listitem>
+
+ <listitem><para>Add an appropriate
+ copyright notice for your modifications adjacent to the other
+ copyright notices.</para>
+ </listitem>
+
+ <listitem><para>Include, immediately
+ after the copyright notices, a license notice giving the public
+ permission to use the Modified Version under the terms of this
+ License, in the form shown in the Addendum below.</para>
+ </listitem>
+
+ <listitem><para>Preserve in that license
+ notice the full lists of Invariant Sections and required Cover
+ Texts given in the Document's license notice.</para>
+ </listitem>
+
+ <listitem><para>Include an unaltered
+ copy of this License.</para>
+ </listitem>
+
+ <listitem><para>Preserve the section
+ entitled "History", and its title, and add to it an item stating
+ at least the title, year, new authors, and publisher of the
+ Modified Version as given on the Title Page. If there is no
+ section entitled "History" in the Document, create one stating
+ the title, year, authors, and publisher of the Document as given
+ on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.</para>
+ </listitem>
+
+ <listitem><para>Preserve the network
+ location, if any, given in the Document for public access to a
+ Transparent copy of the Document, and likewise the network
+ locations given in the Document for previous versions it was
+ based on. These may be placed in the "History" section. You
+ may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.</para>
+ </listitem>
+
+ <listitem><para>In any section entitled
+ "Acknowledgements" or "Dedications", preserve the section's
+ title, and preserve in the section all the substance and tone of
+ each of the contributor acknowledgements and/or dedications
+ given therein.</para>
+ </listitem>
+
+ <listitem><para>Preserve all the
+ Invariant Sections of the Document, unaltered in their text and
+ in their titles. Section numbers or the equivalent are not
+ considered part of the section titles.</para>
+ </listitem>
+
+ <listitem><para>Delete any section
+ entitled "Endorsements". Such a section may not be included in
+ the Modified Version.</para>
+ </listitem>
+
+ <listitem><para>Do not retitle any
+ existing section as "Endorsements" or to conflict in title with
+ any Invariant Section.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If the Modified Version includes new front-matter sections
+ or appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.</para>
+
+ <para>You may add a section entitled "Endorsements", provided it
+ contains nothing but endorsements of your Modified Version by
+ various parties--for example, statements of peer review or that
+ the text has been approved by an organization as the authoritative
+ definition of a standard.</para>
+
+ <para>You may add a passage of up to five words as a Front-Cover
+ Text, and a passage of up to 25 words as a Back-Cover Text, to the
+ end of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.</para>
+
+ <para>The author(s) and publisher(s) of the Document do not by
+ this License give permission to use their names for publicity for
+ or to assert or imply endorsement of any Modified Version.</para>
+ </sect1>
+
+ <sect1 label="5">
+ <title>COMBINING DOCUMENTS</title>
+
+ <para>You may combine the Document with other documents released
+ under this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice.</para>
+
+ <para>The combined work need only contain one copy of this
+ License, and multiple identical Invariant Sections may be replaced
+ with a single copy. If there are multiple Invariant Sections with
+ the same name but different contents, make the title of each such
+ section unique by adding at the end of it, in parentheses, the
+ name of the original author or publisher of that section if known,
+ or else a unique number. Make the same adjustment to the section
+ titles in the list of Invariant Sections in the license notice of
+ the combined work.</para>
+
+ <para>In the combination, you must combine any sections entitled
+ "History" in the various original documents, forming one section
+ entitled "History"; likewise combine any sections entitled
+ "Acknowledgements", and any sections entitled "Dedications". You
+ must delete all sections entitled "Endorsements."</para>
+ </sect1>
+
+ <sect1 label="6">
+ <title>COLLECTIONS OF DOCUMENTS</title>
+
+ <para>You may make a collection consisting of the Document and
+ other documents released under this License, and replace the
+ individual copies of this License in the various documents with a
+ single copy that is included in the collection, provided that you
+ follow the rules of this License for verbatim copying of each of
+ the documents in all other respects.</para>
+
+ <para>You may extract a single document from such a collection,
+ and distribute it individually under this License, provided you
+ insert a copy of this License into the extracted document, and
+ follow this License in all other respects regarding verbatim
+ copying of that document.</para>
+ </sect1>
+
+ <sect1 label="7">
+ <title>AGGREGATION WITH INDEPENDENT WORKS</title>
+
+ <para>A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, does not as a whole count as a
+ Modified Version of the Document, provided no compilation
+ copyright is claimed for the compilation. Such a compilation is
+ called an "aggregate", and this License does not apply to the
+ other self-contained works thus compiled with the Document, on
+ account of their being thus compiled, if they are not themselves
+ derivative works of the Document.</para>
+
+ <para>If the Cover Text requirement of section 3 is applicable to
+ these copies of the Document, then if the Document is less than
+ one quarter of the entire aggregate, the Document's Cover Texts
+ may be placed on covers that surround only the Document within the
+ aggregate. Otherwise they must appear on covers around the whole
+ aggregate.</para>
+ </sect1>
+
+ <sect1 label="8">
+ <title>TRANSLATION</title>
+
+ <para>Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires
+ special permission from their copyright holders, but you may
+ include translations of some or all Invariant Sections in addition
+ to the original versions of these Invariant Sections. You may
+ include a translation of this License provided that you also
+ include the original English version of this License. In case of
+ a disagreement between the translation and the original English
+ version of this License, the original English version will
+ prevail.</para>
+ </sect1>
+
+ <sect1 label="9">
+ <title>TERMINATION</title>
+
+ <para>You may not copy, modify, sublicense, or distribute the
+ Document except as expressly provided for under this License. Any
+ other attempt to copy, modify, sublicense or distribute the
+ Document is void, and will automatically terminate your rights
+ under this License. However, parties who have received copies, or
+ rights, from you under this License will not have their licenses
+ terminated so long as such parties remain in full
+ compliance.</para>
+ </sect1>
+
+ <sect1 label="10">
+ <title>FUTURE REVISIONS OF THIS LICENSE</title>
+
+ <para>The Free Software Foundation may publish new, revised
+ versions of the GNU Free Documentation License from time to time.
+ Such new versions will be similar in spirit to the present
+ version, but may differ in detail to address new problems or
+ concerns. See <ulink
+ url="http://www.gnu.org/copyleft/">http://www.gnu.org/copyleft/</ulink>.</para>
+
+ <para>Each version of the License is given a distinguishing
+ version number. If the Document specifies that a particular
+ numbered version of this License "or any later version" applies to
+ it, you have the option of following the terms and conditions
+ either of that specified version or of any later version that has
+ been published (not as a draft) by the Free Software Foundation.
+ If the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation.</para>
+ </sect1>
+
+ <sect1 label="">
+ <title>How to use this License for your documents</title>
+
+ <para>To use this License in a document you have written, include
+ a copy of the License in the document and put the following
+ copyright and license notices just after the title page:</para>
+
+<blockquote><para>
+ Copyright (c) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+</para></blockquote>
+
+ <para>If you have no Invariant Sections, write "with no Invariant
+ Sections" instead of saying which ones are invariant. If you have
+ no Front-Cover Texts, write "no Front-Cover Texts" instead of
+ "Front-Cover Texts being LIST"; likewise for Back-Cover
+ Texts.</para>
+
+ <para>If your document contains nontrivial examples of program
+ code, we recommend releasing these examples in parallel under your
+ choice of free software license, such as the GNU General Public
+ License, to permit their use in free software.</para>
+ </sect1>
+
+</appendix>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-parent-document: ("referenz.sgml" "appendix")
+sgml-exposed-tags:nil
+sgml-local-ecat-files:nil
+sgml-local-catalogs: CATALOG
+sgml-validate-command: "nsgmls -s referenz.sgml"
+ispell-skip-sgml: t
+End:
+-->
+
+</book>
diff --git a/doc/using.texi b/doc/using.texi
new file mode 100644
index 0000000..70b7147
--- /dev/null
+++ b/doc/using.texi
@@ -0,0 +1,46 @@
+@node Using libgimpprint, Integrating libgimpprint, Overview, Top
+@chapter Using libgimpprint
+@cindex using
+
+This chapter describes how to write programs that use libgimpprint.
+
+
+@section Code prerequisites
+To use libgimpprint with a program, several steps must be taken:
+
+@enumerate
+@item Include the master libgimpprint header @code{<gimp-print/gimp-print.h>.}
+@item Call @code{stp_init()}.
+@item Link with libgimpprint.
+@end enumerate
+
+The following is a short example program. It does not do anything useful,
+but it does everything required to link with libgimpprint and call other
+functions from libgimpprint.
+
+@example
+#include <gimp-print/gimp-print.h>
+
+int
+main (int argc, char *argv[])
+@{
+ stp_init ();
+ return (0);
+@}
+@end example
+
+@section Linking with libgimpprint
+
+To link a program with libgimpprint, then @samp{-lgimpprint} needs to be passed
+to the compiler when linking. For example, to compile and link @file{prog.c}
+the following commands would be used:
+
+@example
+gcc -c prog.c
+gcc -o prog -lgimpprint prog.o
+@end example
+
+The compiler and linker flags needed may vary depending on the options
+GIMP-Print was configured with when it was built. The
+@command{gimpprint-config} script will give the correct parameters for
+the local installation (@pxref{gimpprint-config}).
diff --git a/doc/weave.texi b/doc/weave.texi
new file mode 100644
index 0000000..19e9854
--- /dev/null
+++ b/doc/weave.texi
@@ -0,0 +1,1290 @@
+@node Weaving, ESC/P2, Dithering, Appendices
+@appendix Weaving for inkjet printers
+@cindex weaving
+
+@noindent
+by Charles Briscoe-Smith and Robert Krawitz.
+
+@menu
+* Weaving introduction:: Just what is weaving?
+* Weaving algorithms:: How to weave.
+@end menu
+
+
+@node Weaving introduction, Weaving algorithms, , Weaving
+@appendixsection Introduction
+
+The Epson Stylus Color/Photo printers don't have memory to print using
+all of the nozzles in the print head. For example, the Stylus Photo
+700/EX has 32 nozzles. At 720 dpi, with an 8" wide image, a single line
+requires @math{(8 * 720 * 6 / 8)} bytes, or 4320 bytes (because the
+Stylus Photo printers have 6 ink colors). To use 32 nozzles per color
+would require 138240 bytes. It's actually worse than that, though,
+because the nozzles are spaced 8 rows apart. Therefore, in order to
+store enough data to permit sending the page as a simple raster, the
+printer would require enough memory to store 256 rows, or 1105920 bytes.
+Considering that the Photo EX can print 11" wide, we're looking at more
+like 1.5 MB. In fact, these printers are capable of 1440 dpi horizontal
+resolution. This would require 3 MB. The printers actually have
+64K-256K.
+
+With the newer (740/750 and later) printers it's even worse, since these
+printers support multiple dot sizes; of course, the even newer
+2880x720 printers don't help either.
+
+Older Epson printers had a mode called @dfn{MicroWeave} (tm). In this
+mode, the host fed the printer individual rows of dots, and the printer
+bundled them up and sent them to the print head in the correct order to
+achieve high quality. This MicroWeave mode still works in new printers,
+but in some cases the implementation is very minimal: the printer uses
+exactly one nozzle of each color (the first one). This makes printing
+extremely slow (more than 30 minutes for one 8.5x11" page), although the
+quality is extremely high with no visible banding whatsoever. It's not
+good for the print head, though, since no ink is flowing through the
+other nozzles. This leads to drying of ink and possible permanent
+damage to the print head.
+
+By the way, although the Epson manual says that microweave mode should be
+used at 720 dpi, 360 dpi continues to work in much the same way. At 360
+dpi, data is fed to the printer one row at a time on all Epson printers.
+The pattern that the printer uses to print is very prone to banding.
+However, 360 dpi is inherently a low quality mode; if you're using it,
+presumably you don't much care about quality. It is possible to do
+microweave at 360 DPI, with significantly improved quality.
+
+Except for the Stylus Pro printers (5000, 5500, 7000, 7500, 9000,
+9500, and when it's released the 10000), which can do microweave at
+any resolution, printers from roughly the Stylus Color 600 and later
+do not have the capability to do MicroWeave correctly in many cases
+(some printers can do MicroWeave correctly at 720 DPI). Instead, the
+host must arrange the output in the order that it will be sent to the
+print head. This is a very complex process; the jets in the print
+head are spaced more than one row (1/720") apart, so we can't simply
+send consecutive rows of dots to the printer. Instead, we have to
+pass e. g. the first, ninth, 17th, 25th... rows in order for them to
+print in the correct position on the paper. This interleaving process
+is called "soft" weaving.
+
+This decision was probably made to save money on memory in the
+printer. It certainly makes the driver code far more complicated than
+it would be if the printer could arrange the output. Is that a bad
+thing? Usually this takes far less CPU time than the dithering
+process, and it does allow us more control over the printing process,
+e.g. to reduce banding. Conceivably, we could even use this ability
+to map out bad jets.
+
+Interestingly, apparently the Windows (and presumably Macintosh) drivers
+for most or all Epson printers still list a ``microweave'' mode.
+Experiments have demonstrated that this does not in fact use the
+``microweave'' mode of the printer. Possibly it does nothing, or it
+uses a different weave pattern from what the non-``microweave'' mode
+does. This is unnecessarily confusing, at least for people who write
+drivers who try to explain them to people who don't.
+
+What makes this interesting is that there are many different ways of of
+accomplishing this goal. The naive way would be to divide the image up
+into groups of 256 rows (for a printer with 32 jets and a separation of
+8 rows), and print all the mod8=0 rows in the first pass, mod8=1 rows in
+the second, and so forth. The problem with this approach is that the
+individual ink jets are not perfectly uniform; some emit slightly bigger
+or smaller drops than others. Since each group of 8 adjacent rows is
+printed with the same nozzle, that means that there will be distinct
+streaks of lighter and darker bands within the image (8 rows is 1/90",
+which is visible; 1/720" is not). Possibly worse is that these patterns
+will repeat every 256 rows. This creates banding patterns that are
+about 1/3" wide.
+
+So we have to do something to break up this patterning.
+
+Epson does not publish the weaving algorithms that they use in their
+bundled drivers. Indeed, their developer web site
+(http://www.ercipd.com/isv/edr_docs.htm) does not even describe how to
+do this weaving at all; it says that the only way to achieve 720 dpi is
+to use MicroWeave. It does note (correctly) that 1440 dpi horizontal
+can only be achieved by the driver (i. e. in software). The manual
+actually makes it fairly clear how to do this (it requires two passes
+with horizontal head movement between passes), and it is presumably
+possible to do this with MicroWeave.
+
+The information about how to do this is apparently available under
+non-disclosure agreement (NDA). It's actually easy enough to reverse
+engineer what's inside a print file with a simple Perl script, which is
+supplied with the Gimp-Print distribution as tests/parse-escp2. In any
+event, we weren't particularly interested in the weaving patterns Epson
+used. There are many factors that go into choosing a good weaving
+pattern; we're learning them as we go along. Issues such as drying time
+(giving the ink a few seconds more or less to dry can have highly
+visible effects) affect the quality of the output.
+
+The Uniprint GhostScript driver has been able to do weaving for a long
+time. It uses patterns that must be specified for each choice of
+resolution and printer. We preferred an algorithmic approach that
+computes a weave pattern for any given choice of inputs. This
+obviously requires extensive testing; we developed a test suite
+specifically for this purpose.
+
+
+@node Weaving algorithms, , Weaving introduction, Weaving
+@appendixsection Weaving algorithms
+@cindex weaving algorithms
+
+I considered a few algorithms to perform the weave. The first one I
+devised let me use only @math{(jets-distance_between_jets+1)}
+nozzles, or 25. This is OK in principle, but it's slower than using all
+nozzles. By playing around with it some more, I came up with an
+algorithm that lets me use all of the nozzles, except near the top and
+bottom of the page.
+
+This still produces some banding, though. Even better quality can be
+achieved by using multiple nozzles on the same line. How do we do
+this? In 1440x720 mode, we're printing two output lines at the same
+vertical position. However, if we want four passes, we have to
+effectively print each line twice. Actually doing this would increase
+the density, so what we do is print half the dots on each pass. This
+produces near-perfect output, and it's far faster than using (pseudo)
+``MicroWeave''.
+
+Yet another complication is how to get near the top and bottom of the
+page. This algorithm lets us print to within one head width of the
+top of the page, and a bit more than one head width from the bottom.
+That leaves a lot of blank space. Doing the weave properly outside of
+this region is increasingly difficult as we get closer to the edge of
+the paper; in the interior region, any nozzle can print any line, but
+near the top and bottom edges, only some nozzles can print. We
+originally handled this by using the naive way mentioned above near
+the borders, and switching over to the high quality method in the
+interior. Unfortunately, this meant that the quality is quite visibly
+degraded near the top and bottom of the page. We have since devised
+better algorithms that allow printing to the extreme top and bottom of
+the region that can physically be printed, with only minimal loss of
+quality.
+
+Epson does not advertise that the printers can print at the very top
+of the page, although in practice most of them can. The quality is
+degraded to some degree, and we have observed that in some cases not
+all of the dots get printed. Epson may have decided that the
+degradation in quality is sufficient that printing in that region
+should not be allowed. That is a valid decision, although we have
+taken another approach.
+
+@menu
+* Simple weaving algorithms:: Starting to weave.
+* Perfect weaving:: Improving the weave.
+* Weaving collisions:: Bang!
+* What is perfect weaving?:: What makes a ``perfect'' weave?
+* Oversampling:: Increasing resolution, reducing banding
+@end menu
+
+@node Simple weaving algorithms, Perfect weaving, Weaving algorithms, Weaving algorithms
+@appendixsubsec Simple weaving algorithms
+
+The initial problem is to calculate the starting position of each
+pass; the row number of the printer's top jet when printing that pass.
+Since we assume the paper cannot be reverse-fed, the print head must,
+for each pass, start either further down the page than the previous
+pass or at the same position. Each pass's start point is therefore at
+a non-negative offset from the previous pass's start point.
+
+Once we have a formula for the starting row of each pass, we then turn
+that ``inside out'' to get a formula for the pass number containing each
+row.
+
+First, let's define how our printer works. We measure vertical
+position on the paper in ``rows''; the resolution with which the printer
+can position the paper vertically. The print head contains @math{J} ink
+jets, which are spaced @math{S} rows apart.
+
+Consider a very simple case: we want to print a page as quickly as
+possible, and we mostly don't care how sparse the printing is, so long
+as it's fairly even.
+
+It's pretty obvious how to do this. We make one pass with the print
+head, printing @math{J} lines of data, each line @math{S} rows after the
+previous one. We then advance the paper by @math{S*J} rows and print
+the next row. For example, if @math{J=7} and @math{S=4}, this method
+can be illustrated like this:
+
+@example
+pass number
+| row number------->
+| | 111111111122222222223333333333444444444455555555556666666666
+| 0123456789012345678901234567890123456789012345678901234567890123456789
+0 *---*---*---*---*---*---*
+1 *---*---*---*---*---*---*
+2 \-----------------------/ *---*---*---*---*---*-
+ 7 jets \---/
+ 4 rows offset from one jet to the next
+ \---------------------------/
+ 7*4=28 rows offset from one pass to the next
+@end example
+
+In these examples, the vertical axis can be thought of as the time axis,
+with the pass number shown at the left margin, while the row number runs
+horizontally. A @samp{*} shows each row printed by a pass, and a row of
+@samp{-} is used to link together the rows printed by one pass of the
+print head. The first pass is numbered @samp{0} and starts at row 0.
+Each subsequent pass @math{p} starts at row @math{p*S*J}. Each pass
+prints @math{J} lines, each line being @math{S} rows after the previous
+one. (For ease of viewing this file on a standard terminal, I'm
+clipping the examples at column 80.)
+
+This method covers the whole page with lines printed evenly @math{S}
+rows apart. However, we want to fill in all the other rows with
+printing to get a full-density page (we're ignoring oversampling at this
+stage). Where we have previously printed a single pass, we'll now print
+a ``pass block'': we print extra passes to fill in the empty rows. A
+naive implementation might look like this:
+
+@example
+0 *---*---*---*---*---*---*
+1 *---*---*---*---*---*---*
+2 *---*---*---*---*---*---*
+3 *---*---*---*---*---*---*
+4 *---*---*---*---*---*---*
+5 *---*---*---*---*---*---*
+6 *---*---*---*---*---*---*
+7 *---*---*---*---*---*---*
+8 *---*---*---*---*---*-
+9 *---*---*---*---*---*
+10 *---*---*---*---*---
+11 *---*---*---*---*--
+@end example
+
+@noindent
+(Now you can see why this process is called ``weaving''!)
+
+
+@node Perfect weaving, Weaving collisions, Simple weaving algorithms, Weaving algorithms
+@appendixsubsec Perfect weaving
+@cindex perfect weave
+
+This simple weave pattern prints every row, but will give conspicuous
+banding patterns for the reasons discussed above.
+
+Let's start improving this for our simple case. We can reduce banding
+by making sure that any given jet never prints a row too close to
+another row printed by the same jet. This means we want to space the
+rows printed by a given jet evenly down the page. In turn, this
+implies we want to advance the paper by as nearly an equal amount
+after each pass as possible.
+
+Each pass block prints @math{S*J} lines in @math{S} passes. The first
+line printed in each pass block is @math{S*J} rows lower on the page
+than the first line printed in the previous pass block. Therefore, if
+we advance the paper by @math{J} rows between each pass, we can print
+the right number of passes in each block and advance the paper perfectly
+evenly.
+
+Here's what this ``perfect'' weave looks like:
+
+@example
+ start of full weave
+ |
+0 *---*---*---*---*---*---*
+1 *---*---*---*---*---*---*
+2 *---*---*---*---*---*---*
+3 *---*---*---*---*---*---*
+4 *---*---*---*---*---*---*
+5 *---*---*---*---*---*---*
+6 *---*---*---*---*---*---*
+7 *---*---*---*---*---*---*
+8 *---*---*---*---*---*-
+9 *---*---*---*--
+10 *---*---
+11 *
+@end example
+
+You'll notice that, for the first few rows, this weave is too sparse.
+It is not until the row marked ``start of full weave'' that every
+subsequent row is printed. We can calculate this start position as
+follows:
+
+@example
+@math{start = (S-1) * (J-1)}
+@end example
+
+For the moment, we will ignore this problem with the weave. We'll
+consider later how to fill in the missing rows.
+
+Let's look at a few more examples of perfect weaves:
+
+
+@noindent
+@math{S=2}, @math{J=7}, @math{start=(2-1)*(7-1)=6}:
+
+@example
+ starting row of full weave
+ |
+0 *-*-*-*-*-*-*
+1 *-*-*-*-*-*-*
+2 *-*-*-*-*-*-*
+3 *-*-*-*-*-*-*
+4 *-*-*-*-*-*-*
+5 *-*-*-*-*-*-*
+6 *-*-*-*-*-*-*
+7 *-*-*-*-*-*-*
+@end example
+
+@noindent
+@math{S=7}, @math{J=2}, @math{start=6}:
+
+@example
+ start
+ |
+0 *------*
+1 *------*
+2 *------*
+3 *------*
+4 *------*
+5 *------*
+6 *------*
+7 *------*
+8 *------*
+9 *------*
+@end example
+
+@noindent
+@math{S=4}, @math{J=13}, @math{start=36}:
+
+@example
+ start
+ |
+0 *---*---*---*---*---*---*---*---*---*---*---*---*
+1 *---*---*---*---*---*---*---*---*---*---*---*---*
+2 *---*---*---*---*---*---*---*---*---*---*---*---*
+3 *---*---*---*---*---*---*---*---*---*--
+4 *---*---*---*---*---*---*-
+5 *---*---*---*
+@end example
+
+@noindent
+@math{S=13}, @math{J=4}, @math{start=36}:
+
+@example
+ start
+ |
+0 *------------*------------*------------*
+1 *------------*------------*------------*
+2 *------------*------------*------------*
+3 *------------*------------*------------*
+4 *------------*------------*------------*
+5 *------------*------------*------------*
+6 *------------*------------*------------*
+7 *------------*------------*------------*
+8 *------------*------------*------------*
+9 *------------*------------*------------*
+10 *------------*------------*-----------
+11 *------------*------------*-------
+12 *------------*------------*---
+13 *------------*------------
+14 *------------*--------
+15 *------------*----
+16 *------------*
+17 *---------
+18 *-----
+19 *-
+@end example
+
+@noindent
+@math{S=8}, @math{J=5}, @math{start=28}:
+
+@example
+ start
+ |
+0 *-------*-------*-------*-------*
+1 *-------*-------*-------*-------*
+2 *-------*-------*-------*-------*
+3 *-------*-------*-------*-------*
+4 *-------*-------*-------*-------*
+5 *-------*-------*-------*-------*
+6 *-------*-------*-------*-------*
+7 *-------*-------*-------*-------*
+8 *-------*-------*-------*-------*
+9 *-------*-------*-------*-------*
+10 *-------*-------*-------*---
+11 *-------*-------*------
+12 *-------*-------*-
+13 *-------*----
+14 *-------
+15 *--
+@end example
+
+@noindent
+@math{S=9}, @math{J=5}, @math{start=32}:
+
+@example
+ start
+ |
+0 *--------*--------*--------*--------*
+1 *--------*--------*--------*--------*
+2 *--------*--------*--------*--------*
+3 *--------*--------*--------*--------*
+4 *--------*--------*--------*--------*
+5 *--------*--------*--------*--------*
+6 *--------*--------*--------*--------*
+7 *--------*--------*--------*--------*
+8 *--------*--------*--------*--------*
+9 *--------*--------*--------*-----
+10 *--------*--------*--------*
+11 *--------*--------*----
+12 *--------*--------
+13 *--------*---
+14 *-------
+15 *--
+@end example
+
+@noindent
+@math{S=6}, @math{J=7}, @math{start=30}:
+
+@example
+ start
+ |
+0 *-----*-----*-----*-----*-----*-----*
+1 *-----*-----*-----*-----*-----*-----*
+2 *-----*-----*-----*-----*-----*-----*
+3 *-----*-----*-----*-----*-----*-----*
+4 *-----*-----*-----*-----*-----*-----*
+5 *-----*-----*-----*-----*-----*-----*
+6 *-----*-----*-----*-----*-----*-----
+7 *-----*-----*-----*-----*----
+8 *-----*-----*-----*---
+9 *-----*-----*--
+10 *-----*-
+11 *
+@end example
+
+
+@node Weaving collisions, What is perfect weaving?, Perfect weaving, Weaving algorithms
+@appendixsubsec Weaving collisions
+@cindex collisions
+@cindex weaving collisions
+
+This perfect weave is not possible in all cases. Let's look at another
+example:
+
+@noindent
+@math{S=6}, @math{J=4}:
+
+@example
+0 *-----*-----*-----*
+1 *-----*-----*-----*
+2 *-----*-----*-----*
+3 *-----*-----*-----*
+4 ^ *-^---*-----*-----*
+5 | ^ | *-^---*-----*-----*
+ OUCH! ^ | ^
+ | |
+@end example
+
+@noindent
+Here we have a collision. Some lines printed in later passes overprint
+lines printed by earlier passes. We can see why by considering which
+row number is printed by a given jet number @math{j} (numbered from 0)
+of a given pass, @math{p}:
+
+@example
+@math{row(p, j) = p*J + j*S}
+@end example
+
+Because @math{J=4} and @math{S=6} have a common factor of 2, jet 2 of
+pass 0 prints the same row as jet 0 of pass 3:
+
+@example
+@math{row(0, 2) = 0*4 + 2*6 = 12}
+@math{row(3, 0) = 3*4 + 0*6 = 12}
+@end example
+
+In fact, with this particular weave pattern, jets 0 and 1 of pass
+@math{p+3} always overprint jets 2 and 3 of pass @math{p}. We'll
+represent overprinting rows by a @samp{^} in our diagrams, and correct
+rows by @samp{*}:
+
+@noindent
+@math{S=6} @math{J=4}:
+
+@example
+0 *-----*-----*-----*
+1 *-----*-----*-----*
+2 *-----*-----*-----*
+3 ^-----^-----*-----*
+4 ^-----^-----*-----*
+5 ^-----^-----*-----*
+@end example
+
+@node What is perfect weaving?, Oversampling, Weaving collisions, Weaving algorithms
+@appendixsubsec What makes a ``perfect'' weave?
+@cindex perfect weave
+
+So what causes the perfect weave cases to be perfect, and the other
+cases not to be? In all the perfect cases above, @math{S} and @math{J}
+are relatively prime (i.e. their greatest common divisor (GCD) is 1).
+As we mentioned above, @math{S=6} and @math{J=4} have a common factor,
+which causes the overprinting. Where @math{S} and @math{J} have a GCD
+of 1, they have no common factor other than 1 and, as a result, no
+overprinting occurs. If @math{S} and @math{J} are not relatively prime,
+their common factor will cause overprinting.
+
+We can work out the greatest common divisor of a pair of natural numbers
+using Euler's algorithm:
+
+@itemize
+@item Start with the two numbers: (e.g.) 9, 24
+@item Swap them if necessary so that the larger one comes first: 24, 9
+@item Subtract the second number from the first: 15, 9
+@item Repeat until the first number becomes smaller: 6, 9
+
+@item Swap the numbers again, so the larger one comes first: 9, 6
+@item Subtract again: 3, 6
+
+@item Swap: 6, 3
+@item Subtract: 3, 3
+@item And again: 0, 3
+@item When one of the numbers becomes 0, the other number is the GCD of the two numbers you started with.
+@end itemize
+
+These repeated subtractions can be done with C's @samp{%} operator, so we
+can write this in C as follows:
+
+@example
+unsigned int
+gcd(unsigned int x, unsigned int y)
+@{
+ if (y == 0)
+ return x;
+ while (x != 0) @{
+ if (y > x)
+ swap (&x, &y);
+ x %= y;
+ @}
+ return y;
+@}
+@end example
+
+@samp{gcd(S,J)} will feature quite prominently in our weaving algorithm.
+
+If @math{0 <= j < J}, there should only be a single pair @math{(p, j)}
+for any given row number. If @math{S} and @math{J} are not relatively
+prime, this assumption breaks down. (For conciseness, let
+@math{G=@r{GCD}(S,J)}.)
+
+@noindent
+@math{S=8}, @math{J=6}, @math{G=2}:
+
+@example
+0 *-------*-------*-------*-------*-------*
+1 *-------*-------*-------*-------*-------*
+2 *-------*-------*-------*-------*-------*
+3 *-------*-------*-------*-------*-------*
+4 ^-------^-------^-------*-------*-------*
+5 ^-------^-------^-------*-------*-------*
+@end example
+
+In this case, jets 0, 1 and 2 of pass @math{p+4} collide with jets 3, 4
+and 5 of pass @math{p}.
+
+How can we calculate these numbers? Suppose we were to print using
+fewer jets, say @math{J/G} jets. The greatest common divisor of
+@math{J/G} and @math{S} is 1, enabling a perfect weave. But to get a
+perfect weave, we also have to advance the paper by a factor of @math{G}
+less:
+
+@example
+0 *-------*-------* - - -
+1 *-------*-------* - - -
+2 *-------*-------* - - -
+3 *-------*-------* - - -
+4 *-------*-------* - - -
+5 *-------*-------* - - -
+@end example
+
+If we left the paper advance alone, we'd get a sparse weave; only one
+row can be printed every @math{G} rows:
+
+@example
+0 *-------*-------* - - -
+1 *-------*-------* - - -
+2 *-------*-------* - - -
+3 *-------*-------* - - -
+4 *-------*-------* - - -
+5 *-------*-------* - - -
+ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+ These rows need filling in.
+@end example
+
+The rows that would have been printed by the jets we've now omitted
+(shown as @samp{-}) are printed by other jets on later passes.
+
+Let's analyse this. Consider how a pass @math{p} could collide with
+pass 0. Pass @math{p} starts at offset @math{p*J}. Pass 0 prints at
+rows which are multiples of @math{S}. If @math{p*J} is exactly
+divisible by @math{S}, a collision has occurred, unless @math{p*J >=
+J*S} (which will happen when we finish a pass block).
+
+So, we want to find @math{p} and @math{q} such that @math{p*J=q*S} and
+@math{p} is minimised. Then @math{p} is the number of rows before a
+collision, and @math{q} is the number of jets in pass 0 which are not
+involved in the collision. To do this, we find the lowest common
+multiple of @math{J} and @math{S}, which is @math{L=J*S/G}. @math{L/J}
+is the number of rows before a collision, and @math{L/S} is the number
+of jets in the first pass not involved in the collision.
+
+Thus, we see that the first @math{J/G} rows printed by a given pass are
+not overprinted by any later pass. However, the rest of the rows
+printed by pass @math{p} are overprinted by the first
+@math{J-(J/G)} jets of pass @math{p+(S/G)}. We will use @math{C}
+to refer to @math{S/G}, the number of rows after which a collision
+occurs.
+
+Another example:
+
+@noindent
+@math{S=6}, @math{J=9}, @math{G=3}, @math{C=S/G=2}:
+
+@example
+0 *-----*-----*-----*-----*-----*-----*-----*-----*
+1 *-----*-----*-----*-----*-----*-----*-----*-----*
+2 ^-----^-----^-----^-----^-----^-----*-----*-----*
+3 ^-----^-----^-----^-----^-----^-----*-----*-----*
+4 ^-----^-----^-----^-----^-----^-----*-----
+5 ^-----^-----^-----^-----^-----^--
+ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^
+ These rows need filling in.
+@end example
+
+@noindent
+In this case, the first @math{J-(J/G) = 9-9/3 = 6} jets of pass
+@math{p+(6/3)=p+2} collide with the last 6 jets of pass @math{p}. Only
+one row in every @math{G=2} rows is printed by this weave.
+
+@noindent
+@math{S=9}, @math{J=6}, @math{G=3}, @math{C=3}:
+
+@example
+0 *--------*--------*--------*--------*--------*
+1 *--------*--------*--------*--------*--------*
+2 *--------*--------*--------*--------*--------*
+3 ^--------^--------^--------^--------*--------*
+4 ^--------^--------^--------^--------*--------*
+5 ^--------^--------^--------^--------*--------*
+@end example
+
+@noindent
+Here, the first @math{J-(J/G) = 6-6/3 = 4} jets of pass
+@math{p+(9/3)=p+3} collide with the last 4 jets of pass @math{p}.
+
+Note that, in these overprinting cases, only rows divisible by @math{G}
+are ever printed. The other rows, those not divisible by @math{G}, are
+not touched by this weave.
+
+We can modify our weave pattern to avoid overprinting any rows and
+simultaneously fill in the missing rows. Instead of using @math{J}
+alone to determine the start of each pass from the previous pass, we
+adjust the starting position of some passes. As mentioned before, we
+will divide the page into pass blocks, with @math{S} passes in each
+block. This ensures that the first jet of the first pass in a block
+prints the row which the @math{J}th jet of the first pass of the
+previous block would have printed, if the print head had one extra jet.
+
+Looking back at an example of a perfect weave, we can divide it into
+pass blocks:
+
+@noindent
+@math{S=7}, @math{J=2}, @math{G=1}:
+
+@example
+ imaginary extra jet
+ |
+0 *------* * <--start of pass block 0
+1 *------* |
+2 *------* |
+3 *------*|
+4 *-----|*
+5 *---|--*
+6 *-|----*
+ |
+7 *------* <--start of pass block 1
+8 *------*
+9 *------*
+@end example
+
+We can now calculate the start of a given pass by reference to its pass
+block. The first pass of pass block @math{b} always starts at row
+@math{(b*S*J)}. The start row of each of the other passes in the block
+are calculated using offsets from this row.
+
+For the example above, there are 7 passes in each pass block, and their
+offsets are 0, 2, 4, 6, 8, 10 and 12. The next pass block is offset
+@math{S*J=14} rows from the start of the current pass block.
+
+The simplest way to modify the ``perfect'' weave pattern to give a
+correct weave in cases where @math{G!=1} is to simply change any offsets
+which would result in a collision, until the collision disappears.
+Every printed row in the weave, as we have shown it up to now, is
+separated from each of its neighbouring printed rows by @math{G} blank
+rows. We will add an extra offset to each colliding pass in such a way
+that we push the pass onto these otherwise blank rows.
+
+We have seen that, unless @math{G=1}, the plain weave pattern results in
+each pass colliding with the pass @math{S/G} passes before. We will now
+subdivide our pass block into subblocks, each consisting of @math{B=S/G}
+passes. There are therefore @math{G} subblocks in a pass block.
+
+For each subblock, the passes in that subblock have a constant offset
+added to them. The offset is different for each subblock in a block.
+There are many ways we can choose the offsets, but the simplest is to
+make the offset equal to the subblock number (starting from 0).
+
+Thus, the passes in the first subblock in each pass block remain at the
+offsets we've already calculated from @math{J}. The passes in the
+second subblock each have 1 added to their offset, the passes in the
+third subblock have 2 added, and so on. Thus, the offset of pass
+@math{p} (numbered relative to the start of its pass block) is @math{p*J
++ @r{floor}(p/B)}.
+
+This gives us a weave pattern looking like this:
+
+@noindent
+@math{S=6}, @math{J=9}, @math{G=3}, @math{B=2}:
+
+@example
+0 *-----*-----*-----*-----*-----*-----*-----*-----*
+1 ^ *-----*-----*-----*-----*-----*-----*-----*-----*
+2 | +-> *-----*-----*-----*-----*-----*-----*-----*-----*
+3 | | *-----*-----*-----*-----*-----*-----*-----*-----*
+4 | | +-> *-----*-----*-----*-----*-----*-----*---
+5 | | | *-----*-----*-----*-----*-----*
+6 | | | +-> *-----*-----*-----*-----
+7 | | | | *-----*-----*--
+ | | | start of pass block 1
+ | | | (offset returns to 0)
+ | | start of subblock 2 (offset 2 rows)
+ | start of subblock 1 (following passes offset by 1 row)
+ start of passblock 0, subblock 0 (pass start calculated as p*J)
+@end example
+
+@noindent
+@math{S=9}, @math{J=6}, @math{G=3}, @math{B=3}:
+
+@example
+0 *--------*--------*--------*--------*--------*
+1 *--------*--------*--------*--------*--------*
+2 *--------*--------*--------*--------*--------*
+3 *--------*--------*--------*--------*--------*
+4 *--------*--------*--------*--------*--------*
+5 *--------*--------*--------*--------*--------*
+6 *--------*--------*--------*--------*---
+7 *--------*--------*--------*------
+8 *--------*--------*--------*
+9 *--------*--------*-----
+10 \---/ *--------*--------
+11 small offset *--------*--
+12 *----
+@end example
+
+This method of choosing offsets for subblocks can result in an occasional
+small offset (as shown above) between one pass and the next, particularly
+when @math{G} is large compared to @math{J}. For example:
+
+@noindent
+@math{S=8}, @math{J=4}, @math{G=4}, @math{B=2}:
+
+@example
+0 *-------*-------*-------*
+1 *-------*-------*-------*
+2 *-------*-------*-------*
+3 *-------*-------*-------*
+4 *-------*-------*-------*
+5 *-------*-------*-------*
+6 *-------*-------*-------*
+7 *-------*-------*-------*
+8 *-------*-------*-------*
+9 \/ *-------*-------*-------*
+ very small offset!
+@end example
+
+We can plot the offset against the subblock number as follows:
+
+@example
+subblock number
+| offset
+| |
+| 0123
+0 *
+1 *
+2 *
+3 *
+0 *
+1 *
+2 *
+3 *
+@end example
+
+@noindent
+The discontinuity in this plot results in the small offset between
+passes.
+
+As we said at the beginning, we want the offsets from each pass to the
+next to be as similar as possible. We can fix this by calculating the
+offset for a given subblock b as follows:
+
+@example
+ offset(b) = 2*b , if b < ceiling(G/2)
+ = 2*(G-b)-1 , otherwise
+@end example
+
+We can visualise this as follows, for @math{G=10}:
+
+@example
+ 0123456789
+0 *
+1 *
+2 *
+3 *
+4 *
+5 *
+6 *
+7 *
+8 *
+9 *
+0 *
+1 *
+2 *
+3 *
+4 *
+5 *
+6 *
+7 *
+8 *
+9 *
+@end example
+
+@noindent
+and for @math{G=11}:
+
+@example
+ 1
+ 01234567890
+ 0 *
+ 1 *
+ 2 *
+ 3 *
+ 4 *
+ 5 *
+ 6 *
+ 7 *
+ 8 *
+ 9 *
+10 *
+ 0 *
+ 1 *
+ 2 *
+ 3 *
+ 4 *
+ 5 *
+ 6 *
+ 7 *
+ 8 *
+ 9 *
+10 *
+@end example
+
+@noindent
+This gives a weave looking like this:
+
+@noindent
+@math{S=12}, @math{J=6}, @math{G=6}, @math{B=2}:
+
+@example
+0 *-----------*-----------*-----------*-----------*-----------*
+1 *-----------*-----------*-----------*-----------*-----------*
+2 *-----------*-----------*-----------*-----------*-----------*
+3 *-----------*-----------*-----------*-----------*---------
+4 *-----------*-----------*-----------*-----------*-
+5 *-----------*-----------*-----------*-------
+6 *-----------*-----------*-----------*
+7 *-----------*-----------*------
+8 *-----------*-----------*--
+9 *-----------*--------
+10 *-----------*----
+11 *----------
+12 *-----
+@end example
+
+This method ensures that the offset between passes is always in the range
+@math{[J-2,J+2]}.
+
+(This might seem odd, but it occurs to me that a good weave pattern
+might also make a good score for bell ringers. When church bells are
+rung, a list of ``changes'' are used. For example, if 8 bells are being
+used, they will, at first, be rung in order: 12345678. If the first
+change is for bells 5 and 6, the bells will then be rung in the order
+12346578. If the second change is 1 and 2, the next notes are 21346578.
+After a long list of changes, the order the bells are rung in can become
+quite complex.
+
+For a group of bell-ringers to change the order of the notes, they must
+each either delay their bell's next ring, hasten it, or keep it the same
+as the time it takes to ring all the bells once. The length of time
+between each ring of a given bell can only be changed a little each
+time, though; with an ink-jet weave pattern, we want the same to apply
+to the distance between passes.)
+
+Finally, knowing the number of jets @math{J} and their separation
+@math{S}, we can calculate the starting row of any given pass @math{p}
+as follows:
+
+@example
+passesperblock = S
+passblock = floor(p / passesperblock)
+offsetinpassblock = p - passblock * passesperblock
+subblocksperblock = gcd(S, J)
+passespersubblock = S / subblocksperblock
+subpassblock = floor(offsetinpassblock / passespersubblock)
+if subpassblock < ceiling(subblocksperblock/2)
+ subblockoffset = 2*subpassblock
+else
+ subblockoffset = 2*(subblocksperblock-subpassblock)-1
+startingrow = passblock * S * J + offsetinpassblock * J + subblockoffset
+@end example
+
+We can simplify this down to the following:
+
+@example
+subblocksperblock = gcd(S, J)
+subpassblock = floor((p % S) * subblocksperblock / S)
+if subpassblock * 2 < subblocksperblock
+ subblockoffset = 2*subpassblock
+else
+ subblockoffset = 2*(subblocksperblock-subpassblock)-1
+startingrow = p * J + subblockoffset
+@end example
+
+So the row number of jet @math{j} of pass @math{p} is
+
+@example
+subblocksperblock = gcd(S, J)
+
+subblockoffset(p)
+ = 2*subpassblock , if subpassblock * 2 < subblocksperblock
+ = 2*(subblocksperblock-subpassblock)-1 , otherwise
+ where
+ subpassblock = floor((p % S) * subblocksperblock / S)
+
+row(j, p) = p * J + subblockoffset(p) + j * S
+@end example
+
+Together with the inequality @math{0 <= j < J}, we can use this
+definition in reverse to calculate the pass number containing a given
+row, @math{r}. Working out the inverse definition involves a little
+guesswork, but one possible result is as follows. Given a row,
+@math{r}, which is known to be the first row of a pass, we can calculate
+the pass number as follows:
+
+@example
+subblocksperblock = gcd(S, J)
+subblockoffset = r % subblocksperblock
+pass = (r - subblockoffset) / J
+@end example
+
+If @math{G==1}, we can determine the pass number with this algorithm:
+
+@example
+offset = r % J
+pass = (r - offset) / J
+while (offset % S != 0)
+@{
+ pass--
+ offset += J
+@}
+jet = offset / S
+@end example
+
+Generalising, we come up with this algorithm. Given @math{r}, @math{S}
+and @math{J}:
+
+@example
+G = gcd(S, J)
+passespersubblock = S/G
+subblockoffset = r % G
+subpassblock = subblockoffset / 2 , if subblockoffset % 2 == 0
+ = G - (subblockoffset+1)/2 , otherwise
+baserow = r - subblockoffset - (subpassblock * passespersubblock * J)
+offset = baserow % J
+pass = (baserow - offset) / J
+while (offset % S != 0)
+@{
+ offset += J
+ pass -= 1
+@}
+subblockretreat = floor(pass / passespersubblock) % G
+pass -= subblockretreat * passespersubblock
+pass += subpassblock * passespersubblock
+jet = (r - subblockoffset - pass * J) / S
+@end example
+
+Let's look at some examples of imperfect but correct weave patterns:
+
+@noindent
+@math{S=6}, @math{J=4}, @math{@r{GCD}=2},
+@*passesperblock=@math{S}=6,
+@*passespersubblock=@math{S/G}=6/2=3:
+
+@example
+0 *-----*-----*-----*
+1 *-----*-----*-----*
+2 *-----*-----*-----*
+3 *-----*-----*-----*
+4 *-----*-----*-----*
+5 *-----*-----*-----*
+6 *-----*-----*-----*
+7 *-----*-----*-----*
+8 *-----*-----*-----*
+9 *-----*-----*-----*
+10 *-----*-----*-----*
+11 *-----*-----*-----*
+12 *-----*-----*-----*
+13 *-----*-----*-----*
+14 *-----*-----*-----*
+15 *-----*-----*----
+16 *-----*-----*
+17 *-----*--
+18 *-----
+19 *-
+@end example
+
+@noindent
+@math{S=8}, @math{J=6}, @math{G=2},
+@*passesperblock=@math{S}=8,
+@*passespersubblock=@math{S/G}=8/2=4:
+
+@example
+0 *-------*-------*-------*-------*-------*
+1 *-------*-------*-------*-------*-------*
+2 *-------*-------*-------*-------*-------*
+3 *-------*-------*-------*-------*-------*
+4 *-------*-------*-------*-------*-------*
+5 *-------*-------*-------*-------*-------*
+6 *-------*-------*-------*-------*-------*
+7 *-------*-------*-------*-------*--
+8 *-------*-------*-------*-----
+9 *-------*-------*-------
+10 *-------*-------*-
+11 *-------*---
+12 *----
+@end example
+
+@noindent
+@math{S=6}, @math{J=12}, @math{G=6},
+@*passesperblock=@math{S}=6,
+@*passespersubblock=@math{S/G}=6/6=1:
+
+@example
+0 *-----*-----*-----*-----*-----*-----*-----*-----*-----*-----*-----*
+1 *-----*-----*-----*-----*-----*-----*-----*-----*-----*-----*---
+2 *-----*-----*-----*-----*-----*-----*-----*-----*-
+3 *-----*-----*-----*-----*-----*-----*
+4 *-----*-----*-----*-----*--
+5 *-----*-----*----
+6 *-----
+@end example
+
+We have now solved the basic weaving problem. There are two further
+refinements we need to consider: oversampling, and filling in the
+missing rows at the start of the weave.
+
+@node Oversampling, , What is perfect weaving?, Weaving algorithms
+@appendixsubsec Oversampling
+@cindex oversampling
+
+By oversampling, we mean printing on the same row more than once.
+There are two reasons for oversampling: to increase the horizontal
+resolution of the printout and to reduce banding.
+
+Oversampling to increase horizontal resolution is necessary because,
+although the printer might be able to position an ink drop to, for
+example, 1/1440" horizontally, it may not be able to lay down two such
+drops 1/1440" apart. If it can print two drops 1/720" apart, 2x
+oversampling will be necessary to get a 1/1440" horizontal resolution.
+If it can only print two drops 1/360" apart, 4x oversampling will be
+necessary for a 1/1440" horizontal resolution. The printer enforces
+this ``drop spacing'' by only accepting raster passes with a horizontal
+resolution matching the spacing with which it can print dots, so we
+must print passes at different horizontal positions if we are to
+obtain a higher horizontal resolution. (Another reason it does this
+may be to reduce the amount of memory needed in the printer.)
+
+Oversampling can also be done to decrease the banding apparent in an
+image. By splitting a row into two or more sets of dots (``lines'') and
+printing each line on the same row, but with a different nozzle for
+each line, we can get a smoother print.
+
+To quantify these two kinds of oversampling, we'll introduce two new
+constants: @math{H} shows how many different horizontal offsets we want
+to print at (the ``horizontal oversampling'') while @math{O} shows how
+many times we want to print each row, over and above the number of times
+necessary for horizontal oversampling (the ``extra oversampling'').
+
+It is necessary for all the lines printed by a given pass to have the
+same horizontal offset, but there need not be any relation between
+them in terms of extra oversampling. For the moment, however, we will
+treat all oversampling as potentially requiring this alignment; all
+lines in one pass must be derived from the original row data in the
+same way. Thus, we'll assume @math{O=1} for now.
+
+So, how do we do this oversampling? In fact, it can be done easily:
+advance the paper by a factor of @math{H} less between each pass. We'll
+define a new variable, @math{A}, to show how much we advance the paper
+between passes. Previously, we'd have defined @math{A=J}; we now let
+@math{A=J/H}. This also affects our pass blocks. Printing one pass
+block used to involve advancing the paper @math{S*J} rows; it now
+advances the paper @math{S*J/H} rows. We therefore name a group of
+@math{H} pass blocks a ``band''. Printing one band involves advancing
+the paper @math{S*J} rows, as a pass block did before.
+
+To keep our weave pattern working correctly, so that overprinting does
+not occur within a pass block, we also have to redefine @math{G} as
+@math{@r{GCD}(S,A)}. Here's an example of an oversampled weave pattern:
+
+@noindent
+@math{S=4}, @math{J=10}, @math{H=2}, @math{A=J/H=10/2=5},
+@math{G=@r{GCD}(4,5)=1},
+@*passesperblock=@math{S}=4,
+@*passespersubblock=@math{S/G}=4/1=4:
+
+@example
+0 *---*---*---*---*---*---*---*---*---*
+1 *---*---*---*---*---*---*---*---*---*
+2 *---*---*---*---*---*---*---*---*---*
+3 *---*---*---*---*---*---*---*---*---*
+4 *---*---*---*---*---*---*---*---*---*
+5 *---*---*---*---*---*---*---*---*---*
+6 *---*---*---*---*---*---*---*---*---*
+7 *---*---*---*---*---*---*---*---*---*
+8 *---*---*---*---*---*---*---*---*---*
+9 *---*---*---*---*---*---*---*---*
+10 *---*---*---*---*---*---*---
+11 *---*---*---*---*---*--
+12 *---*---*---*---*-
+13 *---*---*---*
+14 *---*---
+15 *--
+@end example
+
+Now we have to determine which line is printed by each jet on each
+pass. If we number each line generated as we split up a row, we can
+use these numbers. We'll number the lines in our diagram by replacing
+the @samp{*}s with integers in the range [0@dots{}@math{H-1}].
+
+Overprinting occurs once per pass block, so we can simply print pass
+block 0 with line 0, pass block 1 with line 1, pass block 2 with line
+2, etc, wrapping to 0 when we've run out of lines:
+
+@example
+0 0---0---0---0---0---0---0---0---0---0
+1 0---0---0---0---0---0---0---0---0---0
+2 0---0---0---0---0---0---0---0---0---0
+3 0---0---0---0---0---0---0---0---0---0
+4 1---1---1---1---1---1---1---1---1---1
+5 1---1---1---1---1---1---1---1---1---1
+6 1---1---1---1---1---1---1---1---1---1
+7 1---1---1---1---1---1---1---1---1---1
+8 0---0---0---0---0---0---0---0---0---0
+9 0---0---0---0---0---0---0---0---0
+10 0---0---0---0---0---0---0---
+11 0---0---0---0---0---0--
+12 1---1---1---1---1-
+13 1---1---1---1
+14 1---1---
+15 1--
+@end example
+
+@noindent
+@math{S=4}, @math{J=12}, @math{H=2}, @math{A=J/H=12/2=6}, @math{G=@r{GCD}(4,6)=2},
+@*passesperblock=@math{S}=4,
+@*passespersubblock=@math{S/G}=4/2=2:
+
+@example
+0 0---0---0---0---0---0---0---0---0---0---0---0
+1 0---0---0---0---0---0---0---0---0---0---0---0
+2 0---0---0---0---0---0---0---0---0---0---0---0
+3 0---0---0---0---0---0---0---0---0---0---0---0
+4 1---1---1---1---1---1---1---1---1---1---1---1
+5 1---1---1---1---1---1---1---1---1---1---1---1
+6 1---1---1---1---1---1---1---1---1---1---1
+7 1---1---1---1---1---1---1---1---1--
+8 0---0---0---0---0---0---0---0-
+9 0---0---0---0---0---0---
+10 0---0---0---0---0
+11 0---0---0--
+12 1---1-
+@end example
+
+But what do we do if @math{J} is not an exact multiple of @math{H}?
+This is a difficult problem, which I struggled with for quite a few days
+before giving in and taking the easy (but less elegant) way out. The
+easy solution is to round @math{J/H} down, then add on the accumulated
+error at the end of each band.
+
+@noindent
+@math{S=4}, @math{J=11}, @math{H=2} @math{A=@r{floor}(J/H)=@r{floor}(11/2)=5}, @math{G=@r{GCD}(4,5)},
+@*passesperblock=@math{S}=4,
+@*passespersubblock=@math{S/G}=4/1=4
+
+@example
+Band 0:
+0 0---0---0---0---0---0---0---0---0---0---0
+1 0---0---0---0---0---0---0---0---0---0---0
+2 0---0---0---0---0---0---0---0---0---0---0
+3 0---0---0---0---0---0---0---0---0---0---0
+4 1---1---1---1---1---1---1---1---1---1---1
+5 1---1---1---1---1---1---1---1---1---1---1
+6 1---1---1---1---1---1---1---1---1---1---1
+7 1---1---1---1---1---1---1---1---1---1---
+
+Band 1:
+8 | 0---0---0---0---0---0---0---0---0-
+9 \-----------------------------------------/ 0---0---0---0---0---0---0---0
+10 S*J rows 0---0---0---0---0---0---
+11 0---0---0---0---0--
+12 1---1---1---1-
+13 1---1---1
+14 1---
+@end example
+
+We can calculate the starting row and subpass number of a given pass
+in this scheme as follows:
+
+@example
+A = floor(J / H)
+subblocksperblock = gcd(S, A)
+subpassblock = floor((p % S) * subblocksperblock / S)
+if subpassblock * 2 < subblocksperblock
+ subblockoffset = 2*subpassblock
+else
+ subblockoffset = 2*(subblocksperblock-subpassblock)-1
+band = floor(P / (S * H))
+passinband = P % (S * H)
+startingrow = band * S * J + passinband * A + subblockoffset
+subpass = passinband / S
+@end example
+
+So the row number of jet @math{j} of pass @math{p} is
+
+@example
+A = floor(J / H)
+subblocksperblock = gcd(S, A)
+
+subblockoffset(p)
+ = 2*subpassblock , if subpassblock * 2 < subblocksperblock
+ = 2*(subblocksperblock-subpassblock)-1 , otherwise
+ where
+ subpassblock = floor((p % S) * subblocksperblock / S)
+
+band(p) = floor(p / (S * H))
+passinband(p) = p % (S * H)
+
+row(j, p) = band(p) * S * J + passinband(p) * A + subblockoffset(p) + j * S
+row(j, p) = p * J + subblockoffset(p) + j * S
+@end example
+
+To be continued@enddots{}