mirror of
https://github.com/MopriaAlliance/CUPS-for-Android.git
synced 2026-05-06 15:26:17 +08:00
adding CUPS code
This commit is contained in:
61
filter/Dependencies
Normal file
61
filter/Dependencies
Normal file
@@ -0,0 +1,61 @@
|
||||
error.o: error.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h \
|
||||
../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h \
|
||||
../cups/array.h ../cups/language.h ../cups/ppd.h \
|
||||
../cups/debug-private.h ../cups/string-private.h ../config.h
|
||||
interpret.o: interpret.c ../cups/raster-private.h ../cups/raster.h \
|
||||
../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \
|
||||
../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h \
|
||||
../cups/debug-private.h ../cups/string-private.h ../config.h
|
||||
raster.o: raster.c ../cups/raster-private.h ../cups/raster.h \
|
||||
../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \
|
||||
../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h \
|
||||
../cups/debug-private.h ../cups/string-private.h ../config.h
|
||||
commandtops.o: commandtops.c ../cups/cups-private.h \
|
||||
../cups/string-private.h ../config.h ../cups/debug-private.h \
|
||||
../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
|
||||
../cups/http.h ../cups/array.h ../cups/http-private.h \
|
||||
../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
|
||||
../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
|
||||
../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
|
||||
../cups/sidechannel.h
|
||||
gziptoany.o: gziptoany.c ../cups/cups-private.h ../cups/string-private.h \
|
||||
../config.h ../cups/debug-private.h ../cups/versioning.h \
|
||||
../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
|
||||
../cups/http-private.h ../cups/md5-private.h \
|
||||
../cups/language-private.h ../cups/transcode.h ../cups/language.h \
|
||||
../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
|
||||
../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h
|
||||
common.o: common.c common.h ../cups/string-private.h ../config.h \
|
||||
../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \
|
||||
../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h
|
||||
pstops.o: pstops.c common.h ../cups/string-private.h ../config.h \
|
||||
../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \
|
||||
../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h \
|
||||
../cups/language-private.h ../cups/transcode.h
|
||||
rasterbench.o: rasterbench.c ../config.h ../cups/raster.h ../cups/cups.h \
|
||||
../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h \
|
||||
../cups/array.h ../cups/language.h ../cups/ppd.h
|
||||
rastertoepson.o: rastertoepson.c ../cups/cups.h ../cups/file.h \
|
||||
../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
|
||||
../cups/language.h ../cups/ppd.h ../cups/string-private.h ../config.h \
|
||||
../cups/language-private.h ../cups/transcode.h ../cups/raster.h
|
||||
rastertohp.o: rastertohp.c ../cups/cups.h ../cups/file.h \
|
||||
../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
|
||||
../cups/language.h ../cups/ppd.h ../cups/string-private.h ../config.h \
|
||||
../cups/language-private.h ../cups/transcode.h ../cups/raster.h
|
||||
rastertolabel.o: rastertolabel.c ../cups/cups.h ../cups/file.h \
|
||||
../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
|
||||
../cups/language.h ../cups/ppd.h ../cups/string-private.h ../config.h \
|
||||
../cups/language-private.h ../cups/transcode.h ../cups/raster.h
|
||||
rastertopwg.o: rastertopwg.c ../cups/cups-private.h \
|
||||
../cups/string-private.h ../config.h ../cups/debug-private.h \
|
||||
../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
|
||||
../cups/http.h ../cups/array.h ../cups/http-private.h \
|
||||
../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
|
||||
../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
|
||||
../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
|
||||
../cups/raster.h
|
||||
testraster.o: testraster.c ../cups/raster-private.h ../cups/raster.h \
|
||||
../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \
|
||||
../cups/http.h ../cups/array.h ../cups/language.h ../cups/ppd.h \
|
||||
../cups/debug-private.h ../cups/string-private.h ../config.h
|
||||
400
filter/Makefile
Normal file
400
filter/Makefile
Normal file
@@ -0,0 +1,400 @@
|
||||
#
|
||||
# "$Id: Makefile 7871 2008-08-27 21:12:43Z mike $"
|
||||
#
|
||||
# Filter makefile for CUPS.
|
||||
#
|
||||
# Copyright 2007-2012 by Apple Inc.
|
||||
# Copyright 1997-2006 by Easy Software Products.
|
||||
#
|
||||
# These coded instructions, statements, and computer programs are the
|
||||
# property of Apple Inc. and are protected by Federal copyright
|
||||
# law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
# which should have been included with this file. If this file is
|
||||
# file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
#
|
||||
# This file is subject to the Apple OS-Developed Software exception.
|
||||
#
|
||||
|
||||
include ../Makedefs
|
||||
|
||||
|
||||
FILTERS = \
|
||||
commandtops \
|
||||
gziptoany \
|
||||
pstops \
|
||||
rastertoepson \
|
||||
rastertohp \
|
||||
rastertolabel \
|
||||
rastertopwg
|
||||
LIBTARGETS = \
|
||||
$(LIBCUPSIMAGE) \
|
||||
libcupsimage.a
|
||||
UNITTARGETS = \
|
||||
rasterbench \
|
||||
testraster
|
||||
TARGETS = \
|
||||
$(LIBTARGETS) \
|
||||
$(FILTERS)
|
||||
|
||||
IMAGEOBJS = error.o interpret.o raster.o
|
||||
OBJS = $(IMAGEOBJS) \
|
||||
commandtops.o gziptoany.o common.o pstops.o \
|
||||
rasterbench.o rastertoepson.o rastertohp.o rastertolabel.o \
|
||||
rastertopwg.o testraster.o
|
||||
|
||||
|
||||
#
|
||||
# Make all targets...
|
||||
#
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
|
||||
#
|
||||
# Make library targets...
|
||||
#
|
||||
|
||||
libs: $(LIBTARGETS)
|
||||
|
||||
|
||||
#
|
||||
# Make unit tests...
|
||||
#
|
||||
|
||||
unittests: $(UNITTARGETS)
|
||||
|
||||
|
||||
#
|
||||
# Clean all object files...
|
||||
#
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS) $(TARGETS) $(UNITTARGETS)
|
||||
$(RM) libcupsimage.so libcupsimage.sl libcupsimage.dylib
|
||||
|
||||
|
||||
#
|
||||
# Update dependencies (without system header dependencies...)
|
||||
#
|
||||
|
||||
depend:
|
||||
$(CC) -MM $(ALL_CFLAGS) $(OBJS:.o=.c) >Dependencies
|
||||
|
||||
|
||||
#
|
||||
# Install all targets...
|
||||
#
|
||||
|
||||
install: all install-data install-headers install-libs install-exec
|
||||
|
||||
|
||||
#
|
||||
# Install data files...
|
||||
#
|
||||
|
||||
install-data:
|
||||
|
||||
|
||||
#
|
||||
# Install programs...
|
||||
#
|
||||
|
||||
install-exec:
|
||||
$(INSTALL_DIR) -m 755 $(SERVERBIN)/filter
|
||||
for file in $(FILTERS); do \
|
||||
$(INSTALL_BIN) $$file $(SERVERBIN)/filter; \
|
||||
done
|
||||
$(RM) $(SERVERBIN)/filter/rastertodymo
|
||||
$(LN) rastertolabel $(SERVERBIN)/filter/rastertodymo
|
||||
if test "x$(SYMROOT)" != "x"; then \
|
||||
$(INSTALL_DIR) $(SYMROOT); \
|
||||
for file in $(FILTERS); do \
|
||||
cp $$file $(SYMROOT); \
|
||||
done \
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Install headers...
|
||||
#
|
||||
|
||||
install-headers:
|
||||
|
||||
|
||||
#
|
||||
# Install libraries...
|
||||
#
|
||||
|
||||
install-libs: $(INSTALLSTATIC)
|
||||
$(INSTALL_DIR) -m 755 $(LIBDIR)
|
||||
$(INSTALL_LIB) $(LIBCUPSIMAGE) $(LIBDIR)
|
||||
-if test $(LIBCUPSIMAGE) = "libcupsimage.so.2" -o $(LIBCUPSIMAGE) = "libcupsimage.sl.2"; then \
|
||||
$(RM) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \
|
||||
$(LN) $(LIBCUPSIMAGE) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \
|
||||
fi
|
||||
-if test $(LIBCUPSIMAGE) = "libcupsimage.2.dylib"; then \
|
||||
$(RM) $(LIBDIR)/libcupsimage.dylib; \
|
||||
$(LN) $(LIBCUPSIMAGE) $(LIBDIR)/libcupsimage.dylib; \
|
||||
fi
|
||||
if test "x$(SYMROOT)" != "x"; then \
|
||||
$(INSTALL_DIR) $(SYMROOT); \
|
||||
cp $(LIBCUPSIMAGE) $(SYMROOT); \
|
||||
fi
|
||||
|
||||
installstatic:
|
||||
$(INSTALL_DIR) -m 755 $(LIBDIR)
|
||||
$(INSTALL_LIB) -m 755 libcupsimage.a $(LIBDIR)
|
||||
$(RANLIB) $(LIBDIR)/libcupsimage.a
|
||||
$(CHMOD) 555 $(LIBDIR)/libcupsimage.a
|
||||
|
||||
|
||||
#
|
||||
# Uninstall all targets...
|
||||
#
|
||||
|
||||
uninstall:
|
||||
for file in $(FILTERS); do \
|
||||
$(RM) $(SERVERBIN)/filter/$$file; \
|
||||
done
|
||||
$(RM) $(SERVERBIN)/filter/rastertodymo
|
||||
-$(RMDIR) $(SERVERBIN)/filter
|
||||
-$(RMDIR) $(SERVERBIN)
|
||||
$(RM) $(LIBDIR)/libcupsimage.2.dylib
|
||||
$(RM) $(LIBDIR)/libcupsimage.a
|
||||
$(RM) $(LIBDIR)/libcupsimage.dylib
|
||||
$(RM) $(LIBDIR)/libcupsimage_s.a
|
||||
$(RM) $(LIBDIR)/libcupsimage.sl
|
||||
$(RM) $(LIBDIR)/libcupsimage.sl.2
|
||||
$(RM) $(LIBDIR)/libcupsimage.so
|
||||
$(RM) $(LIBDIR)/libcupsimage.so.2
|
||||
-$(RMDIR) $(LIBDIR)
|
||||
|
||||
|
||||
#
|
||||
# Automatic API help files...
|
||||
#
|
||||
|
||||
apihelp:
|
||||
echo Generating CUPS API help files...
|
||||
mxmldoc --section "Programming" --title "Raster API" \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header api-raster.header --intro api-raster.shtml \
|
||||
api-raster.xml \
|
||||
../cups/raster.h interpret.c raster.c \
|
||||
>../doc/help/api-raster.html
|
||||
mxmldoc --tokens help/api-raster.html api-raster.xml >../doc/help/api-raster.tokens
|
||||
$(RM) api-raster.xml
|
||||
mxmldoc --section "Programming" \
|
||||
--title "Developing PostScript Printer Drivers" \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header postscript-driver.header \
|
||||
--intro postscript-driver.shtml \
|
||||
>../doc/help/postscript-driver.html
|
||||
mxmldoc --section "Programming" \
|
||||
--title "Introduction to the PPD Compiler" \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header ppd-compiler.header \
|
||||
--intro ppd-compiler.shtml \
|
||||
>../doc/help/ppd-compiler.html
|
||||
mxmldoc --section "Programming" \
|
||||
--title "Developing Raster Printer Drivers" \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header raster-driver.header \
|
||||
--intro raster-driver.shtml \
|
||||
>../doc/help/raster-driver.html
|
||||
mxmldoc --section "Specifications" \
|
||||
--title "CUPS PPD Extensions" \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header spec-ppd.header \
|
||||
--intro spec-ppd.shtml \
|
||||
>../doc/help/spec-ppd.html
|
||||
|
||||
framedhelp:
|
||||
echo Generating CUPS API help files...
|
||||
mxmldoc --section "Programming" --title "Raster API" \
|
||||
--framed ../cups/api-raster \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header api-raster.header --intro api-raster.shtml \
|
||||
../cups/raster.h interpret.c raster.c
|
||||
mxmldoc --section "Programming" \
|
||||
--title "Developing PostScript Printer Drivers" \
|
||||
--framed ../cups/postscript-driver \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header postscript-driver.header \
|
||||
--intro postscript-driver.shtml
|
||||
mxmldoc --section "Programming" \
|
||||
--title "Introduction to the PPD Compiler" \
|
||||
--framed ../cups/ppd-compiler \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header ppd-compiler.header \
|
||||
--intro ppd-compiler.shtml
|
||||
mxmldoc --section "Programming" \
|
||||
--title "Developing Raster Printer Drivers" \
|
||||
--framed ../cups/raster-driver \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header raster-driver.header \
|
||||
--intro raster-driver.shtml
|
||||
mxmldoc --section "Specifications" \
|
||||
--title "CUPS PPD Extensions" \
|
||||
--framed ../cups/spec-ppd \
|
||||
--css ../doc/cups-printable.css \
|
||||
--header spec-ppd.header \
|
||||
--intro spec-ppd.shtml \
|
||||
|
||||
|
||||
#
|
||||
# commandtops
|
||||
#
|
||||
|
||||
commandtops: commandtops.o ../cups/$(LIBCUPS)
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ commandtops.o $(LIBS)
|
||||
|
||||
|
||||
#
|
||||
# gziptoany
|
||||
#
|
||||
|
||||
gziptoany: gziptoany.o ../Makedefs ../cups/$(LIBCUPS)
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ gziptoany.o $(LIBZ) $(LIBS)
|
||||
|
||||
|
||||
#
|
||||
# libcupsimage.so.2, libcupsimage.sl.2
|
||||
#
|
||||
|
||||
libcupsimage.so.2 libcupsimage.sl.2: $(IMAGEOBJS)
|
||||
echo Linking $@...
|
||||
$(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS) $(DSOLIBS) \
|
||||
-L../cups $(LINKCUPS)
|
||||
$(RM) `basename $@ .2`
|
||||
$(LN) $@ `basename $@ .2`
|
||||
|
||||
|
||||
#
|
||||
# libcupsimage.2.dylib
|
||||
#
|
||||
|
||||
libcupsimage.2.dylib: $(IMAGEOBJS) $(LIBCUPSIMAGEORDER)
|
||||
echo Linking $@...
|
||||
$(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \
|
||||
-install_name $(libdir)/$@ \
|
||||
-current_version 2.3.0 \
|
||||
-compatibility_version 2.0.0 \
|
||||
$(IMAGEOBJS) $(DSOLIBS) -L../cups $(LINKCUPS)
|
||||
$(RM) libcupsimage.dylib
|
||||
$(LN) $@ libcupsimage.dylib
|
||||
|
||||
|
||||
#
|
||||
# libcupsimage_s.a
|
||||
#
|
||||
|
||||
libcupsimage_s.a: $(IMAGEOBJS) libcupsimage_s.exp
|
||||
echo Linking $@...
|
||||
$(DSO) $(DSOFLAGS) -Wl,-berok,-bexport:libcupsimage_s.exp \
|
||||
-o libcupsimage_s.o $(IMAGEOBJS) $(DSOLIBS)
|
||||
$(RM) $@
|
||||
$(AR) $(ARFLAGS) $@ libcupsimage_s.o
|
||||
|
||||
|
||||
#
|
||||
# libcupsimage.la
|
||||
#
|
||||
|
||||
libcupsimage.la: $(IMAGEOBJS)
|
||||
echo Linking $@...
|
||||
$(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS:.o=.lo) $(DSOLIBS) \
|
||||
-L../cups $(LINKCUPS) \
|
||||
-rpath $(LIBDIR) -version-info 2:3
|
||||
|
||||
|
||||
#
|
||||
# libcupsimage.a
|
||||
#
|
||||
|
||||
libcupsimage.a: $(IMAGEOBJS)
|
||||
echo Archiving $@...
|
||||
$(RM) $@
|
||||
$(AR) $(ARFLAGS) $@ $(IMAGEOBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
|
||||
#
|
||||
# pstops
|
||||
#
|
||||
|
||||
pstops: pstops.o common.o ../cups/$(LIBCUPS)
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ pstops.o common.o $(LIBS)
|
||||
|
||||
|
||||
#
|
||||
# rastertoepson
|
||||
#
|
||||
|
||||
rastertoepson: rastertoepson.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ rastertoepson.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
|
||||
|
||||
|
||||
#
|
||||
# rastertohp
|
||||
#
|
||||
|
||||
rastertohp: rastertohp.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ rastertohp.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
|
||||
|
||||
|
||||
#
|
||||
# rastertolabel
|
||||
#
|
||||
|
||||
rastertolabel: rastertolabel.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ rastertolabel.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
|
||||
|
||||
|
||||
#
|
||||
# rastertopwg
|
||||
#
|
||||
|
||||
rastertopwg: rastertopwg.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ rastertopwg.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
|
||||
|
||||
|
||||
#
|
||||
# testraster
|
||||
#
|
||||
|
||||
testraster: testraster.o ../cups/$(LIBCUPSSTATIC) libcupsimage.a
|
||||
echo Linking $@...
|
||||
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testraster.o libcupsimage.a \
|
||||
../cups/$(LIBCUPSSTATIC) $(IMGLIBS) $(DSOLIBS) $(COMMONLIBS) \
|
||||
$(SSLLIBS) $(DNSSDLIBS) $(LIBGSSAPI)
|
||||
echo Running raster API tests...
|
||||
./testraster
|
||||
|
||||
|
||||
#
|
||||
# rasterbench
|
||||
#
|
||||
|
||||
rasterbench: rasterbench.o libcupsimage.a
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ rasterbench.o libcupsimage.a $(LIBS)
|
||||
|
||||
|
||||
#
|
||||
# Dependencies...
|
||||
#
|
||||
|
||||
include Dependencies
|
||||
|
||||
|
||||
#
|
||||
# End of "$Id: Makefile 7871 2008-08-27 21:12:43Z mike $".
|
||||
#
|
||||
37
filter/api-raster.header
Normal file
37
filter/api-raster.header
Normal file
@@ -0,0 +1,37 @@
|
||||
<!--
|
||||
"$Id$"
|
||||
|
||||
Raster API documentation for CUPS.
|
||||
|
||||
Copyright 2008-2010 by Apple Inc.
|
||||
|
||||
These coded instructions, statements, and computer programs are the
|
||||
property of Apple Inc. and are protected by Federal copyright
|
||||
law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
which should have been included with this file. If this file is
|
||||
file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
-->
|
||||
|
||||
<h1 class='title'>Raster API</h1>
|
||||
|
||||
<div class='summary'><table summary='General Information'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Header</th>
|
||||
<th>cups/raster.h</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Library</th>
|
||||
<td>-lcupsimage</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>See Also</th>
|
||||
<td>Programming: <a href='api-overview.html'>Introduction to CUPS Programming</a><br>
|
||||
Programming: <a href='api-cups.html'>CUPS API</a><br>
|
||||
Programming: <a href='api-cups.html'>PPD API</a><br>
|
||||
References: <a href='spec-ppd.html'>CUPS PPD Specification</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
160
filter/api-raster.shtml
Normal file
160
filter/api-raster.shtml
Normal file
@@ -0,0 +1,160 @@
|
||||
<!--
|
||||
"$Id$"
|
||||
|
||||
Raster API introduction for CUPS.
|
||||
|
||||
Copyright 2007-2013 by Apple Inc.
|
||||
Copyright 1997-2006 by Easy Software Products, all rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs are the
|
||||
property of Apple Inc. and are protected by Federal copyright
|
||||
law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
which should have been included with this file. If this file is
|
||||
file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
-->
|
||||
|
||||
<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
|
||||
|
||||
<p>The CUPS raster API provides a standard interface for reading and writing
|
||||
CUPS raster streams which are used for printing to raster printers. Because the
|
||||
raster format is updated from time to time, it is important to use this API to
|
||||
avoid incompatibilities with newer versions of CUPS.</p>
|
||||
|
||||
<p>Two kinds of CUPS filters use the CUPS raster API - raster image processor
|
||||
(RIP) filters such as <code>pstoraster</code> and <code>cgpdftoraster</code>
|
||||
(OS X) that produce CUPS raster files and printer driver filters that
|
||||
convert CUPS raster files into a format usable by the printer. Printer
|
||||
driver filters are by far the most common.</p>
|
||||
|
||||
<p>CUPS raster files (<code>application/vnd.cups-raster</code>) consists of
|
||||
a stream of raster page descriptions produced by one of the RIP filters such as
|
||||
<var>pstoraster</var>, <var>imagetoraster</var>, or
|
||||
<var>cgpdftoraster</var>. CUPS raster files are referred to using the
|
||||
<a href='#cups_raster_t'><code>cups_raster_t</code></a> type and are
|
||||
opened using the <a href='#cupsRasterOpen'><code>cupsRasterOpen</code></a>
|
||||
function. For example, to read raster data from the standard input, open
|
||||
file descriptor 0:</p>
|
||||
|
||||
<pre class="example">
|
||||
#include <cups/raster.h>>
|
||||
|
||||
<a href="#cups_raster_t">cups_raster_t</a> *ras = <a href="#cupsRasterOpen">cupsRasterOpen</a>(0, CUPS_RASTER_READ);
|
||||
</pre>
|
||||
|
||||
<p>Each page of data begins with a page dictionary structure called
|
||||
<a href="#cups_page_header2_t"><code>cups_page_header2_t</code></a>. This
|
||||
structure contains the colorspace, bits per color, media size, media type,
|
||||
hardware resolution, and so forth used for the page.</p>
|
||||
|
||||
<blockquote><b>Note:</b>
|
||||
|
||||
<p>Do not confuse the colorspace in the page header with the PPD
|
||||
<tt>ColorModel</tt> keyword. <tt>ColorModel</tt> refers to the general type of
|
||||
color used for a device (Gray, RGB, CMYK, DeviceN) and is often used to
|
||||
select a particular colorspace for the page header along with the associate
|
||||
color profile. The page header colorspace (<tt>cupsColorSpace</tt>) describes
|
||||
both the type and organization of the color data, for example KCMY (black
|
||||
first) instead of CMYK and RGBA (RGB + alpha) instead of RGB.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<p>You read the page header using the
|
||||
<a href="#cupsRasterReadHeader2"><code>cupsRasterReadHeader2</code></a>
|
||||
function:</p>
|
||||
|
||||
<pre class="example">
|
||||
#include <cups/raster.h>>
|
||||
|
||||
<a href="#cups_raster_t">cups_raster_t</a> *ras = <a href="#cupsRasterOpen">cupsRasterOpen</a>(0, CUPS_RASTER_READ);
|
||||
<a href="#cups_page_header2_t">cups_page_header2_t</a> header;
|
||||
|
||||
while (<a href="#cupsRasterReadHeader2">cupsRasterReadHeader2</a>(ras, &header))
|
||||
{
|
||||
/* setup this page */
|
||||
|
||||
/* read raster data */
|
||||
|
||||
/* finish this page */
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>After the page dictionary comes the page data which is a full-resolution,
|
||||
possibly compressed bitmap representing the page in the printer's output
|
||||
colorspace. You read uncompressed raster data using the
|
||||
<a href="#cupsRasterReadPixels"><code>cupsRasterReadPixels</code></a>
|
||||
function. A <code>for</code> loop is normally used to read the page one line
|
||||
at a time:</p>
|
||||
|
||||
<pre class="example">
|
||||
#include <cups/raster.h>>
|
||||
|
||||
<a href="#cups_raster_t">cups_raster_t</a> *ras = <a href="#cupsRasterOpen">cupsRasterOpen</a>(0, CUPS_RASTER_READ);
|
||||
<a href="#cups_page_header2_t">cups_page_header2_t</a> header;
|
||||
int page = 0;
|
||||
int y;
|
||||
char *buffer;
|
||||
|
||||
while (<a href="#cupsRasterReadHeader2">cupsRasterReadHeader2</a>(ras, &header))
|
||||
{
|
||||
/* setup this page */
|
||||
page ++;
|
||||
fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies);
|
||||
|
||||
/* allocate memory for 1 line */
|
||||
buffer = malloc(header.cupsBytesPerLine);
|
||||
|
||||
/* read raster data */
|
||||
for (y = 0; y < header.cupsHeight; y ++)
|
||||
{
|
||||
if (<a href="#cupsRasterReadPixels">cupsRasterReadPixels</a>(ras, buffer, header.cupsBytesPerLine) == 0)
|
||||
break;
|
||||
|
||||
/* write raster data to printer on stdout */
|
||||
}
|
||||
|
||||
/* finish this page */
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>When you are done reading the raster data, call the
|
||||
<a href="#cupsRasterClose"><code>cupsRasterClose</code></a> function to free
|
||||
the memory used to read the raster file:</p>
|
||||
|
||||
<pre class="example">
|
||||
<a href="#cups_raster_t">cups_raster_t</a> *ras;
|
||||
|
||||
<a href="#cupsRasterClose">cupsRasterClose</a>(ras);
|
||||
</pre>
|
||||
|
||||
|
||||
<h2 class='title'><a name="TASKS">Functions by Task</a></h2>
|
||||
|
||||
<h3><a name="OPENCLOSE">Opening and Closing Raster Streams</a></h3>
|
||||
|
||||
<ul class="code">
|
||||
|
||||
<li><a href="#cupsRasterClose" title="Close a raster stream.">cupsRasterClose</a></li>
|
||||
<li><a href="#cupsRasterOpen" title="Open a raster stream.">cupsRasterOpen</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h3><a name="READING">Reading Raster Streams</a></h3>
|
||||
|
||||
<ul class="code">
|
||||
|
||||
<li><a href="#cupsRasterReadHeader" title="Read a raster page header and store it in a version 1 page header structure.">cupsRasterReadHeader</a> <span class="info">Deprecated in CUPS 1.2/OS X 10.5</span></li>
|
||||
<li><a href="#cupsRasterReadHeader2" title="Read a raster page header and store it in a version 2 page header structure.">cupsRasterReadHeader2</a></li>
|
||||
<li><a href="#cupsRasterReadPixels" title="Read raster pixels.">cupsRasterReadPixels</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h3><a name="WRITING">Writing Raster Streams</a></h3>
|
||||
|
||||
<ul class="code">
|
||||
|
||||
<li><a href="#cupsRasterInterpretPPD" title="Interpret PPD commands to create a page header.">cupsRasterInterpretPPD</a></li>
|
||||
<li><a href="#cupsRasterWriteHeader" title="Write a raster page header from a version 1 page header structure.">cupsRasterWriteHeader</a> <span class="info">Deprecated in CUPS 1.2/OS X 10.5</span></li>
|
||||
<li><a href="#cupsRasterWriteHeader2" title="Write a raster page header from a version 2 page header structure.">cupsRasterWriteHeader2</a></li>
|
||||
<li><a href="#cupsRasterWritePixels" title="Write raster pixels.">cupsRasterWritePixels</a></li>
|
||||
|
||||
</ul>
|
||||
538
filter/commandtops.c
Normal file
538
filter/commandtops.c
Normal file
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* "$Id: commandtops.c 3794 2012-04-23 22:44:16Z msweet $"
|
||||
*
|
||||
* PostScript command filter for CUPS.
|
||||
*
|
||||
* Copyright 2008-2012 by Apple Inc.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Apple Inc. and are protected by Federal copyright
|
||||
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
* which should have been included with this file. If this file is
|
||||
* file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
*
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* main() - Process a CUPS command file.
|
||||
* auto_configure() - Automatically configure the printer using
|
||||
* PostScript query commands and/or SNMP lookups.
|
||||
* begin_ps() - Send the standard PostScript prolog.
|
||||
* end_ps() - Send the standard PostScript trailer.
|
||||
* print_self_test_page() - Print a self-test page.
|
||||
* report_levels() - Report supply levels.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <cups/cups-private.h>
|
||||
#include <cups/ppd.h>
|
||||
#include <cups/sidechannel.h>
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
static int auto_configure(ppd_file_t *ppd, const char *user);
|
||||
static void begin_ps(ppd_file_t *ppd, const char *user);
|
||||
static void end_ps(ppd_file_t *ppd);
|
||||
static void print_self_test_page(ppd_file_t *ppd, const char *user);
|
||||
static void report_levels(ppd_file_t *ppd, const char *user);
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Process a CUPS command file.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
int status = 0; /* Exit status */
|
||||
cups_file_t *fp; /* Command file */
|
||||
char line[1024], /* Line from file */
|
||||
*value; /* Value on line */
|
||||
int linenum; /* Line number in file */
|
||||
ppd_file_t *ppd; /* PPD file */
|
||||
|
||||
|
||||
/*
|
||||
* Check for valid arguments...
|
||||
*/
|
||||
|
||||
if (argc < 6 || argc > 7)
|
||||
{
|
||||
/*
|
||||
* We don't have the correct number of arguments; write an error message
|
||||
* and return.
|
||||
*/
|
||||
|
||||
_cupsLangPrintf(stderr,
|
||||
_("Usage: %s job-id user title copies options [file]"),
|
||||
argv[0]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the PPD file...
|
||||
*/
|
||||
|
||||
if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL)
|
||||
{
|
||||
fputs("ERROR: Unable to open PPD file!\n", stderr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the command file as needed...
|
||||
*/
|
||||
|
||||
if (argc == 7)
|
||||
{
|
||||
if ((fp = cupsFileOpen(argv[6], "r")) == NULL)
|
||||
{
|
||||
perror("ERROR: Unable to open command file - ");
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
fp = cupsFileStdin();
|
||||
|
||||
/*
|
||||
* Read the commands from the file and send the appropriate commands...
|
||||
*/
|
||||
|
||||
linenum = 0;
|
||||
|
||||
while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
|
||||
{
|
||||
/*
|
||||
* Parse the command...
|
||||
*/
|
||||
|
||||
if (!_cups_strcasecmp(line, "AutoConfigure"))
|
||||
status |= auto_configure(ppd, argv[2]);
|
||||
else if (!_cups_strcasecmp(line, "PrintSelfTestPage"))
|
||||
print_self_test_page(ppd, argv[2]);
|
||||
else if (!_cups_strcasecmp(line, "ReportLevels"))
|
||||
report_levels(ppd, argv[2]);
|
||||
else
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "ERROR",
|
||||
_("Invalid printer command \"%s\"."), line);
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'auto_configure()' - Automatically configure the printer using PostScript
|
||||
* query commands and/or SNMP lookups.
|
||||
*/
|
||||
|
||||
static int /* O - Exit status */
|
||||
auto_configure(ppd_file_t *ppd, /* I - PPD file */
|
||||
const char *user) /* I - Printing user */
|
||||
{
|
||||
int status = 0; /* Exit status */
|
||||
ppd_option_t *option; /* Current option in PPD */
|
||||
ppd_attr_t *attr; /* Query command attribute */
|
||||
const char *valptr; /* Pointer into attribute value */
|
||||
char buffer[1024], /* String buffer */
|
||||
*bufptr; /* Pointer into buffer */
|
||||
ssize_t bytes; /* Number of bytes read */
|
||||
int datalen; /* Side-channel data length */
|
||||
|
||||
|
||||
/*
|
||||
* See if the backend supports bidirectional I/O...
|
||||
*/
|
||||
|
||||
datalen = 1;
|
||||
if (cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, buffer, &datalen,
|
||||
30.0) != CUPS_SC_STATUS_OK ||
|
||||
buffer[0] != CUPS_SC_BIDI_SUPPORTED)
|
||||
{
|
||||
fputs("DEBUG: Unable to auto-configure PostScript Printer - no "
|
||||
"bidirectional I/O available!\n", stderr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the printer in PostScript mode...
|
||||
*/
|
||||
|
||||
begin_ps(ppd, user);
|
||||
|
||||
/*
|
||||
* (STR #4028)
|
||||
*
|
||||
* As a lot of PPDs contain bad PostScript query code, we need to prevent one
|
||||
* bad query sequence from affecting all auto-configuration. The following
|
||||
* error handler allows us to log PostScript errors to cupsd.
|
||||
*/
|
||||
|
||||
puts("/cups_handleerror {\n"
|
||||
" $error /newerror false put\n"
|
||||
" (:PostScript error in \") print cups_query_keyword print (\": ) "
|
||||
"print\n"
|
||||
" $error /errorname get 128 string cvs print\n"
|
||||
" (; offending command:) print $error /command get 128 string cvs "
|
||||
"print (\n) print flush\n"
|
||||
"} bind def\n"
|
||||
"errordict /timeout {} put\n"
|
||||
"/cups_query_keyword (?Unknown) def\n");
|
||||
fflush(stdout);
|
||||
|
||||
/*
|
||||
* Wait for the printer to become connected...
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
sleep(1);
|
||||
datalen = 1;
|
||||
}
|
||||
while (cupsSideChannelDoRequest(CUPS_SC_CMD_GET_CONNECTED, buffer, &datalen,
|
||||
5.0) == CUPS_SC_STATUS_OK && !buffer[0]);
|
||||
|
||||
/*
|
||||
* Then loop through every option in the PPD file and ask for the current
|
||||
* value...
|
||||
*/
|
||||
|
||||
fputs("DEBUG: Auto-configuring PostScript printer...\n", stderr);
|
||||
|
||||
for (option = ppdFirstOption(ppd); option; option = ppdNextOption(ppd))
|
||||
{
|
||||
/*
|
||||
* See if we have a query command for this option...
|
||||
*/
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "?%s", option->keyword);
|
||||
|
||||
if ((attr = ppdFindAttr(ppd, buffer, NULL)) == NULL || !attr->value)
|
||||
{
|
||||
fprintf(stderr, "DEBUG: Skipping %s option...\n", option->keyword);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the query code to the printer...
|
||||
*/
|
||||
|
||||
fprintf(stderr, "DEBUG: Querying %s...\n", option->keyword);
|
||||
|
||||
for (bufptr = buffer, valptr = attr->value; *valptr; valptr ++)
|
||||
{
|
||||
/*
|
||||
* Log the query code, breaking at newlines...
|
||||
*/
|
||||
|
||||
if (*valptr == '\n')
|
||||
{
|
||||
*bufptr = '\0';
|
||||
fprintf(stderr, "DEBUG: %s\\n\n", buffer);
|
||||
bufptr = buffer;
|
||||
}
|
||||
else if (*valptr < ' ')
|
||||
{
|
||||
if (bufptr >= (buffer + sizeof(buffer) - 4))
|
||||
{
|
||||
*bufptr = '\0';
|
||||
fprintf(stderr, "DEBUG: %s\n", buffer);
|
||||
bufptr = buffer;
|
||||
}
|
||||
|
||||
if (*valptr == '\r')
|
||||
{
|
||||
*bufptr++ = '\\';
|
||||
*bufptr++ = 'r';
|
||||
}
|
||||
else if (*valptr == '\t')
|
||||
{
|
||||
*bufptr++ = '\\';
|
||||
*bufptr++ = 't';
|
||||
}
|
||||
else
|
||||
{
|
||||
*bufptr++ = '\\';
|
||||
*bufptr++ = '0' + ((*valptr / 64) & 7);
|
||||
*bufptr++ = '0' + ((*valptr / 8) & 7);
|
||||
*bufptr++ = '0' + (*valptr & 7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bufptr >= (buffer + sizeof(buffer) - 1))
|
||||
{
|
||||
*bufptr = '\0';
|
||||
fprintf(stderr, "DEBUG: %s\n", buffer);
|
||||
bufptr = buffer;
|
||||
}
|
||||
|
||||
*bufptr++ = *valptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (bufptr > buffer)
|
||||
{
|
||||
*bufptr = '\0';
|
||||
fprintf(stderr, "DEBUG: %s\n", buffer);
|
||||
}
|
||||
|
||||
printf("/cups_query_keyword (?%s) def\n", option->keyword);
|
||||
/* Set keyword for error reporting */
|
||||
fputs("{ (", stdout);
|
||||
for (valptr = attr->value; *valptr; valptr ++)
|
||||
{
|
||||
if (*valptr == '(' || *valptr == ')' || *valptr == '\\')
|
||||
putchar('\\');
|
||||
putchar(*valptr);
|
||||
}
|
||||
fputs(") cvx exec } stopped { cups_handleerror } if clear\n", stdout);
|
||||
/* Send query code */
|
||||
fflush(stdout);
|
||||
|
||||
datalen = 0;
|
||||
cupsSideChannelDoRequest(CUPS_SC_CMD_DRAIN_OUTPUT, buffer, &datalen, 5.0);
|
||||
|
||||
/*
|
||||
* Read the response data...
|
||||
*/
|
||||
|
||||
bufptr = buffer;
|
||||
buffer[0] = '\0';
|
||||
while ((bytes = cupsBackChannelRead(bufptr,
|
||||
sizeof(buffer) - (bufptr - buffer) - 1,
|
||||
10.0)) > 0)
|
||||
{
|
||||
/*
|
||||
* No newline at the end? Go on reading ...
|
||||
*/
|
||||
|
||||
bufptr += bytes;
|
||||
*bufptr = '\0';
|
||||
|
||||
if (bytes == 0 ||
|
||||
(bufptr > buffer && bufptr[-1] != '\r' && bufptr[-1] != '\n'))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Trim whitespace and control characters from both ends...
|
||||
*/
|
||||
|
||||
bytes = bufptr - buffer;
|
||||
|
||||
for (bufptr --; bufptr >= buffer; bufptr --)
|
||||
if (isspace(*bufptr & 255) || iscntrl(*bufptr & 255))
|
||||
*bufptr = '\0';
|
||||
else
|
||||
break;
|
||||
|
||||
for (bufptr = buffer; isspace(*bufptr & 255) || iscntrl(*bufptr & 255);
|
||||
bufptr ++);
|
||||
|
||||
if (bufptr > buffer)
|
||||
{
|
||||
_cups_strcpy(buffer, bufptr);
|
||||
bufptr = buffer;
|
||||
}
|
||||
|
||||
fprintf(stderr, "DEBUG: Got %d bytes.\n", (int)bytes);
|
||||
|
||||
/*
|
||||
* Skip blank lines...
|
||||
*/
|
||||
|
||||
if (!buffer[0])
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Check the response...
|
||||
*/
|
||||
|
||||
if ((bufptr = strchr(buffer, ':')) != NULL)
|
||||
{
|
||||
/*
|
||||
* PostScript code for this option in the PPD is broken; show the
|
||||
* interpreter's error message that came back...
|
||||
*/
|
||||
|
||||
fprintf(stderr, "DEBUG%s\n", bufptr);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the result is a valid option choice...
|
||||
*/
|
||||
|
||||
if (!ppdFindChoice(option, buffer))
|
||||
{
|
||||
if (!strcasecmp(buffer, "Unknown"))
|
||||
break;
|
||||
|
||||
bufptr = buffer;
|
||||
buffer[0] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out the result and move on to the next option...
|
||||
*/
|
||||
|
||||
fprintf(stderr, "PPD: Default%s=%s\n", option->keyword, buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Printer did not answer this option's query
|
||||
*/
|
||||
|
||||
if (bytes <= 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"DEBUG: No answer to query for option %s within 10 seconds.\n",
|
||||
option->keyword);
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish the job...
|
||||
*/
|
||||
|
||||
fflush(stdout);
|
||||
end_ps(ppd);
|
||||
|
||||
/*
|
||||
* Return...
|
||||
*/
|
||||
|
||||
if (status)
|
||||
_cupsLangPrintFilter(stderr, "WARNING",
|
||||
_("Unable to configure printer options."));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'begin_ps()' - Send the standard PostScript prolog.
|
||||
*/
|
||||
|
||||
static void
|
||||
begin_ps(ppd_file_t *ppd, /* I - PPD file */
|
||||
const char *user) /* I - Username */
|
||||
{
|
||||
(void)user;
|
||||
|
||||
if (ppd->jcl_begin)
|
||||
{
|
||||
fputs(ppd->jcl_begin, stdout);
|
||||
fputs(ppd->jcl_ps, stdout);
|
||||
}
|
||||
|
||||
puts("%!");
|
||||
puts("userdict dup(\\004)cvn{}put (\\004\\004)cvn{}put\n");
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'end_ps()' - Send the standard PostScript trailer.
|
||||
*/
|
||||
|
||||
static void
|
||||
end_ps(ppd_file_t *ppd) /* I - PPD file */
|
||||
{
|
||||
if (ppd->jcl_end)
|
||||
fputs(ppd->jcl_end, stdout);
|
||||
else
|
||||
putchar(0x04);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'print_self_test_page()' - Print a self-test page.
|
||||
*/
|
||||
|
||||
static void
|
||||
print_self_test_page(ppd_file_t *ppd, /* I - PPD file */
|
||||
const char *user) /* I - Printing user */
|
||||
{
|
||||
/*
|
||||
* Put the printer in PostScript mode...
|
||||
*/
|
||||
|
||||
begin_ps(ppd, user);
|
||||
|
||||
/*
|
||||
* Send a simple file the draws a box around the imageable area and shows
|
||||
* the product/interpreter information...
|
||||
*/
|
||||
|
||||
puts("\r%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
|
||||
"%%%%%%%%%%%%%\n"
|
||||
"\r%%%% If you can read this, you are using the wrong driver for your "
|
||||
"printer. %%%%\n"
|
||||
"\r%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
|
||||
"%%%%%%%%%%%%%\n"
|
||||
"0 setgray\n"
|
||||
"2 setlinewidth\n"
|
||||
"initclip newpath clippath gsave stroke grestore pathbbox\n"
|
||||
"exch pop exch pop exch 9 add exch 9 sub moveto\n"
|
||||
"/Courier findfont 12 scalefont setfont\n"
|
||||
"0 -12 rmoveto gsave product show grestore\n"
|
||||
"0 -12 rmoveto gsave version show ( ) show revision 20 string cvs show "
|
||||
"grestore\n"
|
||||
"0 -12 rmoveto gsave serialnumber 20 string cvs show grestore\n"
|
||||
"showpage");
|
||||
|
||||
/*
|
||||
* Finish the job...
|
||||
*/
|
||||
|
||||
end_ps(ppd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'report_levels()' - Report supply levels.
|
||||
*/
|
||||
|
||||
static void
|
||||
report_levels(ppd_file_t *ppd, /* I - PPD file */
|
||||
const char *user) /* I - Printing user */
|
||||
{
|
||||
/*
|
||||
* Put the printer in PostScript mode...
|
||||
*/
|
||||
|
||||
begin_ps(ppd, user);
|
||||
|
||||
/*
|
||||
* Don't bother sending any additional PostScript commands, since we just
|
||||
* want the backend to have enough time to collect the supply info.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Finish the job...
|
||||
*/
|
||||
|
||||
end_ps(ppd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: commandtops.c 3794 2012-04-23 22:44:16Z msweet $".
|
||||
*/
|
||||
535
filter/common.c
Normal file
535
filter/common.c
Normal file
@@ -0,0 +1,535 @@
|
||||
/*
|
||||
* "$Id: common.c 6649 2007-07-11 21:46:42Z mike $"
|
||||
*
|
||||
* Common filter routines for CUPS.
|
||||
*
|
||||
* Copyright 2007-2011 by Apple Inc.
|
||||
* Copyright 1997-2006 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Apple Inc. and are protected by Federal copyright
|
||||
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
* which should have been included with this file. If this file is
|
||||
* file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
*
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* SetCommonOptions() - Set common filter options for media size,
|
||||
* etc.
|
||||
* UpdatePageVars() - Update the page variables for the orientation.
|
||||
* WriteComment() - Write a DSC comment.
|
||||
* WriteCommon() - Write common procedures...
|
||||
* WriteLabelProlog() - Write the prolog with the classification
|
||||
* and page label.
|
||||
* WriteLabels() - Write the actual page labels.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <locale.h>
|
||||
|
||||
|
||||
/*
|
||||
* Globals...
|
||||
*/
|
||||
|
||||
int Orientation = 0, /* 0 = portrait, 1 = landscape, etc. */
|
||||
Duplex = 0, /* Duplexed? */
|
||||
LanguageLevel = 1, /* Language level of printer */
|
||||
ColorDevice = 1; /* Do color text? */
|
||||
float PageLeft = 18.0f, /* Left margin */
|
||||
PageRight = 594.0f, /* Right margin */
|
||||
PageBottom = 36.0f, /* Bottom margin */
|
||||
PageTop = 756.0f, /* Top margin */
|
||||
PageWidth = 612.0f, /* Total page width */
|
||||
PageLength = 792.0f; /* Total page length */
|
||||
|
||||
|
||||
/*
|
||||
* 'SetCommonOptions()' - Set common filter options for media size, etc.
|
||||
*/
|
||||
|
||||
ppd_file_t * /* O - PPD file */
|
||||
SetCommonOptions(
|
||||
int num_options, /* I - Number of options */
|
||||
cups_option_t *options, /* I - Options */
|
||||
int change_size) /* I - Change page size? */
|
||||
{
|
||||
ppd_file_t *ppd; /* PPD file */
|
||||
ppd_size_t *pagesize; /* Current page size */
|
||||
const char *val; /* Option value */
|
||||
|
||||
|
||||
#ifdef LC_TIME
|
||||
setlocale(LC_TIME, "");
|
||||
#endif /* LC_TIME */
|
||||
|
||||
ppd = ppdOpenFile(getenv("PPD"));
|
||||
|
||||
ppdMarkDefaults(ppd);
|
||||
cupsMarkOptions(ppd, num_options, options);
|
||||
|
||||
if ((pagesize = ppdPageSize(ppd, NULL)) != NULL)
|
||||
{
|
||||
PageWidth = pagesize->width;
|
||||
PageLength = pagesize->length;
|
||||
PageTop = pagesize->top;
|
||||
PageBottom = pagesize->bottom;
|
||||
PageLeft = pagesize->left;
|
||||
PageRight = pagesize->right;
|
||||
|
||||
fprintf(stderr, "DEBUG: Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
|
||||
PageWidth, PageLength, PageLeft, PageBottom, PageRight, PageTop);
|
||||
}
|
||||
|
||||
if (ppd != NULL)
|
||||
{
|
||||
ColorDevice = ppd->color_device;
|
||||
LanguageLevel = ppd->language_level;
|
||||
}
|
||||
|
||||
if ((val = cupsGetOption("landscape", num_options, options)) != NULL)
|
||||
{
|
||||
if (_cups_strcasecmp(val, "no") != 0 && _cups_strcasecmp(val, "off") != 0 &&
|
||||
_cups_strcasecmp(val, "false") != 0)
|
||||
{
|
||||
if (ppd && ppd->landscape > 0)
|
||||
Orientation = 1;
|
||||
else
|
||||
Orientation = 3;
|
||||
}
|
||||
}
|
||||
else if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL)
|
||||
{
|
||||
/*
|
||||
* Map IPP orientation values to 0 to 3:
|
||||
*
|
||||
* 3 = 0 degrees = 0
|
||||
* 4 = 90 degrees = 1
|
||||
* 5 = -90 degrees = 3
|
||||
* 6 = 180 degrees = 2
|
||||
*/
|
||||
|
||||
Orientation = atoi(val) - 3;
|
||||
if (Orientation >= 2)
|
||||
Orientation ^= 1;
|
||||
}
|
||||
|
||||
if ((val = cupsGetOption("page-left", num_options, options)) != NULL)
|
||||
{
|
||||
switch (Orientation & 3)
|
||||
{
|
||||
case 0 :
|
||||
PageLeft = (float)atof(val);
|
||||
break;
|
||||
case 1 :
|
||||
PageBottom = (float)atof(val);
|
||||
break;
|
||||
case 2 :
|
||||
PageRight = PageWidth - (float)atof(val);
|
||||
break;
|
||||
case 3 :
|
||||
PageTop = PageLength - (float)atof(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((val = cupsGetOption("page-right", num_options, options)) != NULL)
|
||||
{
|
||||
switch (Orientation & 3)
|
||||
{
|
||||
case 0 :
|
||||
PageRight = PageWidth - (float)atof(val);
|
||||
break;
|
||||
case 1 :
|
||||
PageTop = PageLength - (float)atof(val);
|
||||
break;
|
||||
case 2 :
|
||||
PageLeft = (float)atof(val);
|
||||
break;
|
||||
case 3 :
|
||||
PageBottom = (float)atof(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL)
|
||||
{
|
||||
switch (Orientation & 3)
|
||||
{
|
||||
case 0 :
|
||||
PageBottom = (float)atof(val);
|
||||
break;
|
||||
case 1 :
|
||||
PageLeft = (float)atof(val);
|
||||
break;
|
||||
case 2 :
|
||||
PageTop = PageLength - (float)atof(val);
|
||||
break;
|
||||
case 3 :
|
||||
PageRight = PageWidth - (float)atof(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((val = cupsGetOption("page-top", num_options, options)) != NULL)
|
||||
{
|
||||
switch (Orientation & 3)
|
||||
{
|
||||
case 0 :
|
||||
PageTop = PageLength - (float)atof(val);
|
||||
break;
|
||||
case 1 :
|
||||
PageRight = PageWidth - (float)atof(val);
|
||||
break;
|
||||
case 2 :
|
||||
PageBottom = (float)atof(val);
|
||||
break;
|
||||
case 3 :
|
||||
PageLeft = (float)atof(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (change_size)
|
||||
UpdatePageVars();
|
||||
|
||||
if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
|
||||
ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
|
||||
ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
|
||||
ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
|
||||
ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
|
||||
ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
|
||||
ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
|
||||
ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))
|
||||
Duplex = 1;
|
||||
|
||||
return (ppd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'UpdatePageVars()' - Update the page variables for the orientation.
|
||||
*/
|
||||
|
||||
void
|
||||
UpdatePageVars(void)
|
||||
{
|
||||
float temp; /* Swapping variable */
|
||||
|
||||
|
||||
switch (Orientation & 3)
|
||||
{
|
||||
case 0 : /* Portait */
|
||||
break;
|
||||
|
||||
case 1 : /* Landscape */
|
||||
temp = PageLeft;
|
||||
PageLeft = PageBottom;
|
||||
PageBottom = temp;
|
||||
|
||||
temp = PageRight;
|
||||
PageRight = PageTop;
|
||||
PageTop = temp;
|
||||
|
||||
temp = PageWidth;
|
||||
PageWidth = PageLength;
|
||||
PageLength = temp;
|
||||
break;
|
||||
|
||||
case 2 : /* Reverse Portrait */
|
||||
temp = PageWidth - PageLeft;
|
||||
PageLeft = PageWidth - PageRight;
|
||||
PageRight = temp;
|
||||
|
||||
temp = PageLength - PageBottom;
|
||||
PageBottom = PageLength - PageTop;
|
||||
PageTop = temp;
|
||||
break;
|
||||
|
||||
case 3 : /* Reverse Landscape */
|
||||
temp = PageWidth - PageLeft;
|
||||
PageLeft = PageWidth - PageRight;
|
||||
PageRight = temp;
|
||||
|
||||
temp = PageLength - PageBottom;
|
||||
PageBottom = PageLength - PageTop;
|
||||
PageTop = temp;
|
||||
|
||||
temp = PageLeft;
|
||||
PageLeft = PageBottom;
|
||||
PageBottom = temp;
|
||||
|
||||
temp = PageRight;
|
||||
PageRight = PageTop;
|
||||
PageTop = temp;
|
||||
|
||||
temp = PageWidth;
|
||||
PageWidth = PageLength;
|
||||
PageLength = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'WriteCommon()' - Write common procedures...
|
||||
*/
|
||||
|
||||
void
|
||||
WriteCommon(void)
|
||||
{
|
||||
puts("% x y w h ESPrc - Clip to a rectangle.\n"
|
||||
"userdict/ESPrc/rectclip where{pop/rectclip load}\n"
|
||||
"{{newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
|
||||
"neg 0 rlineto closepath clip newpath}bind}ifelse put");
|
||||
puts("% x y w h ESPrf - Fill a rectangle.\n"
|
||||
"userdict/ESPrf/rectfill where{pop/rectfill load}\n"
|
||||
"{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
|
||||
"neg 0 rlineto closepath fill grestore}bind}ifelse put");
|
||||
puts("% x y w h ESPrs - Stroke a rectangle.\n"
|
||||
"userdict/ESPrs/rectstroke where{pop/rectstroke load}\n"
|
||||
"{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
|
||||
"neg 0 rlineto closepath stroke grestore}bind}ifelse put");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'WriteLabelProlog()' - Write the prolog with the classification
|
||||
* and page label.
|
||||
*/
|
||||
|
||||
void
|
||||
WriteLabelProlog(const char *label, /* I - Page label */
|
||||
float bottom, /* I - Bottom position in points */
|
||||
float top, /* I - Top position in points */
|
||||
float width) /* I - Width in points */
|
||||
{
|
||||
const char *classification; /* CLASSIFICATION environment variable */
|
||||
const char *ptr; /* Temporary string pointer */
|
||||
|
||||
|
||||
/*
|
||||
* First get the current classification...
|
||||
*/
|
||||
|
||||
if ((classification = getenv("CLASSIFICATION")) == NULL)
|
||||
classification = "";
|
||||
if (strcmp(classification, "none") == 0)
|
||||
classification = "";
|
||||
|
||||
/*
|
||||
* If there is nothing to show, bind an empty 'write labels' procedure
|
||||
* and return...
|
||||
*/
|
||||
|
||||
if (!classification[0] && (label == NULL || !label[0]))
|
||||
{
|
||||
puts("userdict/ESPwl{}bind put");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the classification + page label string...
|
||||
*/
|
||||
|
||||
printf("userdict");
|
||||
if (strcmp(classification, "confidential") == 0)
|
||||
printf("/ESPpl(CONFIDENTIAL");
|
||||
else if (strcmp(classification, "classified") == 0)
|
||||
printf("/ESPpl(CLASSIFIED");
|
||||
else if (strcmp(classification, "secret") == 0)
|
||||
printf("/ESPpl(SECRET");
|
||||
else if (strcmp(classification, "topsecret") == 0)
|
||||
printf("/ESPpl(TOP SECRET");
|
||||
else if (strcmp(classification, "unclassified") == 0)
|
||||
printf("/ESPpl(UNCLASSIFIED");
|
||||
else
|
||||
{
|
||||
printf("/ESPpl(");
|
||||
|
||||
for (ptr = classification; *ptr; ptr ++)
|
||||
if (*ptr < 32 || *ptr > 126)
|
||||
printf("\\%03o", *ptr);
|
||||
else if (*ptr == '_')
|
||||
putchar(' ');
|
||||
else
|
||||
{
|
||||
if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
|
||||
putchar('\\');
|
||||
|
||||
putchar(*ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (label)
|
||||
{
|
||||
if (classification[0])
|
||||
printf(" - ");
|
||||
|
||||
/*
|
||||
* Quote the label string as needed...
|
||||
*/
|
||||
|
||||
for (ptr = label; *ptr; ptr ++)
|
||||
if (*ptr < 32 || *ptr > 126)
|
||||
printf("\\%03o", *ptr);
|
||||
else
|
||||
{
|
||||
if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
|
||||
putchar('\\');
|
||||
|
||||
putchar(*ptr);
|
||||
}
|
||||
}
|
||||
|
||||
puts(")put");
|
||||
|
||||
/*
|
||||
* Then get a 14 point Helvetica-Bold font...
|
||||
*/
|
||||
|
||||
puts("userdict/ESPpf /Helvetica-Bold findfont 14 scalefont put");
|
||||
|
||||
/*
|
||||
* Finally, the procedure to write the labels on the page...
|
||||
*/
|
||||
|
||||
puts("userdict/ESPwl{");
|
||||
puts(" ESPpf setfont");
|
||||
printf(" ESPpl stringwidth pop dup 12 add exch -0.5 mul %.0f add\n",
|
||||
width * 0.5f);
|
||||
puts(" 1 setgray");
|
||||
printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", bottom - 2.0);
|
||||
printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", top - 18.0);
|
||||
puts(" 0 setgray");
|
||||
printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", bottom - 2.0);
|
||||
printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", top - 18.0);
|
||||
printf(" dup %.0f moveto ESPpl show\n", bottom + 2.0);
|
||||
printf(" %.0f moveto ESPpl show\n", top - 14.0);
|
||||
puts("pop");
|
||||
puts("}bind put");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'WriteLabels()' - Write the actual page labels.
|
||||
*/
|
||||
|
||||
void
|
||||
WriteLabels(int orient) /* I - Orientation of the page */
|
||||
{
|
||||
float width, /* Width of page */
|
||||
length; /* Length of page */
|
||||
|
||||
|
||||
puts("gsave");
|
||||
|
||||
if ((orient ^ Orientation) & 1)
|
||||
{
|
||||
width = PageLength;
|
||||
length = PageWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = PageWidth;
|
||||
length = PageLength;
|
||||
}
|
||||
|
||||
switch (orient & 3)
|
||||
{
|
||||
case 1 : /* Landscape */
|
||||
printf("%.1f 0.0 translate 90 rotate\n", length);
|
||||
break;
|
||||
case 2 : /* Reverse Portrait */
|
||||
printf("%.1f %.1f translate 180 rotate\n", width, length);
|
||||
break;
|
||||
case 3 : /* Reverse Landscape */
|
||||
printf("0.0 %.1f translate -90 rotate\n", width);
|
||||
break;
|
||||
}
|
||||
|
||||
puts("ESPwl");
|
||||
puts("grestore");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'WriteTextComment()' - Write a DSC text comment.
|
||||
*/
|
||||
|
||||
void
|
||||
WriteTextComment(const char *name, /* I - Comment name ("Title", etc.) */
|
||||
const char *value) /* I - Comment value */
|
||||
{
|
||||
int len; /* Current line length */
|
||||
|
||||
|
||||
/*
|
||||
* DSC comments are of the form:
|
||||
*
|
||||
* %%name: value
|
||||
*
|
||||
* The name and value must be limited to 7-bit ASCII for most printers,
|
||||
* so we escape all non-ASCII and ASCII control characters as described
|
||||
* in the Adobe Document Structuring Conventions specification.
|
||||
*/
|
||||
|
||||
printf("%%%%%s: (", name);
|
||||
len = 5 + strlen(name);
|
||||
|
||||
while (*value)
|
||||
{
|
||||
if (*value < ' ' || *value >= 127)
|
||||
{
|
||||
/*
|
||||
* Escape this character value...
|
||||
*/
|
||||
|
||||
if (len >= 251) /* Keep line < 254 chars */
|
||||
break;
|
||||
|
||||
printf("\\%03o", *value & 255);
|
||||
len += 4;
|
||||
}
|
||||
else if (*value == '\\')
|
||||
{
|
||||
/*
|
||||
* Escape the backslash...
|
||||
*/
|
||||
|
||||
if (len >= 253) /* Keep line < 254 chars */
|
||||
break;
|
||||
|
||||
putchar('\\');
|
||||
putchar('\\');
|
||||
len += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Put this character literally...
|
||||
*/
|
||||
|
||||
if (len >= 254) /* Keep line < 254 chars */
|
||||
break;
|
||||
|
||||
putchar(*value);
|
||||
len ++;
|
||||
}
|
||||
|
||||
value ++;
|
||||
}
|
||||
|
||||
puts(")");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: common.c 6649 2007-07-11 21:46:42Z mike $".
|
||||
*/
|
||||
78
filter/common.h
Normal file
78
filter/common.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* "$Id: common.h 6649 2007-07-11 21:46:42Z mike $"
|
||||
*
|
||||
* Common filter definitions for CUPS.
|
||||
*
|
||||
* Copyright 2007-2010 by Apple Inc.
|
||||
* Copyright 1997-2006 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Apple Inc. and are protected by Federal copyright
|
||||
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
* which should have been included with this file. If this file is
|
||||
* file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
*
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <cups/string-private.h>
|
||||
#include <cups/cups.h>
|
||||
#include <cups/ppd.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
/*
|
||||
* C++ magic...
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/*
|
||||
* Globals...
|
||||
*/
|
||||
|
||||
extern int Orientation, /* 0 = portrait, 1 = landscape, etc. */
|
||||
Duplex, /* Duplexed? */
|
||||
LanguageLevel, /* Language level of printer */
|
||||
ColorDevice; /* Do color text? */
|
||||
extern float PageLeft, /* Left margin */
|
||||
PageRight, /* Right margin */
|
||||
PageBottom, /* Bottom margin */
|
||||
PageTop, /* Top margin */
|
||||
PageWidth, /* Total page width */
|
||||
PageLength; /* Total page length */
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes...
|
||||
*/
|
||||
|
||||
extern ppd_file_t *SetCommonOptions(int num_options, cups_option_t *options,
|
||||
int change_size);
|
||||
extern void UpdatePageVars(void);
|
||||
extern void WriteCommon(void);
|
||||
extern void WriteLabelProlog(const char *label, float bottom,
|
||||
float top, float width);
|
||||
extern void WriteLabels(int orient);
|
||||
extern void WriteTextComment(const char *name, const char *value);
|
||||
|
||||
|
||||
/*
|
||||
* C++ magic...
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: common.h 6649 2007-07-11 21:46:42Z mike $".
|
||||
*/
|
||||
286
filter/error.c
Normal file
286
filter/error.c
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* "$Id: error.c 7460 2008-04-16 02:19:54Z mike $"
|
||||
*
|
||||
* Raster error handling for CUPS.
|
||||
*
|
||||
* Copyright 2007-2012 by Apple Inc.
|
||||
* Copyright 2007 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Apple Inc. and are protected by Federal copyright
|
||||
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
* which should have been included with this file. If this file is
|
||||
* file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
*
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* _cupsRasterAddError() - Add an error message to the error buffer.
|
||||
* _cupsRasterClearError() - Clear the error buffer.
|
||||
* cupsRasterErrorString() - Return the last error from a raster function.
|
||||
* get_error_buffer() - Return a pointer to thread local storage.
|
||||
* raster_init() - Initialize error buffer once.
|
||||
* raster_destructor() - Free memory allocated by get_error_buffer().
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <cups/raster-private.h>
|
||||
|
||||
|
||||
/*
|
||||
* Local structures...
|
||||
*/
|
||||
|
||||
typedef struct _cups_raster_error_s /**** Error buffer structure ****/
|
||||
{
|
||||
char *start, /* Start of buffer */
|
||||
*current, /* Current position in buffer */
|
||||
*end; /* End of buffer */
|
||||
} _cups_raster_error_t;
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
static _cups_raster_error_t *get_error_buffer(void);
|
||||
|
||||
|
||||
/*
|
||||
* '_cupsRasterAddError()' - Add an error message to the error buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
_cupsRasterAddError(const char *f, /* I - Printf-style error message */
|
||||
...) /* I - Additional arguments as needed */
|
||||
{
|
||||
_cups_raster_error_t *buf = get_error_buffer();
|
||||
/* Error buffer */
|
||||
va_list ap; /* Pointer to additional arguments */
|
||||
char s[2048]; /* Message string */
|
||||
size_t bytes; /* Bytes in message string */
|
||||
|
||||
|
||||
va_start(ap, f);
|
||||
bytes = vsnprintf(s, sizeof(s), f, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (bytes <= 0)
|
||||
return;
|
||||
|
||||
bytes ++;
|
||||
|
||||
if (bytes >= sizeof(s))
|
||||
return;
|
||||
|
||||
if (bytes > (size_t)(buf->end - buf->current))
|
||||
{
|
||||
/*
|
||||
* Allocate more memory...
|
||||
*/
|
||||
|
||||
char *temp; /* New buffer */
|
||||
size_t size; /* Size of buffer */
|
||||
|
||||
|
||||
size = buf->end - buf->start + 2 * bytes + 1024;
|
||||
|
||||
if (buf->start)
|
||||
temp = realloc(buf->start, size);
|
||||
else
|
||||
temp = malloc(size);
|
||||
|
||||
if (!temp)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Update pointers...
|
||||
*/
|
||||
|
||||
buf->end = temp + size;
|
||||
buf->current = temp + (buf->current - buf->start);
|
||||
buf->start = temp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append the message to the end of the current string...
|
||||
*/
|
||||
|
||||
memcpy(buf->current, s, bytes);
|
||||
buf->current += bytes - 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* '_cupsRasterClearError()' - Clear the error buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
_cupsRasterClearError(void)
|
||||
{
|
||||
_cups_raster_error_t *buf = get_error_buffer();
|
||||
/* Error buffer */
|
||||
|
||||
|
||||
buf->current = buf->start;
|
||||
|
||||
if (buf->start)
|
||||
*(buf->start) = '\0';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'cupsRasterErrorString()' - Return the last error from a raster function.
|
||||
*
|
||||
* If there are no recent errors, NULL is returned.
|
||||
*
|
||||
* @since CUPS 1.3/OS X 10.5@
|
||||
*/
|
||||
|
||||
const char * /* O - Last error */
|
||||
cupsRasterErrorString(void)
|
||||
{
|
||||
_cups_raster_error_t *buf = get_error_buffer();
|
||||
/* Error buffer */
|
||||
|
||||
|
||||
if (buf->current == buf->start)
|
||||
return (NULL);
|
||||
else
|
||||
return (buf->start);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_PTHREAD_H
|
||||
/*
|
||||
* Implement per-thread globals...
|
||||
*/
|
||||
|
||||
# include <pthread.h>
|
||||
|
||||
|
||||
/*
|
||||
* Local globals...
|
||||
*/
|
||||
|
||||
static pthread_key_t raster_key = -1;
|
||||
/* Thread local storage key */
|
||||
static pthread_once_t raster_key_once = PTHREAD_ONCE_INIT;
|
||||
/* One-time initialization object */
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
static void raster_init(void);
|
||||
static void raster_destructor(void *value);
|
||||
|
||||
|
||||
/*
|
||||
* 'get_error_buffer()' - Return a pointer to thread local storage.
|
||||
*/
|
||||
|
||||
_cups_raster_error_t * /* O - Pointer to error buffer */
|
||||
get_error_buffer(void)
|
||||
{
|
||||
_cups_raster_error_t *buf; /* Pointer to error buffer */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the global data exactly once...
|
||||
*/
|
||||
|
||||
DEBUG_puts("get_error_buffer()");
|
||||
|
||||
pthread_once(&raster_key_once, raster_init);
|
||||
|
||||
/*
|
||||
* See if we have allocated the data yet...
|
||||
*/
|
||||
|
||||
if ((buf = (_cups_raster_error_t *)pthread_getspecific(raster_key))
|
||||
== NULL)
|
||||
{
|
||||
DEBUG_puts("get_error_buffer: allocating memory for thread...");
|
||||
|
||||
/*
|
||||
* No, allocate memory as set the pointer for the key...
|
||||
*/
|
||||
|
||||
buf = calloc(1, sizeof(_cups_raster_error_t));
|
||||
pthread_setspecific(raster_key, buf);
|
||||
|
||||
DEBUG_printf((" buf=%p\n", buf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the pointer to the data...
|
||||
*/
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'raster_init()' - Initialize error buffer once.
|
||||
*/
|
||||
|
||||
static void
|
||||
raster_init(void)
|
||||
{
|
||||
pthread_key_create(&raster_key, raster_destructor);
|
||||
|
||||
DEBUG_printf(("raster_init(): raster_key=%x(%u)\n", (unsigned)raster_key,
|
||||
(unsigned)raster_key));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'raster_destructor()' - Free memory allocated by get_error_buffer().
|
||||
*/
|
||||
|
||||
static void
|
||||
raster_destructor(void *value) /* I - Data to free */
|
||||
{
|
||||
_cups_raster_error_t *buf = (_cups_raster_error_t *)value;
|
||||
/* Error buffer */
|
||||
|
||||
|
||||
DEBUG_printf(("raster_destructor(value=%p)\n", value));
|
||||
|
||||
if (buf->start)
|
||||
free(buf->start);
|
||||
|
||||
free(value);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
/*
|
||||
* Implement static globals...
|
||||
*/
|
||||
|
||||
/*
|
||||
* 'get_error_buffer()' - Return a pointer to thread local storage.
|
||||
*/
|
||||
|
||||
_cups_raster_error_t * /* O - Pointer to error buffer */
|
||||
get_error_buffer(void)
|
||||
{
|
||||
static _cups_raster_error_t buf = { 0, 0, 0 };
|
||||
/* Error buffer */
|
||||
|
||||
|
||||
return (&buf);
|
||||
}
|
||||
#endif /* HAVE_PTHREAD_H */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: error.c 7460 2008-04-16 02:19:54Z mike $".
|
||||
*/
|
||||
112
filter/gziptoany.c
Normal file
112
filter/gziptoany.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* "$Id: gziptoany.c 6649 2007-07-11 21:46:42Z mike $"
|
||||
*
|
||||
* GZIP/raw pre-filter for CUPS.
|
||||
*
|
||||
* Copyright 2007-2012 by Apple Inc.
|
||||
* Copyright 1993-2007 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Apple Inc. and are protected by Federal copyright
|
||||
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
* which should have been included with this file. If this file is
|
||||
* file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
*
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* main() - Copy (and uncompress) files to stdout.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <cups/cups-private.h>
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Copy (and uncompress) files to stdout.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
cups_file_t *fp; /* File */
|
||||
char buffer[8192]; /* Data buffer */
|
||||
int bytes; /* Number of bytes read/written */
|
||||
int copies; /* Number of copies */
|
||||
|
||||
|
||||
/*
|
||||
* Check command-line...
|
||||
*/
|
||||
|
||||
if (argc != 7)
|
||||
{
|
||||
_cupsLangPrintf(stderr,
|
||||
_("Usage: %s job-id user title copies options [file]"),
|
||||
argv[0]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the copy count; if we have no final content type, this is a
|
||||
* raw queue or raw print file, so we need to make copies...
|
||||
*/
|
||||
|
||||
if (!getenv("FINAL_CONTENT_TYPE"))
|
||||
copies = atoi(argv[4]);
|
||||
else
|
||||
copies = 1;
|
||||
|
||||
/*
|
||||
* Open the file...
|
||||
*/
|
||||
|
||||
if ((fp = cupsFileOpen(argv[6], "r")) == NULL)
|
||||
{
|
||||
_cupsLangPrintError("ERROR", _("Unable to open print file"));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the file to stdout...
|
||||
*/
|
||||
|
||||
while (copies > 0)
|
||||
{
|
||||
if (!getenv("FINAL_CONTENT_TYPE"))
|
||||
fputs("PAGE: 1 1\n", stderr);
|
||||
|
||||
cupsFileRewind(fp);
|
||||
|
||||
while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
|
||||
if (write(1, buffer, bytes) < bytes)
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "ERROR",
|
||||
_("Unable to write uncompressed print data: %s"),
|
||||
strerror(errno));
|
||||
cupsFileClose(fp);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
copies --;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the file and return...
|
||||
*/
|
||||
|
||||
cupsFileClose(fp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: gziptoany.c 6649 2007-07-11 21:46:42Z mike $".
|
||||
*/
|
||||
1688
filter/interpret.c
Normal file
1688
filter/interpret.c
Normal file
File diff suppressed because it is too large
Load Diff
14
filter/libcupsimage2.def
Normal file
14
filter/libcupsimage2.def
Normal file
@@ -0,0 +1,14 @@
|
||||
LIBRARY libcupsimage2
|
||||
VERSION 2.3
|
||||
EXPORTS
|
||||
cupsRasterClose
|
||||
cupsRasterErrorString
|
||||
cupsRasterInterpretPPD
|
||||
cupsRasterOpen
|
||||
cupsRasterOpenIO
|
||||
cupsRasterReadHeader
|
||||
cupsRasterReadHeader2
|
||||
cupsRasterReadPixels
|
||||
cupsRasterWriteHeader
|
||||
cupsRasterWriteHeader2
|
||||
cupsRasterWritePixels
|
||||
16
filter/libcupsimage_s.exp
Normal file
16
filter/libcupsimage_s.exp
Normal file
@@ -0,0 +1,16 @@
|
||||
_cupsImagePutCol
|
||||
_cupsImagePutRow
|
||||
_cupsImageReadBMP
|
||||
_cupsImageReadGIF
|
||||
_cupsImageReadJPEG
|
||||
_cupsImageReadPIX
|
||||
_cupsImageReadPNG
|
||||
_cupsImageReadPNM
|
||||
_cupsImageReadPhotoCD
|
||||
_cupsImageReadSGI
|
||||
_cupsImageReadSunRaster
|
||||
_cupsImageReadTIFF
|
||||
_cupsImageZoomDelete
|
||||
_cupsImageZoomFill
|
||||
_cupsImageZoomNew
|
||||
_cupsRasterExecPS
|
||||
32
filter/postscript-driver.header
Normal file
32
filter/postscript-driver.header
Normal file
@@ -0,0 +1,32 @@
|
||||
<!--
|
||||
"$Id$"
|
||||
|
||||
PostScript printer driver documentation for CUPS.
|
||||
|
||||
Copyright 2007-2012 by Apple Inc.
|
||||
Copyright 1997-2007 by Easy Software Products.
|
||||
|
||||
These coded instructions, statements, and computer programs are the
|
||||
property of Apple Inc. and are protected by Federal copyright
|
||||
law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
which should have been included with this file. If this file is
|
||||
file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
-->
|
||||
|
||||
<h1 class='title'>Developing PostScript Printer Drivers</h1>
|
||||
|
||||
<p>This document describes how to develop printer drivers for PostScript printers. Topics include: <a href='#BASICS'>printer driver basics</a>, <a href='#CREATE'>creating new PPD files</a>, <a href='#IMPORT'>importing existing PPD files</a>, <a href='#FILTERS'>using custom filters</a>, <a href='#COLOR'>implementing color management</a>, and <a href='#MACOSX'>adding OS X features</a>.</p>
|
||||
|
||||
<div class='summary'><table summary='General Information'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>See Also</th>
|
||||
<td>Programming: <a href='raster-driver.html'>Developing Raster Printer Drivers</a><br>
|
||||
Programming: <a href='api-filter.html'>Filter and Backend Programming</a><br>
|
||||
Programming: <a href='ppd-compiler.html'>Introduction to the PPD Compiler</a><br>
|
||||
Programming: <a href='api-raster.html'>Raster API</a><br>
|
||||
References: <a href='ref-ppdcfile.html'>PPD Compiler Driver Information File Reference</a><br>
|
||||
Specifications: <a href='spec-ppd.html'>CUPS PPD Extensions</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
276
filter/postscript-driver.shtml
Normal file
276
filter/postscript-driver.shtml
Normal file
@@ -0,0 +1,276 @@
|
||||
<h2 class='title'><a name='BASICS'>Printer Driver Basics</a></h2>
|
||||
|
||||
<p>A CUPS PostScript printer driver consists of a PostScript Printer Description (PPD) file that describes the features and capabilities of the device, zero or more <em>filter</em> programs that prepare print data for the device, and zero or more support files for color management, online help, and so forth. The PPD file includes references to all of the filters and support files used by the driver.</p>
|
||||
|
||||
<p>Every time a user prints something the scheduler program, <a href='man-cupsd.html'>cupsd(8)</a>, determines the format of the print job and the programs required to convert that job into something the printer understands. CUPS includes filter programs for many common formats, for example to convert Portable Document Format (PDF) files into device-independent PostScript, and then from device-independent PostScript to device-dependent PostScript. <a href='#FIGURE_1'>Figure 1</a> shows the data flow of a typical print job.</p>
|
||||
|
||||
<div class='figure'><table summary='PostScript Filter Chain'>
|
||||
<caption>Figure 1: <a name='FIGURE_1'>PostScript Filter Chain</a></caption>
|
||||
<tr><td><img src='../images/cups-postscript-chain.png' width='700' height='150' alt='PostScript Filter Chain'></td></tr>
|
||||
</table></div>
|
||||
|
||||
<p>The optional PostScript filter can be provided to add printer-specific commands to the PostScript output that cannot be represented in the PPD file or to reorganize the output for special printer features. Typically this is used to support advanced job management or finishing functions on the printer. CUPS includes a generic PostScript filter that handles all PPD-defined commands.</p>
|
||||
|
||||
<p>The optional port monitor handles interface-specific protocol or encoding issues. For example, many PostScript printers support the Binary Communications Protocol (BCP) and Tagged Binary Communications Protocol (TBCP) to allow applications to print 8-bit ("binary") PostScript jobs. CUPS includes port monitors for BCP and TBCP, and you can supply your own port monitors as needed.</p>
|
||||
|
||||
<p>The backend handles communications with the printer, sending print data from the last filter to the printer and relaying back-channel data from the printer to the upstream filters. CUPS includes backend programs for common direct-connect interfaces and network protocols, and you can provide your own backend to support custom interfaces and protocols.</p>
|
||||
|
||||
<p>The scheduler also supports a special "command" file format for sending maintenance commands and status queries to a printer or printer driver. Command print jobs typically use a single command filter program defined in the PPD file to generate the appropriate printer commands and handle any responses from the printer. <a href='#FIGURE_2'>Figure 2</a> shows the data flow of a typical command job.</p>
|
||||
|
||||
<div class='figure'><table summary='Command Filter Chain'>
|
||||
<caption>Figure 2: <a name='FIGURE_2'>Command Filter Chain</a></caption>
|
||||
<tr><td><img src='../images/cups-command-chain.png' width='575' height='150' alt='Command Filter Chain'></td></tr>
|
||||
</table></div>
|
||||
|
||||
<p>PostScript printer drivers typically do not require their own command filter since CUPS includes a generic PostScript command filter that supports all of the standard functions using PPD-defined commands.</p>
|
||||
|
||||
|
||||
<h2 class='title'><a name='CREATING'>Creating New PPD Files</a></h2>
|
||||
|
||||
<p>We recommend using the CUPS PPD compiler, <a href='man-ppdc.html'>ppdc(1)</a>, to create new PPD files since it manages many of the tedious (and error-prone!) details of paper sizes and localization for you. It also allows you to easily support multiple devices from a single source file. For more information see the "<a href='ppd-compiler.html'>Introduction to the PPD Compiler</a>" document. <a href='#LISTING_1'>Listing 1</a> shows a driver information file for a black-and-white PostScript printer.</p>
|
||||
|
||||
<p class='example'>Listing 1: <a name='LISTING_1'>"examples/postscript.drv"</a></p>
|
||||
|
||||
<pre class='example'>
|
||||
// Include standard font and media definitions
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <font.defs>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <media.defs>
|
||||
|
||||
// Specify this is a PostScript printer driver
|
||||
<a href='ref-ppdcfile.html#DriverType'>DriverType</a> ps
|
||||
|
||||
// List the fonts that are supported, in this case all standard fonts
|
||||
<a href='ref-ppdcfile.html#Font'>Font</a> *
|
||||
|
||||
// Manufacturer, model name, and version
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "Foo"
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "Foo LaserProofer 2000"
|
||||
<a href='ref-ppdcfile.html#Version'>Version</a> 1.0
|
||||
|
||||
// PostScript printer attributes
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> DefaultColorSpace "" Gray
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> LandscapeOrientation "" Minus90
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> LanguageLevel "" "3"
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> Product "" "(Foo LaserProofer 2000)"
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> PSVersion "" "(3010) 0"
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> TTRasterizer "" Type42
|
||||
|
||||
// Supported page sizes
|
||||
*<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Letter
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Legal
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A4
|
||||
|
||||
// Query command for page size
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> "?PageSize" "" "
|
||||
save
|
||||
currentpagedevice /PageSize get aload pop
|
||||
2 copy gt {exch} if (Unknown)
|
||||
23 dict
|
||||
dup [612 792] (Letter) put
|
||||
dup [612 1008] (Legal) put
|
||||
dup [595 842] (A4) put
|
||||
{exch aload pop 4 index sub abs 5 le exch
|
||||
5 index sub abs 5 le and
|
||||
{exch pop exit} {pop} ifelse
|
||||
} bind forall = flush pop pop
|
||||
restore"
|
||||
|
||||
// Specify the name of the PPD file we want to generate
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "fooproof.ppd"
|
||||
</pre>
|
||||
|
||||
<h3>Required Attributes</h3>
|
||||
|
||||
<p>PostScript drivers require the attributes listed in <a href='#TABLE_1'>Table 1</a>. If not specified, the defaults for CUPS drivers are used. A typical PostScript driver information file would include the following attributes:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> DefaultColorSpace "" Gray
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> LandscapeOrientation "" Minus90
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> LanguageLevel "" "3"
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> Product "" "(Foo LaserProofer 2000)"
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> PSVersion "" "(3010) 0"
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> TTRasterizer "" Type42
|
||||
</pre>
|
||||
|
||||
<div class='table'><table summary='Required PostScript Printer Driver Attributes'>
|
||||
<caption>Table 1: <a name='TABLE_1'>Required PostScript Printer Driver Attributes</a></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Attribute</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><tt>DefaultColorSpace</tt></td>
|
||||
<td>The default colorspace:
|
||||
<tt>Gray</tt>, <tt>RGB</tt>, <tt>CMY</tt>, or
|
||||
<tt>CMYK</tt>. If not specified, then <tt>RGB</tt> is
|
||||
assumed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>LandscapeOrientation</tt></td>
|
||||
<td>The preferred landscape
|
||||
orientation: <tt>Plus90</tt>, <tt>Minus90</tt>, or
|
||||
<tt>Any</tt>. If not specified, <tt>Plus90</tt> is
|
||||
assumed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>LanguageLevel</tt></td>
|
||||
<td>The PostScript language
|
||||
level supported by the device: 1, 2, or 3. If not
|
||||
specified, 2 is assumed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>Product</tt></td>
|
||||
<td>The string returned by
|
||||
the PostScript <tt>product</tt> operator, which
|
||||
<i>must</i> include parenthesis to conform with
|
||||
PostScript syntax rules for strings. Multiple
|
||||
<tt>Product</tt> attributes may be specified to support
|
||||
multiple products with the same PPD file. If not
|
||||
specified, "(ESP Ghostscript)" and "(GNU Ghostscript)"
|
||||
are assumed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>PSVersion</tt></td>
|
||||
<td>The PostScript
|
||||
interpreter version numbers as returned by the
|
||||
<tt>version</tt> and <tt>revision</tt> operators. The
|
||||
required format is "(version) revision". Multiple
|
||||
<tt>PSVersion</tt> attributes may be specified to
|
||||
support multiple interpreter version numbers. If not
|
||||
specified, "(3010) 705" and "(3010) 707" are
|
||||
assumed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>TTRasterizer</tt></td>
|
||||
<td>The type of TrueType
|
||||
font rasterizer supported by the device, if any. The
|
||||
supported values are <tt>None</tt>, <tt>Accept68k</tt>,
|
||||
<tt>Type42</tt>, and <tt>TrueImage</tt>. If not
|
||||
specified, <tt>None</tt> is assumed.</td>
|
||||
</tr>
|
||||
</table></div>
|
||||
|
||||
<h3>Query Commands</h3>
|
||||
|
||||
<p>Most PostScript printer PPD files include query commands (<tt>?PageSize</tt>, etc.) that allow applications to query the printer for its current settings and configuration. Query commands are included in driver information files as attributes. For example, the example in <a href='#LISTING_1'>Listing 1</a> uses the following definition for the <tt>PageSize</tt> query command:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> "?PageSize" "" "
|
||||
save
|
||||
currentpagedevice /PageSize get aload pop
|
||||
2 copy gt {exch} if (Unknown)
|
||||
23 dict
|
||||
dup [612 792] (Letter) put
|
||||
dup [612 1008] (Legal) put
|
||||
dup [595 842] (A4) put
|
||||
{exch aload pop 4 index sub abs 5 le exch
|
||||
5 index sub abs 5 le and
|
||||
{exch pop exit} {pop} ifelse
|
||||
} bind forall = flush pop pop
|
||||
restore"
|
||||
</pre>
|
||||
|
||||
<p>Query commands can span multiple lines, however no single line may contain more than 255 characters.</p>
|
||||
|
||||
<h3><a name='IMPORT'>Importing Existing PPD Files</a></h3>
|
||||
|
||||
<P>CUPS includes a utility called <a href='man-ppdi.html'>ppdi(1)</a>
|
||||
which allows you to import existing PPD files into the driver information file
|
||||
format used by the PPD compiler <a href='man-ppdc.html'>ppdc(1)</a>. Once
|
||||
imported, you can modify, localize, and regenerate the PPD files easily. Type
|
||||
the following command to import the PPD file <VAR>mydevice.ppd</VAR> into the
|
||||
driver information file <VAR>mydevice.drv</VAR>:</P>
|
||||
|
||||
<pre class='command'>
|
||||
ppdi -o mydevice.drv mydevice.ppd
|
||||
</pre>
|
||||
|
||||
<P>If you have a whole directory of PPD files that you would like to import,
|
||||
you can list multiple filenames or use shell wildcards to import more than one
|
||||
PPD file on the command-line:</P>
|
||||
|
||||
<pre class='command'>
|
||||
ppdi -o mydevice.drv mydevice1.ppd mydevice2.ppd
|
||||
ppdi -o mydevice.drv *.ppd
|
||||
</pre>
|
||||
|
||||
<P>If the driver information file already exists, the new PPD
|
||||
file entries are appended to the end of the file. Each PPD file
|
||||
is placed in its own group of curly braces within the driver
|
||||
information file.</P>
|
||||
|
||||
|
||||
<h2 class='title'><a name='FILTERS'>Using Custom Filters</a></h2>
|
||||
|
||||
<p>Normally a PostScript printer driver will not utilize any additional print filters. For drivers that provide additional filters such as a CUPS command file filter for doing printer maintenance, you must also list the following <tt>Filter</tt> directive to handle printing PostScript files:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-postscript 0 -
|
||||
</pre>
|
||||
|
||||
<h3>Custom Command Filters</h3>
|
||||
|
||||
<p>The <tt>application/vnd.cups-command</tt> file type is used for CUPS command files. Use the following <tt>Filter</tt> directive to handle CUPS command files:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-command 100 /path/to/command/filter
|
||||
</pre>
|
||||
|
||||
<p>To use the standard PostScript command filter, specify <var>commandtops</var> as the path to the command filter.</p>
|
||||
|
||||
<h3>Custom PDF Filters</h3>
|
||||
|
||||
<p>The <tt>application/pdf</tt> file type is used for unfiltered PDF files while the <tt>application/vnd.cups-pdf</tt> file type is used for filtered PDF files. Use the following <tt>Filter</tt> directive to handle filtered PDF files:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-pdf 100 /path/to/pdf/filter
|
||||
</pre>
|
||||
|
||||
<p>For unfiltered PDF files, use:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/pdf 100 /path/to/pdf/filter
|
||||
</pre>
|
||||
|
||||
<p>Custom PDF filters that accept filtered data do not need to perform number-up processing and other types of page imposition, while those that accept unfiltered data MUST do the number-up processing themselves.</p>
|
||||
|
||||
<h3>Custom PostScript Filters</h3>
|
||||
|
||||
<p>The <tt>application/vnd.cups-postscript</tt> file type is used for filtered PostScript files. Use the following <tt>Filter</tt> directive to handle PostScript files:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-postscript 100 /path/to/postscript/filter
|
||||
</pre>
|
||||
|
||||
|
||||
<h2 class='title'><a name='COLOR'>Implementing Color Management</a></h2>
|
||||
|
||||
<p>CUPS uses ICC color profiles to provide more accurate color reproduction. The <a href='spec-ppd.html#cupsICCProfile'><tt>cupsICCProfile</tt></a> attribute defines the color profiles that are available for a given printer, for example:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsICCProfile "ColorModel.MediaType.Resolution/Description" /path/to/ICC/profile
|
||||
</pre>
|
||||
|
||||
<p>where "ColorModel.MediaType.Resolution" defines a selector based on the corresponding option selections. A simple driver might only define profiles for the color models that are supported, for example a printer supporting Gray and RGB might use:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsICCProfile "Gray../Grayscale Profile" /path/to/ICC/gray-profile
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsICCProfile "RGB../Full Color Profile" /path/to/ICC/rgb-profile
|
||||
</pre>
|
||||
|
||||
<p>The options used for profile selection can be customized using the <tt>cupsICCQualifier2</tt> and <tt>cupsICCQualifier3</tt> attributes.</p>
|
||||
|
||||
|
||||
<h2 class='title'><a name='MACOSX'>Adding OS X Features</a></h2>
|
||||
|
||||
<p>OS X printer drivers can provide <a href='spec-ppd.html#MACOSX'>additional attributes</a> to specify additional option panes in the print dialog, an image of the printer, a help book, and option presets for the driver software:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APDialogExtension "" /Library/Printers/Vendor/filename.plugin
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APHelpBook "" /Library/Printers/Vendor/filename.bundle
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APPrinterIconPath "" /Library/Printers/Vendor/filename.icns
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APPrinterPreset "name/text" "*option choice ..."
|
||||
</pre>
|
||||
40
filter/ppd-compiler.header
Normal file
40
filter/ppd-compiler.header
Normal file
@@ -0,0 +1,40 @@
|
||||
<!--
|
||||
"$Id$"
|
||||
|
||||
PPD compiler documentation for CUPS.
|
||||
|
||||
Copyright 2007-2012 by Apple Inc.
|
||||
Copyright 1997-2007 by Easy Software Products.
|
||||
|
||||
These coded instructions, statements, and computer programs are the
|
||||
property of Apple Inc. and are protected by Federal copyright
|
||||
law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
which should have been included with this file. If this file is
|
||||
file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
-->
|
||||
|
||||
<h1 class='title'>Introduction to the PPD Compiler</h1>
|
||||
|
||||
<P>This document describes how to use the CUPS PostScript Printer Description
|
||||
(PPD) file compiler. The PPD compiler generates PPD files from simple text files
|
||||
that describe the features and capabilities of one or more printers.</P>
|
||||
|
||||
<BLOCKQUOTE><B>Note:</B>
|
||||
|
||||
<P>The PPD compiler and related tools are deprecated and will be removed in a future release of CUPS.</P>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<div class='summary'><table summary='General Information'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>See Also</th>
|
||||
<td>Programming: <a href='raster-driver.html'>Developing Raster Printer Drivers</a><br>
|
||||
Programming: <a href='postscript-driver.html'>Developing PostScript Printer Drivers</a><br>
|
||||
Programming: <a href='api-filter.html'>Filter and Backend Programming</a><br>
|
||||
Programming: <a href='api-raster.html'>Raster API</a><br>
|
||||
References: <a href='ref-ppdcfile.html'>PPD Compiler Driver Information File Reference</a><br>
|
||||
Specifications: <a href='spec-ppd.html'>CUPS PPD Extensions</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
883
filter/ppd-compiler.shtml
Normal file
883
filter/ppd-compiler.shtml
Normal file
@@ -0,0 +1,883 @@
|
||||
<h2 class='title'><a name='BASICS'>The Basics</a></h2>
|
||||
|
||||
<P>The PPD compiler, <a href='man-ppdc.html'><code>ppdc(1)</code></a>, is a
|
||||
simple command-line tool that takes a single <I>driver information file</I>,
|
||||
which by convention uses the extension <VAR>.drv</VAR>, and produces one or more
|
||||
PPD files that may be distributed with your printer drivers for use with CUPS.
|
||||
For example, you would run the following command to create the English language
|
||||
PPD files defined by the driver information file <VAR>mydrivers.drv</VAR>:</P>
|
||||
|
||||
<pre class='command'>
|
||||
ppdc mydrivers.drv
|
||||
</pre>
|
||||
|
||||
<P>The PPD files are placed in a subdirectory called
|
||||
<VAR>ppd</VAR>. The <TT>-d</TT> option is used to put the PPD
|
||||
files in a different location, for example:</p>
|
||||
|
||||
<pre class='command'>
|
||||
ppdc -d myppds mydrivers.drv
|
||||
</pre>
|
||||
|
||||
<P>places the PPD files in a subdirectory named
|
||||
<VAR>myppds</VAR>. Finally, use the <TT>-l</TT> option to
|
||||
specify the language localization for the PPD files that are
|
||||
created, for example:</P>
|
||||
|
||||
<pre class='command'>
|
||||
ppdc -d myppds/de -l de mydrivers.drv
|
||||
ppdc -d myppds/en -l en mydrivers.drv
|
||||
ppdc -d myppds/es -l es mydrivers.drv
|
||||
ppdc -d myppds/fr -l fr mydrivers.drv
|
||||
ppdc -d myppds/it -l it mydrivers.drv
|
||||
</pre>
|
||||
|
||||
<P>creates PPD files in German (de), English (en), Spanish (es),
|
||||
French (fr), and Italian (it) in the corresponding
|
||||
subdirectories. Specify multiple languages (separated by commas) to produce
|
||||
"globalized" PPD files:</p>
|
||||
|
||||
<pre class='command'>
|
||||
ppdc -d myppds -l de,en,es,fr,it mydrivers.drv
|
||||
</pre>
|
||||
|
||||
|
||||
<h2 class='title'><a name='DRV'>Driver Information Files</a></h2>
|
||||
|
||||
<P>The driver information files accepted by the PPD compiler are
|
||||
plain text files that define the various attributes and options
|
||||
that are included in the PPD files that are generated. A driver
|
||||
information file can define the information for one or more printers and
|
||||
their corresponding PPD files.</P>
|
||||
|
||||
<p class='example'><a name="LISTING1">Listing 1: "examples/minimum.drv"</a></p>
|
||||
|
||||
<pre class='example'>
|
||||
<I>// Include standard font and media definitions</I>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <font.defs>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <media.defs>
|
||||
|
||||
<I>// List the fonts that are supported, in this case all standard fonts...</I>
|
||||
<a href='ref-ppdcfile.html#Font'>Font</a> *
|
||||
|
||||
<I>// Manufacturer, model name, and version</I>
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "Foo"
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2000"
|
||||
<a href='ref-ppdcfile.html#Version'>Version</a> 1.0
|
||||
|
||||
<I>// Each filter provided by the driver...</I>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-raster 100 rastertofoo
|
||||
|
||||
<I>// Supported page sizes</I>
|
||||
*<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Letter
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A4
|
||||
|
||||
<I>// Supported resolutions</I>
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> k 8 0 0 0 "600dpi/600 DPI"
|
||||
|
||||
<I>// Specify the name of the PPD file we want to generate...</I>
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "foojet2k.ppd"
|
||||
</pre>
|
||||
|
||||
|
||||
<h3><a name='SIMPLE'>A Simple Example</a></h3>
|
||||
|
||||
<P>The example in <A HREF="#LISTING1">Listing 1</A> shows a driver information
|
||||
file which defines the minimum required attributes to provide a valid PPD file.
|
||||
The first part of the file includes standard definition files for fonts and
|
||||
media sizes:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <font.defs>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <media.defs>
|
||||
</pre>
|
||||
|
||||
<P>The <TT>#include</TT> directive works just like the C/C++ include directive;
|
||||
files included using the angle brackets (<TT><filename></TT>) are found
|
||||
in any of the standard include directories and files included using quotes
|
||||
(<TT>"filename"</TT>) are found in the same directory as the source or include
|
||||
file. The <TT><font.defs></TT> include file defines the standard fonts
|
||||
which are included with GPL Ghostscript and the Apple PDF RIP, while the
|
||||
<TT><media.defs></TT> include file defines the standard media sizes
|
||||
listed in Appendix B of the Adobe PostScript Printer Description File Format
|
||||
Specification.</P>
|
||||
|
||||
<P>CUPS provides several other standard include files:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI><TT><epson.h></TT> - Defines all of the rastertoepson driver
|
||||
constants.</LI>
|
||||
|
||||
<LI><TT><escp.h></TT> - Defines all of the rastertoescpx driver
|
||||
constants.</LI>
|
||||
|
||||
<LI><TT><hp.h></TT> - Defines all of the rastertohp driver
|
||||
constants.</LI>
|
||||
|
||||
<LI><TT><label.h></TT> - Defines all of the rastertolabel driver
|
||||
constants.</LI>
|
||||
|
||||
<LI><TT><pcl.h></TT> - Defines all of the rastertopclx driver
|
||||
constants.</LI>
|
||||
|
||||
<LI><TT><raster.defs></TT> - Defines all of the CUPS raster format
|
||||
constants.</LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>Next we list all of the fonts that are available in the driver; for CUPS
|
||||
raster drivers, the following line is all that is usually supplied:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Font'>Font</a> *
|
||||
</pre>
|
||||
|
||||
<P>The <TT>Font</TT> directive specifies the name of a single font or the
|
||||
asterisk to specify all fonts. For example, you would use the following line to
|
||||
define an additional bar code font that you are supplying with your printer
|
||||
driver:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<I>// name encoding version charset status</I>
|
||||
<a href='ref-ppdcfile.html#Font'>Font</a> Barcode-Foo Special "(1.0)" Special ROM
|
||||
</pre>
|
||||
|
||||
<P>The name of the font is <TT>Barcode-Foo</TT>. Since it is not a standard
|
||||
text font, the encoding and charset name <TT>Special</TT> is used. The version
|
||||
number is <TT>1.0</TT> and the status (where the font is located) is
|
||||
<TT>ROM</TT> to indicate that the font does not need to be embedded in
|
||||
documents that use the font for this printer.</P>
|
||||
|
||||
<P>Third comes the manufacturer, model name, and version number information
|
||||
strings:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "Foo"
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2000"
|
||||
<a href='ref-ppdcfile.html#Version'>Version</a> 1.0
|
||||
</pre>
|
||||
|
||||
<P>These strings are used when the user (or auto-configuration program) selects
|
||||
the printer driver for a newly connected device.</p>
|
||||
|
||||
<P>The list of filters comes after the information strings; for the example in
|
||||
<A HREF="#LISTING1">Listing 1</A>, we have a single filter that takes CUPS
|
||||
raster data:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-raster 100 rastertofoo
|
||||
</pre>
|
||||
|
||||
<P>Each filter specified in the driver information file is the equivalent of a
|
||||
printer driver for that format; if a user submits a print job in a different
|
||||
format, CUPS figures out the sequence of commands that will produce a supported
|
||||
format for the least relative cost.</P>
|
||||
|
||||
<P>Once we have defined the driver information we specify the supported options.
|
||||
For the example driver we support a single resolution of 600 dots per inch and
|
||||
two media sizes, A4 and Letter:</P>
|
||||
|
||||
<pre class='example'>
|
||||
*<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Letter
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A4
|
||||
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> k 8 0 0 0 "600dpi/600 DPI"
|
||||
</pre>
|
||||
|
||||
<P>The asterisk in front of the <TT>MediaSize</TT> and <TT>Resolution</TT>
|
||||
directives specify that those option choices are the default. The
|
||||
<TT>MediaSize</TT> directive is followed by a media size name which is normally
|
||||
defined in the <TT><media.defs></TT> file and corresponds to a standard
|
||||
Adobe media size name. If the default media size is <TT>Letter</TT>, the PPD
|
||||
compiler will override it to be <TT>A4</TT> for non-English localizations for
|
||||
you automatically.</P>
|
||||
|
||||
<P>The <TT>Resolution</TT> directive accepts several values after it as
|
||||
follows:</P>
|
||||
|
||||
<OL>
|
||||
|
||||
<LI>Colorspace for this resolution, if any. In the example file, the
|
||||
colorspace <TT>k</TT> is used which corresponds to black. For printer
|
||||
drivers that support color printing, this field is usually specified as
|
||||
"-" for "no change".</LI>
|
||||
|
||||
<LI>Bits per color. In the example file, we define 8 bits per color, for
|
||||
a continuous-tone grayscale output. All versions of CUPS support 1 and
|
||||
8 bits per color. CUPS 1.2 and higher (OS X 10.5 and higher) also
|
||||
supports 16 bits per color.</LI>
|
||||
|
||||
<LI>Rows per band. In the example file, we define 0 rows per band to
|
||||
indicate that our printer driver does not process the page in
|
||||
bands.</LI>
|
||||
|
||||
<LI>Row feed. In the example, we define the feed value to be 0 to
|
||||
indicate that our printer driver does not interleave the output.</LI>
|
||||
|
||||
<LI>Row step. In the example, we define the step value to be 0 to
|
||||
indicate that our printer driver does not interleave the output. This
|
||||
value normally indicates the spacing between the nozzles of an inkjet
|
||||
printer - when combined with the previous two values, it informs the
|
||||
driver how to stagger the output on the page to produce interleaved
|
||||
lines on the page for higher-resolution output.</LI>
|
||||
|
||||
<LI>Choice name and text. In the example, we define the choice name and
|
||||
text to be <TT>"600dpi/600 DPI"</TT>. The name and text are separated by
|
||||
slash (<TT>/</TT>) character; if no text is specified, then the name is
|
||||
used as the text. The PPD compiler parses the name to determine the
|
||||
actual resolution; the name can be of the form
|
||||
<TT><I>RESOLUTION</I>dpi</TT> for resolutions that are equal
|
||||
horizontally and vertically or <TT><I>HRES</I>x<I>VRES</I>dpi</TT> for
|
||||
isometric resolutions. Only integer resolution values are supported, so
|
||||
a resolution name of <TT>300dpi</TT> is valid while <TT>300.1dpi</TT> is
|
||||
not.</LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<P>Finally, the <TT>PCFileName</TT> directive specifies that the named PPD file
|
||||
should be written for the current driver definitions:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "foojet2k.ppd"
|
||||
</pre>
|
||||
|
||||
<P>The filename follows the directive and <I>must</I> conform to the Adobe
|
||||
filename requirements in the Adobe Postscript Printer Description File Format
|
||||
Specification. Specifically, the filename may not exceed 8 characters followed
|
||||
by the extension <VAR>.ppd</VAR>. The <TT>FileName</TT> directive can be used to
|
||||
specify longer filenames:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#FileName'>FileName</a> "FooJet 2000"
|
||||
</pre>
|
||||
|
||||
|
||||
<h3><a name='GROUPING'>Grouping and Inheritance</a></h3>
|
||||
|
||||
<P>The previous example created a single PPD file. Driver information files can
|
||||
also define multiple printers by using the PPD compiler grouping functionality.
|
||||
Directives are grouped using the curly braces (<TT>{</TT> and <TT>}</TT>) and
|
||||
every group that uses the <TT>PCFileName</TT> or <TT>FileName</TT> directives
|
||||
produces a PPD file with that name. <A HREF="#LISTING2">Listing 2</A> shows a
|
||||
variation of the original example that uses two groups to define two printers
|
||||
that share the same printer driver filter but provide two different resolution
|
||||
options.</P>
|
||||
|
||||
<p class='example'><a name="LISTING2">Listing 2: "examples/grouping.drv"</a></p>
|
||||
|
||||
<pre class='example'>
|
||||
|
||||
<I>// Include standard font and media definitions</I>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <font.defs>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <media.defs>
|
||||
|
||||
<I>// List the fonts that are supported, in this case all standard fonts...</I>
|
||||
<a href='ref-ppdcfile.html#Font'>Font</a> *
|
||||
|
||||
<I>// Manufacturer and version</I>
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "Foo"
|
||||
<a href='ref-ppdcfile.html#Version'>Version</a> 1.0
|
||||
|
||||
<I>// Each filter provided by the driver...</I>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-raster 100 rastertofoo
|
||||
|
||||
<I>// Supported page sizes</I>
|
||||
*<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Letter
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A4
|
||||
|
||||
{
|
||||
<I>// Supported resolutions</I>
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> k 8 0 0 0 "600dpi/600 DPI"
|
||||
|
||||
<I>// Specify the model name and filename...</I>
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2000"
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "foojet2k.ppd"
|
||||
}
|
||||
|
||||
{
|
||||
<I>// Supported resolutions</I>
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> k 8 0 0 0 "1200dpi/1200 DPI"
|
||||
|
||||
<I>// Specify the model name and filename...</I>
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2001"
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "foojt2k1.ppd"
|
||||
}
|
||||
</pre>
|
||||
|
||||
<P>The second example is essentially the same as the first, except that each
|
||||
printer model is defined inside of a pair of curly braces. For example, the
|
||||
first printer is defined using:</P>
|
||||
|
||||
<pre class='example'>
|
||||
{
|
||||
// Supported resolutions
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> k 8 0 0 0 "600dpi/600 DPI"
|
||||
|
||||
// Specify the model name and filename...
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2000"
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "foojet2k.ppd"
|
||||
}
|
||||
</pre>
|
||||
|
||||
<P>The printer <I>inherits</I> all of the definitions from the parent group (the
|
||||
top part of the file) and adds the additional definitions inside the curly
|
||||
braces for that printer driver. When we define the second group, it also
|
||||
inherits the same definitions from the parent group but <I>none</I> of the
|
||||
definitions from the first driver. Groups can be nested to any number of levels
|
||||
to support variations of similar models without duplication of information.</P>
|
||||
|
||||
|
||||
<h3><a name='COLOR'>Color Support</a></h3>
|
||||
|
||||
<P>For printer drivers that support color printing, the
|
||||
<TT>ColorDevice</TT> and <TT>ColorModel</TT> directives should be
|
||||
used to tell the printing system that color output is desired
|
||||
and in what formats. <A HREF="#LISTING3">Listing 3</A> shows a
|
||||
variation of the previous example which includes a color printer
|
||||
that supports printing at 300 and 600 DPI.</P>
|
||||
|
||||
<P>The key changes are the addition of the <TT>ColorDevice</TT>
|
||||
directive:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#ColorDevice'>ColorDevice</a> true
|
||||
</pre>
|
||||
|
||||
<P>which tells the printing system that the printer supports
|
||||
color printing, and the <TT>ColorModel</TT> directives:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#ColorModel'>ColorModel</a> Gray/Grayscale w chunky 0
|
||||
*<a href='ref-ppdcfile.html#ColorModel'>ColorModel</a> RGB/Color rgb chunky 0
|
||||
</pre>
|
||||
|
||||
<P>which tell the printing system which colorspaces are supported by the printer
|
||||
driver for color printing. Each of the <TT>ColorModel</TT> directives is
|
||||
followed by the option name and text (<TT>Gray/Grayscale</TT> and
|
||||
<TT>RGB/Color</TT>), the colorspace name (<TT>w</TT> and <TT>rgb</TT>), the
|
||||
color organization (<TT>chunky</TT>), and the compression mode number
|
||||
(<TT>0</TT>) to be passed to the driver. The option name can be any of the
|
||||
standard Adobe <TT>ColorModel</TT> names:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI><TT>Gray</TT> - Grayscale output.
|
||||
|
||||
<LI><TT>RGB</TT> - Color output, typically using the RGB
|
||||
colorspace, but without a separate black channel.
|
||||
|
||||
<LI><TT>CMYK</TT> - Color output with a separate black
|
||||
channel.
|
||||
|
||||
</UL>
|
||||
|
||||
<P>Custom names can be used, however it is recommended that you use your vendor
|
||||
prefix for any custom names, for example "fooName".</P>
|
||||
|
||||
<P>The colorspace name can be any of the following universally supported
|
||||
colorspaces:</P>
|
||||
|
||||
<UL>
|
||||
<LI><TT>w</TT> - Luminance</LI>
|
||||
|
||||
<LI><TT>rgb</TT> - Red, green, blue</LI>
|
||||
|
||||
<LI><TT>k</TT> - Black</LI>
|
||||
|
||||
<LI><TT>cmy</TT> - Cyan, magenta, yellow</LI>
|
||||
|
||||
<LI><TT>cmyk</TT> - Cyan, magenta, yellow, black</LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>The color organization can be any of the following values:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI><TT>chunky</TT> - Color values are passed together on a line
|
||||
as RGB RGB RGB RGB</LI>
|
||||
|
||||
<LI><TT>banded</TT> - Color values are passed separately
|
||||
on a line as RRRR GGGG BBBB; not supported by the Apple
|
||||
RIP filters</LI>
|
||||
|
||||
<LI><TT>planar</TT> - Color values are passed separately
|
||||
on a page as RRRR RRRR RRRR ... GGGG GGGG GGGG ... BBBB
|
||||
BBBB BBBB; not supported by the Apple RIP filters</LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>The compression mode value is passed to the driver in the
|
||||
<TT>cupsCompression</TT> attribute. It is traditionally used to select an
|
||||
appropriate compression mode for the color model but can be used for any
|
||||
purpose, such as specifying a photo mode vs. standard mode.</P>
|
||||
|
||||
<p class='example'><a name="LISTING3">Listing 3: "examples/color.drv"</a></p>
|
||||
|
||||
<pre class='example'>
|
||||
|
||||
<I>// Include standard font and media definitions</I>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <font.defs>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <media.defs>
|
||||
|
||||
<I>// List the fonts that are supported, in this case all standard fonts...</I>
|
||||
<a href='ref-ppdcfile.html#Font'>Font</a> *
|
||||
|
||||
<I>// Manufacturer and version</I>
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "Foo"
|
||||
<a href='ref-ppdcfile.html#Version'>Version</a> 1.0
|
||||
|
||||
<I>// Each filter provided by the driver...</I>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-raster 100 rastertofoo
|
||||
|
||||
<I>// Supported page sizes</I>
|
||||
*<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Letter
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A4
|
||||
|
||||
{
|
||||
<I>// Supported resolutions</I>
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> k 8 0 0 0 "600dpi/600 DPI"
|
||||
|
||||
<I>// Specify the model name and filename...</I>
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2000"
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "foojet2k.ppd"
|
||||
}
|
||||
|
||||
{
|
||||
<I>// Supports color printing</I>
|
||||
<a href='ref-ppdcfile.html#ColorDevice'>ColorDevice</a> true
|
||||
|
||||
<I>// Supported colorspaces</I>
|
||||
<a href='ref-ppdcfile.html#ColorModel'>ColorModel</a> Gray/Grayscale w chunky 0
|
||||
*<a href='ref-ppdcfile.html#ColorModel'>ColorModel</a> RGB/Color rgb chunky 0
|
||||
|
||||
<I>// Supported resolutions</I>
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> - 8 0 0 0 "300dpi/300 DPI"
|
||||
<a href='ref-ppdcfile.html#Resolution'>Resolution</a> - 8 0 0 0 "600dpi/600 DPI"
|
||||
|
||||
<I>// Specify the model name and filename...</I>
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet Color"
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "foojetco.ppd"
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<h3><a name='OPTIONS'>Defining Custom Options and Option Groups</a></h3>
|
||||
|
||||
<P>The <TT>Group</TT>, <TT>Option</TT>, and <TT>Choice</TT>
|
||||
directives are used to define or select a group, option, or
|
||||
choice. <A HREF="#LISTING4">Listing 4</A> shows a variation of
|
||||
the first example that provides two custom options in a group
|
||||
named "Footasm".</P>
|
||||
|
||||
<p class='example'><a name="LISTING4">Listing 4: "examples/custom.drv"</a></p>
|
||||
|
||||
<pre class='example'>
|
||||
|
||||
<I>// Include standard font and media definitions</I>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <font.defs>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <media.defs>
|
||||
|
||||
<I>// List the fonts that are supported, in this case all standard fonts...</I>
|
||||
<a href='ref-ppdcfile.html#Font'>Font</a> *
|
||||
|
||||
<I>// Manufacturer, model name, and version</I>
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "Foo"
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2000"
|
||||
<a href='ref-ppdcfile.html#Version'>Version</a> 1.0
|
||||
|
||||
<I>// Each filter provided by the driver...</I>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-raster 100 rastertofoo
|
||||
|
||||
<I>// Supported page sizes</I>
|
||||
*<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Letter
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A4
|
||||
|
||||
<I>// Supported resolutions</I>
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> k 8 0 0 0 "600dpi/600 DPI"
|
||||
|
||||
<I>// Option Group</I>
|
||||
<a href='ref-ppdcfile.html#Group'>Group</a> "Footasm"
|
||||
|
||||
<I>// Boolean option</I>
|
||||
<a href='ref-ppdcfile.html#Option'>Option</a> "fooEnhance/Resolution Enhancement" Boolean AnySetup 10
|
||||
*<a href='ref-ppdcfile.html#Choice'>Choice</a> True/Yes "<</cupsCompression 1>>setpagedevice"
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> False/No "<</cupsCompression 0>>setpagedevice"
|
||||
|
||||
<I>// Multiple choice option</I>
|
||||
<a href='ref-ppdcfile.html#Option'>Option</a> "fooOutputType/Output Quality" PickOne AnySetup 10
|
||||
*<a href='ref-ppdcfile.html#Choice'>Choice</a> "Auto/Automatic Selection"
|
||||
"<</OutputType(Auto)>>setpagedevice""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "Text/Optimize for Text"
|
||||
"<</OutputType(Text)>>setpagedevice""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "Graph/Optimize for Graphics"
|
||||
"<</OutputType(Graph)>>setpagedevice""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "Photo/Optimize for Photos"
|
||||
"<</OutputType(Photo)>>setpagedevice""
|
||||
|
||||
<I>// Specify the name of the PPD file we want to generate...</I>
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "foojet2k.ppd"
|
||||
</pre>
|
||||
|
||||
<P>The custom group is introduced by the <TT>Group</TT>
|
||||
directive which is followed by the name and optionally text for
|
||||
the user:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Group'>Group</a> "Footasm/Footastic Options"
|
||||
</pre>
|
||||
|
||||
<P>The group name must conform to the PPD specification and
|
||||
cannot exceed 40 characters in length. If you specify user text,
|
||||
it cannot exceed 80 characters in length. The groups
|
||||
<TT>General</TT>, <TT>Extra</TT>, and
|
||||
<TT>InstallableOptions</TT> are predefined by CUPS; the general
|
||||
and extra groups are filled by the UI options defined by the PPD
|
||||
specification. The <TT>InstallableOptions</TT> group is reserved
|
||||
for options that define whether accessories for the printer
|
||||
(duplexer unit, finisher, stapler, etc.) are installed.</P>
|
||||
|
||||
<P>Once the group is specified, the <TT>Option</TT> directive is
|
||||
used to introduce a new option:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Option'>Option</a> "fooEnhance/Resolution Enhancement" Boolean AnySetup 10
|
||||
</pre>
|
||||
|
||||
<P>The directive is followed by the name of the option and any
|
||||
optional user text, the option type, the PostScript document group, and
|
||||
the sort order number. The option name must conform to the PPD specification
|
||||
and cannot exceed 40 characters in length. If you specify user text, it
|
||||
cannot exceed 80 characters in length.</P>
|
||||
|
||||
<P>The option type can be <TT>Boolean</TT> for true/false
|
||||
selections, <TT>PickOne</TT> for picking one of many choices, or
|
||||
<TT>PickMany</TT> for picking zero or more choices. Boolean
|
||||
options can have at most two choices with the names
|
||||
<TT>False</TT> and <TT>True</TT>. Pick options can have any
|
||||
number of choices, although for Windows compatibility reasons
|
||||
the number of choices should not exceed 255.</P>
|
||||
|
||||
<P>The PostScript document group is typically <TT>AnySetup</TT>,
|
||||
meaning that the option can be introduced at any point in the
|
||||
PostScript document. Other values include <TT>PageSetup</TT> to
|
||||
include the option before each page and <TT>DocumentSetup</TT>
|
||||
to include the option once at the beginning of the document.</P>
|
||||
|
||||
<P>The sort order number is used to sort the printer commands
|
||||
associated with each option choice within the PostScript
|
||||
document. This allows you to setup certain options before others
|
||||
as required by the printer. For most CUPS raster printer
|
||||
drivers, the value <TT>10</TT> can be used for all options.</P>
|
||||
|
||||
<P>Once the option is specified, each option choice can be
|
||||
listed using the <TT>Choice</TT> directive:</P>
|
||||
|
||||
<pre class='example'>
|
||||
*<a href='ref-ppdcfile.html#Choice'>Choice</a> True/Yes "<</cupsCompression 1>>setpagedevice"
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> False/No "<</cupsCompression 0>>setpagedevice"
|
||||
</pre>
|
||||
|
||||
<P>The directive is followed by the choice name and optionally
|
||||
user text, and the PostScript commands that should be inserted
|
||||
when printing a file to this printer. The option name must
|
||||
conform to the PPD specification and cannot exceed 40 characters
|
||||
in length. If you specify user text, it cannot exceed 80
|
||||
characters in length.</P>
|
||||
|
||||
<P>The PostScript commands are also interpreted by any RIP
|
||||
filters, so these commands typically must be present for all
|
||||
option choices. Most commands take the form:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<</name value>>setpagedevice
|
||||
</pre>
|
||||
|
||||
<P>where <TT>name</TT> is the name of the PostScript page device
|
||||
attribute and <TT>value</TT> is the numeric or string value for
|
||||
that attribute.</P>
|
||||
|
||||
|
||||
<h3><a name='DEFINE'>Defining Constants</a></h3>
|
||||
|
||||
<P>Sometimes you will want to define constants for your drivers
|
||||
so that you can share values in different groups within the same
|
||||
driver information file, or to share values between different
|
||||
driver information files using the <TT>#include</TT> directive.
|
||||
The <TT>#define</TT> directive is used to define constants for
|
||||
use in your printer definitions:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#_define'>#define</a> NAME value
|
||||
</pre>
|
||||
|
||||
<P>The <TT>NAME</TT> is any sequence of letters, numbers, and
|
||||
the underscore. The <TT>value</TT> is a number or string; if the
|
||||
value contains spaces you must put double quotes around it, for
|
||||
example:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#_define'>#define</a> FOO "My String Value"
|
||||
</pre>
|
||||
|
||||
<P>Constants can also be defined on the command-line using the <tt>-D</tt>
|
||||
option:</P>
|
||||
|
||||
<pre class='command'>
|
||||
ppdc -DNAME="value" filename.drv
|
||||
</pre>
|
||||
|
||||
<P>Once defined, you use the notation <TT>$NAME</TT> to substitute the value of
|
||||
the constant in the file, for example:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#_define'>#define</a> MANUFACTURER "Foo"
|
||||
<a href='ref-ppdcfile.html#_define'>#define</a> FOO_600 0
|
||||
<a href='ref-ppdcfile.html#_define'>#define</a> FOO_1200 1
|
||||
|
||||
{
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "$MANUFACTURER"
|
||||
<a href='ref-ppdcfile.html#ModelNumber'>ModelNumber</a> $FOO_600
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2000"
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "$MANUFACTURER"
|
||||
<a href='ref-ppdcfile.html#ModelNumber'>ModelNumber</a> $FOO_1200
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2001"
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<P>Numeric constants can be bitwise OR'd together by placing the constants
|
||||
inside parenthesis, for example:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<I>// ModelNumber capability bits</I>
|
||||
<a href='ref-ppdcfile.html#_define'>#define</a> DUPLEX 1
|
||||
<a href='ref-ppdcfile.html#_define'>#define</a> COLOR 2
|
||||
|
||||
...
|
||||
|
||||
{
|
||||
<I>// Define a model number specifying the capabilities of the printer...</I>
|
||||
<a href='ref-ppdcfile.html#ModelNumber'>ModelNumber</a> ($DUPLEX $COLOR)
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<h3><a name='CONDITIONAL'>Conditional Statements</a></h3>
|
||||
|
||||
<p>The PPD compiler supports conditional compilation using the <tt>#if</tt>,
|
||||
<tt>#elif</tt>, <tt>#else</tt>, and <tt>#endif</tt> directives. The <tt>#if</tt>
|
||||
and <tt>#elif</tt> directives are followed by a constant name or an expression.
|
||||
For example, to include a group of options when "ADVANCED" is defined:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#_if'>#if</a> ADVANCED
|
||||
<a href='ref-ppdcfile.html#Group'>Group</a> "Advanced/Advanced Options"
|
||||
<a href='ref-ppdcfile.html#Option'>Option</a> "fooCyanAdjust/Cyan Adjustment"
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "plus10/+10%" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "plus5/+5%" ""
|
||||
*<a href='ref-ppdcfile.html#Choice'>Choice</a> "none/No Adjustment" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "minus5/-5%" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "minus10/-10%" ""
|
||||
<a href='ref-ppdcfile.html#Option'>Option</a> "fooMagentaAdjust/Magenta Adjustment"
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "plus10/+10%" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "plus5/+5%" ""
|
||||
*<a href='ref-ppdcfile.html#Choice'>Choice</a> "none/No Adjustment" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "minus5/-5%" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "minus10/-10%" ""
|
||||
<a href='ref-ppdcfile.html#Option'>Option</a> "fooYellowAdjust/Yellow Adjustment"
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "plus10/+10%" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "plus5/+5%" ""
|
||||
*<a href='ref-ppdcfile.html#Choice'>Choice</a> "none/No Adjustment" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "minus5/-5%" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "minus10/-10%" ""
|
||||
<a href='ref-ppdcfile.html#Option'>Option</a> "fooBlackAdjust/Black Adjustment"
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "plus10/+10%" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "plus5/+5%" ""
|
||||
*<a href='ref-ppdcfile.html#Choice'>Choice</a> "none/No Adjustment" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "minus5/-5%" ""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "minus10/-10%" ""
|
||||
<a href='ref-ppdcfile.html#_endif'>#endif</a>
|
||||
</pre>
|
||||
|
||||
|
||||
<h3><a name='CONSTRAINTS'>Defining Constraints</a></h3>
|
||||
|
||||
<P>Constraints are strings that are used to specify that one or more option
|
||||
choices are incompatible, for example two-sided printing on transparency media.
|
||||
Constraints are also used to prevent the use of uninstalled features such as the
|
||||
duplexer unit, additional media trays, and so forth.</P>
|
||||
|
||||
<P>The <TT>UIConstraints</TT> directive is used to specify a constraint that is
|
||||
placed in the PPD file. The directive is followed by a string using one of the
|
||||
following formats:</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*Option1 *Option2"
|
||||
<a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*Option1 Choice1 *Option2"
|
||||
<a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*Option1 *Option2 Choice2"
|
||||
<a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*Option1 Choice1 *Option2 Choice2"
|
||||
</pre>
|
||||
|
||||
<P>Each option name is preceded by the asterisk (<TT>*</TT>). If no choice is
|
||||
given for an option, then all choices <I>except</I> <TT>False</TT> and
|
||||
<TT>None</TT> will conflict with the other option and choice(s). Since the PPD
|
||||
compiler automatically adds reciprocal constraints (option A conflicts with
|
||||
option B, so therefore option B conflicts with option A), you need only specify
|
||||
the constraint once.</P>
|
||||
|
||||
<p class='example'><a name="LISTING5">Listing 5: "examples/constraint.drv"</a></p>
|
||||
|
||||
<pre class='example'>
|
||||
|
||||
<I>// Include standard font and media definitions</I>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <font.defs>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <media.defs>
|
||||
|
||||
<I>// List the fonts that are supported, in this case all standard fonts...</I>
|
||||
<a href='ref-ppdcfile.html#Font'>Font</a> *
|
||||
|
||||
<I>// Manufacturer, model name, and version</I>
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "Foo"
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "FooJet 2000"
|
||||
<a href='ref-ppdcfile.html#Version'>Version</a> 1.0
|
||||
|
||||
<I>// Each filter provided by the driver...</I>
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-raster 100 rastertofoo
|
||||
|
||||
<I>// Supported page sizes</I>
|
||||
*<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Letter
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A4
|
||||
|
||||
<I>// Supported resolutions</I>
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> k 8 0 0 0 "600dpi/600 DPI"
|
||||
|
||||
<I>// Installable Option Group</I>
|
||||
<a href='ref-ppdcfile.html#Group'>Group</a> "InstallableOptions/Options Installed"
|
||||
|
||||
<I>// Duplexing unit option</I>
|
||||
<a href='ref-ppdcfile.html#Option'>Option</a> "OptionDuplexer/Duplexing Unit" Boolean AnySetup 10
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> True/Installed ""
|
||||
*<a href='ref-ppdcfile.html#Choice'>Choice</a> "False/Not Installed" ""
|
||||
|
||||
<I>// General Option Group</I>
|
||||
<a href='ref-ppdcfile.html#Group'>Group</a> General
|
||||
|
||||
<I>// Duplexing option</I>
|
||||
<a href='ref-ppdcfile.html#Option'>Option</a> "Duplex/Two-Sided Printing" PickOne AnySetup 10
|
||||
*<a href='ref-ppdcfile.html#Choice'>Choice</a> "None/No" "<</Duplex false>>setpagedevice""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "DuplexNoTumble/Long Edge Binding"
|
||||
"<</Duplex true/Tumble false>>setpagedevice""
|
||||
<a href='ref-ppdcfile.html#Choice'>Choice</a> "DuplexTumble/Short Edge Binding"
|
||||
"<</Duplex true/Tumble true>>setpagedevice""
|
||||
|
||||
<I>// Only allow duplexing if the duplexer is installed</I>
|
||||
<a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*Duplex *OptionDuplexer False"
|
||||
|
||||
<I>// Specify the name of the PPD file we want to generate...</I>
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "foojet2k.ppd"
|
||||
</pre>
|
||||
|
||||
<P><A HREF="#LISTING5">Listing 5</A> shows a variation of the first example with
|
||||
an added <TT>Duplex</TT> option and installable option for the duplexer,
|
||||
<TT>OptionDuplex</TT>. A constraint is added at the end to specify that any
|
||||
choice of the <TT>Duplex</TT> option that is not <TT>None</TT> is incompatible
|
||||
with the "Duplexer Installed" option set to "Not Installed"
|
||||
(<TT>False</TT>):</P>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*Duplex *OptionDuplexer False"
|
||||
</pre>
|
||||
|
||||
<h4>Enhanced Constraints</h4>
|
||||
|
||||
<p>CUPS 1.4 supports constraints between 2 or more options using the
|
||||
<TT>Attribute</TT> directive. <TT>cupsUIConstraints</TT> attributes define
|
||||
the constraints, while <TT>cupsUIResolver</TT> attributes define option changes
|
||||
to resolve constraints. For example, we can specify the previous duplex
|
||||
constraint with a resolver that turns off duplexing with the following two
|
||||
lines:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsUIConstraints DuplexOff "*Duplex *OptionDuplexer False"
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsUIResolver DuplexOff "*Duplex None"
|
||||
</pre>
|
||||
|
||||
<h2 class='title'><a name='LOCALIZATION'>Localization</a></h2>
|
||||
|
||||
<p>The PPD compiler provides localization of PPD files in different languages
|
||||
through <i>message catalog</i> files in the GNU gettext or Apple .strings
|
||||
formats. Each user text string and several key PPD attribute values such as
|
||||
<tt>LanguageVersion</tt> and <tt>LanguageEncoding</tt> are looked up in the
|
||||
corresponding message catalog and the translated text is substituted in the
|
||||
generated PPD files. One message catalog file can be used by multiple driver
|
||||
information files, and each file contains a single language translation.</p>
|
||||
|
||||
<h3><a name='PPDPO'>The ppdpo Utility</a></h3>
|
||||
|
||||
<p>While CUPS includes localizations of all standard media sizes and options in
|
||||
several languages, your driver information files may provide their own media
|
||||
sizes and options that need to be localized. CUPS provides a utility program to
|
||||
aid in the localization of drivers called <a
|
||||
href='man-ppdpo.html'><tt>ppdpo(1)</tt></a>. The <tt>ppdpo</tt> program creates
|
||||
or updates a message catalog file based upon one or more driver information
|
||||
files. New messages are added with the word "TRANSLATE" added to the front of
|
||||
the translation string to make locating new strings for translation easier. The
|
||||
program accepts the message catalog filename and one or more driver information
|
||||
files.</p>
|
||||
|
||||
<p>For example, run the following command to create a new German message catalog
|
||||
called <var>de.po</var> for all of the driver information files in the current
|
||||
directory:</p>
|
||||
|
||||
<pre class='command'>
|
||||
ppdpo -o de.po *.drv
|
||||
</pre>
|
||||
|
||||
<p>If the file <var>de.po</var> already exists, <tt>ppdpo</tt> will update the
|
||||
contents of the file with any new messages that need to be translated. To create
|
||||
an Apple .strings file instead, specify the output filename with a .strings
|
||||
extension, for example:</p>
|
||||
|
||||
<pre class='command'>
|
||||
ppdpo -o de.strings *.drv
|
||||
</pre>
|
||||
|
||||
<h3><a name='PPDC_CATALOG'>Using Message Catalogs with the PPD Compiler</a></h3>
|
||||
|
||||
<p>Once you have created a message catalog, use the <a
|
||||
href='ref-ppdcfile.html#_po'><tt>#po</tt></a> directive to declare it in each
|
||||
driver information file. For example, to declare the German message catalog for
|
||||
a driver use:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#_po'>#po</a> de "de.po" // German
|
||||
</pre>
|
||||
|
||||
<p>In fact, you can use the <tt>#po</tt> directive as many times as needed:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#_po'>#po</a> de "de.po" // German
|
||||
<a href='ref-ppdcfile.html#_po'>#po</a> es "es.po" // Spanish
|
||||
<a href='ref-ppdcfile.html#_po'>#po</a> fr "fr.po" // French
|
||||
<a href='ref-ppdcfile.html#_po'>#po</a> it "it.po" // Italian
|
||||
<a href='ref-ppdcfile.html#_po'>#po</a> ja "ja.po" // Japanese
|
||||
</pre>
|
||||
|
||||
<p>The filename ("de.po", etc.) can be relative to the location of the driver
|
||||
information file or an absolute path. Once defined, the PPD compiler will
|
||||
automatically generate a globalized PPD for every language declared in your
|
||||
driver information file. To generate a single-language PPD file, simply use the
|
||||
<tt>-l</tt> option to list the corresponding locale, for example:</p>
|
||||
|
||||
<pre class='command'>
|
||||
ppdc -l de -d ppd/de mydrivers.drv
|
||||
</pre>
|
||||
|
||||
<p>to generate German PPD files.</p>
|
||||
3433
filter/pstops.c
Normal file
3433
filter/pstops.c
Normal file
File diff suppressed because it is too large
Load Diff
32
filter/raster-driver.header
Normal file
32
filter/raster-driver.header
Normal file
@@ -0,0 +1,32 @@
|
||||
<!--
|
||||
"$Id$"
|
||||
|
||||
Raster printer driver documentation for CUPS.
|
||||
|
||||
Copyright 2007-2012 by Apple Inc.
|
||||
Copyright 1997-2007 by Easy Software Products.
|
||||
|
||||
These coded instructions, statements, and computer programs are the
|
||||
property of Apple Inc. and are protected by Federal copyright
|
||||
law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
which should have been included with this file. If this file is
|
||||
file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
-->
|
||||
|
||||
<h1 class='title'>Developing Raster Printer Drivers</h1>
|
||||
|
||||
<p>This document describes how to develop printer drivers for raster printers. Topics include: <a href='#BASICS'>printer driver basics</a>, <a href='#CREATE'>creating new PPD files</a>, <a href='#FILTERS'>using filters</a>, <a href='#COLOR'>implementing color management</a>, and <a href='#MACOSX'>adding OS X features</a>.</p>
|
||||
|
||||
<div class='summary'><table summary='General Information'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>See Also</th>
|
||||
<td>Programming: <a href='postscript-driver.html'>Developing PostScript Printer Drivers</a><br>
|
||||
Programming: <a href='api-filter.html'>Filter and Backend Programming</a><br>
|
||||
Programming: <a href='ppd-compiler.html'>Introduction to the PPD Compiler</a><br>
|
||||
Programming: <a href='api-raster.html'>Raster API</a><br>
|
||||
References: <a href='ref-ppdcfile.html'>PPD Compiler Driver Information File Reference</a><br>
|
||||
Specifications: <a href='spec-ppd.html'>CUPS PPD Extensions</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
194
filter/raster-driver.shtml
Normal file
194
filter/raster-driver.shtml
Normal file
@@ -0,0 +1,194 @@
|
||||
<h2 class='title'><a name='BASICS'>Printer Driver Basics</a></h2>
|
||||
|
||||
<p>A CUPS raster printer driver consists of a PostScript Printer Description (PPD) file that describes the features and capabilities of the device, one or more <em>filter</em> programs that prepare print data for the device, and zero or more support files for color management, online help, and so forth. The PPD file includes references to all of the filters and support files used by the driver.</p>
|
||||
|
||||
<p>Every time a user prints something the scheduler program, <a href='man-cupsd.html'>cupsd(8)</a>, determines the format of the print job and the programs required to convert that job into something the printer understands. CUPS includes filter programs for many common formats, for example to convert Portable Document Format (PDF) files into CUPS raster data. <a href='#FIGURE_1'>Figure 1</a> shows the data flow of a typical print job.</p>
|
||||
|
||||
<div class='figure'><table summary='Raster Filter Chain'>
|
||||
<caption>Figure 1: <a name='FIGURE_1'>Raster Filter Chain</a></caption>
|
||||
<tr><td><img src='../images/cups-raster-chain.png' width='700' height='150' alt='Raster Filter Chain'></td></tr>
|
||||
</table></div>
|
||||
|
||||
<p>The raster filter converts CUPS raster data into a format the printer understands, for example HP-PCL. CUPS includes several sample raster filters supporting standard page description languages (PDLs). <a href='#TABLE_1'>Table 1</a> shows the raster filters that are bundled with CUPS and the languages they support.</p>
|
||||
|
||||
<div class='table'><table summary='Standard CUPS Raster Filters'>
|
||||
<caption>Table 1: <a name='TABLE_1'>Standard CUPS Raster Filters</a></caption>
|
||||
<thead>
|
||||
<tr><th>Filter</th><th>PDLs</th><th>ppdc DriverType</th><th>ppdc #include file</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>rastertoepson</td><td>ESC/P, ESC/P2</td><td>epson</td><td>epson.h</td></tr>
|
||||
<tr><td>rastertoescpx</td><td>ESC/P, ESC/P2, EPSON Remote Mode</td><td>escp</td><td>escp.h</td></tr>
|
||||
<tr><td>rastertohp</td><td>HP-PCL3, HP-PCL5</td><td>hp</td><td>hp.h</td></tr>
|
||||
<tr><td>rastertolabel</td><td>CPCL, Dymo, EPL1, EPL2, Intellitech PCL, ZPL</td><td>label</td><td>label.h</td></tr>
|
||||
<tr><td>rastertopclx</td><td>HP-RTL, HP-PCL3, HP-PCL3GUI, HP-PCL5, HP-PCL5c, HP-PCL5e</td><td>pcl</td><td>pcl.h</td></tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
|
||||
<p>The optional port monitor handles interface-specific protocol or encoding issues. For example, some raster printers use the 1284.4 communications protocol.</p>
|
||||
|
||||
<p>The backend handles communications with the printer, sending print data from the last filter to the printer and relaying back-channel data from the printer to the upstream filters. CUPS includes backend programs for common direct-connect interfaces and network protocols, and you can provide your own backend to support custom interfaces and protocols.</p>
|
||||
|
||||
<p>The scheduler also supports a special "command" file format for sending maintenance commands and status queries to a printer or printer driver. Command print jobs typically use a single command filter program defined in the PPD file to generate the appropriate printer commands and handle any responses from the printer. <a href='#FIGURE_2'>Figure 2</a> shows the data flow of a typical command job.</p>
|
||||
|
||||
<div class='figure'><table summary='Command Filter Chain'>
|
||||
<caption>Figure 2: <a name='FIGURE_2'>Command Filter Chain</a></caption>
|
||||
<tr><td><img src='../images/cups-command-chain.png' width='575' height='150' alt='Command Filter Chain'></td></tr>
|
||||
</table></div>
|
||||
|
||||
<p>Raster printer drivers must provide their own command filter.</p>
|
||||
|
||||
|
||||
<h2 class='title'><a name='CREATING'>Creating New PPD Files</a></h2>
|
||||
|
||||
<p>We recommend using the CUPS PPD compiler, <a href='man-ppdc.html'>ppdc(1)</a>, to create new PPD files since it manages many of the tedious (and error-prone!) details of paper sizes and localization for you. It also allows you to easily support multiple devices from a single source file. For more information see the "<a href='ppd-compiler.html'>Introduction to the PPD Compiler</a>" document. <a href='#LISTING_1'>Listing 1</a> shows a driver information file for several similar black-and-white HP-PCL5 laser printers.</p>
|
||||
|
||||
<p class='example'>Listing 1: <a name='LISTING_1'>"examples/laserjet-basic.drv"</a></p>
|
||||
|
||||
<pre class='example'>
|
||||
<I>// Include standard font and media definitions</I>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <font.defs>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <media.defs>
|
||||
|
||||
<I>// Include HP-PCL driver definitions</I>
|
||||
<a href='ref-ppdcfile.html#_include'>#include</a> <pcl.h>
|
||||
|
||||
<I>// Specify that this driver uses the HP-PCL driver...</I>
|
||||
<a href='ref-ppdcfile.html#DriverType'>DriverType</a> pcl
|
||||
|
||||
<I>// Specify the driver options via the model number...</I>
|
||||
<a href='ref-ppdcfile.html#ModelNumber'>ModelNumber</a> ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)
|
||||
|
||||
<I>// List the fonts that are supported, in this case all standard fonts...</I>
|
||||
<a href='ref-ppdcfile.html#Font'>Font</a> *
|
||||
|
||||
<I>// Manufacturer and driver version</I>
|
||||
<a href='ref-ppdcfile.html#Manufacturer'>Manufacturer</a> "HP"
|
||||
<a href='ref-ppdcfile.html#Version'>Version</a> 1.0
|
||||
|
||||
<I>// Supported page sizes and their margins</I>
|
||||
<a href='ref-ppdcfile.html#HWMargins'>HWMargins</a> 18 12 18 12
|
||||
*<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Letter
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Legal
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Executive
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Monarch
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Statement
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> FanFoldGermanLegal
|
||||
|
||||
<a href='ref-ppdcfile.html#HWMargins'>HWMargins</a> 18 12.72 18 12.72
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Env10
|
||||
|
||||
<a href='ref-ppdcfile.html#HWMargins'>HWMargins</a> 9.72 12 9.72 12
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A4
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> A5
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> B5
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> EnvC5
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> EnvDL
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> EnvISOB5
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> Postcard
|
||||
<a href='ref-ppdcfile.html#MediaSize'>MediaSize</a> DoublePostcard
|
||||
|
||||
<I>// Only black-and-white output with mode 3 compression...</I>
|
||||
<a href='ref-ppdcfile.html#ColorModel'>ColorModel</a> Gray k chunky 3
|
||||
|
||||
<I>// Supported resolutions</I>
|
||||
<a href='ref-ppdcfile.html#Resolution'>Resolution</a> - 1 0 0 0 "300dpi/300 DPI"
|
||||
*<a href='ref-ppdcfile.html#Resolution'>Resolution</a> - 8 0 0 0 "600dpi/600 DPI"
|
||||
|
||||
<I>// Supported input slots</I>
|
||||
*<a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 7 "Auto/Automatic Selection"
|
||||
<a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 2 "Manual/Tray 1 - Manual Feed"
|
||||
<a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 4 "Upper/Tray 1"
|
||||
<a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 1 "Lower/Tray 2"
|
||||
<a href='ref-ppdcfile.html#InputSlot'>InputSlot</a> 5 "LargeCapacity/Tray 3"
|
||||
|
||||
<I>// Tray 3 is an option...</I>
|
||||
<a href='ref-ppdcfile.html#Installable'>Installable</a> "OptionLargeCapacity/Tray 3 Installed"
|
||||
<a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*OptionLargeCapacity False *InputSlot LargeCapacity"
|
||||
|
||||
{
|
||||
<I>// HP LaserJet 2100 Series</I>
|
||||
<a href='ref-ppdcfile.html#Throughput'>Throughput</a> 10
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "LaserJet 2100 Series"
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "hpljt211.ppd"
|
||||
}
|
||||
|
||||
{
|
||||
<I>// LaserJet 2200 and 2300 series have duplexer option...</I>
|
||||
<a href='ref-ppdcfile.html#Duplex'>Duplex</a> normal
|
||||
<a href='ref-ppdcfile.html#Installable'>Installable</a> "OptionDuplex/Duplexer Installed"
|
||||
<a href='ref-ppdcfile.html#UIConstraints'>UIConstraints</a> "*OptionDuplex False *Duplex"
|
||||
|
||||
{
|
||||
<I>// HP LaserJet 2200 Series</I>
|
||||
<a href='ref-ppdcfile.html#Throughput'>Throughput</a> 19
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "LaserJet 2200 Series"
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "hpljt221.ppd"
|
||||
}
|
||||
|
||||
{
|
||||
<I>// HP LaserJet 2300 Series</I>
|
||||
<a href='ref-ppdcfile.html#Throughput'>Throughput</a> 25
|
||||
<a href='ref-ppdcfile.html#ModelName'>ModelName</a> "LaserJet 2300 Series"
|
||||
<a href='ref-ppdcfile.html#PCFileName'>PCFileName</a> "hpljt231.ppd"
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<h2 class='title'><a name='FILTERS'>Using Filters</a></h2>
|
||||
|
||||
<p>The standard CUPS raster filters can be specified using the
|
||||
<a href='ref-ppdcfile.html#DriverType'><tt>DriverType</tt></a> directive, for example:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<I>// Specify that this driver uses the HP-PCL driver...</I>
|
||||
<a href='ref-ppdcfile.html#DriverType'>DriverType</a> pcl
|
||||
</pre>
|
||||
|
||||
<p><a href='#TABLE_1'>Table 1</a> shows the driver types for each of the standard CUPS raster filters. For drivers that do not use the standard raster filters, the "custom" type is used with <a href='ref-ppdcfile.html#Filter'><tt>Filter</tt></a> directives:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#DriverType'>DriverType</a> custom
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-raster 100 /path/to/raster/filter
|
||||
<a href='ref-ppdcfile.html#Filter'>Filter</a> application/vnd.cups-command 100 /path/to/command/filter
|
||||
</pre>
|
||||
|
||||
|
||||
<h2 class='title'><a name='COLOR'>Implementing Color Management</a></h2>
|
||||
|
||||
<p>CUPS uses ICC color profiles to provide more accurate color reproduction. The <a href='spec-ppd.html#cupsICCProfile'><tt>cupsICCProfile</tt></a> attribute defines the color profiles that are available for a given printer, for example:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsICCProfile "ColorModel.MediaType.Resolution/Description" /path/to/ICC/profile
|
||||
</pre>
|
||||
|
||||
<p>where "ColorModel.MediaType.Resolution" defines a selector based on the corresponding option selections. A simple driver might only define profiles for the color models that are supported, for example a printer supporting Gray and RGB might use:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsICCProfile "Gray../Grayscale Profile" /path/to/ICC/gray-profile
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> cupsICCProfile "RGB../Full Color Profile" /path/to/ICC/rgb-profile
|
||||
</pre>
|
||||
|
||||
<p>The options used for profile selection can be customized using the <tt>cupsICCQualifier2</tt> and <tt>cupsICCQualifier3</tt> attributes.</p>
|
||||
|
||||
<h3><span class='info'>Since OS X 10.5</span>Custom Color Matching Support</h3>
|
||||
|
||||
<p>OS X printer drivers that are based on an existing standard RGB colorspace can tell the system to use the corresponding colorspace instead of an arbitrary ICC color profile when doing color management. The <a href='#APCustom'><tt>APSupportsCustomColorMatching</tt></a> and <tt>APDefaultCustomColorMatchingProfile</tt> attributes can be used to enable this mode:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APSupportsCustomColorMatching "" true
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APDefaultCustomColorMatchingProfile "" sRGB
|
||||
</pre>
|
||||
|
||||
|
||||
<h2 class='title'><a name='MACOSX'>Adding OS X Features</a></h2>
|
||||
|
||||
<p>OS X printer drivers can provide <a href='spec-ppd.html#MACOSX'>additional attributes</a> to specify additional option panes in the print dialog, an image of the printer, a help book, and option presets for the driver software:</p>
|
||||
|
||||
<pre class='example'>
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APDialogExtension "" /Library/Printers/Vendor/filename.plugin
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APHelpBook "" /Library/Printers/Vendor/filename.bundle
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APPrinterIconPath "" /Library/Printers/Vendor/filename.icns
|
||||
<a href='ref-ppdcfile.html#Attribute'>Attribute</a> APPrinterPreset "name/text" "*option choice ..."
|
||||
</pre>
|
||||
1479
filter/raster.c
Normal file
1479
filter/raster.c
Normal file
File diff suppressed because it is too large
Load Diff
355
filter/rasterbench.c
Normal file
355
filter/rasterbench.c
Normal file
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* "$Id: rasterbench.c 7376 2008-03-19 21:07:45Z mike $"
|
||||
*
|
||||
* Raster benchmark program for CUPS.
|
||||
*
|
||||
* Copyright 2007-2011 by Apple Inc.
|
||||
* Copyright 1997-2006 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Apple Inc. and are protected by Federal copyright
|
||||
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
* which should have been included with this file. If this file is
|
||||
* file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
*
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* main() - Benchmark the raster read/write functions.
|
||||
* compute_median() - Compute the median time for a test.
|
||||
* read_test() - Benchmark the raster read functions.
|
||||
* write_test() - Benchmark the raster write functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <cups/raster.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
||||
/*
|
||||
* Constants...
|
||||
*/
|
||||
|
||||
#define TEST_WIDTH 1024
|
||||
#define TEST_HEIGHT 1024
|
||||
#define TEST_PAGES 16
|
||||
#define TEST_PASSES 20
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
static double compute_median(double *secs);
|
||||
static double get_time(void);
|
||||
static void read_test(int fd);
|
||||
static int run_read_test(void);
|
||||
static void write_test(int fd, cups_mode_t mode);
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Benchmark the raster read/write functions.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line args */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
int ras_fd, /* File descriptor for read process */
|
||||
status; /* Exit status of read process */
|
||||
double start_secs, /* Start time */
|
||||
write_secs, /* Write time */
|
||||
read_secs, /* Read time */
|
||||
pass_secs[TEST_PASSES]; /* Total test times */
|
||||
cups_mode_t mode; /* Write mode */
|
||||
|
||||
|
||||
/*
|
||||
* See if we have anything on the command-line...
|
||||
*/
|
||||
|
||||
if (argc > 2 || (argc == 2 && strcmp(argv[1], "-z")))
|
||||
{
|
||||
puts("Usage: rasterbench [-z]");
|
||||
return (1);
|
||||
}
|
||||
|
||||
mode = argc > 1 ? CUPS_RASTER_WRITE_COMPRESSED : CUPS_RASTER_WRITE;
|
||||
|
||||
/*
|
||||
* Ignore SIGPIPE...
|
||||
*/
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
/*
|
||||
* Run the tests several times to get a good average...
|
||||
*/
|
||||
|
||||
printf("Test read/write speed of %d pages, %dx%d pixels...\n\n",
|
||||
TEST_PAGES, TEST_WIDTH, TEST_HEIGHT);
|
||||
for (i = 0; i < TEST_PASSES; i ++)
|
||||
{
|
||||
printf("PASS %2d: ", i + 1);
|
||||
fflush(stdout);
|
||||
|
||||
ras_fd = run_read_test();
|
||||
start_secs = get_time();
|
||||
|
||||
write_test(ras_fd, mode);
|
||||
|
||||
write_secs = get_time();
|
||||
printf(" %.3f write,", write_secs - start_secs);
|
||||
fflush(stdout);
|
||||
|
||||
close(ras_fd);
|
||||
wait(&status);
|
||||
|
||||
read_secs = get_time();
|
||||
pass_secs[i] = read_secs - start_secs;
|
||||
printf(" %.3f read, %.3f total\n", read_secs - write_secs, pass_secs[i]);
|
||||
}
|
||||
|
||||
printf("\nMedian Total Time: %.3f seconds per document\n",
|
||||
compute_median(pass_secs));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'compute_median()' - Compute the median time for a test.
|
||||
*/
|
||||
|
||||
static double /* O - Median time in seconds */
|
||||
compute_median(double *secs) /* I - Array of time samples */
|
||||
{
|
||||
int i, j; /* Looping vars */
|
||||
double temp; /* Swap variable */
|
||||
|
||||
|
||||
/*
|
||||
* Sort the array into ascending order using a quicky bubble sort...
|
||||
*/
|
||||
|
||||
for (i = 0; i < (TEST_PASSES - 1); i ++)
|
||||
for (j = i + 1; j < TEST_PASSES; j ++)
|
||||
if (secs[i] > secs[j])
|
||||
{
|
||||
temp = secs[i];
|
||||
secs[i] = secs[j];
|
||||
secs[j] = temp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the average of the middle two samples...
|
||||
*/
|
||||
|
||||
return (0.5 * (secs[TEST_PASSES / 2 - 1] + secs[TEST_PASSES / 2]));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'get_time()' - Get the current time in seconds.
|
||||
*/
|
||||
|
||||
static double /* O - Time in seconds */
|
||||
get_time(void)
|
||||
{
|
||||
struct timeval curtime; /* Current time */
|
||||
|
||||
|
||||
gettimeofday(&curtime, NULL);
|
||||
return (curtime.tv_sec + 0.000001 * curtime.tv_usec);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'read_test()' - Benchmark the raster read functions.
|
||||
*/
|
||||
|
||||
static void
|
||||
read_test(int fd) /* I - File descriptor to read from */
|
||||
{
|
||||
int y; /* Looping var */
|
||||
cups_raster_t *r; /* Raster stream */
|
||||
cups_page_header2_t header; /* Page header */
|
||||
unsigned char buffer[8 * TEST_WIDTH];
|
||||
/* Read buffer */
|
||||
|
||||
|
||||
/*
|
||||
* Test read speed...
|
||||
*/
|
||||
|
||||
if ((r = cupsRasterOpen(fd, CUPS_RASTER_READ)) == NULL)
|
||||
{
|
||||
perror("Unable to create raster input stream");
|
||||
return;
|
||||
}
|
||||
|
||||
while (cupsRasterReadHeader2(r, &header))
|
||||
{
|
||||
for (y = 0; y < header.cupsHeight; y ++)
|
||||
cupsRasterReadPixels(r, buffer, header.cupsBytesPerLine);
|
||||
}
|
||||
|
||||
cupsRasterClose(r);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'run_read_test()' - Run the read test as a child process via pipes.
|
||||
*/
|
||||
|
||||
static int /* O - Standard input of child */
|
||||
run_read_test(void)
|
||||
{
|
||||
int ras_pipes[2]; /* Raster data pipes */
|
||||
int pid; /* Child process ID */
|
||||
|
||||
|
||||
if (pipe(ras_pipes))
|
||||
return (-1);
|
||||
|
||||
if ((pid = fork()) < 0)
|
||||
{
|
||||
/*
|
||||
* Fork error - return -1 on error...
|
||||
*/
|
||||
|
||||
close(ras_pipes[0]);
|
||||
close(ras_pipes[1]);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
else if (pid == 0)
|
||||
{
|
||||
/*
|
||||
* Child comes here - read data from the input pipe...
|
||||
*/
|
||||
|
||||
close(ras_pipes[1]);
|
||||
read_test(ras_pipes[0]);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Parent comes here - return the output pipe...
|
||||
*/
|
||||
|
||||
close(ras_pipes[0]);
|
||||
return (ras_pipes[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'write_test()' - Benchmark the raster write functions.
|
||||
*/
|
||||
|
||||
static void
|
||||
write_test(int fd, /* I - File descriptor to write to */
|
||||
cups_mode_t mode) /* I - Write mode */
|
||||
{
|
||||
int page, x, y; /* Looping vars */
|
||||
int count; /* Number of bytes to set */
|
||||
cups_raster_t *r; /* Raster stream */
|
||||
cups_page_header2_t header; /* Page header */
|
||||
unsigned char data[32][8 * TEST_WIDTH];
|
||||
/* Raster data to write */
|
||||
|
||||
|
||||
/*
|
||||
* Create a combination of random data and repeated data to simulate
|
||||
* text with some whitespace.
|
||||
*/
|
||||
|
||||
CUPS_SRAND(time(NULL));
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
|
||||
for (y = 0; y < 28; y ++)
|
||||
{
|
||||
for (x = CUPS_RAND() & 127, count = (CUPS_RAND() & 15) + 1;
|
||||
x < sizeof(data[0]);
|
||||
x ++, count --)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
x += (CUPS_RAND() & 15) + 1;
|
||||
count = (CUPS_RAND() & 15) + 1;
|
||||
|
||||
if (x >= sizeof(data[0]))
|
||||
break;
|
||||
}
|
||||
|
||||
data[y][x] = CUPS_RAND();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test write speed...
|
||||
*/
|
||||
|
||||
if ((r = cupsRasterOpen(fd, mode)) == NULL)
|
||||
{
|
||||
perror("Unable to create raster output stream");
|
||||
return;
|
||||
}
|
||||
|
||||
for (page = 0; page < TEST_PAGES; page ++)
|
||||
{
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.cupsWidth = TEST_WIDTH;
|
||||
header.cupsHeight = TEST_HEIGHT;
|
||||
header.cupsBytesPerLine = TEST_WIDTH;
|
||||
|
||||
if (page & 1)
|
||||
{
|
||||
header.cupsBytesPerLine *= 4;
|
||||
header.cupsColorSpace = CUPS_CSPACE_CMYK;
|
||||
header.cupsColorOrder = CUPS_ORDER_CHUNKED;
|
||||
}
|
||||
else
|
||||
{
|
||||
header.cupsColorSpace = CUPS_CSPACE_K;
|
||||
header.cupsColorOrder = CUPS_ORDER_BANDED;
|
||||
}
|
||||
|
||||
if (page & 2)
|
||||
{
|
||||
header.cupsBytesPerLine *= 2;
|
||||
header.cupsBitsPerColor = 16;
|
||||
header.cupsBitsPerPixel = (page & 1) ? 64 : 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
header.cupsBitsPerColor = 8;
|
||||
header.cupsBitsPerPixel = (page & 1) ? 32 : 8;
|
||||
}
|
||||
|
||||
cupsRasterWriteHeader2(r, &header);
|
||||
|
||||
for (y = 0; y < TEST_HEIGHT; y ++)
|
||||
cupsRasterWritePixels(r, data[y & 31], header.cupsBytesPerLine);
|
||||
}
|
||||
|
||||
cupsRasterClose(r);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: rasterbench.c 7376 2008-03-19 21:07:45Z mike $".
|
||||
*/
|
||||
1157
filter/rastertoepson.c
Normal file
1157
filter/rastertoepson.c
Normal file
File diff suppressed because it is too large
Load Diff
886
filter/rastertohp.c
Normal file
886
filter/rastertohp.c
Normal file
@@ -0,0 +1,886 @@
|
||||
/*
|
||||
* "$Id: rastertohp.c 7834 2008-08-04 21:02:09Z mike $"
|
||||
*
|
||||
* Hewlett-Packard Page Control Language filter for CUPS.
|
||||
*
|
||||
* Copyright 2007-2012 by Apple Inc.
|
||||
* Copyright 1993-2007 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Apple Inc. and are protected by Federal copyright
|
||||
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
* which should have been included with this file. If this file is
|
||||
* file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
*
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* Setup() - Prepare the printer for printing.
|
||||
* StartPage() - Start a page of graphics.
|
||||
* EndPage() - Finish a page of graphics.
|
||||
* Shutdown() - Shutdown the printer.
|
||||
* CancelJob() - Cancel the current job...
|
||||
* CompressData() - Compress a line of graphics.
|
||||
* OutputLine() - Output a line of graphics.
|
||||
* main() - Main entry and processing of driver.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <cups/cups.h>
|
||||
#include <cups/ppd.h>
|
||||
#include <cups/string-private.h>
|
||||
#include <cups/language-private.h>
|
||||
#include <cups/raster.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
|
||||
|
||||
/*
|
||||
* Globals...
|
||||
*/
|
||||
|
||||
unsigned char *Planes[4], /* Output buffers */
|
||||
*CompBuffer, /* Compression buffer */
|
||||
*BitBuffer; /* Buffer for output bits */
|
||||
int NumPlanes, /* Number of color planes */
|
||||
ColorBits, /* Number of bits per color */
|
||||
Feed, /* Number of lines to skip */
|
||||
Duplex, /* Current duplex mode */
|
||||
Page, /* Current page number */
|
||||
Canceled; /* Has the current job been canceled? */
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes...
|
||||
*/
|
||||
|
||||
void Setup(void);
|
||||
void StartPage(ppd_file_t *ppd, cups_page_header2_t *header);
|
||||
void EndPage(void);
|
||||
void Shutdown(void);
|
||||
|
||||
void CancelJob(int sig);
|
||||
void CompressData(unsigned char *line, int length, int plane, int type);
|
||||
void OutputLine(cups_page_header2_t *header);
|
||||
|
||||
|
||||
/*
|
||||
* 'Setup()' - Prepare the printer for printing.
|
||||
*/
|
||||
|
||||
void
|
||||
Setup(void)
|
||||
{
|
||||
/*
|
||||
* Send a PCL reset sequence.
|
||||
*/
|
||||
|
||||
putchar(0x1b);
|
||||
putchar('E');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'StartPage()' - Start a page of graphics.
|
||||
*/
|
||||
|
||||
void
|
||||
StartPage(ppd_file_t *ppd, /* I - PPD file */
|
||||
cups_page_header2_t *header) /* I - Page header */
|
||||
{
|
||||
int plane; /* Looping var */
|
||||
|
||||
|
||||
/*
|
||||
* Show page device dictionary...
|
||||
*/
|
||||
|
||||
fprintf(stderr, "DEBUG: StartPage...\n");
|
||||
fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass);
|
||||
fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor);
|
||||
fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType);
|
||||
fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType);
|
||||
|
||||
fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance);
|
||||
fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia);
|
||||
fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate);
|
||||
fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia);
|
||||
fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex);
|
||||
fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0],
|
||||
header->HWResolution[1]);
|
||||
fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
|
||||
header->ImagingBoundingBox[0], header->ImagingBoundingBox[1],
|
||||
header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]);
|
||||
fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet);
|
||||
fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog);
|
||||
fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge);
|
||||
fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0],
|
||||
header->Margins[1]);
|
||||
fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed);
|
||||
fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition);
|
||||
fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight);
|
||||
fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint);
|
||||
fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint);
|
||||
fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies);
|
||||
fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation);
|
||||
fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp);
|
||||
fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0],
|
||||
header->PageSize[1]);
|
||||
fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations);
|
||||
fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch);
|
||||
fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble);
|
||||
fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth);
|
||||
fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight);
|
||||
fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType);
|
||||
fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor);
|
||||
fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel);
|
||||
fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine);
|
||||
fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder);
|
||||
fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace);
|
||||
fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression);
|
||||
|
||||
/*
|
||||
* Setup printer/job attributes...
|
||||
*/
|
||||
|
||||
Duplex = header->Duplex;
|
||||
ColorBits = header->cupsBitsPerColor;
|
||||
|
||||
if ((!Duplex || (Page & 1)) && header->MediaPosition)
|
||||
printf("\033&l%dH", /* Set media position */
|
||||
header->MediaPosition);
|
||||
|
||||
if (Duplex && ppd && ppd->model_number == 2)
|
||||
{
|
||||
/*
|
||||
* Handle duplexing on new DeskJet printers...
|
||||
*/
|
||||
|
||||
printf("\033&l-2H"); /* Load media */
|
||||
|
||||
if (Page & 1)
|
||||
printf("\033&l2S"); /* Set duplex mode */
|
||||
}
|
||||
|
||||
if (!Duplex || (Page & 1) || (ppd && ppd->model_number == 2))
|
||||
{
|
||||
/*
|
||||
* Set the media size...
|
||||
*/
|
||||
|
||||
printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */
|
||||
printf("\033&l0O"); /* Set portrait orientation */
|
||||
|
||||
switch (header->PageSize[1])
|
||||
{
|
||||
case 540 : /* Monarch Envelope */
|
||||
printf("\033&l80A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 595 : /* A5 */
|
||||
printf("\033&l25A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 624 : /* DL Envelope */
|
||||
printf("\033&l90A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 649 : /* C5 Envelope */
|
||||
printf("\033&l91A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 684 : /* COM-10 Envelope */
|
||||
printf("\033&l81A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 709 : /* B5 Envelope */
|
||||
printf("\033&l100A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 756 : /* Executive */
|
||||
printf("\033&l1A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 792 : /* Letter */
|
||||
printf("\033&l2A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 842 : /* A4 */
|
||||
printf("\033&l26A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 1008 : /* Legal */
|
||||
printf("\033&l3A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 1191 : /* A3 */
|
||||
printf("\033&l27A"); /* Set page size */
|
||||
break;
|
||||
|
||||
case 1224 : /* Tabloid */
|
||||
printf("\033&l6A"); /* Set page size */
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\033&l%dP", /* Set page length */
|
||||
header->PageSize[1] / 12);
|
||||
printf("\033&l0E"); /* Set top margin to 0 */
|
||||
}
|
||||
|
||||
if (!Duplex || (Page & 1))
|
||||
{
|
||||
/*
|
||||
* Set other job options...
|
||||
*/
|
||||
|
||||
printf("\033&l%dX", header->NumCopies); /* Set number copies */
|
||||
|
||||
if (header->cupsMediaType &&
|
||||
(!ppd || ppd->model_number != 2 || header->HWResolution[0] == 600))
|
||||
printf("\033&l%dM", /* Set media type */
|
||||
header->cupsMediaType);
|
||||
|
||||
if (!ppd || ppd->model_number != 2)
|
||||
{
|
||||
int mode = Duplex ? 1 + header->Tumble != 0 : 0;
|
||||
|
||||
printf("\033&l%dS", mode); /* Set duplex mode */
|
||||
printf("\033&l0L"); /* Turn off perforation skip */
|
||||
}
|
||||
}
|
||||
else if (!ppd || ppd->model_number != 2)
|
||||
printf("\033&a2G"); /* Set back side */
|
||||
|
||||
/*
|
||||
* Set graphics mode...
|
||||
*/
|
||||
|
||||
if (ppd && ppd->model_number == 2)
|
||||
{
|
||||
/*
|
||||
* Figure out the number of color planes...
|
||||
*/
|
||||
|
||||
if (header->cupsColorSpace == CUPS_CSPACE_KCMY)
|
||||
NumPlanes = 4;
|
||||
else
|
||||
NumPlanes = 1;
|
||||
|
||||
/*
|
||||
* Set the resolution and top-of-form...
|
||||
*/
|
||||
|
||||
printf("\033&u%dD", header->HWResolution[0]);
|
||||
/* Resolution */
|
||||
printf("\033&l0e0L"); /* Reset top and don't skip */
|
||||
printf("\033*p0Y\033*p0X"); /* Set top of form */
|
||||
|
||||
/*
|
||||
* Send 26-byte configure image data command with horizontal and
|
||||
* vertical resolutions as well as a color count...
|
||||
*/
|
||||
|
||||
printf("\033*g26W");
|
||||
putchar(2); /* Format 2 */
|
||||
putchar(NumPlanes); /* Output planes */
|
||||
|
||||
putchar(header->HWResolution[0] >> 8); /* Black resolution */
|
||||
putchar(header->HWResolution[0]);
|
||||
putchar(header->HWResolution[1] >> 8);
|
||||
putchar(header->HWResolution[1]);
|
||||
putchar(0);
|
||||
putchar(1 << ColorBits); /* # of black levels */
|
||||
|
||||
putchar(header->HWResolution[0] >> 8); /* Cyan resolution */
|
||||
putchar(header->HWResolution[0]);
|
||||
putchar(header->HWResolution[1] >> 8);
|
||||
putchar(header->HWResolution[1]);
|
||||
putchar(0);
|
||||
putchar(1 << ColorBits); /* # of cyan levels */
|
||||
|
||||
putchar(header->HWResolution[0] >> 8); /* Magenta resolution */
|
||||
putchar(header->HWResolution[0]);
|
||||
putchar(header->HWResolution[1] >> 8);
|
||||
putchar(header->HWResolution[1]);
|
||||
putchar(0);
|
||||
putchar(1 << ColorBits); /* # of magenta levels */
|
||||
|
||||
putchar(header->HWResolution[0] >> 8); /* Yellow resolution */
|
||||
putchar(header->HWResolution[0]);
|
||||
putchar(header->HWResolution[1] >> 8);
|
||||
putchar(header->HWResolution[1]);
|
||||
putchar(0);
|
||||
putchar(1 << ColorBits); /* # of yellow levels */
|
||||
|
||||
printf("\033&l0H"); /* Set media position */
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\033*t%dR", header->HWResolution[0]);
|
||||
/* Set resolution */
|
||||
|
||||
if (header->cupsColorSpace == CUPS_CSPACE_KCMY)
|
||||
{
|
||||
NumPlanes = 4;
|
||||
printf("\033*r-4U"); /* Set KCMY graphics */
|
||||
}
|
||||
else if (header->cupsColorSpace == CUPS_CSPACE_CMY)
|
||||
{
|
||||
NumPlanes = 3;
|
||||
printf("\033*r-3U"); /* Set CMY graphics */
|
||||
}
|
||||
else
|
||||
NumPlanes = 1; /* Black&white graphics */
|
||||
|
||||
/*
|
||||
* Set size and position of graphics...
|
||||
*/
|
||||
|
||||
printf("\033*r%dS", header->cupsWidth); /* Set width */
|
||||
printf("\033*r%dT", header->cupsHeight); /* Set height */
|
||||
|
||||
printf("\033&a0H"); /* Set horizontal position */
|
||||
|
||||
if (ppd)
|
||||
printf("\033&a%.0fV", /* Set vertical position */
|
||||
10.0 * (ppd->sizes[0].length - ppd->sizes[0].top));
|
||||
else
|
||||
printf("\033&a0V"); /* Set top-of-page */
|
||||
}
|
||||
|
||||
printf("\033*r1A"); /* Start graphics */
|
||||
|
||||
if (header->cupsCompression)
|
||||
printf("\033*b%dM", /* Set compression */
|
||||
header->cupsCompression);
|
||||
|
||||
Feed = 0; /* No blank lines yet */
|
||||
|
||||
/*
|
||||
* Allocate memory for a line of graphics...
|
||||
*/
|
||||
|
||||
if ((Planes[0] = malloc(header->cupsBytesPerLine)) == NULL)
|
||||
{
|
||||
fputs("ERROR: Unable to allocate memory\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (plane = 1; plane < NumPlanes; plane ++)
|
||||
Planes[plane] = Planes[0] + plane * header->cupsBytesPerLine / NumPlanes;
|
||||
|
||||
if (ColorBits > 1)
|
||||
BitBuffer = malloc(ColorBits * ((header->cupsWidth + 7) / 8));
|
||||
else
|
||||
BitBuffer = NULL;
|
||||
|
||||
if (header->cupsCompression)
|
||||
CompBuffer = malloc(header->cupsBytesPerLine * 2);
|
||||
else
|
||||
CompBuffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'EndPage()' - Finish a page of graphics.
|
||||
*/
|
||||
|
||||
void
|
||||
EndPage(void)
|
||||
{
|
||||
/*
|
||||
* Eject the current page...
|
||||
*/
|
||||
|
||||
if (NumPlanes > 1)
|
||||
{
|
||||
printf("\033*rC"); /* End color GFX */
|
||||
|
||||
if (!(Duplex && (Page & 1)))
|
||||
printf("\033&l0H"); /* Eject current page */
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\033*r0B"); /* End GFX */
|
||||
|
||||
if (!(Duplex && (Page & 1)))
|
||||
printf("\014"); /* Eject current page */
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
/*
|
||||
* Free memory...
|
||||
*/
|
||||
|
||||
free(Planes[0]);
|
||||
|
||||
if (BitBuffer)
|
||||
free(BitBuffer);
|
||||
|
||||
if (CompBuffer)
|
||||
free(CompBuffer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'Shutdown()' - Shutdown the printer.
|
||||
*/
|
||||
|
||||
void
|
||||
Shutdown(void)
|
||||
{
|
||||
/*
|
||||
* Send a PCL reset sequence.
|
||||
*/
|
||||
|
||||
putchar(0x1b);
|
||||
putchar('E');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'CancelJob()' - Cancel the current job...
|
||||
*/
|
||||
|
||||
void
|
||||
CancelJob(int sig) /* I - Signal */
|
||||
{
|
||||
(void)sig;
|
||||
|
||||
Canceled = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'CompressData()' - Compress a line of graphics.
|
||||
*/
|
||||
|
||||
void
|
||||
CompressData(unsigned char *line, /* I - Data to compress */
|
||||
int length, /* I - Number of bytes */
|
||||
int plane, /* I - Color plane */
|
||||
int type) /* I - Type of compression */
|
||||
{
|
||||
unsigned char *line_ptr, /* Current byte pointer */
|
||||
*line_end, /* End-of-line byte pointer */
|
||||
*comp_ptr, /* Pointer into compression buffer */
|
||||
*start; /* Start of compression sequence */
|
||||
int count; /* Count of bytes for output */
|
||||
|
||||
|
||||
switch (type)
|
||||
{
|
||||
default :
|
||||
/*
|
||||
* Do no compression...
|
||||
*/
|
||||
|
||||
line_ptr = line;
|
||||
line_end = line + length;
|
||||
break;
|
||||
|
||||
case 1 :
|
||||
/*
|
||||
* Do run-length encoding...
|
||||
*/
|
||||
|
||||
line_end = line + length;
|
||||
for (line_ptr = line, comp_ptr = CompBuffer;
|
||||
line_ptr < line_end;
|
||||
comp_ptr += 2, line_ptr += count)
|
||||
{
|
||||
for (count = 1;
|
||||
(line_ptr + count) < line_end &&
|
||||
line_ptr[0] == line_ptr[count] &&
|
||||
count < 256;
|
||||
count ++);
|
||||
|
||||
comp_ptr[0] = count - 1;
|
||||
comp_ptr[1] = line_ptr[0];
|
||||
}
|
||||
|
||||
line_ptr = CompBuffer;
|
||||
line_end = comp_ptr;
|
||||
break;
|
||||
|
||||
case 2 :
|
||||
/*
|
||||
* Do TIFF pack-bits encoding...
|
||||
*/
|
||||
|
||||
line_ptr = line;
|
||||
line_end = line + length;
|
||||
comp_ptr = CompBuffer;
|
||||
|
||||
while (line_ptr < line_end)
|
||||
{
|
||||
if ((line_ptr + 1) >= line_end)
|
||||
{
|
||||
/*
|
||||
* Single byte on the end...
|
||||
*/
|
||||
|
||||
*comp_ptr++ = 0x00;
|
||||
*comp_ptr++ = *line_ptr++;
|
||||
}
|
||||
else if (line_ptr[0] == line_ptr[1])
|
||||
{
|
||||
/*
|
||||
* Repeated sequence...
|
||||
*/
|
||||
|
||||
line_ptr ++;
|
||||
count = 2;
|
||||
|
||||
while (line_ptr < (line_end - 1) &&
|
||||
line_ptr[0] == line_ptr[1] &&
|
||||
count < 127)
|
||||
{
|
||||
line_ptr ++;
|
||||
count ++;
|
||||
}
|
||||
|
||||
*comp_ptr++ = 257 - count;
|
||||
*comp_ptr++ = *line_ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Non-repeated sequence...
|
||||
*/
|
||||
|
||||
start = line_ptr;
|
||||
line_ptr ++;
|
||||
count = 1;
|
||||
|
||||
while (line_ptr < (line_end - 1) &&
|
||||
line_ptr[0] != line_ptr[1] &&
|
||||
count < 127)
|
||||
{
|
||||
line_ptr ++;
|
||||
count ++;
|
||||
}
|
||||
|
||||
*comp_ptr++ = count - 1;
|
||||
|
||||
memcpy(comp_ptr, start, count);
|
||||
comp_ptr += count;
|
||||
}
|
||||
}
|
||||
|
||||
line_ptr = CompBuffer;
|
||||
line_end = comp_ptr;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the length of the data and write a raster plane...
|
||||
*/
|
||||
|
||||
printf("\033*b%d%c", (int)(line_end - line_ptr), plane);
|
||||
fwrite(line_ptr, line_end - line_ptr, 1, stdout);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'OutputLine()' - Output a line of graphics.
|
||||
*/
|
||||
|
||||
void
|
||||
OutputLine(cups_page_header2_t *header) /* I - Page header */
|
||||
{
|
||||
int plane, /* Current plane */
|
||||
bytes, /* Bytes to write */
|
||||
count; /* Bytes to convert */
|
||||
unsigned char bit, /* Current plane data */
|
||||
bit0, /* Current low bit data */
|
||||
bit1, /* Current high bit data */
|
||||
*plane_ptr, /* Pointer into Planes */
|
||||
*bit_ptr; /* Pointer into BitBuffer */
|
||||
|
||||
|
||||
/*
|
||||
* Output whitespace as needed...
|
||||
*/
|
||||
|
||||
if (Feed > 0)
|
||||
{
|
||||
printf("\033*b%dY", Feed);
|
||||
Feed = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write bitmap data as needed...
|
||||
*/
|
||||
|
||||
bytes = (header->cupsWidth + 7) / 8;
|
||||
|
||||
for (plane = 0; plane < NumPlanes; plane ++)
|
||||
if (ColorBits == 1)
|
||||
{
|
||||
/*
|
||||
* Send bits as-is...
|
||||
*/
|
||||
|
||||
CompressData(Planes[plane], bytes, plane < (NumPlanes - 1) ? 'V' : 'W',
|
||||
header->cupsCompression);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Separate low and high bit data into separate buffers.
|
||||
*/
|
||||
|
||||
for (count = header->cupsBytesPerLine / NumPlanes,
|
||||
plane_ptr = Planes[plane], bit_ptr = BitBuffer;
|
||||
count > 0;
|
||||
count -= 2, plane_ptr += 2, bit_ptr ++)
|
||||
{
|
||||
bit = plane_ptr[0];
|
||||
|
||||
bit0 = ((bit & 64) << 1) | ((bit & 16) << 2) | ((bit & 4) << 3) | ((bit & 1) << 4);
|
||||
bit1 = (bit & 128) | ((bit & 32) << 1) | ((bit & 8) << 2) | ((bit & 2) << 3);
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
bit = plane_ptr[1];
|
||||
|
||||
bit0 |= (bit & 1) | ((bit & 4) >> 1) | ((bit & 16) >> 2) | ((bit & 64) >> 3);
|
||||
bit1 |= ((bit & 2) >> 1) | ((bit & 8) >> 2) | ((bit & 32) >> 3) | ((bit & 128) >> 4);
|
||||
}
|
||||
|
||||
bit_ptr[0] = bit0;
|
||||
bit_ptr[bytes] = bit1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send low and high bits...
|
||||
*/
|
||||
|
||||
CompressData(BitBuffer, bytes, 'V', header->cupsCompression);
|
||||
CompressData(BitBuffer + bytes, bytes, plane < (NumPlanes - 1) ? 'V' : 'W',
|
||||
header->cupsCompression);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Main entry and processing of driver.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
int fd; /* File descriptor */
|
||||
cups_raster_t *ras; /* Raster stream for printing */
|
||||
cups_page_header2_t header; /* Page header from file */
|
||||
int y; /* Current line */
|
||||
ppd_file_t *ppd; /* PPD file */
|
||||
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
|
||||
struct sigaction action; /* Actions for POSIX signals */
|
||||
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
|
||||
|
||||
|
||||
/*
|
||||
* Make sure status messages are not buffered...
|
||||
*/
|
||||
|
||||
setbuf(stderr, NULL);
|
||||
|
||||
/*
|
||||
* Check command-line...
|
||||
*/
|
||||
|
||||
if (argc < 6 || argc > 7)
|
||||
{
|
||||
/*
|
||||
* We don't have the correct number of arguments; write an error message
|
||||
* and return.
|
||||
*/
|
||||
|
||||
_cupsLangPrintFilter(stderr, "ERROR",
|
||||
_("%s job-id user title copies options [file]"),
|
||||
"rastertohp");
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the page stream...
|
||||
*/
|
||||
|
||||
if (argc == 7)
|
||||
{
|
||||
if ((fd = open(argv[6], O_RDONLY)) == -1)
|
||||
{
|
||||
_cupsLangPrintError("ERROR", _("Unable to open raster file"));
|
||||
sleep(1);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
fd = 0;
|
||||
|
||||
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
|
||||
|
||||
/*
|
||||
* Register a signal handler to eject the current page if the
|
||||
* job is cancelled.
|
||||
*/
|
||||
|
||||
Canceled = 0;
|
||||
|
||||
#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
|
||||
sigset(SIGTERM, CancelJob);
|
||||
#elif defined(HAVE_SIGACTION)
|
||||
memset(&action, 0, sizeof(action));
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_handler = CancelJob;
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
#else
|
||||
signal(SIGTERM, CancelJob);
|
||||
#endif /* HAVE_SIGSET */
|
||||
|
||||
/*
|
||||
* Initialize the print device...
|
||||
*/
|
||||
|
||||
ppd = ppdOpenFile(getenv("PPD"));
|
||||
if (!ppd)
|
||||
{
|
||||
ppd_status_t status; /* PPD error */
|
||||
int linenum; /* Line number */
|
||||
|
||||
_cupsLangPrintFilter(stderr, "ERROR",
|
||||
_("The PPD file could not be opened."));
|
||||
|
||||
status = ppdLastError(&linenum);
|
||||
|
||||
fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
Setup();
|
||||
|
||||
/*
|
||||
* Process pages as needed...
|
||||
*/
|
||||
|
||||
Page = 0;
|
||||
|
||||
while (cupsRasterReadHeader2(ras, &header))
|
||||
{
|
||||
/*
|
||||
* Write a status message with the page number and number of copies.
|
||||
*/
|
||||
|
||||
if (Canceled)
|
||||
break;
|
||||
|
||||
Page ++;
|
||||
|
||||
fprintf(stderr, "PAGE: %d %d\n", Page, header.NumCopies);
|
||||
_cupsLangPrintFilter(stderr, "INFO", _("Starting page %d."), Page);
|
||||
|
||||
/*
|
||||
* Start the page...
|
||||
*/
|
||||
|
||||
StartPage(ppd, &header);
|
||||
|
||||
/*
|
||||
* Loop for each line on the page...
|
||||
*/
|
||||
|
||||
for (y = 0; y < header.cupsHeight; y ++)
|
||||
{
|
||||
/*
|
||||
* Let the user know how far we have progressed...
|
||||
*/
|
||||
|
||||
if (Canceled)
|
||||
break;
|
||||
|
||||
if ((y & 127) == 0)
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "INFO",
|
||||
_("Printing page %d, %d%% complete."),
|
||||
Page, 100 * y / header.cupsHeight);
|
||||
fprintf(stderr, "ATTR: job-media-progress=%d\n",
|
||||
100 * y / header.cupsHeight);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a line of graphics...
|
||||
*/
|
||||
|
||||
if (cupsRasterReadPixels(ras, Planes[0], header.cupsBytesPerLine) < 1)
|
||||
break;
|
||||
|
||||
/*
|
||||
* See if the line is blank; if not, write it to the printer...
|
||||
*/
|
||||
|
||||
if (Planes[0][0] ||
|
||||
memcmp(Planes[0], Planes[0] + 1, header.cupsBytesPerLine - 1))
|
||||
OutputLine(&header);
|
||||
else
|
||||
Feed ++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Eject the page...
|
||||
*/
|
||||
|
||||
_cupsLangPrintFilter(stderr, "INFO", _("Finished page %d."), Page);
|
||||
|
||||
EndPage();
|
||||
|
||||
if (Canceled)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shutdown the printer...
|
||||
*/
|
||||
|
||||
Shutdown();
|
||||
|
||||
if (ppd)
|
||||
ppdClose(ppd);
|
||||
|
||||
/*
|
||||
* Close the raster stream...
|
||||
*/
|
||||
|
||||
cupsRasterClose(ras);
|
||||
if (fd != 0)
|
||||
close(fd);
|
||||
|
||||
/*
|
||||
* If no pages were printed, send an error message...
|
||||
*/
|
||||
|
||||
if (Page == 0)
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "ERROR", _("No pages were found."));
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: rastertohp.c 7834 2008-08-04 21:02:09Z mike $".
|
||||
*/
|
||||
1312
filter/rastertolabel.c
Normal file
1312
filter/rastertolabel.c
Normal file
File diff suppressed because it is too large
Load Diff
461
filter/rastertopwg.c
Normal file
461
filter/rastertopwg.c
Normal file
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
* "$Id: rastertopwg.c 3427 2011-09-20 18:40:57Z msweet $"
|
||||
*
|
||||
* CUPS raster to PWG raster format filter for CUPS.
|
||||
*
|
||||
* Copyright 2011 Apple Inc.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Apple Inc. and are protected by Federal copyright law.
|
||||
* Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
* which should have been included with this file. If this file is
|
||||
* file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
*
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* main() - Main entry for filter.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <cups/cups-private.h>
|
||||
#include <cups/raster.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Main entry for filter.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line args */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
int fd; /* Raster file */
|
||||
cups_raster_t *inras, /* Input raster stream */
|
||||
*outras; /* Output raster stream */
|
||||
cups_page_header2_t inheader, /* Input raster page header */
|
||||
outheader; /* Output raster page header */
|
||||
int y; /* Current line */
|
||||
unsigned char *line; /* Line buffer */
|
||||
int page = 0, /* Current page */
|
||||
page_width, /* Actual page width */
|
||||
page_height, /* Actual page height */
|
||||
page_top, /* Top margin */
|
||||
page_bottom, /* Bottom margin */
|
||||
page_left, /* Left margin */
|
||||
linesize, /* Bytes per line */
|
||||
lineoffset; /* Offset into line */
|
||||
unsigned char white; /* White pixel */
|
||||
ppd_file_t *ppd; /* PPD file */
|
||||
ppd_attr_t *back; /* cupsBackSize attribute */
|
||||
_ppd_cache_t *cache; /* PPD cache */
|
||||
_pwg_size_t *pwg_size; /* PWG media size */
|
||||
_pwg_media_t *pwg_media; /* PWG media name */
|
||||
int num_options; /* Number of options */
|
||||
cups_option_t *options = NULL;/* Options */
|
||||
const char *val; /* Option value */
|
||||
|
||||
|
||||
if (argc < 6 || argc > 7)
|
||||
{
|
||||
puts("Usage: rastertopwg job user title copies options [filename]");
|
||||
return (1);
|
||||
}
|
||||
else if (argc == 7)
|
||||
{
|
||||
if ((fd = open(argv[6], O_RDONLY)) < 0)
|
||||
{
|
||||
perror("ERROR: Unable to open print file");
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
fd = 0;
|
||||
|
||||
inras = cupsRasterOpen(fd, CUPS_RASTER_READ);
|
||||
outras = cupsRasterOpen(1, CUPS_RASTER_WRITE_PWG);
|
||||
|
||||
ppd = ppdOpenFile(getenv("PPD"));
|
||||
back = ppdFindAttr(ppd, "cupsBackSide", NULL);
|
||||
|
||||
num_options = cupsParseOptions(argv[5], 0, &options);
|
||||
|
||||
ppdMarkDefaults(ppd);
|
||||
cupsMarkOptions(ppd, num_options, options);
|
||||
|
||||
cache = ppd ? ppd->cache : NULL;
|
||||
|
||||
while (cupsRasterReadHeader2(inras, &inheader))
|
||||
{
|
||||
/*
|
||||
* Compute the real raster size...
|
||||
*/
|
||||
|
||||
page ++;
|
||||
|
||||
fprintf(stderr, "PAGE: %d %d\n", page, inheader.NumCopies);
|
||||
|
||||
page_width = (int)(inheader.cupsPageSize[0] * inheader.HWResolution[0] /
|
||||
72.0);
|
||||
page_height = (int)(inheader.cupsPageSize[1] * inheader.HWResolution[1] /
|
||||
72.0);
|
||||
page_left = (int)(inheader.cupsImagingBBox[0] *
|
||||
inheader.HWResolution[0] / 72.0);
|
||||
page_bottom = (int)(inheader.cupsImagingBBox[1] *
|
||||
inheader.HWResolution[1] / 72.0);
|
||||
page_top = page_height - page_bottom - inheader.cupsHeight;
|
||||
linesize = (page_width * inheader.cupsBitsPerPixel + 7) / 8;
|
||||
lineoffset = page_left * inheader.cupsBitsPerPixel / 8; /* Round down */
|
||||
|
||||
switch (inheader.cupsColorSpace)
|
||||
{
|
||||
case CUPS_CSPACE_W :
|
||||
case CUPS_CSPACE_RGB :
|
||||
case CUPS_CSPACE_SW :
|
||||
case CUPS_CSPACE_SRGB :
|
||||
case CUPS_CSPACE_ADOBERGB :
|
||||
white = 255;
|
||||
break;
|
||||
|
||||
case CUPS_CSPACE_K :
|
||||
case CUPS_CSPACE_CMYK :
|
||||
case CUPS_CSPACE_DEVICE1 :
|
||||
case CUPS_CSPACE_DEVICE2 :
|
||||
case CUPS_CSPACE_DEVICE3 :
|
||||
case CUPS_CSPACE_DEVICE4 :
|
||||
case CUPS_CSPACE_DEVICE5 :
|
||||
case CUPS_CSPACE_DEVICE6 :
|
||||
case CUPS_CSPACE_DEVICE7 :
|
||||
case CUPS_CSPACE_DEVICE8 :
|
||||
case CUPS_CSPACE_DEVICE9 :
|
||||
case CUPS_CSPACE_DEVICEA :
|
||||
case CUPS_CSPACE_DEVICEB :
|
||||
case CUPS_CSPACE_DEVICEC :
|
||||
case CUPS_CSPACE_DEVICED :
|
||||
case CUPS_CSPACE_DEVICEE :
|
||||
case CUPS_CSPACE_DEVICEF :
|
||||
white = 0;
|
||||
break;
|
||||
|
||||
default :
|
||||
_cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
|
||||
fprintf(stderr, "DEBUG: Unsupported cupsColorSpace %d on page %d.\n",
|
||||
inheader.cupsColorSpace, page);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (inheader.cupsColorOrder != CUPS_ORDER_CHUNKED)
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
|
||||
fprintf(stderr, "DEBUG: Unsupported cupsColorOrder %d on page %d.\n",
|
||||
inheader.cupsColorOrder, page);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (inheader.cupsBitsPerPixel != 1 &&
|
||||
inheader.cupsBitsPerColor != 8 && inheader.cupsBitsPerColor != 16)
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
|
||||
fprintf(stderr, "DEBUG: Unsupported cupsBitsPerColor %d on page %d.\n",
|
||||
inheader.cupsBitsPerColor, page);
|
||||
return (1);
|
||||
}
|
||||
|
||||
memcpy(&outheader, &inheader, sizeof(outheader));
|
||||
outheader.cupsWidth = page_width;
|
||||
outheader.cupsHeight = page_height;
|
||||
outheader.cupsBytesPerLine = linesize;
|
||||
|
||||
outheader.cupsInteger[14] = 0; /* VendorIdentifier */
|
||||
outheader.cupsInteger[15] = 0; /* VendorLength */
|
||||
|
||||
if ((val = cupsGetOption("print-content-optimize", num_options,
|
||||
options)) != NULL)
|
||||
{
|
||||
if (!strcmp(val, "automatic"))
|
||||
strlcpy(outheader.OutputType, "Automatic",
|
||||
sizeof(outheader.OutputType));
|
||||
else if (!strcmp(val, "graphics"))
|
||||
strlcpy(outheader.OutputType, "Graphics", sizeof(outheader.OutputType));
|
||||
else if (!strcmp(val, "photo"))
|
||||
strlcpy(outheader.OutputType, "Photo", sizeof(outheader.OutputType));
|
||||
else if (!strcmp(val, "text"))
|
||||
strlcpy(outheader.OutputType, "Text", sizeof(outheader.OutputType));
|
||||
else if (!strcmp(val, "text-and-graphics"))
|
||||
strlcpy(outheader.OutputType, "TextAndGraphics",
|
||||
sizeof(outheader.OutputType));
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "DEBUG: Unsupported print-content-type \"%s\".\n", val);
|
||||
outheader.OutputType[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if ((val = cupsGetOption("print-quality", num_options, options)) != NULL)
|
||||
{
|
||||
int quality = atoi(val); /* print-quality value */
|
||||
|
||||
if (quality >= IPP_QUALITY_DRAFT && quality <= IPP_QUALITY_HIGH)
|
||||
outheader.cupsInteger[8] = quality;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "DEBUG: Unsupported print-quality %d.\n", quality);
|
||||
outheader.cupsInteger[8] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((val = cupsGetOption("print-rendering-intent", num_options,
|
||||
options)) != NULL)
|
||||
{
|
||||
if (!strcmp(val, "absolute"))
|
||||
strlcpy(outheader.cupsRenderingIntent, "Absolute",
|
||||
sizeof(outheader.cupsRenderingIntent));
|
||||
else if (!strcmp(val, "automatic"))
|
||||
strlcpy(outheader.cupsRenderingIntent, "Automatic",
|
||||
sizeof(outheader.cupsRenderingIntent));
|
||||
else if (!strcmp(val, "perceptual"))
|
||||
strlcpy(outheader.cupsRenderingIntent, "Perceptual",
|
||||
sizeof(outheader.cupsRenderingIntent));
|
||||
else if (!strcmp(val, "relative"))
|
||||
strlcpy(outheader.cupsRenderingIntent, "Relative",
|
||||
sizeof(outheader.cupsRenderingIntent));
|
||||
else if (!strcmp(val, "relative-bpc"))
|
||||
strlcpy(outheader.cupsRenderingIntent, "RelativeBpc",
|
||||
sizeof(outheader.cupsRenderingIntent));
|
||||
else if (!strcmp(val, "saturation"))
|
||||
strlcpy(outheader.cupsRenderingIntent, "Saturation",
|
||||
sizeof(outheader.cupsRenderingIntent));
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "DEBUG: Unsupported print-rendering-intent \"%s\".\n",
|
||||
val);
|
||||
outheader.cupsRenderingIntent[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (inheader.cupsPageSizeName[0] &&
|
||||
(pwg_size = _ppdCacheGetSize(cache, inheader.cupsPageSizeName)) != NULL)
|
||||
{
|
||||
strlcpy(outheader.cupsPageSizeName, pwg_size->map.pwg,
|
||||
sizeof(outheader.cupsPageSizeName));
|
||||
}
|
||||
else
|
||||
{
|
||||
pwg_media = _pwgMediaForSize((int)(2540.0 * inheader.cupsPageSize[0] /
|
||||
72.0),
|
||||
(int)(2540.0 * inheader.cupsPageSize[1] /
|
||||
72.0));
|
||||
|
||||
if (pwg_media)
|
||||
strlcpy(outheader.cupsPageSizeName, pwg_media->pwg,
|
||||
sizeof(outheader.cupsPageSizeName));
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "DEBUG: Unsupported PageSize %.2fx%.2f.\n",
|
||||
inheader.cupsPageSize[0], inheader.cupsPageSize[1]);
|
||||
outheader.cupsPageSizeName[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (inheader.Duplex && !(page & 1) &&
|
||||
back && _cups_strcasecmp(back->value, "Normal"))
|
||||
{
|
||||
if (_cups_strcasecmp(back->value, "Flipped"))
|
||||
{
|
||||
if (inheader.Tumble)
|
||||
{
|
||||
outheader.cupsInteger[1] = -1;/* CrossFeedTransform */
|
||||
outheader.cupsInteger[2] = 1; /* FeedTransform */
|
||||
|
||||
outheader.cupsInteger[3] = page_width - page_left -
|
||||
inheader.cupsWidth;
|
||||
/* ImageBoxLeft */
|
||||
outheader.cupsInteger[4] = page_top;
|
||||
/* ImageBoxTop */
|
||||
outheader.cupsInteger[5] = page_width - page_left;
|
||||
/* ImageBoxRight */
|
||||
outheader.cupsInteger[6] = page_height - page_bottom;
|
||||
/* ImageBoxBottom */
|
||||
}
|
||||
else
|
||||
{
|
||||
outheader.cupsInteger[1] = 1; /* CrossFeedTransform */
|
||||
outheader.cupsInteger[2] = -1;/* FeedTransform */
|
||||
|
||||
outheader.cupsInteger[3] = page_left;
|
||||
/* ImageBoxLeft */
|
||||
outheader.cupsInteger[4] = page_bottom;
|
||||
/* ImageBoxTop */
|
||||
outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
|
||||
/* ImageBoxRight */
|
||||
outheader.cupsInteger[6] = page_height - page_top;
|
||||
/* ImageBoxBottom */
|
||||
}
|
||||
}
|
||||
else if (_cups_strcasecmp(back->value, "ManualTumble"))
|
||||
{
|
||||
if (inheader.Tumble)
|
||||
{
|
||||
outheader.cupsInteger[1] = -1;/* CrossFeedTransform */
|
||||
outheader.cupsInteger[2] = -1;/* FeedTransform */
|
||||
|
||||
outheader.cupsInteger[3] = page_width - page_left -
|
||||
inheader.cupsWidth;
|
||||
/* ImageBoxLeft */
|
||||
outheader.cupsInteger[4] = page_bottom;
|
||||
/* ImageBoxTop */
|
||||
outheader.cupsInteger[5] = page_width - page_left;
|
||||
/* ImageBoxRight */
|
||||
outheader.cupsInteger[6] = page_height - page_top;
|
||||
/* ImageBoxBottom */
|
||||
}
|
||||
else
|
||||
{
|
||||
outheader.cupsInteger[1] = 1; /* CrossFeedTransform */
|
||||
outheader.cupsInteger[2] = 1; /* FeedTransform */
|
||||
|
||||
outheader.cupsInteger[3] = page_left;
|
||||
/* ImageBoxLeft */
|
||||
outheader.cupsInteger[4] = page_top;
|
||||
/* ImageBoxTop */
|
||||
outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
|
||||
/* ImageBoxRight */
|
||||
outheader.cupsInteger[6] = page_height - page_bottom;
|
||||
/* ImageBoxBottom */
|
||||
}
|
||||
}
|
||||
else if (_cups_strcasecmp(back->value, "Rotated"))
|
||||
{
|
||||
if (inheader.Tumble)
|
||||
{
|
||||
outheader.cupsInteger[1] = -1;/* CrossFeedTransform */
|
||||
outheader.cupsInteger[2] = -1;/* FeedTransform */
|
||||
|
||||
outheader.cupsInteger[3] = page_width - page_left -
|
||||
inheader.cupsWidth;
|
||||
/* ImageBoxLeft */
|
||||
outheader.cupsInteger[4] = page_bottom;
|
||||
/* ImageBoxTop */
|
||||
outheader.cupsInteger[5] = page_width - page_left;
|
||||
/* ImageBoxRight */
|
||||
outheader.cupsInteger[6] = page_height - page_top;
|
||||
/* ImageBoxBottom */
|
||||
}
|
||||
else
|
||||
{
|
||||
outheader.cupsInteger[1] = 1; /* CrossFeedTransform */
|
||||
outheader.cupsInteger[2] = 1; /* FeedTransform */
|
||||
|
||||
outheader.cupsInteger[3] = page_left;
|
||||
/* ImageBoxLeft */
|
||||
outheader.cupsInteger[4] = page_top;
|
||||
/* ImageBoxTop */
|
||||
outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
|
||||
/* ImageBoxRight */
|
||||
outheader.cupsInteger[6] = page_height - page_bottom;
|
||||
/* ImageBoxBottom */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Unsupported value...
|
||||
*/
|
||||
|
||||
fprintf(stderr, "DEBUG: Unsupported cupsBackSide \"%s\".\n", back->value);
|
||||
|
||||
outheader.cupsInteger[1] = 1; /* CrossFeedTransform */
|
||||
outheader.cupsInteger[2] = 1; /* FeedTransform */
|
||||
|
||||
outheader.cupsInteger[3] = page_left;
|
||||
/* ImageBoxLeft */
|
||||
outheader.cupsInteger[4] = page_top;
|
||||
/* ImageBoxTop */
|
||||
outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
|
||||
/* ImageBoxRight */
|
||||
outheader.cupsInteger[6] = page_height - page_bottom;
|
||||
/* ImageBoxBottom */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outheader.cupsInteger[1] = 1; /* CrossFeedTransform */
|
||||
outheader.cupsInteger[2] = 1; /* FeedTransform */
|
||||
|
||||
outheader.cupsInteger[3] = page_left;
|
||||
/* ImageBoxLeft */
|
||||
outheader.cupsInteger[4] = page_top;
|
||||
/* ImageBoxTop */
|
||||
outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
|
||||
/* ImageBoxRight */
|
||||
outheader.cupsInteger[6] = page_height - page_bottom;
|
||||
/* ImageBoxBottom */
|
||||
}
|
||||
|
||||
if (!cupsRasterWriteHeader2(outras, &outheader))
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
|
||||
fprintf(stderr, "DEBUG: Unable to write header for page %d.\n", page);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy raster data...
|
||||
*/
|
||||
|
||||
line = malloc(linesize);
|
||||
|
||||
memset(line, white, linesize);
|
||||
for (y = page_top; y > 0; y --)
|
||||
if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
|
||||
fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n",
|
||||
page_top - y + 1, page);
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (y = inheader.cupsHeight; y > 0; y --)
|
||||
{
|
||||
cupsRasterReadPixels(inras, line + lineoffset, inheader.cupsBytesPerLine);
|
||||
if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
|
||||
fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n",
|
||||
inheader.cupsHeight - y + page_top + 1, page);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
memset(line, white, linesize);
|
||||
for (y = page_bottom; y > 0; y --)
|
||||
if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
|
||||
{
|
||||
_cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
|
||||
fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n",
|
||||
page_bottom - y + page_top + inheader.cupsHeight + 1, page);
|
||||
return (1);
|
||||
}
|
||||
|
||||
free(line);
|
||||
}
|
||||
|
||||
cupsRasterClose(inras);
|
||||
if (fd)
|
||||
close(fd);
|
||||
|
||||
cupsRasterClose(outras);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: rastertopwg.c 3427 2011-09-20 18:40:57Z msweet $".
|
||||
*/
|
||||
32
filter/spec-ppd.header
Normal file
32
filter/spec-ppd.header
Normal file
@@ -0,0 +1,32 @@
|
||||
<!--
|
||||
"$Id$"
|
||||
|
||||
PPD extension documentation for CUPS.
|
||||
|
||||
Copyright 2007-2011 by Apple Inc.
|
||||
Copyright 1997-2007 by Easy Software Products.
|
||||
|
||||
These coded instructions, statements, and computer programs are the
|
||||
property of Apple Inc. and are protected by Federal copyright
|
||||
law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
which should have been included with this file. If this file is
|
||||
file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
-->
|
||||
|
||||
<H1 CLASS="title">CUPS PPD Extensions</H1>
|
||||
|
||||
<p>This specification describes the attributes and extensions that CUPS adds to <a href="http://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf" target="_blank">Adobe TechNote #5003: PostScript Printer Description File Format Specification Version 4.3</a>. PostScript Printer Description ("PPD") files describe the capabilities of each printer and are used by CUPS to support printer-specific features and intelligent filtering.</p>
|
||||
|
||||
<div class='summary'><table summary='General Information'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>See Also</th>
|
||||
<td>Programming: <a href='postscript-driver.html'>Developing PostScript Printer Drivers</a><br>
|
||||
Programming: <a href='raster-driver.html'>Developing Raster Printer Drivers</a><br>
|
||||
Programming: <a href='api-filter.html'>Filter and Backend Programming</a><br>
|
||||
Programming: <a href='ppd-compiler.html'>Introduction to the PPD Compiler</a><br>
|
||||
Programming: <a href='api-raster.html'>Raster API</a><br>
|
||||
References: <a href='ref-ppdcfile.html'>PPD Compiler Driver Information File Reference</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
1956
filter/spec-ppd.shtml
Normal file
1956
filter/spec-ppd.shtml
Normal file
File diff suppressed because it is too large
Load Diff
1078
filter/testraster.c
Normal file
1078
filter/testraster.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user