diff options
author | Roger Leigh <rleigh@debian.org> | 2008-10-26 16:10:50 +0000 |
---|---|---|
committer | Roger Leigh <rleigh@debian.org> | 2008-10-26 16:10:50 +0000 |
commit | eb5718390731a9746c556317e641320b671f2091 (patch) | |
tree | 762876b4adf298c1281142328e2ae87007330904 /doc |
Imported Upstream version 4.2.0
Diffstat (limited to 'doc')
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 Binary files differnew file mode 100644 index 0000000..db1af3f --- /dev/null +++ b/doc/print-color.png diff --git a/doc/print-main.png b/doc/print-main.png Binary files differnew file mode 100644 index 0000000..2d78222 --- /dev/null +++ b/doc/print-main.png diff --git a/doc/print-setup.png b/doc/print-setup.png Binary files differnew file mode 100644 index 0000000..904e03b --- /dev/null +++ b/doc/print-setup.png 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 Binary files differnew file mode 100644 index 0000000..464fcc4 --- /dev/null +++ b/doc/users_guide/figures/cups_admin.png diff --git a/doc/users_guide/figures/cups_admin_device.png b/doc/users_guide/figures/cups_admin_device.png Binary files differnew file mode 100644 index 0000000..b258263 --- /dev/null +++ b/doc/users_guide/figures/cups_admin_device.png diff --git a/doc/users_guide/figures/cups_admin_make.png b/doc/users_guide/figures/cups_admin_make.png Binary files differnew file mode 100644 index 0000000..1948ba7 --- /dev/null +++ b/doc/users_guide/figures/cups_admin_make.png diff --git a/doc/users_guide/figures/cups_admin_model.png b/doc/users_guide/figures/cups_admin_model.png Binary files differnew file mode 100644 index 0000000..b476a75 --- /dev/null +++ b/doc/users_guide/figures/cups_admin_model.png diff --git a/doc/users_guide/figures/cups_admin_success.png b/doc/users_guide/figures/cups_admin_success.png Binary files differnew file mode 100644 index 0000000..edebafe --- /dev/null +++ b/doc/users_guide/figures/cups_admin_success.png diff --git a/doc/users_guide/figures/cups_config_printer.png b/doc/users_guide/figures/cups_config_printer.png Binary files differnew file mode 100644 index 0000000..1f980dc --- /dev/null +++ b/doc/users_guide/figures/cups_config_printer.png diff --git a/doc/users_guide/figures/cups_my_printer.png b/doc/users_guide/figures/cups_my_printer.png Binary files differnew file mode 100644 index 0000000..d8441c8 --- /dev/null +++ b/doc/users_guide/figures/cups_my_printer.png diff --git a/doc/users_guide/figures/cups_printers.png b/doc/users_guide/figures/cups_printers.png Binary files differnew file mode 100644 index 0000000..4d45d1c --- /dev/null +++ b/doc/users_guide/figures/cups_printers.png diff --git a/doc/users_guide/figures/cups_startup.png b/doc/users_guide/figures/cups_startup.png Binary files differnew file mode 100644 index 0000000..22d01d0 --- /dev/null +++ b/doc/users_guide/figures/cups_startup.png diff --git a/doc/users_guide/figures/gimp-print-gui-1.png b/doc/users_guide/figures/gimp-print-gui-1.png Binary files differnew file mode 100644 index 0000000..1c083bb --- /dev/null +++ b/doc/users_guide/figures/gimp-print-gui-1.png diff --git a/doc/users_guide/figures/gimp-print-gui.png b/doc/users_guide/figures/gimp-print-gui.png Binary files differnew file mode 100644 index 0000000..a9739fb --- /dev/null +++ b/doc/users_guide/figures/gimp-print-gui.png diff --git a/doc/users_guide/figures/gimp-print-new-printer.png b/doc/users_guide/figures/gimp-print-new-printer.png Binary files differnew file mode 100644 index 0000000..39dd681 --- /dev/null +++ b/doc/users_guide/figures/gimp-print-new-printer.png diff --git a/doc/users_guide/figures/gimp-print-print-color-adjust.png b/doc/users_guide/figures/gimp-print-print-color-adjust.png Binary files differnew file mode 100644 index 0000000..5ab1a33 --- /dev/null +++ b/doc/users_guide/figures/gimp-print-print-color-adjust.png diff --git a/doc/users_guide/figures/gimp-print-setup.png b/doc/users_guide/figures/gimp-print-setup.png Binary files differnew file mode 100644 index 0000000..e406c0b --- /dev/null +++ b/doc/users_guide/figures/gimp-print-setup.png diff --git a/doc/users_guide/figures/gimp_image.png b/doc/users_guide/figures/gimp_image.png Binary files differnew file mode 100644 index 0000000..9193558 --- /dev/null +++ b/doc/users_guide/figures/gimp_image.png diff --git a/doc/users_guide/figures/gimp_startup.png b/doc/users_guide/figures/gimp_startup.png Binary files differnew file mode 100644 index 0000000..b6335e1 --- /dev/null +++ b/doc/users_guide/figures/gimp_startup.png 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 $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{} |