diff options
-rw-r--r-- | CHANGES.txt | 4 | ||||
-rw-r--r-- | conf/mime.convs.in | 92 | ||||
-rw-r--r-- | conf/mime.types | 6 | ||||
-rw-r--r-- | cups/transcode.c | 4 | ||||
-rw-r--r-- | data/classified | 163 | ||||
-rw-r--r-- | data/confidential | 163 | ||||
-rw-r--r-- | data/secret | 163 | ||||
-rw-r--r-- | data/standard | 163 | ||||
-rw-r--r-- | data/testprint.ps | 606 | ||||
-rw-r--r-- | data/topsecret | 163 | ||||
-rw-r--r-- | data/unclassified | 163 | ||||
-rw-r--r-- | doc/Makefile | 1 | ||||
-rw-r--r-- | doc/help/spec-banner.html | 10 | ||||
-rw-r--r-- | filter/Makefile | 8 | ||||
-rw-r--r-- | filter/bannertops.c | 1874 | ||||
-rw-r--r-- | filter/pstext.c | 503 | ||||
-rw-r--r-- | filter/pstext.h | 75 | ||||
-rw-r--r-- | filter/textcommon.c | 5 | ||||
-rw-r--r-- | notifier/testnotify.c | 1 | ||||
-rw-r--r-- | packaging/cups.list.in | 1 | ||||
-rw-r--r-- | scheduler/ipp.c | 14 | ||||
-rwxr-xr-x | test/run-stp-tests.sh | 1 |
22 files changed, 1525 insertions, 2658 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 42840ee51..9fd042a64 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,9 +1,11 @@ -CHANGES.txt - 2008-09-27 +CHANGES.txt - 2008-10-01 ------------------------ CHANGES IN CUPS V1.4b1 - Documentation updates (STR #2567) + - Now support and use a new banner file format for better text + support and easier customization (STR #2490) - The scheduler now sets the PRINTER_INFO and PRINTER_LOCATION environment variables from the corresponding IPP attributes. - The ippRead*() and ippWrite*() functions no longer use a diff --git a/conf/mime.convs.in b/conf/mime.convs.in index d6f4fb371..36c7b9c7e 100644 --- a/conf/mime.convs.in +++ b/conf/mime.convs.in @@ -7,7 +7,7 @@ # # MIME converts file for the Common UNIX Printing System (CUPS). # -# Copyright 2007 by Apple Inc. +# Copyright 2007-2008 by Apple Inc. # Copyright 1997-2007 by Easy Software Products. # # These coded instructions, statements, and computer programs are the @@ -38,62 +38,52 @@ # PostScript filters # -application/pdf application/postscript 33 pdftops -application/postscript application/vnd.cups-postscript 66 pstops -application/vnd.hp-HPGL application/postscript 66 hpgltops -application/x-cshell application/postscript 33 texttops -application/x-csource application/postscript 33 texttops -application/x-perl application/postscript 33 texttops -application/x-shell application/postscript 33 texttops -text/plain application/postscript 33 texttops -text/html application/postscript 33 texttops -image/gif application/vnd.cups-postscript 66 imagetops -image/png application/vnd.cups-postscript 66 imagetops -image/jpeg application/vnd.cups-postscript 66 imagetops -image/tiff application/vnd.cups-postscript 66 imagetops -image/x-bitmap application/vnd.cups-postscript 66 imagetops -image/x-photocd application/vnd.cups-postscript 66 imagetops -image/x-portable-anymap application/vnd.cups-postscript 66 imagetops -image/x-portable-bitmap application/vnd.cups-postscript 66 imagetops -image/x-portable-graymap application/vnd.cups-postscript 66 imagetops -image/x-portable-pixmap application/vnd.cups-postscript 66 imagetops -image/x-sgi-rgb application/vnd.cups-postscript 66 imagetops -image/x-xbitmap application/vnd.cups-postscript 66 imagetops -image/x-xpixmap application/vnd.cups-postscript 66 imagetops -#image/x-xwindowdump application/vnd.cups-postscript 66 imagetops -image/x-sun-raster application/vnd.cups-postscript 66 imagetops - - -######################################################################## -# -# Form filter... -# -# This filter does not currently exist, but the file format is defined -# in the IDD and registered with the IANA for future use... -# - -#application/vnd.cups-form application/vnd.cups-postscript 33 formtops +application/pdf application/postscript 33 pdftops +application/postscript application/vnd.cups-postscript 66 pstops +application/vnd.hp-HPGL application/postscript 66 hpgltops +application/x-cshell application/postscript 33 texttops +application/x-csource application/postscript 33 texttops +application/x-perl application/postscript 33 texttops +application/x-shell application/postscript 33 texttops +text/plain application/postscript 33 texttops +text/html application/postscript 33 texttops +image/gif application/vnd.cups-postscript 66 imagetops +image/png application/vnd.cups-postscript 66 imagetops +image/jpeg application/vnd.cups-postscript 66 imagetops +image/tiff application/vnd.cups-postscript 66 imagetops +image/x-bitmap application/vnd.cups-postscript 66 imagetops +image/x-photocd application/vnd.cups-postscript 66 imagetops +image/x-portable-anymap application/vnd.cups-postscript 66 imagetops +image/x-portable-bitmap application/vnd.cups-postscript 66 imagetops +image/x-portable-graymap application/vnd.cups-postscript 66 imagetops +image/x-portable-pixmap application/vnd.cups-postscript 66 imagetops +image/x-sgi-rgb application/vnd.cups-postscript 66 imagetops +image/x-xbitmap application/vnd.cups-postscript 66 imagetops +image/x-xpixmap application/vnd.cups-postscript 66 imagetops +#image/x-xwindowdump application/vnd.cups-postscript 66 imagetops +image/x-sun-raster application/vnd.cups-postscript 66 imagetops +application/vnd.cups-banner application/vnd.cups-postscript 33 bannertops ######################################################################## # # Raster filters... # -image/gif application/vnd.cups-raster 100 imagetoraster -image/png application/vnd.cups-raster 100 imagetoraster -image/jpeg application/vnd.cups-raster 100 imagetoraster -image/tiff application/vnd.cups-raster 100 imagetoraster -image/x-bitmap application/vnd.cups-raster 100 imagetoraster -image/x-photocd application/vnd.cups-raster 100 imagetoraster -image/x-portable-anymap application/vnd.cups-raster 100 imagetoraster -image/x-portable-bitmap application/vnd.cups-raster 100 imagetoraster -image/x-portable-graymap application/vnd.cups-raster 100 imagetoraster -image/x-portable-pixmap application/vnd.cups-raster 100 imagetoraster -image/x-sgi-rgb application/vnd.cups-raster 100 imagetoraster -image/x-xbitmap application/vnd.cups-raster 100 imagetoraster -image/x-xpixmap application/vnd.cups-raster 100 imagetoraster -#image/x-xwindowdump application/vnd.cups-raster 100 imagetoraster -image/x-sun-raster application/vnd.cups-raster 100 imagetoraster +image/gif application/vnd.cups-raster 100 imagetoraster +image/png application/vnd.cups-raster 100 imagetoraster +image/jpeg application/vnd.cups-raster 100 imagetoraster +image/tiff application/vnd.cups-raster 100 imagetoraster +image/x-bitmap application/vnd.cups-raster 100 imagetoraster +image/x-photocd application/vnd.cups-raster 100 imagetoraster +image/x-portable-anymap application/vnd.cups-raster 100 imagetoraster +image/x-portable-bitmap application/vnd.cups-raster 100 imagetoraster +image/x-portable-graymap application/vnd.cups-raster 100 imagetoraster +image/x-portable-pixmap application/vnd.cups-raster 100 imagetoraster +image/x-sgi-rgb application/vnd.cups-raster 100 imagetoraster +image/x-xbitmap application/vnd.cups-raster 100 imagetoraster +image/x-xpixmap application/vnd.cups-raster 100 imagetoraster +#image/x-xwindowdump application/vnd.cups-raster 100 imagetoraster +image/x-sun-raster application/vnd.cups-raster 100 imagetoraster # pstoraster is part of GPL Ghostscript... application/vnd.cups-postscript application/vnd.cups-raster 100 pstoraster diff --git a/conf/mime.types b/conf/mime.types index 83a079a77..21089d60b 100644 --- a/conf/mime.types +++ b/conf/mime.types @@ -151,12 +151,14 @@ application/rss+xml rss # CUPS-specific types... # +application/vnd.cups-banner string(0,'#CUPS-BANNER') application/vnd.cups-command string(0,'#CUPS-COMMAND') -application/vnd.cups-form string(0,"<CUPSFORM>") application/vnd.cups-pdf application/vnd.cups-postscript application/vnd.cups-ppd ppd string(0,"*PPD-Adobe:") -application/vnd.cups-raster string(0,"RaSt") string(0,"tSaR") +application/vnd.cups-raster string(0,"RaSt") string(0,"tSaR") \ + string(0,"RaS2") string(0,"2SaR") \ + string(0,"RaS3") string(0,"3SaR") application/vnd.cups-raw (string(0,<1B>E) + !string(2,<1B>%0B)) \ string(0,<1B>@) \ (contains(0,128,<1B>%-12345X) + \ diff --git a/cups/transcode.c b/cups/transcode.c index b0f895cd6..417db314e 100644 --- a/cups/transcode.c +++ b/cups/transcode.c @@ -487,11 +487,9 @@ cupsUTF8ToUTF32( } /* - * Convert input UTF-8 to output UTF-32 (and insert BOM)... + * Convert input UTF-8 to output UTF-32... */ - *dest++ = 0xfeff; - for (i = maxout - 1; *src && i > 0; i --) { ch = *src++; diff --git a/data/classified b/data/classified index 8776b7b1a..fe5e08bd1 100644 --- a/data/classified +++ b/data/classified @@ -1,159 +1,6 @@ -%!PS-Adobe-3.0 -%%BoundingBox: 0 0 612 792 -%%Pages: 1 -%%LanguageLevel: 1 -%%DocumentData: Clean7Bit -%%DocumentSuppliedResources: procset bannerprint/1.0 -%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman -%%Creator: Michael Sweet, Apple Inc. -%%CreationDate: D:20070620123000+0700 -%%Title: Test Page -%%EndComments -%%BeginProlog -%%BeginResource procset bannerprint 1.3 0 -% -% PostScript banner page for the Common UNIX Printing System ("CUPS"). -% -% Copyright 2007 Apple Inc. -% Copyright 1993-2005 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 is included with the CUPS source distribution. -% -/CENTER { % Draw centered text - % (name) CENTER - - dup stringwidth pop % Get the width of the string - 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance - show % Show the string -} bind def -/RIGHT { % Draw right-justified text - % (name) RIGHT - - dup stringwidth pop % Get the width of the string - neg 0 rmoveto % Shift left the entire distance - show % Show the string -} bind def -/NUMBER { % Draw a number - % power n NUMBER - - 1 index 1 eq { % power == 1? - round cvi exch pop % Convert "n" to integer - } { - 1 index mul round exch div % Truncate extra decimal places - } ifelse - 100 string cvs show % Convert to a string and show it... -} bind def -%%EndResource -%%EndProlog -%%Page: 1 1 -gsave +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Classified +Footer Classified +Image images/cups.rgb - % Determine the imageable area and device resolution... - initclip newpath clippath pathbbox % Get bounding rectangle - 72 div /pageTop exch def % Get top margin in inches - 72 div /pageRight exch def % Get right margin in inches - 72 div /pageBottom exch def % Get bottom margin in inches - 72 div /pageLeft exch def % Get left margin in inches - - /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft - /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom - - /boxWidth % width of text box - pageWidth pageHeight lt - { pageWidth 54 mul } - { pageHeight 42 mul } - ifelse def - - newpath % Clear bounding path - - % Create fonts... - /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold - pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33) - - /mediumFont /Helvetica findfont % mediumFont = Helvetica - pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5) - - % Offset page to account for lower-left margin... - pageLeft 72 mul - pageBottom 72 mul - translate - - % Draw the label at the top and bottom... - 0 setgray % Color - - pageWidth 36 mul % Center of page - pageHeight 72 mul % Top of page - pageWidth 9 mul sub % - 3 lines - moveto % Position text - bigFont setfont % Font - (Classified) CENTER % Show text centered - - pageWidth 36 mul % Center of page - pageHeight 6 mul % Bottom of page - moveto % Position text - bigFont setfont % Font - (Classified) CENTER % Show text centered - - % Job information box... - pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - 0.5 setgray rectfill % Draw a shadow - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul % y = pageHeight * 1/4 * 72 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - - 4 copy 1 setgray rectfill % Clear the box to white - 0 setgray rectstroke % Draw a black box around it... - - % Job information text... - mediumFont setfont % Medium sized font - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - pageHeight 36 mul % y = pageHeight * 1/2 * 72 - pageHeight 5 mul add % y += 3.333 lines - 2 copy % Copy X & Y - moveto - (Job ID: ) RIGHT - 2 copy % Copy X & Y - moveto - ({printer-name}-{job-id}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Title: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-name}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Requesting User: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-originating-user-name}) show - - ({?job-billing}) () ne { - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Billing Info: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-billing}) show - } if - -% Show the page... -grestore -showpage -% -% End of "$Id: classified 6649 2007-07-11 21:46:42Z mike $". -% -%%EOF diff --git a/data/confidential b/data/confidential index 9e4d9eadb..5b0e790ee 100644 --- a/data/confidential +++ b/data/confidential @@ -1,159 +1,6 @@ -%!PS-Adobe-3.0 -%%BoundingBox: 0 0 612 792 -%%Pages: 1 -%%LanguageLevel: 1 -%%DocumentData: Clean7Bit -%%DocumentSuppliedResources: procset bannerprint/1.0 -%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman -%%Creator: Michael Sweet, Apple Inc. -%%CreationDate: D:20070620123000+0700 -%%Title: Test Page -%%EndComments -%%BeginProlog -%%BeginResource procset bannerprint 1.3 0 -% -% PostScript banner page for the Common UNIX Printing System ("CUPS"). -% -% Copyright 2007 Apple Inc. -% Copyright 1993-2005 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 is included with the CUPS source distribution. -% -/CENTER { % Draw centered text - % (name) CENTER - - dup stringwidth pop % Get the width of the string - 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance - show % Show the string -} bind def -/RIGHT { % Draw right-justified text - % (name) RIGHT - - dup stringwidth pop % Get the width of the string - neg 0 rmoveto % Shift left the entire distance - show % Show the string -} bind def -/NUMBER { % Draw a number - % power n NUMBER - - 1 index 1 eq { % power == 1? - round cvi exch pop % Convert "n" to integer - } { - 1 index mul round exch div % Truncate extra decimal places - } ifelse - 100 string cvs show % Convert to a string and show it... -} bind def -%%EndResource -%%EndProlog -%%Page: 1 1 -gsave +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Confidential +Footer Confidential +Image images/cups.rgb - % Determine the imageable area and device resolution... - initclip newpath clippath pathbbox % Get bounding rectangle - 72 div /pageTop exch def % Get top margin in inches - 72 div /pageRight exch def % Get right margin in inches - 72 div /pageBottom exch def % Get bottom margin in inches - 72 div /pageLeft exch def % Get left margin in inches - - /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft - /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom - - /boxWidth % width of text box - pageWidth pageHeight lt - { pageWidth 54 mul } - { pageHeight 42 mul } - ifelse def - - newpath % Clear bounding path - - % Create fonts... - /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold - pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33) - - /mediumFont /Helvetica findfont % mediumFont = Helvetica - pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5) - - % Offset page to account for lower-left margin... - pageLeft 72 mul - pageBottom 72 mul - translate - - % Draw the label at the top and bottom... - 0 setgray % Color - - pageWidth 36 mul % Center of page - pageHeight 72 mul % Top of page - pageWidth 9 mul sub % - 3 lines - moveto % Position text - bigFont setfont % Font - (Confidential) CENTER % Show text centered - - pageWidth 36 mul % Center of page - pageHeight 6 mul % Bottom of page - moveto % Position text - bigFont setfont % Font - (Confidential) CENTER % Show text centered - - % Job information box... - pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - 0.5 setgray rectfill % Draw a shadow - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul % y = pageHeight * 1/4 * 72 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - - 4 copy 1 setgray rectfill % Clear the box to white - 0 setgray rectstroke % Draw a black box around it... - - % Job information text... - mediumFont setfont % Medium sized font - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - pageHeight 36 mul % y = pageHeight * 1/2 * 72 - pageHeight 5 mul add % y += 3.333 lines - 2 copy % Copy X & Y - moveto - (Job ID: ) RIGHT - 2 copy % Copy X & Y - moveto - ({printer-name}-{job-id}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Title: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-name}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Requesting User: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-originating-user-name}) show - - ({?job-billing}) () ne { - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Billing Info: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-billing}) show - } if - -% Show the page... -grestore -showpage -% -% End of "$Id: confidential 6649 2007-07-11 21:46:42Z mike $". -% -%%EOF diff --git a/data/secret b/data/secret index cb2619e76..06ce0eb32 100644 --- a/data/secret +++ b/data/secret @@ -1,159 +1,6 @@ -%!PS-Adobe-3.0 -%%BoundingBox: 0 0 612 792 -%%Pages: 1 -%%LanguageLevel: 1 -%%DocumentData: Clean7Bit -%%DocumentSuppliedResources: procset bannerprint/1.0 -%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman -%%Creator: Michael Sweet, Apple Inc. -%%CreationDate: D:20070620123000+0700 -%%Title: Test Page -%%EndComments -%%BeginProlog -%%BeginResource procset bannerprint 1.3 0 -% -% PostScript banner page for the Common UNIX Printing System ("CUPS"). -% -% Copyright 2007 Apple Inc. -% Copyright 1993-2005 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 is included with the CUPS source distribution. -% -/CENTER { % Draw centered text - % (name) CENTER - - dup stringwidth pop % Get the width of the string - 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance - show % Show the string -} bind def -/RIGHT { % Draw right-justified text - % (name) RIGHT - - dup stringwidth pop % Get the width of the string - neg 0 rmoveto % Shift left the entire distance - show % Show the string -} bind def -/NUMBER { % Draw a number - % power n NUMBER - - 1 index 1 eq { % power == 1? - round cvi exch pop % Convert "n" to integer - } { - 1 index mul round exch div % Truncate extra decimal places - } ifelse - 100 string cvs show % Convert to a string and show it... -} bind def -%%EndResource -%%EndProlog -%%Page: 1 1 -gsave +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Secret +Footer Secret +Image images/cups.rgb - % Determine the imageable area and device resolution... - initclip newpath clippath pathbbox % Get bounding rectangle - 72 div /pageTop exch def % Get top margin in inches - 72 div /pageRight exch def % Get right margin in inches - 72 div /pageBottom exch def % Get bottom margin in inches - 72 div /pageLeft exch def % Get left margin in inches - - /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft - /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom - - /boxWidth % width of text box - pageWidth pageHeight lt - { pageWidth 54 mul } - { pageHeight 42 mul } - ifelse def - - newpath % Clear bounding path - - % Create fonts... - /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold - pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33) - - /mediumFont /Helvetica findfont % mediumFont = Helvetica - pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5) - - % Offset page to account for lower-left margin... - pageLeft 72 mul - pageBottom 72 mul - translate - - % Draw the label at the top and bottom... - 0 setgray % Color - - pageWidth 36 mul % Center of page - pageHeight 72 mul % Top of page - pageWidth 9 mul sub % - 3 lines - moveto % Position text - bigFont setfont % Font - (Secret) CENTER % Show text centered - - pageWidth 36 mul % Center of page - pageHeight 6 mul % Bottom of page - moveto % Position text - bigFont setfont % Font - (Secret) CENTER % Show text centered - - % Job information box... - pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - 0.5 setgray rectfill % Draw a shadow - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul % y = pageHeight * 1/4 * 72 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - - 4 copy 1 setgray rectfill % Clear the box to white - 0 setgray rectstroke % Draw a black box around it... - - % Job information text... - mediumFont setfont % Medium sized font - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - pageHeight 36 mul % y = pageHeight * 1/2 * 72 - pageHeight 5 mul add % y += 3.333 lines - 2 copy % Copy X & Y - moveto - (Job ID: ) RIGHT - 2 copy % Copy X & Y - moveto - ({printer-name}-{job-id}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Title: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-name}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Requesting User: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-originating-user-name}) show - - ({?job-billing}) () ne { - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Billing Info: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-billing}) show - } if - -% Show the page... -grestore -showpage -% -% End of "$Id: secret 6649 2007-07-11 21:46:42Z mike $". -% -%%EOF diff --git a/data/standard b/data/standard index 6f03745d0..54623372e 100644 --- a/data/standard +++ b/data/standard @@ -1,159 +1,6 @@ -%!PS-Adobe-3.0 -%%BoundingBox: 0 0 612 792 -%%Pages: 1 -%%LanguageLevel: 1 -%%DocumentData: Clean7Bit -%%DocumentSuppliedResources: procset bannerprint/1.0 -%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman -%%Creator: Michael Sweet, Apple Inc. -%%CreationDate: D:20070620123000+0700 -%%Title: Test Page -%%EndComments -%%BeginProlog -%%BeginResource procset bannerprint 1.3 0 -% -% PostScript banner page for the Common UNIX Printing System ("CUPS"). -% -% Copyright 2007 Apple Inc. -% Copyright 1993-2005 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 is included with the CUPS source distribution. -% -/CENTER { % Draw centered text - % (name) CENTER - - dup stringwidth pop % Get the width of the string - 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance - show % Show the string -} bind def -/RIGHT { % Draw right-justified text - % (name) RIGHT - - dup stringwidth pop % Get the width of the string - neg 0 rmoveto % Shift left the entire distance - show % Show the string -} bind def -/NUMBER { % Draw a number - % power n NUMBER - - 1 index 1 eq { % power == 1? - round cvi exch pop % Convert "n" to integer - } { - 1 index mul round exch div % Truncate extra decimal places - } ifelse - 100 string cvs show % Convert to a string and show it... -} bind def -%%EndResource -%%EndProlog -%%Page: 1 1 -gsave +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Cover Page +Footer Cover Page +Image images/cups.rgb - % Determine the imageable area and device resolution... - initclip newpath clippath pathbbox % Get bounding rectangle - 72 div /pageTop exch def % Get top margin in inches - 72 div /pageRight exch def % Get right margin in inches - 72 div /pageBottom exch def % Get bottom margin in inches - 72 div /pageLeft exch def % Get left margin in inches - - /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft - /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom - - /boxWidth % width of text box - pageWidth pageHeight lt - { pageWidth 54 mul } - { pageHeight 42 mul } - ifelse def - - newpath % Clear bounding path - - % Create fonts... - /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold - pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33) - - /mediumFont /Helvetica findfont % mediumFont = Helvetica - pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5) - - % Offset page to account for lower-left margin... - pageLeft 72 mul - pageBottom 72 mul - translate - - % Draw the label at the top and bottom... - 0 setgray % Color - - pageWidth 36 mul % Center of page - pageHeight 72 mul % Top of page - pageWidth 9 mul sub % - 3 lines - moveto % Position text - bigFont setfont % Font - (Cover Page) CENTER % Show text centered - - pageWidth 36 mul % Center of page - pageHeight 6 mul % Bottom of page - moveto % Position text - bigFont setfont % Font - (Cover Page) CENTER % Show text centered - - % Job information box... - pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - 0.5 setgray rectfill % Draw a shadow - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul % y = pageHeight * 1/4 * 72 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - - 4 copy 1 setgray rectfill % Clear the box to white - 0 setgray rectstroke % Draw a black box around it... - - % Job information text... - mediumFont setfont % Medium sized font - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - pageHeight 36 mul % y = pageHeight * 1/2 * 72 - pageHeight 5 mul add % y += 3.333 lines - 2 copy % Copy X & Y - moveto - (Job ID: ) RIGHT - 2 copy % Copy X & Y - moveto - ({printer-name}-{job-id}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Title: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-name}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Requesting User: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-originating-user-name}) show - - ({?job-billing}) () ne { - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Billing Info: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-billing}) show - } if - -% Show the page... -grestore -showpage -% -% End of "$Id: standard 6649 2007-07-11 21:46:42Z mike $". -% -%%EOF diff --git a/data/testprint.ps b/data/testprint.ps index 7b1ed89c8..b2a9c8a46 100644 --- a/data/testprint.ps +++ b/data/testprint.ps @@ -1,598 +1,8 @@ -%!PS-Adobe-3.0 -%%BoundingBox: 0 0 612 792 -%%Pages: 1 -%%LanguageLevel: 1 -%%DocumentData: Clean7Bit -%%DocumentSuppliedResources: procset testprint/1.3 -%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman -%%Creator: Michael Sweet, Apple Inc. -%%CreationDate: D:20070606214000+0500 -%%Title: Test Page -%%EndComments -%%BeginProlog -%%BeginResource procset testprint 1.3 0 -% -% PostScript test page for the Common UNIX Printing System ("CUPS"). -% -% Copyright 2007-2008 Apple Inc. -% Copyright 1993-2007 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 is included with the CUPS source distribution. -% -/SEXTANT { % Draw a color wheel sextant... - % (name) white radius r g b SEXTANT - - % Loop through 100 shades... - 0 0.010101 0.98 { - % Set the color... - dup 0.75 le { % Get "white" value - % Start from black - dup 0.75 div % val2 = val / 0.75 - - 0 index 5 index mul % R = R * val2 - 1 index 5 index mul % G = G * val2 - 2 index 5 index mul % B = B * val2 - - 4 -1 roll pop % Discard val2 - } { - % Fade to white - dup neg 1 add 4 mul % val2 = (1 - val) * 4 - - 0 index 5 index mul % R = R * val2 - 1 index neg 1 add add % + (1 - val2) - 1 index 5 index mul % G = G * val2 - 2 index neg 1 add add % + (1 - val2) - 2 index 5 index mul % B = B * val2 - 3 index neg 1 add add % + (1 - val2) - - 4 -1 roll pop % Discard val2 - } ifelse - setrgbcolor % Set the color... - - % Draw the polygon... - newpath % Start a new path... - dup 5 index mul % r1 = radius * val - 0 0 3 -1 roll 0 60 arc % Draw the inner arc - - dup 0.010101 add 5 index mul% r2 = (radius + 0.010101) * val - 0 0 3 -1 roll 60 0 arcn % Draw the outer arc - - closepath % Close the path - fill % Fill it... - - pop % Pop value... - } for - - % Draw a line around the polygons... - pop pop pop dup % Pop R, G, B, start - 0 setgray % Black - newpath - 0 0 moveto % Center - 0 0 3 -1 roll 0 60 arc % Arc around octant - closepath % Back to center - stroke % Stroke it... - - % Draw the label... - dup % Save radius - dup 30 cos mul % X = radius * cos(30) - exch 30 sin mul % Y = radius * sin(30) - moveto % Position label - - gsave - 30 rotate % Rotate label - dup 0.05 mul % Offset to the right - exch -0.05 mul % and down... - rmoveto % Offset label - show % Show label - grestore -} bind def -/CENTER { % Draw centered text - % (name) CENTER - - dup stringwidth pop % Get the width of the string - 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance - show % Show the string -} bind def -/RIGHT { % Draw right-justified text - % (name) RIGHT - - dup stringwidth pop % Get the width of the string - neg 0 rmoveto % Shift left the entire distance - show % Show the string -} bind def -/NUMBER { % Draw a number - % power n NUMBER - - 1 index 1 eq { % power == 1? - round cvi exch pop % Convert "n" to integer - } { - 1 index mul round exch div % Truncate extra decimal places - } ifelse - 100 string cvs show % Convert to a string and show it... -} bind def -/CUPSLOGO { % Draw the CUPS logo - % height CUPSLOGO - % Start with a big C... - /Helvetica findfont 1 index scalefont setfont - 0 setgray - 0 0 moveto - (C) show - - % Then "UNIX Printing System" much smaller... - /Helvetica-Bold findfont 1 index 9 div scalefont setfont - 0.25 mul - dup dup 2.0 mul moveto - (UNIX) show - dup dup 1.6 mul moveto - (Printing) show - dup 1.2 mul moveto - (System) show -} bind def -%%EndResource -%%EndProlog -%%Page: 1 1 -gsave - - % Determine the imageable area and device resolution... - initclip newpath clippath pathbbox % Get bounding rectangle - 72 div /pageTop exch def % Get top margin in inches - 72 div /pageRight exch def % Get right margin in inches - 72 div /pageBottom exch def % Get bottom margin in inches - 72 div /pageLeft exch def % Get left margin in inches - - 4 setlinewidth % Draw wide lines - 0 setgray closepath stroke % Draw a clipping rectangle - - /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft - /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom - - 72 72 dtransform % Get device resolution per inch - /yResolution exch abs def % yResolution = abs(yres) - /xResolution exch abs def % xResolution = abs(xres) - - % Figure out the sizes of things... - /wheelSize % size of wheels - pageWidth pageHeight lt - { pageWidth 9 mul } - { pageHeight 7 mul } - ifelse def - - % Create fonts... - /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold - pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33) - - /mediumFont /Helvetica findfont % mediumFont = Helvetica - pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5) - - /smallFont /Times-Roman findfont % smallFont = Times-Roman - pageHeight scalefont def % size = pageHeight (nominally 11) - - % Draw rulers along the edges... - /CENTIMETER 72 2.54 div def - /MILLIMETER 72 25.4 div def - - /Times-Roman findfont % Font for ruler numbers - 11 scalefont setfont % 11 points - - gsave % Left side inches - pageLeft 72 mul 0 translate % Offset left edge - - 1 setlinewidth % Draw normal lines - 72 72 pageTop 72 mul { % Height inches - dup dup - 0 exch moveto 24 0 rlineto stroke % Draw tic mark - 24 exch pageHeight sub moveto % Draw number - 72 div cvi 10 string cvs RIGHT - } for - - 0.5 setlinewidth % Draw thin lines - 18 18 pageTop 72 mul { % 1/4 inches - 0 exch moveto 15 0 rlineto stroke % Draw tic mark - } for - - 9 9 pageTop 72 mul { % 1/8 inches - 0 exch moveto 6 0 rlineto stroke % Draw tic mark - } for - grestore - - gsave % Bottom inches - 0 pageBottom 72 mul translate % Offset bottom edge - - 1 setlinewidth % Draw normal lines - 72 72 pageRight 72 mul { % Width inches - dup dup - 0 moveto 0 24 rlineto stroke % Draw tic mark - 3 add 27 pageHeight sub moveto % Draw number - 72 div cvi 10 string cvs show - } for - - 0.5 setlinewidth % Draw thin lines - 18 18 pageRight 72 mul { % 1/4 inches - 0 moveto 0 15 rlineto stroke % Draw tic mark - } for - - 9 9 pageRight 72 mul { % 1/8 inches - 0 moveto 0 6 rlineto stroke % Draw tic mark - } for - grestore - - gsave % Right side centimeters - pageRight 72 mul 0 translate % Offset right edge - - 1 setlinewidth % Draw normal lines - CENTIMETER CENTIMETER - pageTop 72 mul { % Height centimeters - 0 exch moveto -24 0 rlineto stroke% Draw tic mark - } for - 1 1 pageTop 2.54 mul { % Height labels - dup - -24 exch CENTIMETER mul - pageHeight sub moveto % Draw number - cvi 10 string cvs show - } for - - 0.5 setlinewidth % Draw thin lines - 0 0.5 CENTIMETER mul - pageTop 72 mul { % 1/2 centimeters - 0 exch moveto -15 0 rlineto stroke% Draw tic mark - } for - 0 MILLIMETER pageTop 72 mul { % Millimeters - 0 exch moveto -6 0 rlineto stroke % Draw tic mark - } for - grestore - - gsave % Top centimeters - 0 pageTop 72 mul translate % Offset top edge - - 1 setlinewidth % Draw normal lines - CENTIMETER CENTIMETER - pageRight 72 mul { % Width centimeters - 0 moveto 0 -24 rlineto stroke % Draw tic mark - } for - 1 1 pageRight 2.54 mul { % Width labels - dup - CENTIMETER mul 3 add -24 moveto % Draw number - cvi 10 string cvs show - } for - - 0.5 setlinewidth % Draw thin lines - 0 0.5 CENTIMETER mul - pageRight 72 mul { % 1/2 centimeters - 0 moveto 0 -15 rlineto stroke % Draw tic mark - } for - 0 MILLIMETER pageRight 72 mul { % Millimeters - 0 moveto 0 -6 rlineto stroke % Draw tic mark - } for - grestore - - % Offset page to account for lower-left margin... - pageLeft 72 mul - pageBottom 72 mul - translate - - % Set text font and color... - mediumFont setfont % Font - 0 setgray % Color - 1 setlinewidth % Draw normal lines - - % Draw the color wheel... - gsave - % Position the wheel on the left side... - pageWidth 18 mul % x = pageWidth * 1/4 * 72 - pageHeight 54 mul % y = pageHeight * 3/4 * 72 - translate - - % Size the wheel... - wheelSize - - % Draw the colors... - dup (C) 3 -1 roll 0 1 1 SEXTANT 60 rotate - dup (M) 3 -1 roll 1 0 1 SEXTANT 60 rotate - dup (Y) 3 -1 roll 1 1 0 SEXTANT 60 rotate - dup (R) 3 -1 roll 1 0 0 SEXTANT 60 rotate - dup (G) 3 -1 roll 0 1 0 SEXTANT 60 rotate - dup (B) 3 -1 roll 0 0 1 SEXTANT 60 rotate - - pop - grestore - - % Label the color wheel... - pageWidth 18 mul % x = pageWidth * 1/4 * 72 - pageHeight 43 mul % y = pageHeight * 19/32 * 72 - moveto % Position the text - (Color Wheel) CENTER % Show the text centered - - % Draw the gray ramp... - gsave - % Position the gray ramp in the center... - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - pageHeight 54 mul % y = pageHeight * 3/4 * 72 - wheelSize sub % - wheelSize - translate - - % Loop through 100 shades... - 0 0.010101 0.98 { - % Set the color... - dup setgray % Set the grayscale... - - % Draw the polygon... - newpath % Start a new path... - - wheelSize -0.2 mul % X = -wheelSize / 5 - 1 index 2 mul wheelSize mul % Y = val * 2 * wheelSize - moveto % Move there... - - wheelSize 0.4 mul 0 rlineto % Right side... - - wheelSize 0.2 mul % X = wheelSize / 5 - 1 index 0.010101 add 2 mul wheelSize mul - % Y = (val + 0.010101) * 2 * wheelSize - lineto % Move there... - - wheelSize -0.4 mul 0 rlineto % Left side... - - closepath % Close the path - fill % Fill it... - - pop % Pop value... - } for - - 0 setgray % Black - - newpath % Start a new path - wheelSize -0.2 mul 0 moveto % Bottom left - wheelSize 0.4 mul 0 rlineto % Bottom right - 0 wheelSize 2 mul rlineto % Upper right - wheelSize -0.4 mul 0 rlineto % Upper left - closepath % Close the path - stroke % Stroke it... - - 0 wheelSize -0.2 mul moveto % Center bottom for label - (K) CENTER % Center K at bottom - - 0 wheelSize 2.05 mul moveto % Center top for label - (W) CENTER % Center W at top - grestore - - % Label the gray ramp... - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - pageHeight 43 mul % y = pageHeight * 19/32 * 72 - moveto % Position the text - (Gray Ramp) CENTER % Show the text centered - - - % Draw radial lines... - gsave - 0 setlinewidth % 1 pixel lines - - % Position the lines on the left side... - pageWidth 54 mul % x = pageWidth * 3/4 * 72 - pageHeight 54 mul % y = pageHeight * 3/4 * 72 - translate - - % Size the wheel... - wheelSize - - % Loop at 1 degree increments - 0 1 359 { - pop % Discard angle - not used - 0 0 moveto % Start line at the center - dup 0 lineto % Draw to the radius - 1 rotate % Rotate 1 degree - } for - - pop % Discard radius - not needed anymore - stroke % Draw lines... - - grestore - - % Label the lines... - pageWidth 54 mul % x = pageWidth * 3/4 * 72 - pageHeight 43 mul % y = pageHeight * 19/32 * 72 - moveto % Position the text - (1 Degree Radial Lines) CENTER % Show the text centered - - % Imageable area... - pageHeight 15 mul % Height of imageable area - - pageWidth 4.5 mul % x = pageWidth * 1/16 * 72 - pageHeight 35.5 mul % y = pageHeight * 1/2 * 72 - 2 index sub % y -= height - pageWidth 28 mul % width = pageWidth * 1/4 * 72 - 3 index % height - 0.5 setgray rectfill % Draw a shadow - - pageWidth 4 mul % x = pageWidth * 1/16 * 72 - pageHeight 36 mul % y = pageHeight * 1/2 * 72 - 2 index sub % y -= height - pageWidth 28 mul % width = pageWidth * 3/8 * 72 - 3 index % height - 4 copy 1 setgray rectfill % Clear the box to white - 0 setgray rectstroke % Draw a black box around it... - - pop % Discard height - - % Label the imageable area... - pageWidth 4 mul % x = pageWidth * 1/16 * 72 - pageHeight 37 mul % y = pageHeight * 1/2 * 72 - moveto % Position the text - mediumFont setfont % Font - (Imageable Area) show % Show the text - - smallFont setfont % Font - pageWidth 14 mul % x = pageWidth * 3/16 * 72 - pageHeight 36 mul % y = pageWidth * 1/2 * 72 - pageHeight -2 mul add % y -= 2 * smallFont height - - % Page Size inches - 2 copy moveto % Move to x & y - (Page Size: ) RIGHT % Label - 100 pageWidth NUMBER % pageWidth - (x) show % "x" - 100 pageHeight NUMBER % pageHeight - (in) show % "in" - - % Page Size millimeters - pageHeight sub % Move down... - - 2 copy moveto % Move to x & y - 10 pageWidth 25.4 mul NUMBER % pageWidth - (x) show % "x" - 10 pageHeight 25.4 mul NUMBER % pageHeight - (mm) show % "mm" - - % Lower-left inches - pageHeight 2 mul sub % Move down... - - 2 copy moveto % Move to x & y - (Lower-Left: ) RIGHT % Label - 100 pageLeft NUMBER % pageLeft - (x) show % "x" - 100 pageBottom NUMBER % pageBottom - (in) show % "in" - - % Lower-left millimeters - pageHeight sub % Move down... - - 2 copy moveto % Move to x & y - 10 pageLeft 25.4 mul NUMBER % pageLeft - (x) show % "x" - 10 pageBottom 25.4 mul NUMBER % pageBottom - (mm) show % "mm" - - % Upper-right inches - pageHeight 2 mul sub % Move down... - - 2 copy moveto % Move to x & y - (Upper-Right: ) RIGHT % Label - 100 pageRight NUMBER % pageRight - (x) show % "x" - 100 pageTop NUMBER % pageTop - (in) show % "in" - - % Upper-right millimeters - pageHeight sub % Move down... - - 2 copy moveto % Move to x & y - 10 pageRight 25.4 mul NUMBER % pageRight - (x) show % "x" - 10 pageTop 25.4 mul NUMBER % pageTop - (mm) show % "mm" - - % Resolution dots-per-inch - pageHeight 2 mul sub % Move down... - - 2 copy moveto % Move to x & y - (Resolution: ) RIGHT % Label - 1 xResolution NUMBER % xResolution - (x) show % "x" - 1 yResolution NUMBER % yResolution - (dpi) show % "dpi" - - % Resolution dots-per-meter - pageHeight sub % Move down... - - moveto % Move to x & y - 1 xResolution 39.27 mul NUMBER % xResolution - (x) show % "x" - 1 yResolution 39.27 mul NUMBER % yResolution - (dpm) show % "dpm" - - % Interpreter Information... - pageHeight 15 mul % Height of interpreter information - - pageWidth 40.5 mul % x = pageWidth * 9/16 * 72 - pageHeight 35.5 mul % y = pageHeight * 1/2 * 72 - 2 index sub % y -= height - pageWidth 28 mul % width = pageWidth * 1/4 * 72 - 3 index % height - 0.5 setgray rectfill % Draw a shadow - - pageWidth 40 mul % x = pageWidth * 9/16 * 72 - pageHeight 36 mul % y = pageHeight * 1/2 * 72 - 2 index sub % y -= height - pageWidth 28 mul % width = pageWidth * 3/8 * 72 - 3 index % height - 4 copy 1 setgray rectfill % Clear the box to white - 0 setgray rectstroke % Draw a black box around it... - - pop % Discard height - - % Label the interpreter info... - pageWidth 40 mul % x = pageWidth * 9/16 * 72 - pageHeight 37 mul % y = pageHeight * 1/2 * 72 - moveto % Position the text - mediumFont setfont % Font - (Interpreter Information) show % Show the text - - smallFont setfont % Font - pageWidth 49 mul % x = pageWidth * 11/16 * 72 - pageHeight 36 mul % y = pageWidth * 1/2 * 72 - pageHeight 2 mul sub % y -= 2 * smallFont height - - % Language level - 2 copy moveto % Move to x & y - (PostScript: ) RIGHT % Label - (Level ) show % "Level " - 1 languagelevel NUMBER % Language level - - % Version - pageHeight 2 mul sub % Move down... - 2 copy moveto % Move to x & y - (Version: ) RIGHT % Label - version show % Version - ( \() show % " (" - 1 revision NUMBER % Revision - (\)) show % ")" - - % Product - pageHeight 2 mul sub % Move down... - 2 copy moveto % Move to x & y - (Product: ) RIGHT % Label - product show % Product name - - % Serial Number - pageHeight 2 mul sub % Move down... - moveto % Move to x & y - (Serial #: ) RIGHT % Label - 1 serialnumber NUMBER % S/N - - % Draw the label at the top... - pageWidth 36 mul % Center of page - pageHeight 66 mul % Top of page (11/12ths) - moveto % Position text - bigFont setfont % Font - (Printer Test Page) CENTER % Show text centered - - % Draw the copyright notice at the bottom... - pageWidth 17 mul % Center of page - pageHeight 10 mul % Bottom of page - moveto % Position text - (Printed Using CUPS v1.4.x) show - - pageWidth 17 mul % Left side of page - pageHeight 8 mul % Move down... - 2 copy moveto % Position text - smallFont setfont % Font - (Copyright 2007-2008 Apple Inc., All Rights Reserved. CUPS and the CUPS logo are the) show - pageHeight 2 add sub % Move down... - 2 copy moveto % Position text - (trademark property of Apple Inc., 1 Infinite Loop, Cupertino, CA 95014, USA.) show - pageHeight 2 mul 4 add sub % Move down... - moveto % Position text - (Need help? Contact your operating system vendor or visit "http://www.cups.org/".) show - - % Then the CUPS logo.... - gsave - pageWidth 4 mul - pageHeight 4 mul - translate - pageWidth 15 mul CUPSLOGO - grestore - -% Show the page... -grestore -showpage -% -% End of "$Id: testprint.ps 7157 2008-01-02 21:22:42Z mike $". -% -%%EOF +#CUPS-BANNER +# While this file has a .ps extension, it is really just a special banner +# page - we are retaining the original filename for backwards-compatibility. +Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area +Header Printer Test Page +Footer Printer Test Page +Notice This test page was produced by CUPS 1.4. +Image images/cups.rgb diff --git a/data/topsecret b/data/topsecret index 7ac9b5b63..6839af849 100644 --- a/data/topsecret +++ b/data/topsecret @@ -1,159 +1,6 @@ -%!PS-Adobe-3.0 -%%BoundingBox: 0 0 612 792 -%%Pages: 1 -%%LanguageLevel: 1 -%%DocumentData: Clean7Bit -%%DocumentSuppliedResources: procset bannerprint/1.0 -%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman -%%Creator: Michael Sweet, Apple Inc. -%%CreationDate: D:20070620123000+0700 -%%Title: Test Page -%%EndComments -%%BeginProlog -%%BeginResource procset bannerprint 1.3 0 -% -% PostScript banner page for the Common UNIX Printing System ("CUPS"). -% -% Copyright 2007 Apple Inc. -% Copyright 1993-2005 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 is included with the CUPS source distribution. -% -/CENTER { % Draw centered text - % (name) CENTER - - dup stringwidth pop % Get the width of the string - 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance - show % Show the string -} bind def -/RIGHT { % Draw right-justified text - % (name) RIGHT - - dup stringwidth pop % Get the width of the string - neg 0 rmoveto % Shift left the entire distance - show % Show the string -} bind def -/NUMBER { % Draw a number - % power n NUMBER - - 1 index 1 eq { % power == 1? - round cvi exch pop % Convert "n" to integer - } { - 1 index mul round exch div % Truncate extra decimal places - } ifelse - 100 string cvs show % Convert to a string and show it... -} bind def -%%EndResource -%%EndProlog -%%Page: 1 1 -gsave +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Top Secret +Footer Top Secret +Image images/cups.rgb - % Determine the imageable area and device resolution... - initclip newpath clippath pathbbox % Get bounding rectangle - 72 div /pageTop exch def % Get top margin in inches - 72 div /pageRight exch def % Get right margin in inches - 72 div /pageBottom exch def % Get bottom margin in inches - 72 div /pageLeft exch def % Get left margin in inches - - /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft - /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom - - /boxWidth % width of text box - pageWidth pageHeight lt - { pageWidth 54 mul } - { pageHeight 42 mul } - ifelse def - - newpath % Clear bounding path - - % Create fonts... - /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold - pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33) - - /mediumFont /Helvetica findfont % mediumFont = Helvetica - pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5) - - % Offset page to account for lower-left margin... - pageLeft 72 mul - pageBottom 72 mul - translate - - % Draw the label at the top and bottom... - 0 setgray % Color - - pageWidth 36 mul % Center of page - pageHeight 72 mul % Top of page - pageWidth 9 mul sub % - 3 lines - moveto % Position text - bigFont setfont % Font - (Top Secret) CENTER % Show text centered - - pageWidth 36 mul % Center of page - pageHeight 6 mul % Bottom of page - moveto % Position text - bigFont setfont % Font - (Top Secret) CENTER % Show text centered - - % Job information box... - pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - 0.5 setgray rectfill % Draw a shadow - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul % y = pageHeight * 1/4 * 72 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - - 4 copy 1 setgray rectfill % Clear the box to white - 0 setgray rectstroke % Draw a black box around it... - - % Job information text... - mediumFont setfont % Medium sized font - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - pageHeight 36 mul % y = pageHeight * 1/2 * 72 - pageHeight 5 mul add % y += 3.333 lines - 2 copy % Copy X & Y - moveto - (Job ID: ) RIGHT - 2 copy % Copy X & Y - moveto - ({printer-name}-{job-id}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Title: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-name}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Requesting User: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-originating-user-name}) show - - ({?job-billing}) () ne { - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Billing Info: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-billing}) show - } if - -% Show the page... -grestore -showpage -% -% End of "$Id: topsecret 6649 2007-07-11 21:46:42Z mike $". -% -%%EOF diff --git a/data/unclassified b/data/unclassified index 385f903a9..2c5d9162d 100644 --- a/data/unclassified +++ b/data/unclassified @@ -1,159 +1,6 @@ -%!PS-Adobe-3.0 -%%BoundingBox: 0 0 612 792 -%%Pages: 1 -%%LanguageLevel: 1 -%%DocumentData: Clean7Bit -%%DocumentSuppliedResources: procset bannerprint/1.0 -%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman -%%Creator: Michael Sweet, Apple Inc. -%%CreationDate: D:20070620123000+0700 -%%Title: Test Page -%%EndComments -%%BeginProlog -%%BeginResource procset bannerprint 1.3 0 -% -% PostScript banner page for the Common UNIX Printing System ("CUPS"). -% -% Copyright 2007 Apple Inc. -% Copyright 1993-2005 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 is included with the CUPS source distribution. -% -/CENTER { % Draw centered text - % (name) CENTER - - dup stringwidth pop % Get the width of the string - 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance - show % Show the string -} bind def -/RIGHT { % Draw right-justified text - % (name) RIGHT - - dup stringwidth pop % Get the width of the string - neg 0 rmoveto % Shift left the entire distance - show % Show the string -} bind def -/NUMBER { % Draw a number - % power n NUMBER - - 1 index 1 eq { % power == 1? - round cvi exch pop % Convert "n" to integer - } { - 1 index mul round exch div % Truncate extra decimal places - } ifelse - 100 string cvs show % Convert to a string and show it... -} bind def -%%EndResource -%%EndProlog -%%Page: 1 1 -gsave +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Unclassified +Footer Unclassified +Image images/cups.rgb - % Determine the imageable area and device resolution... - initclip newpath clippath pathbbox % Get bounding rectangle - 72 div /pageTop exch def % Get top margin in inches - 72 div /pageRight exch def % Get right margin in inches - 72 div /pageBottom exch def % Get bottom margin in inches - 72 div /pageLeft exch def % Get left margin in inches - - /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft - /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom - - /boxWidth % width of text box - pageWidth pageHeight lt - { pageWidth 54 mul } - { pageHeight 42 mul } - ifelse def - - newpath % Clear bounding path - - % Create fonts... - /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold - pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33) - - /mediumFont /Helvetica findfont % mediumFont = Helvetica - pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5) - - % Offset page to account for lower-left margin... - pageLeft 72 mul - pageBottom 72 mul - translate - - % Draw the label at the top and bottom... - 0 setgray % Color - - pageWidth 36 mul % Center of page - pageHeight 72 mul % Top of page - pageWidth 9 mul sub % - 3 lines - moveto % Position text - bigFont setfont % Font - (Unclassified) CENTER % Show text centered - - pageWidth 36 mul % Center of page - pageHeight 6 mul % Bottom of page - moveto % Position text - bigFont setfont % Font - (Unclassified) CENTER % Show text centered - - % Job information box... - pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - 0.5 setgray rectfill % Draw a shadow - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - boxWidth 0.5 mul sub % x-= 1/2 box width - pageHeight 30 mul % y = pageHeight * 1/4 * 72 - boxWidth % w = box width - pageHeight 14 mul % h = pageHeight * 1/2 * 72 - - 4 copy 1 setgray rectfill % Clear the box to white - 0 setgray rectstroke % Draw a black box around it... - - % Job information text... - mediumFont setfont % Medium sized font - - pageWidth 36 mul % x = pageWidth * 1/2 * 72 - pageHeight 36 mul % y = pageHeight * 1/2 * 72 - pageHeight 5 mul add % y += 3.333 lines - 2 copy % Copy X & Y - moveto - (Job ID: ) RIGHT - 2 copy % Copy X & Y - moveto - ({printer-name}-{job-id}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Title: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-name}) show - - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Requesting User: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-originating-user-name}) show - - ({?job-billing}) () ne { - pageHeight 3 mul sub % y -= 2 lines - 2 copy % Copy X & Y - moveto - (Billing Info: ) RIGHT - 2 copy % Copy X & Y - moveto - ({job-billing}) show - } if - -% Show the page... -grestore -showpage -% -% End of "$Id: unclassified 6649 2007-07-11 21:46:42Z mike $". -% -%%EOF diff --git a/doc/Makefile b/doc/Makefile index 48fd2768e..bb4fc91e0 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -27,6 +27,7 @@ WEBPAGES = \ robots.txt WEBIMAGES = \ images/cups.png \ + images/cups.rgb \ images/cups-block-diagram.gif \ images/cups-icon.png \ images/left.gif \ diff --git a/doc/help/spec-banner.html b/doc/help/spec-banner.html index 323437978..818cf67ec 100644 --- a/doc/help/spec-banner.html +++ b/doc/help/spec-banner.html @@ -98,11 +98,11 @@ the job information.</p> <h3><a name='Show'>Show</a></h3> <p class='summary'> -Show <em>keyword keyword ... keyword</em> +Show <em>value value ... value</em> </p> <p>The <code>Show</code> key lists the job information that is shown. The -following keywords are supported:</p> +following values are supported:</p> <ul> @@ -126,6 +126,10 @@ following keywords are supported:</p> <li><code>options</code>: The options that were provided with the job</li> + <li><code>paper-name</code>: The name of the paper size used</li> + + <li><code>paper-size</code>: The dimensions of the paper size used.</li> + <li><code>printer-driver-name</code>: The printer driver used</li> <li><code>printer-driver-version</code>: The driver version</li> @@ -141,6 +145,8 @@ following keywords are supported:</p> <li><code>time-at-creation</code>: When the job was submitted</li> + <li><code>time-at-processing</code>: The current date and time</li> + </ul> diff --git a/filter/Makefile b/filter/Makefile index 88e69c35b..d87fc97db 100644 --- a/filter/Makefile +++ b/filter/Makefile @@ -19,6 +19,7 @@ include ../Makedefs FILTERS = \ + bannertops \ commandtops \ gziptoany \ hpgltops \ @@ -53,7 +54,7 @@ IMAGE64OBJS = $(IMAGEOBJS:.o=.64.o) FORMOBJS = form-attr.o form-main.o form-ps.o form-text.o form-tree.o OBJS = $(HPGLOBJS) $(IMAGEOBJS) $(FORMOBJS) \ bannertops.o commandtops.o gziptoany.o imagetops.o \ - imagetoraster.o common.o pdftops.o pstops.o \ + imagetoraster.o common.o pdftops.o pstext.o pstops.o \ rasterbench.o rastertoepson.o rastertohp.o rastertolabel.o \ testimage.o testraster.o textcommon.o texttops.o @@ -236,9 +237,10 @@ framedhelp: # bannertops # -bannertops: bannertops.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) +bannertops: bannertops.o pstext.o common.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ bannertops.o $(LIBS) + $(CC) $(LDFLAGS) -o $@ bannertops.o pstext.o common.o $(LINKCUPSIMAGE) \ + $(IMGLIBS) $(LIBS) # diff --git a/filter/bannertops.c b/filter/bannertops.c index b4af85090..db4bd9112 100644 --- a/filter/bannertops.c +++ b/filter/bannertops.c @@ -21,1273 +21,1059 @@ * Include necessary headers... */ -#include "common.h" +#include "pstext.h" #include "image.h" #include <cups/i18n.h> /* - * Globals... + * Constants... */ -char *Glyphs[65536]; /* PostScript glyphs for Unicode */ -int NumFonts; /* Number of fonts to use */ -char *Fonts[256][4]; /* Fonts to use */ -unsigned short Chars[65536]; /* 0xffcc (ff = font, cc = char) */ -unsigned short Codes[65536]; /* Unicode glyph mapping to fonts */ -int Widths[256]; /* Widths of each font */ -int Directions[256];/* Text directions for each font */ +#define SHOW_IMAGEABLE_AREA 1 /* Show imageable area */ +#define SHOW_JOB_BILLING 2 /* Show billing string */ +#define SHOW_JOB_ID 4 /* Show job ID */ +#define SHOW_JOB_NAME 8 /* Show job title */ +#define SHOW_JOB_ORIGINATING_USER_NAME 16 /* Show owner of job */ +#define SHOW_JOB_ORIGINATING_HOST_NAME 32 /* Show submitting system */ +#define SHOW_JOB_UUID 64 /* Show job UUID */ +#define SHOW_OPTIONS 128 /* Show print options */ +#define SHOW_PAPER_NAME 256 /* Show paper size name */ +#define SHOW_PAPER_SIZE 512 /* Show paper dimensions */ +#define SHOW_PRINTER_DRIVER_NAME 1024 /* Show printer driver name */ +#define SHOW_PRINTER_DRIVER_VERSION 2048 /* Show printer driver version */ +#define SHOW_PRINTER_INFO 4096 /* Show printer description */ +#define SHOW_PRINTER_LOCATION 8192 /* Show printer location */ +#define SHOW_PRINTER_MAKE_AND_MODEL 16384 /* Show printer make and model */ +#define SHOW_PRINTER_NAME 32768 /* Show printer queue ID */ +#define SHOW_TIME_AT_CREATION 65536 /* Show date/time when submitted */ +#define SHOW_TIME_AT_PROCESSING 131072 /* Show date/time when printed */ /* - * Local functions... - */ - -static void write_line(int row, lchar_t *line); -static void write_string(int col, int row, int len, lchar_t *s); -static void write_text(const char *s); - - -/* - * 'main()' - Generate PostScript cover pages. + * Structures... */ -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments */ - char *argv[]) /* I - Command-line arguments */ +typedef struct banner_file_s /**** Banner file data ****/ { -} + int show; /* What to show */ + char *header, /* Header text */ + *footer; /* Footer text */ + cups_array_t *notices, /* Notices to show */ + *images; /* Images to show */ +} banner_file_t; /* - * 'WriteEpilogue()' - Write the PostScript file epilogue. - */ - -void -WriteEpilogue(void) -{ - puts("%%Trailer"); - printf("%%%%Pages: %d\n", NumPages); - puts("%%EOF"); - - free(Page[0]); - free(Page); -} - - -/* - * 'WritePage()' - Write a page of text. + * Local functions... */ -void -WritePage(void) -{ - int line; /* Current line */ - - - NumPages ++; - printf("%%%%Page: %d %d\n", NumPages, NumPages); - - puts("gsave"); - - if (PrettyPrint) - printf("%d H\n", NumPages); - - for (line = 0; line < SizeLines; line ++) - write_line(line, Page[line]); - - puts("grestore"); - puts("showpage"); - - memset(Page[0], 0, sizeof(lchar_t) * SizeColumns * SizeLines); -} +static banner_file_t *load_banner(const char *filename); +static int write_banner(banner_file_t *banner, ppd_file_t *ppd, + ps_text_t *fonts, int job_id, + const char *title, const char *username, + int num_options, cups_option_t *options); +static void write_epilogue(int num_pages); +static ps_text_t *write_prolog(const char *title, const char *user); /* - * 'WriteProlog()' - Write the PostScript file prolog with options. + * 'main()' - Generate PostScript cover pages. */ -void -WriteProlog(const char *title, /* I - Title of job */ - const char *user, /* I - Username */ - const char *classification, /* I - Classification */ - const char *label, /* I - Page label */ - ppd_file_t *ppd) /* I - PPD file info */ +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ { - int i, j, k; /* Looping vars */ - char *charset; /* Character set string */ - char filename[1024]; /* Glyph filenames */ - FILE *fp; /* Glyph files */ - const char *datadir; /* CUPS_DATADIR environment variable */ - char line[1024], /* Line from file */ - *lineptr, /* Pointer into line */ - *valptr; /* Pointer to value in line */ - int ch, unicode; /* Character values */ - int start, end; /* Start and end values for range */ - char glyph[64]; /* Glyph name */ - time_t curtime; /* Current time */ - struct tm *curtm; /* Current date */ - char curdate[255]; /* Current date (text format) */ - int num_fonts; /* Number of unique fonts */ - char *fonts[1024]; /* Unique fonts */ - static char *names[] = /* Font names */ - { - "cupsNormal", - "cupsBold", - "cupsItalic" - }; + banner_file_t *banner; /* Banner file data */ + int num_options; /* Number of print options */ + cups_option_t *options; /* Print options */ + ppd_file_t *ppd; /* PPD file */ + ps_text_t *fonts; /* Fonts for output */ + int job_id; /* Job ID from command-line */ + const char *title, /* Title from command-line */ + *username; /* Username from command-line */ + int num_pages; /* Number of pages printed */ /* - * Get the data directory... + * Make sure status messages are not buffered... */ - if ((datadir = getenv("CUPS_DATADIR")) == NULL) - datadir = CUPS_DATADIR; + setbuf(stderr, NULL); /* - * Adjust margins as necessary... + * Check command-line... */ - if (classification || label) + if (argc < 6 || argc > 7) { - /* - * Leave room for labels... - */ - - PageBottom += 36; - PageTop -= 36; + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + "bannertops"); + return (1); } /* - * Allocate memory for the page... + * Get stuff from command-line... */ - SizeColumns = (PageRight - PageLeft) / 72.0 * CharsPerInch; - SizeLines = (PageTop - PageBottom) / 72.0 * LinesPerInch; + job_id = atoi(argv[1]); + username = argv[2]; + title = argv[3]; + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + banner = load_banner(argv[6]); - Page = calloc(sizeof(lchar_t *), SizeLines); - Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines); - for (i = 1; i < SizeLines; i ++) - Page[i] = Page[0] + i * SizeColumns; + /* + * Set standard options and get the PPD file for this printer... + */ - if (PageColumns > 1) - { - ColumnGutter = CharsPerInch / 2; - ColumnWidth = (SizeColumns - ColumnGutter * (PageColumns - 1)) / - PageColumns; - } - else - ColumnWidth = SizeColumns; + ppd = SetCommonOptions(num_options, options, 1); /* - * Output the DSC header... + * Write a PostScript banner document and return... */ - curtime = time(NULL); - curtm = localtime(&curtime); - strftime(curdate, sizeof(curdate), "%c", curtm); + fonts = write_prolog(title, username); + num_pages = write_banner(banner, ppd, fonts, job_id, title, username, + num_options, options); - puts("%!PS-Adobe-3.0"); - printf("%%%%BoundingBox: 0 0 %.0f %.0f\n", PageWidth, PageLength); - printf("%%cupsRotation: %d\n", (Orientation & 3) * 90); - puts("%%Creator: texttops/" CUPS_SVERSION); - printf("%%%%CreationDate: %s\n", curdate); - WriteTextComment("Title", title); - WriteTextComment("For", user); - puts("%%Pages: (atend)"); + write_epilogue(num_pages); - /* - * Initialize globals... - */ + return (0); +} - NumFonts = 0; - memset(Fonts, 0, sizeof(Fonts)); - memset(Glyphs, 0, sizeof(Glyphs)); - memset(Chars, 0, sizeof(Chars)); - memset(Codes, 0, sizeof(Codes)); - /* - * Load the PostScript glyph names and the corresponding character - * set definition... - */ +/* + * 'load_banner()' - Load the banner file. + */ - snprintf(filename, sizeof(filename), "%s/data/psglyphs", datadir); +static banner_file_t * /* O - Banner file data */ +load_banner(const char *filename) /* I - Filename or NULL for stdin */ +{ + cups_file_t *fp; /* File */ + char line[2048], /* Line buffer */ + *ptr; /* Pointer into line */ + int linenum; /* Current line number */ + banner_file_t *banner; /* Banner file data */ + const char *cups_docroot; /* CUPS_DOCROOT environment variable */ - if ((fp = fopen(filename, "r")) != NULL) - { - while (fscanf(fp, "%x%63s", &unicode, glyph) == 2) - Glyphs[unicode] = strdup(glyph); - fclose(fp); - } + fprintf(stderr, "DEBUG: load_banner(filename=\"%s\")\n", + filename ? filename : "(stdin)"); + + /* + * Open the banner file... + */ + + if (filename) + fp = cupsFileOpen(filename, "r"); else + fp = cupsFileStdin(); + + if (!fp) { - fprintf(stderr, _("ERROR: Unable to open \"%s\" - %s\n"), filename, - strerror(errno)); + _cupsLangPrintf(stderr, + _("ERROR: Unable to open banner file \"%s\" - %s\n"), + filename ? filename : "(stdin)", strerror(errno)); exit(1); } /* - * Get the output character set... + * Read the banner file... */ - charset = getenv("CHARSET"); - if (charset != NULL && strcmp(charset, "us-ascii") != 0) + if ((cups_docroot = getenv("CUPS_DOCROOT")) == NULL) + cups_docroot = CUPS_DOCROOT; + + banner = calloc(1, sizeof(banner_file_t)); + linenum = 0; + + while (cupsFileGets(fp, line, sizeof(line))) { - snprintf(filename, sizeof(filename), "%s/charsets/%s", datadir, charset); + /* + * Skip blank and comment lines... + */ - if ((fp = fopen(filename, "r")) == NULL) - { - /* - * Can't open charset file! - */ + linenum ++; - fprintf(stderr, _("ERROR: Unable to open %s: %s\n"), filename, - strerror(errno)); - exit(1); - } + if (line[0] == '#' || !line[0]) + continue; /* - * Opened charset file; now see if this is really a charset file... + * Break the line into keyword and value parts... */ - if (fgets(line, sizeof(line), fp) == NULL) - { - /* - * Bad/empty charset file! - */ + for (ptr = line; *ptr && !isspace(*ptr & 255); ptr ++); - fclose(fp); - fprintf(stderr, _("ERROR: Bad charset file %s\n"), filename); - exit(1); - } + while (isspace(*ptr & 255)) + *ptr++ = '\0'; - if (strncmp(line, "charset", 7) != 0) + if (!*ptr) { - /* - * Bad format/not a charset file! - */ - - fclose(fp); - fprintf(stderr, _("ERROR: Bad charset file %s\n"), filename); - exit(1); + _cupsLangPrintf(stderr, + _("ERROR: Missing value on line %d of banner file!\n"), + linenum); + continue; } /* - * See if this is an 8-bit or UTF-8 character set file... + * Save keyword values in the appropriate places... */ - line[strlen(line) - 1] = '\0'; /* Drop \n */ - for (lineptr = line + 7; isspace(*lineptr & 255); lineptr ++); /* Skip whitespace */ - - if (strcmp(lineptr, "8bit") == 0) + if (!strcasecmp(line, "Footer")) { - /* - * 8-bit text... - */ + if (banner->footer) + fprintf(stderr, "DEBUG: Extra \"Footer\" on line %d of banner file!\n", + linenum); + else + banner->footer = strdup(ptr); + } + else if (!strcasecmp(line, "Header")) + { + if (banner->header) + fprintf(stderr, "DEBUG: Extra \"Header\" on line %d of banner file!\n", + linenum); + else + banner->header = strdup(ptr); + } + else if (!strcasecmp(line, "Image")) + { + char imagefile[1024]; /* Image filename */ - UTF8 = 0; - NumFonts = 0; - /* - * Read the font description(s)... - */ + if (ptr[0] == '/') + strlcpy(imagefile, ptr, sizeof(imagefile)); + else + snprintf(imagefile, sizeof(imagefile), "%s/%s", cups_docroot, ptr); - while (fgets(line, sizeof(line), fp) != NULL) + if (access(imagefile, R_OK)) { - /* - * Skip comment and blank lines... - */ - - if (line[0] == '#' || line[0] == '\n') - continue; - - /* - * Read the font descriptions that should look like: - * - * first last direction width normal [bold italic bold-italic] - */ - - lineptr = line; - - start = strtol(lineptr, &lineptr, 16); - end = strtol(lineptr, &lineptr, 16); - - while (isspace(*lineptr & 255)) - lineptr ++; - - if (!*lineptr) - break; /* Must be a font mapping */ - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (!*lineptr) - { - /* - * Can't have a font without all required values... - */ - - fprintf(stderr, _("ERROR: Bad font description line: %s\n"), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (strcmp(valptr, "ltor") == 0) - Directions[NumFonts] = 1; - else if (strcmp(valptr, "rtol") == 0) - Directions[NumFonts] = -1; - else - { - fprintf(stderr, _("ERROR: Bad text direction %s\n"), valptr); - fclose(fp); - exit(1); - } - - /* - * Got the direction, now get the width... - */ - - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (!*lineptr) - { - /* - * Can't have a font without all required values... - */ - - fprintf(stderr, _("ERROR: Bad font description line: %s\n"), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (strcmp(valptr, "single") == 0) - Widths[NumFonts] = 1; - else if (strcmp(valptr, "double") == 0) - Widths[NumFonts] = 2; - else - { - fprintf(stderr, _("ERROR: Bad text width %s\n"), valptr); - fclose(fp); - exit(1); - } - - /* - * Get the fonts... - */ - - for (i = 0; *lineptr && i < 4; i ++) - { - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (*lineptr) - *lineptr++ = '\0'; - - if (lineptr > valptr) - Fonts[NumFonts][i] = strdup(valptr); - } - - /* - * Fill in remaining fonts as needed... - */ - - for (j = i; j < 4; j ++) - Fonts[NumFonts][j] = strdup(Fonts[NumFonts][0]); - - /* - * Define the character mappings... - */ - - for (i = start, j = NumFonts * 256; i <= end; i ++, j ++) - Chars[i] = j; - - NumFonts ++; + fprintf(stderr, "DEBUG: Image \"%s\" on line %d of banner file: %s\n", + ptr, linenum, strerror(errno)); } - - /* - * Read encoding lines... - */ - - do + else { - /* - * Skip comment and blank lines... - */ - - if (line[0] == '#' || line[0] == '\n') - continue; + if (!banner->images) + banner->images = cupsArrayNew(NULL, NULL); - /* - * Grab the character and unicode glyph number. - */ - - if (sscanf(line, "%x%x", &ch, &unicode) == 2 && ch < 256) - Codes[Chars[ch]] = unicode; + cupsArrayAdd(banner->images, strdup(imagefile)); } - while (fgets(line, sizeof(line), fp) != NULL); - - fclose(fp); } - else if (strcmp(lineptr, "utf8") == 0) + else if (!strcasecmp(line, "Notice")) { - /* - * UTF-8 (Unicode) text... - */ + if (!banner->notices) + banner->notices = cupsArrayNew(NULL, NULL); - UTF8 = 1; - - /* - * Read the font descriptions... - */ + cupsArrayAdd(banner->notices, strdup(ptr)); + } + else if (!strcasecmp(line, "Show")) + { + char *value; /* Current value */ - NumFonts = 0; - while (fgets(line, sizeof(line), fp) != NULL) + for (value = ptr; *value; value = ptr) { /* - * Skip comment and blank lines... + * Find the end of the current value */ - if (line[0] == '#' || line[0] == '\n') - continue; - - /* - * Read the font descriptions that should look like: - * - * start end direction width normal [bold italic bold-italic] - */ - - lineptr = line; - - start = strtol(lineptr, &lineptr, 16); - end = strtol(lineptr, &lineptr, 16); - - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (!*lineptr) - { - /* - * Can't have a font without all required values... - */ - - fprintf(stderr, _("ERROR: Bad font description line: %s\n"), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (strcmp(valptr, "ltor") == 0) - Directions[NumFonts] = 1; - else if (strcmp(valptr, "rtol") == 0) - Directions[NumFonts] = -1; - else - { - fprintf(stderr, _("ERROR: Bad text direction %s\n"), valptr); - fclose(fp); - exit(1); - } - - /* - * Got the direction, now get the width... - */ - - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (!*lineptr) - { - /* - * Can't have a font without all required values... - */ - - fprintf(stderr, _("ERROR: Bad font description line: %s\n"), valptr); - fclose(fp); - exit(1); - } - - *lineptr++ = '\0'; - - if (strcmp(valptr, "single") == 0) - Widths[NumFonts] = 1; - else if (strcmp(valptr, "double") == 0) - Widths[NumFonts] = 2; - else - { - fprintf(stderr, _("ERROR: Bad text width %s\n"), valptr); - fclose(fp); - exit(1); - } - - /* - * Get the fonts... - */ - - for (i = 0; *lineptr && i < 4; i ++) - { - while (isspace(*lineptr & 255)) - lineptr ++; - - valptr = lineptr; - - while (!isspace(*lineptr & 255) && *lineptr) - lineptr ++; - - if (*lineptr) - *lineptr++ = '\0'; - - if (lineptr > valptr) - Fonts[NumFonts][i] = strdup(valptr); - } - - /* - * Fill in remaining fonts as needed... - */ + while (*ptr && !isspace(*ptr & 255)) + ptr ++; - for (j = i; j < 4; j ++) - Fonts[NumFonts][j] = strdup(Fonts[NumFonts][0]); + while (*ptr && isspace(*ptr & 255)) + *ptr++ = '\0'; /* - * Define the character mappings... + * Add the value to the show flags... */ - - for (i = start, j = NumFonts * 256; i <= end; i ++, j ++) - { - Chars[i] = j; - Codes[j] = i; + if (!strcasecmp(value, "imageable-area")) + banner->show |= SHOW_IMAGEABLE_AREA; + else if (!strcasecmp(value, "job-billing")) + banner->show |= SHOW_JOB_BILLING; + else if (!strcasecmp(value, "job-id")) + banner->show |= SHOW_JOB_ID; + else if (!strcasecmp(value, "job-name")) + banner->show |= SHOW_JOB_NAME; + else if (!strcasecmp(value, "job-originating-host-name")) + banner->show |= SHOW_JOB_ORIGINATING_HOST_NAME; + else if (!strcasecmp(value, "job-originating-user-name")) + banner->show |= SHOW_JOB_ORIGINATING_USER_NAME; + else if (!strcasecmp(value, "job-uuid")) + banner->show |= SHOW_JOB_UUID; + else if (!strcasecmp(value, "options")) + banner->show |= SHOW_OPTIONS; + else if (!strcasecmp(value, "paper-name")) + banner->show |= SHOW_PAPER_NAME; + else if (!strcasecmp(value, "paper-size")) + banner->show |= SHOW_PAPER_SIZE; + else if (!strcasecmp(value, "printer-driver-name")) + banner->show |= SHOW_PRINTER_DRIVER_NAME; + else if (!strcasecmp(value, "printer-driver-version")) + banner->show |= SHOW_PRINTER_DRIVER_VERSION; + else if (!strcasecmp(value, "printer-info")) + banner->show |= SHOW_PRINTER_INFO; + else if (!strcasecmp(value, "printer-location")) + banner->show |= SHOW_PRINTER_LOCATION; + else if (!strcasecmp(value, "printer-make-and-model")) + banner->show |= SHOW_PRINTER_MAKE_AND_MODEL; + else if (!strcasecmp(value, "printer-name")) + banner->show |= SHOW_PRINTER_NAME; + else if (!strcasecmp(value, "time-at-creation")) + banner->show |= SHOW_TIME_AT_CREATION; + else if (!strcasecmp(value, "time-at-processing")) + banner->show |= SHOW_TIME_AT_PROCESSING; + else + { + fprintf(stderr, + "DEBUG: Unknown \"Show\" value \"%s\" on line %d of banner " + "file!\n", value, linenum); } - - /* - * Move to the next font, stopping if needed... - */ - - NumFonts ++; - if (NumFonts >= 256) - break; } - - fclose(fp); } else - { - fprintf(stderr, _("ERROR: Bad charset type %s\n"), lineptr); - fclose(fp); - exit(1); - } + fprintf(stderr, "DEBUG: Unknown key \"%s\" on line %d of banner file!\n", + line, linenum); } - else - { - /* - * Standard ASCII output just uses Courier, Courier-Bold, and - * possibly Courier-Oblique. - */ - NumFonts = 1; + if (filename) + cupsFileClose(fp); - Fonts[0][ATTR_NORMAL] = strdup("Courier"); - Fonts[0][ATTR_BOLD] = strdup("Courier-Bold"); - Fonts[0][ATTR_ITALIC] = strdup("Courier-Oblique"); - Fonts[0][ATTR_BOLDITALIC] = strdup("Courier-BoldOblique"); + return (banner); +} - Widths[0] = 1; - Directions[0] = 1; - /* - * Define US-ASCII characters... - */ +/* + * 'ps_ascii85()' - Print binary data as a series of base-85 numbers. + */ - for (i = 32; i < 127; i ++) - { - Chars[i] = i; - Codes[i] = i; - } - } +static void +ps_ascii85(cups_ib_t *data, /* I - Data to print */ + int length, /* I - Number of bytes to print */ + int last_line) /* I - Last line of raster data? */ +{ + unsigned b; /* Binary data word */ + unsigned char c[5]; /* ASCII85 encoded chars */ + static int col = 0; /* Current column */ - /* - * Generate a list of unique fonts to use... - */ - for (i = 0, num_fonts = 0; i < NumFonts; i ++) - for (j = PrettyPrint ? 2 : 1; j >= 0; j --) - { - for (k = 0; k < num_fonts; k ++) - if (strcmp(Fonts[i][j], fonts[k]) == 0) - break; - - if (k >= num_fonts) - { - /* - * Add new font... - */ + while (length > 3) + { + b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]; - fonts[num_fonts] = Fonts[i][j]; - num_fonts ++; - } + if (b == 0) + { + putchar('z'); + col ++; } - - /* - * List the fonts that will be used... - */ - - for (i = 0; i < num_fonts; i ++) - if (i == 0) - printf("%%%%DocumentNeededResources: font %s\n", fonts[i]); else - printf("%%%%+ font %s\n", fonts[i]); - - puts("%%DocumentSuppliedResources: procset texttops 1.1 0"); - - for (i = 0; i < num_fonts; i ++) - { - if (ppd != NULL) { - fprintf(stderr, "DEBUG: ppd->num_fonts = %d\n", ppd->num_fonts); - - for (j = 0; j < ppd->num_fonts; j ++) - { - fprintf(stderr, "DEBUG: ppd->fonts[%d] = %s\n", j, ppd->fonts[j]); - - if (strcmp(fonts[i], ppd->fonts[j]) == 0) - break; - } + c[4] = (b % 85) + '!'; + b /= 85; + c[3] = (b % 85) + '!'; + b /= 85; + c[2] = (b % 85) + '!'; + b /= 85; + c[1] = (b % 85) + '!'; + b /= 85; + c[0] = b + '!'; + + fwrite(c, 5, 1, stdout); + col += 5; } - else - j = 0; - if ((ppd != NULL && j >= ppd->num_fonts) || - strncmp(fonts[i], "Courier", 7) == 0 || - strcmp(fonts[i], "Symbol") == 0) - { - /* - * Need to embed this font... - */ + data += 4; + length -= 4; - printf("%%%%+ font %s\n", fonts[i]); + if (col >= 75) + { + putchar('\n'); + col = 0; } } - puts("%%EndComments"); - - puts("%%BeginProlog"); - - /* - * Download any missing fonts... - */ - - for (i = 0; i < num_fonts; i ++) + if (last_line) { - if (ppd != NULL) + if (length > 0) { - for (j = 0; j < ppd->num_fonts; j ++) - if (strcmp(fonts[i], ppd->fonts[j]) == 0) - break; + memset(data + length, 0, 4 - length); + b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]; + + c[4] = (b % 85) + '!'; + b /= 85; + c[3] = (b % 85) + '!'; + b /= 85; + c[2] = (b % 85) + '!'; + b /= 85; + c[1] = (b % 85) + '!'; + b /= 85; + c[0] = b + '!'; + + fwrite(c, length + 1, 1, stdout); } - else - j = 0; - if ((ppd != NULL && j >= ppd->num_fonts) || - strncmp(fonts[i], "Courier", 7) == 0 || - strcmp(fonts[i], "Symbol") == 0) - { - /* - * Need to embed this font... - */ + puts("~>"); + col = 0; + } +} - printf("%%%%BeginResource: font %s\n", fonts[i]); - /**** MRS: Need to use CUPS_FONTPATH env var! ****/ - /**** Also look for Fontmap file or name.pfa, name.pfb... ****/ - snprintf(filename, sizeof(filename), "%s/fonts/%s", datadir, fonts[i]); - if ((fp = fopen(filename, "rb")) != NULL) - { - while ((j = fread(line, 1, sizeof(line), fp)) > 0) - fwrite(line, 1, j, stdout); +/* + * 'write_banner()' - Write a banner page... + */ - fclose(fp); - } +static int /* O - Number of pages */ +write_banner(banner_file_t *banner, /* I - Banner file */ + ppd_file_t *ppd, /* I - PPD file */ + ps_text_t *fonts, /* I - Fonts */ + int job_id, /* I - Job ID */ + const char *title, /* I - Title of job */ + const char *username, /* I - Owner of job */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + char *notice; /* Current notice */ + char *imagefile; /* Current image file */ + cups_array_t *images; /* Images */ + cups_image_t *image; /* Current image */ + const char *option; /* Option value */ + int i, j; /* Looping vars */ + float x, /* Current X position */ + y; /* Current Y position */ + cups_lang_t *language; /* Default language */ + int showlines; /* Number of lines to show */ + float fontsize; /* Font size to use */ + int num_pages; /* Number of pages */ + float print_width, /* Printable width of page */ + print_height, /* Printable height of page */ + info_top, /* Top of info fields */ + info_height, /* Height of info fields */ + line_height, /* Height of info lines */ + notices_height, /* Height of all notices */ + images_width, /* Width of all images */ + images_height, /* Height of all images */ + total_height; /* Height of all content */ + char text[1024]; /* Formatted field text */ - puts("\n%%EndResource"); - } - } /* - * Write the encoding array(s)... + * Figure out how many lines of text will be shown... */ - puts("% character encoding(s)"); - - for (i = 0; i < NumFonts; i ++) + showlines = 0; + if (banner->show & SHOW_IMAGEABLE_AREA) + showlines += 2; + if (banner->show & SHOW_JOB_BILLING) + showlines ++; + if (banner->show & SHOW_JOB_ID) + showlines ++; + if (banner->show & SHOW_JOB_NAME) + showlines ++; + if (banner->show & SHOW_JOB_ORIGINATING_USER_NAME) + showlines ++; + if (banner->show & SHOW_JOB_ORIGINATING_HOST_NAME) + showlines ++; + if (banner->show & SHOW_JOB_UUID) + showlines ++; + if (banner->show & SHOW_OPTIONS) { - printf("/cupsEncoding%02x [\n", i); - - for (ch = 0; ch < 256; ch ++) + for (j = 0; j < num_options; j ++) { - if (Glyphs[Codes[i * 256 + ch]]) - printf("/%s", Glyphs[Codes[i * 256 + ch]]); - else if (Codes[i * 256 + ch] > 255) - printf("/uni%04X", Codes[i * 256 + ch]); - else - printf("/.notdef"); - - if ((ch & 7) == 7) - putchar('\n'); + if (strcasecmp("media", options[j].name) && + strcasecmp("PageSize", options[j].name) && + strcasecmp("PageRegion", options[j].name) && + strcasecmp("InputSlot", options[j].name) && + strcasecmp("MediaType", options[j].name) && + strcasecmp("finishings", options[j].name) && + strcasecmp("sides", options[j].name) && + strcasecmp("Duplex", options[j].name) && + strcasecmp("orientation-requested", options[j].name) && + strcasecmp("landscape", options[j].name) && + strcasecmp("number-up", options[j].name) && + strcasecmp("OutputOrder", options[j].name)) + continue; + + showlines ++; } - - puts("] def"); } + if (banner->show & SHOW_PAPER_NAME) + showlines ++; + if (banner->show & SHOW_PAPER_SIZE) + showlines += 2; + if (banner->show & SHOW_PRINTER_DRIVER_NAME) + showlines ++; + if (banner->show & SHOW_PRINTER_DRIVER_VERSION) + showlines ++; + if (banner->show & SHOW_PRINTER_INFO) + showlines ++; + if (banner->show & SHOW_PRINTER_LOCATION) + showlines ++; + if (banner->show & SHOW_PRINTER_MAKE_AND_MODEL) + showlines ++; + if (banner->show & SHOW_PRINTER_NAME) + showlines ++; + if (banner->show & SHOW_TIME_AT_CREATION) + showlines ++; + if (banner->show & SHOW_TIME_AT_PROCESSING) + showlines ++; /* - * Create the fonts... + * Figure out the dimensions and positions of everything... */ - if (NumFonts == 1) - { - /* - * Just reencode the named fonts... - */ + print_width = PageRight - PageLeft; + print_height = PageTop - PageBottom; + fontsize = print_height / 60; /* Nominally 12pts */ + line_height = 1.2 * fontsize; + info_height = showlines * line_height; + notices_height = cupsArrayCount(banner->notices) * line_height; - puts("% Reencode fonts"); + if (cupsArrayCount(banner->images)) + { + images = cupsArrayNew(NULL, NULL); + images_height = print_height / 10; /* Nominally 1" */ - for (i = PrettyPrint ? 2 : 1; i >= 0; i --) + for (imagefile = (char *)cupsArrayFirst(banner->images), images_width = 0.0; + imagefile; + imagefile = (char *)cupsArrayNext(banner->images)) { - printf("/%s findfont\n", Fonts[0][i]); - puts("dup length 1 add dict begin\n" - " { 1 index /FID ne { def } { pop pop } ifelse } forall\n" - " /Encoding cupsEncoding00 def\n" - " currentdict\n" - "end"); - printf("/%s exch definefont pop\n", names[i]); + if ((image = cupsImageOpen(imagefile, ColorDevice ? CUPS_IMAGE_RGB_CMYK : + CUPS_IMAGE_WHITE, + CUPS_IMAGE_WHITE, 100, 0, NULL)) == NULL) + { + fprintf(stderr, "DEBUG: Unable to open image file \"%s\"!\n", + imagefile); + continue; + } + + images_width += cupsImageGetWidth(image) * images_height / + cupsImageGetHeight(image); + cupsArrayAdd(images, image); } } else { - /* - * Construct composite fonts... Start by reencoding the base fonts... - */ - - puts("% Reencode base fonts"); - - for (i = PrettyPrint ? 2 : 1; i >= 0; i --) - for (j = 0; j < NumFonts; j ++) - { - printf("/%s findfont\n", Fonts[j][i]); - printf("dup length 1 add dict begin\n" - " { 1 index /FID ne { def } { pop pop } ifelse } forall\n" - " /Encoding cupsEncoding%02x def\n" - " currentdict\n" - "end\n", j); - printf("/%s%02x exch definefont /%s%02x exch def\n", names[i], j, - names[i], j); - } - - /* - * Then merge them into composite fonts... - */ + images = NULL; + images_height = 0; + } - puts("% Create composite fonts..."); + total_height = info_height + notices_height + images_height; + if (cupsArrayCount(banner->notices) && showlines) + total_height += 2 * line_height; + if (cupsArrayCount(banner->images) && + (showlines || cupsArrayCount(banner->notices))) + total_height += 2 * line_height; - for (i = PrettyPrint ? 2 : 1; i >= 0; i --) - { - puts("8 dict begin"); - puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def/Encoding["); - for (j = 0; j < NumFonts; j ++) - if (j == (NumFonts - 1)) - printf("%d", j); - else if ((j & 15) == 15) - printf("%d\n", j); - else - printf("%d ", j); - puts("]def/FDepVector["); - for (j = 0; j < NumFonts; j ++) - if (j == (NumFonts - 1)) - printf("%s%02x", names[i], j); - else if ((j & 3) == 3) - printf("%s%02x\n", names[i], j); - else - printf("%s%02x ", names[i], j); - puts("]def currentdict end"); - printf("/%s exch definefont pop\n", names[i]); - } - } + info_top = 0.5 * (print_height + total_height); /* - * Output the texttops procset... + * Write the page(s)... */ - puts("%%BeginResource: procset texttops 1.1 0"); - - puts("% Define fonts"); - - printf("/FN /cupsNormal findfont [%.3f 0 0 %.3f 0 0] makefont def\n", - 120.0 / CharsPerInch, 68.0 / LinesPerInch); - printf("/FB /cupsBold findfont [%.3f 0 0 %.3f 0 0] makefont def\n", - 120.0 / CharsPerInch, 68.0 / LinesPerInch); - if (PrettyPrint) - printf("/FI /cupsItalic findfont [%.3f 0 0 %.3f 0 0] makefont def\n", - 120.0 / CharsPerInch, 68.0 / LinesPerInch); + language = cupsLangDefault(); + num_pages = Duplex ? 2 : 1; - puts("% Common procedures"); - - puts("/N { FN setfont moveto } bind def"); - puts("/B { FB setfont moveto } bind def"); - printf("/U { gsave 0.5 setlinewidth 0 %.3f rmoveto " - "0 rlineto stroke grestore } bind def\n", -6.8 / LinesPerInch); - - if (PrettyPrint) + for (i = 1; i <= num_pages; i ++) { - if (ColorDevice) - { - puts("/S { 0.0 setgray show } bind def"); - puts("/r { 0.5 0.0 0.0 setrgbcolor show } bind def"); - puts("/g { 0.0 0.5 0.0 setrgbcolor show } bind def"); - puts("/b { 0.0 0.0 0.5 setrgbcolor show } bind def"); - } - else - { - puts("/S { 0.0 setgray show } bind def"); - puts("/r { 0.2 setgray show } bind def"); - puts("/g { 0.2 setgray show } bind def"); - puts("/b { 0.2 setgray show } bind def"); - } - - puts("/I { FI setfont moveto } bind def"); - - puts("/n {"); - puts("\t20 string cvs % convert page number to string"); - if (NumFonts > 1) - { - /* - * Convert a number to double-byte chars... - */ - - puts("\tdup length % get length"); - puts("\tdup 2 mul string /P exch def % P = string twice as long"); - puts("\t0 1 2 index 1 sub { % loop through each character in the page number"); - puts("\t\tdup 3 index exch get % get character N from the page number"); - puts("\t\texch 2 mul dup % compute offset in P"); - puts("\t\tP exch 0 put % font 0"); - puts("\t\t1 add P exch 2 index put % character"); - puts("\t\tpop % discard character"); - puts("\t} for % do for loop"); - puts("\tpop pop % discard string and length"); - puts("\tP % put string on stack"); - } - puts("} bind def"); - - printf("/T"); - write_text(title); - puts("def"); - - printf("/D"); - write_text(curdate); - puts("def"); - - puts("/H {"); - puts("\tgsave"); - puts("\t0.9 setgray"); + /* + * Start the page... + */ - if (Duplex) - { - puts("\tdup 2 mod 0 eq {"); - printf("\t\t%.3f %.3f translate } {\n", - PageWidth - PageRight, PageTop + 72.0f / LinesPerInch); - printf("\t\t%.3f %.3f translate } ifelse\n", - PageLeft, PageTop + 72.0f / LinesPerInch); - } - else - printf("\t%.3f %.3f translate\n", - PageLeft, PageTop + 72.0f / LinesPerInch); + printf("%%Page: %s %d\n", i == 1 ? "coverpage" : "coverback", i); + puts("gsave"); + printf("%.1f %.1f translate\n", PageLeft, PageBottom); + puts("0 setgray"); - printf("\t0 0 %.3f %.3f rectfill\n", PageRight - PageLeft, - 144.0f / LinesPerInch); + y = info_top; - puts("\tFB setfont"); - puts("\t0 setgray"); + /* + * Information... + */ - if (Duplex) + if (banner->show) { - puts("\tdup 2 mod 0 eq {"); - printf("\t\tT stringwidth pop neg %.3f add %.3f } {\n", - PageRight - PageLeft - 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - printf("\t\t%.3f %.3f } ifelse\n", 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - } - else - printf("\t%.3f %.3f\n", 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - - puts("\tmoveto T show"); + x = 0.33 * print_width; - printf("\tD dup stringwidth pop neg 2 div %.3f add %.3f\n", - (PageRight - PageLeft) * 0.5, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - puts("\tmoveto show"); + if (banner->show & SHOW_PRINTER_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Printer Name: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, getenv("PRINTER_NAME")); + } + if (banner->show & SHOW_JOB_ID) + { + snprintf(text, sizeof(text), "%s-%d", getenv("PRINTER_NAME"), job_id); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Job ID: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } + if (banner->show & SHOW_JOB_UUID) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Job UUID: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + cupsGetOption("job-uuid", num_options, options)); + } + if (banner->show & SHOW_JOB_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Title: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, title); + } + if (banner->show & SHOW_JOB_ORIGINATING_USER_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Printed For: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, username); + } + if (banner->show & SHOW_JOB_ORIGINATING_HOST_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Printed From: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + cupsGetOption("job-originating-host-name", num_options, + options)); + } + if (banner->show & SHOW_JOB_BILLING) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Billing Information: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + cupsGetOption("job-billing", num_options, options)); + } + if (banner->show & SHOW_OPTIONS) + { + printf("%.1f %.1f moveto", x, y); + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Options: "))); - if (Duplex) - { - puts("\tdup n exch 2 mod 0 eq {"); - printf("\t\t%.3f %.3f } {\n", 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - printf("\t\tdup stringwidth pop neg %.3f add %.3f } ifelse\n", - PageRight - PageLeft - 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); - } - else - printf("\tn dup stringwidth pop neg %.3f add %.3f\n", - PageRight - PageLeft - 36.0f / LinesPerInch, - (0.5f + 0.157f) * 72.0f / LinesPerInch); + for (j = 0; j < num_options; j ++) + { + if (strcasecmp("media", options[j].name) && + strcasecmp("PageSize", options[j].name) && + strcasecmp("PageRegion", options[j].name) && + strcasecmp("InputSlot", options[j].name) && + strcasecmp("MediaType", options[j].name) && + strcasecmp("finishings", options[j].name) && + strcasecmp("sides", options[j].name) && + strcasecmp("Duplex", options[j].name) && + strcasecmp("orientation-requested", options[j].name) && + strcasecmp("landscape", options[j].name) && + strcasecmp("number-up", options[j].name) && + strcasecmp("OutputOrder", options[j].name)) + continue; + + if (!strcasecmp("landscape", options[j].name)) + strlcpy(text, "orientation-requested=landscape", sizeof(text)); + else if (!strcasecmp("orientation-requested", options[j].name)) + { + switch (atoi(options[j].value)) + { + default : + case IPP_PORTRAIT : + strlcpy(text, "orientation-requested=portrait", + sizeof(text)); + break; + + case IPP_LANDSCAPE : + strlcpy(text, "orientation-requested=landscape", + sizeof(text)); + break; + + case IPP_REVERSE_PORTRAIT : + strlcpy(text, "orientation-requested=reverse-portrait", + sizeof(text)); + break; + + case IPP_REVERSE_LANDSCAPE : + strlcpy(text, "orientation-requested=reverse-landscape", + sizeof(text)); + break; + } + } + else + snprintf(text, sizeof(text), "%s=%s", options[j].name, + options[j].value); + + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } + } - puts("\tmoveto show"); - puts("\tgrestore"); - puts("} bind def"); - } - else - puts("/S { show } bind def"); + if (banner->show & SHOW_PRINTER_INFO) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Description: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + getenv("PRINTER_INFO")); + } + if (banner->show & SHOW_PRINTER_LOCATION) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Location: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + getenv("PRINTER_LOCATION")); + } + if (banner->show & SHOW_PRINTER_MAKE_AND_MODEL) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Make and Model: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + ppd ? ppd->nickname : NULL); + } - puts("%%EndResource"); + if (banner->show & SHOW_PAPER_NAME) + { + if ((option = cupsGetOption("media", num_options, options)) == NULL) + if ((option = cupsGetOption("PageSize", num_options, options)) == NULL) + if ((option = cupsGetOption("PageRegion", num_options, + options)) == NULL) + option = "Default"; + + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Media Name: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, option); + } + if (banner->show & SHOW_PAPER_SIZE) + { + snprintf(text, sizeof(text), + _cupsLangString(language, _("%.2f x %.2f inches")), + PageWidth / 72.0, PageLength / 72.0); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Media Dimensions: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + + snprintf(text, sizeof(text), + _cupsLangString(language, _("%.0f x %.0f millimeters")), + PageWidth * 25.4 / 72.0, PageLength * 25.4 / 72.0); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } + if (banner->show & SHOW_IMAGEABLE_AREA) + { + snprintf(text, sizeof(text), + _cupsLangString(language, + _("%.2f x %.2f to %.2f x %.2f inches")), + PageLeft / 72.0, PageBottom / 72.0, + PageRight / 72.0, PageTop / 72.0); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Media Limits: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + + snprintf(text, sizeof(text), + _cupsLangString(language, + _("%.0f x %.0f to %.0f x %.0f millimeters")), + PageLeft * 25.4 / 72.0, PageBottom * 25.4 / 72.0, + PageRight * 25.4 / 72.0, PageTop * 25.4 / 72.0); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + + printf("gsave 2 setlinewidth 1 1 %.1f %.1f rectstroke grestore\n", + print_width - 2.0, print_height - 2.0); + } + if (banner->show & SHOW_PRINTER_DRIVER_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Driver Name: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + ppd ? ppd->pcfilename : NULL); + } + if (banner->show & SHOW_PRINTER_DRIVER_VERSION) + { + ppd_attr_t *file_version = ppdFindAttr(ppd, "FileVersion", NULL); + + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Driver Version: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + file_version ? file_version->value : NULL); + } + if (banner->show & SHOW_TIME_AT_CREATION) + { + if ((option = cupsGetOption("time-at-creation", num_options, + options)) != NULL) + { + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ - puts("%%EndProlog"); -} + curtime = (time_t)atoi(option); + curdate = localtime(&curtime); + strftime(text, sizeof(text), "%c", curdate); + } + else + strlcpy(text, "?", sizeof(text)); -/* - * 'write_line()' - Write a row of text. - */ + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Created On: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } + if (banner->show & SHOW_TIME_AT_PROCESSING) + { + if ((option = cupsGetOption("time-at-processing", num_options, + options)) != NULL) + { + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ -static void -write_line(int row, /* I - Row number (0 to N) */ - lchar_t *line) /* I - Line to print */ -{ - int i; /* Looping var */ - int col; /* Current column */ - int attr; /* Current attribute */ - int font, /* Font to use */ - lastfont, /* Last font */ - mono; /* Monospaced? */ - lchar_t *start; /* First character in sequence */ + curtime = (time_t)atoi(option); + curdate = localtime(&curtime); + strftime(text, sizeof(text), "%c", curdate); + } + else + strlcpy(text, "?", sizeof(text)); - for (col = 0; col < SizeColumns;) - { - while (col < SizeColumns && (line->ch == ' ' || line->ch == 0)) - { - col ++; - line ++; + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Printed On: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } } - if (col >= SizeColumns) - break; + /* + * Notices... + */ - if (NumFonts == 1) + if (cupsArrayCount(banner->notices)) { - /* - * All characters in a single font - assume monospaced... - */ + if (banner->show) + y -= 2 * line_height; - attr = line->attr; - start = line; + x = 0.5 * print_width; - while (col < SizeColumns && line->ch != 0 && attr == line->attr) + for (notice = (char *)cupsArrayFirst(banner->notices); + notice; + notice = (char *)cupsArrayNext(banner->notices)) { - col ++; - line ++; + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_CENTER, notice); } - - write_string(col - (line - start), row, line - start, start); } - else - { - /* - * Multiple fonts; break up based on the font... - */ - - attr = line->attr; - start = line; - lastfont = Chars[line->ch] / 256; - mono = strncmp(Fonts[lastfont][0], "Courier", 7) == 0; - col ++; - line ++; - if (mono) - { - while (col < SizeColumns && line->ch != 0 && attr == line->attr) - { - font = Chars[line->ch] / 256; - if (strncmp(Fonts[font][0], "Courier", 7) != 0 || - font != lastfont) - break; + /* + * Images... + */ - col ++; - line ++; - } - } + if (cupsArrayCount(images)) + { + if (banner->show || cupsArrayCount(banner->notices)) + y -= 2 * line_height; - if (Directions[lastfont] > 0) - write_string(col - (line - start), row, line - start, start); - else - { - /* - * Do right-to-left text... - */ + x = 0.5 * (print_width - images_width); - while (col < SizeColumns && line->ch != 0 && attr == line->attr) + for (image = (cups_image_t *)cupsArrayFirst(images); + image; + image = (cups_image_t *)cupsArrayNext(images)) + { + float temp_width; /* Width of this image */ + int depth, /* Bytes per pixel */ + num_cols, /* Number of columns */ + row, /* Current row */ + num_rows, /* Number of rows */ + out_length, /* Length of data to write */ + out_offset; /* Offset in line buffer */ + unsigned char *line; /* Data for current row */ + + + depth = cupsImageGetDepth(image); + num_cols = cupsImageGetWidth(image); + num_rows = cupsImageGetHeight(image); + line = malloc(depth * num_cols + 3); + temp_width = num_cols * images_height / num_rows; + out_offset = 0; + + printf("gsave %.1f %.1f translate %.3f %.3f scale\n", x, y, + temp_width / num_cols, images_height / num_rows); + x += temp_width; + + switch (cupsImageGetColorSpace(image)) { - if (Directions[Chars[line->ch] / 256] > 0 && - !ispunct(line->ch & 255) && !isspace(line->ch & 255)) - break; - - col ++; - line ++; + default : + case CUPS_IMAGE_WHITE : + printf("/DeviceGray setcolorspace" + "<<" + "/ImageType 1" + "/Width %d" + "/Height %d" + "/BitsPerComponent 8" + "/Decode[0 1]\n", + num_cols, num_rows); + break; + + case CUPS_IMAGE_RGB : + printf("/DeviceRGB setcolorspace" + "<<" + "/ImageType 1" + "/Width %d" + "/Height %d" + "/BitsPerComponent 8" + "/Decode[0 1 0 1 0 1]\n", + num_cols, num_rows); + break; + + case CUPS_IMAGE_CMYK : + printf("/DeviceCMYK setcolorspace" + "<<" + "/ImageType 1" + "/Width %d" + "/Height %d" + "/BitsPerComponent 8" + "/Decode[0 1 0 1 0 1 0 1]\n", + num_cols, num_rows); + break; } - for (i = 1; start < line; i ++, start ++) - if (!isspace(start->ch & 255)) - write_string(col - i, row, 1, start); - } - } - } -} - + puts("/DataSource currentfile" + "/ASCII85Decode filter" + "/ImageMatrix[1 0 0 -1 0 1]>>image"); -/* - * 'write_string()' - Write a string of text. - */ - -static void -write_string(int col, /* I - Start column */ - int row, /* I - Row */ - int len, /* I - Number of characters */ - lchar_t *s) /* I - String to print */ -{ - int ch; /* Current character */ - float x, y; /* Position of text */ - unsigned attr; /* Character attributes */ - - - /* - * Position the text and set the font... - */ - - if (Duplex && (NumPages & 1) == 0) - { - x = PageWidth - PageRight; - y = PageTop; - } - else - { - x = PageLeft; - y = PageTop; - } - - x += (float)col * 72.0f / (float)CharsPerInch; - y -= (float)(row + 0.843) * 72.0f / (float)LinesPerInch; - - attr = s->attr; + for (row = 0, out_offset = 0; row < num_rows; row ++) + { + cupsImageGetRow(image, 0, row, num_cols, line + out_offset); - if (attr & ATTR_RAISED) - y += 36.0 / (float)LinesPerInch; - else if (attr & ATTR_LOWERED) - y -= 36.0 / (float)LinesPerInch; + out_length = num_cols * depth + out_offset; + out_offset = out_length & 3; - if (x == (int)x) - printf("%.0f ", x); - else - printf("%.3f ", x); + ps_ascii85(line, out_length, row == (num_rows - 1)); - if (y == (int)y) - printf("%.0f ", y); - else - printf("%.3f ", y); + if (out_offset > 0) + memcpy(line, line + out_length - out_offset, out_offset); + } - if (attr & ATTR_BOLD) - putchar('B'); - else if (attr & ATTR_ITALIC) - putchar('I'); - else - putchar('N'); + puts("grestore"); - if (attr & ATTR_UNDERLINE) - printf(" %.3f U", (float)len * 72.0 / (float)CharsPerInch); + if (i == num_pages) + cupsImageClose(image); + } + } - if (NumFonts > 1) - { /* - * Write a hex string... + * Header and footer... */ - putchar('<'); + x = 0.5 * print_width; - while (len > 0) + if (banner->header) { - printf("%04x", Chars[s->ch]); + printf("%.1f %.1f moveto", x, print_height - 2 * fontsize); + psTextUTF8(fonts, 2 * fontsize, PS_BOLD, PS_CENTER, banner->header); + } - len --; - s ++; + if (banner->footer) + { + printf("%.1f %.1f moveto", x, fontsize); + psTextUTF8(fonts, 2 * fontsize, PS_BOLD, PS_CENTER, banner->footer); } - putchar('>'); - } - else - { /* - * Write a quoted string... + * Show the page... */ - putchar('('); - - while (len > 0) - { - ch = Chars[s->ch]; - - if (ch < 32 || ch > 126) - { - /* - * Quote 8-bit and control characters... - */ - - printf("\\%03o", ch); - } - else - { - /* - * Quote the parenthesis and backslash as needed... - */ - - if (ch == '(' || ch == ')' || ch == '\\') - putchar('\\'); - - putchar(ch); - } - - len --; - s ++; - } - - putchar(')'); + puts("grestore"); + puts("showpage"); } - if (PrettyPrint) - { - if (attr & ATTR_RED) - puts("r"); - else if (attr & ATTR_GREEN) - puts("g"); - else if (attr & ATTR_BLUE) - puts("b"); - else - puts("S"); - } - else - puts("S"); + return (num_pages); } /* - * 'write_text()' - Write a text string, quoting/encoding as needed. + * 'write_epilogue()' - Write the PostScript file epilogue. */ static void -write_text(const char *s) /* I - String to write */ +write_epilogue(int num_pages) /* I - Number of pages */ { - int ch; /* Actual character value (UTF8) */ - const unsigned char *utf8; /* UTF8 text */ - - - if (NumFonts > 1) - { - /* - * 8/8 encoding... - */ - - putchar('<'); + puts("%%Trailer"); + printf("%%%%Pages: %d\n", num_pages); + puts("%%EOF"); +} - utf8 = (const unsigned char *)s; - while (*utf8) - { - if (*utf8 < 0xc0 || !UTF8) - ch = *utf8 ++; - else if ((*utf8 & 0xe0) == 0xc0) - { - /* - * Two byte character... - */ - - ch = ((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f); - utf8 += 2; - } - else - { - /* - * Three byte character... - */ +/* + * 'write_prolog()' - Write the PostScript file prolog with options. + */ - ch = ((((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f)) << 6) | - (utf8[2] & 0x3f); - utf8 += 3; - } +ps_text_t * /* O - Fonts */ +write_prolog(const char *title, /* I - Title of job */ + const char *username) /* I - Username */ +{ + time_t curtime; /* Current time */ + struct tm *curtm; /* Current date */ + char curdate[255]; /* Current date (text format) */ + ps_text_t *fonts; /* Fonts */ - printf("%04x", Chars[ch]); - } - putchar('>'); - } - else - { - /* - * Standard 8-bit encoding... - */ + /* + * Get the fonts we'll need... + */ - putchar('('); + fonts = psTextInitialize(); - while (*s) - { - if (*s < 32 || *s > 126) - printf("\\%03o", *s); - else - { - if (*s == '(' || *s == ')' || *s == '\\') - putchar('\\'); + /* + * Output the DSC header... + */ - putchar(*s); - } + curtime = time(NULL); + curtm = localtime(&curtime); + strftime(curdate, sizeof(curdate), "%c", curtm); - s ++; - } + puts("%!PS-Adobe-3.0"); + printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom, + PageRight, PageTop); + printf("%%cupsRotation: %d\n", (Orientation & 3) * 90); + puts("%%Creator: bannertops/" CUPS_SVERSION); + printf("%%%%CreationDate: %s\n", curdate); + puts("%%LanguageLevel: 2"); + puts("%%DocumentData: Clean7Bit"); + WriteTextComment("Title", title); + WriteTextComment("For", username); + printf("%%%%Pages: %d\n", Duplex ? 2 : 1); + psTextListFonts(fonts); + puts("%%EndComments"); + puts("%%BeginProlog"); + psTextEmbedFonts(fonts); + puts("%%EndProlog"); - putchar(')'); - } + return (fonts); } diff --git a/filter/pstext.c b/filter/pstext.c new file mode 100644 index 000000000..e809e40ff --- /dev/null +++ b/filter/pstext.c @@ -0,0 +1,503 @@ +/* + * "$Id$" + * + * Common PostScript text code for the Common UNIX Printing System (CUPS). + * + * Copyright 2008 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/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * psTextEmbedFonts() - Embed PostScript fonts. + * psTextListFonts() - List PostScript fonts. + * psTextInitialize() - Load and embed font data for UTF-8 text. + * psTextUTF8() - Output UTF-8 text at the current position. + * psTextUTF32() - Output UTF-32 text at the current position. + */ + +/* + * Include necessary headers... + */ + +#include "pstext.h" +#include <cups/i18n.h> + + +/* + * Composite font names... + */ + +static const char * const ps_font_names[] = +{ + "cupsNormal", + "cupsBold", + "cupsItalic", + "cupsBoldItalic" +}; + + +/* + * 'psTextEmbedFonts()'- Embed PostScript fonts. + */ + +void +psTextEmbedFonts(ps_text_t *fonts) /* I - Font data */ +{ + int i, j; /* Looping vars */ + const char *cups_datadir; /* CUPS_DATADIR environment variable */ + char *font; /* Current font */ + char filename[1024]; /* Current filename */ + FILE *fp; /* Current file */ + char line[1024]; /* Line from file */ + int ch; /* Character value */ + + + /* + * Get the data directory... + */ + + if ((cups_datadir = getenv("CUPS_DATADIR")) == NULL) + cups_datadir = CUPS_DATADIR; + + /* + * Embed each font... + */ + + for (font = (char *)cupsArrayFirst(fonts->unique); + font; + font = (char *)cupsArrayNext(fonts->unique)) + { + printf("%%%%BeginResource: font %s\n", font); + + snprintf(filename, sizeof(filename), "%s/fonts/%s", cups_datadir, font); + if ((fp = fopen(filename, "rb")) != NULL) + { + while ((j = fread(line, 1, sizeof(line), fp)) > 0) + fwrite(line, 1, j, stdout); + + fclose(fp); + } + + puts("\n%%EndResource"); + } + + /* + * Write the encoding arrays... + */ + + puts("% Character encodings"); + + for (i = 0; i < fonts->num_fonts; i ++) + { + printf("/cupsEncoding%02x [\n", i); + + for (ch = 0; ch < 256; ch ++) + { + if (fonts->glyphs[fonts->codes[i * 256 + ch]]) + printf("/%s", fonts->glyphs[fonts->codes[i * 256 + ch]]); + else if (fonts->codes[i * 256 + ch] > 255) + printf("/uni%04X", fonts->codes[i * 256 + ch]); + else + printf("/.notdef"); + + if ((ch & 7) == 7) + putchar('\n'); + } + + puts("] def"); + } + + /* + * Construct composite fonts... Start by reencoding the base fonts... + */ + + puts("% Reencode base fonts"); + + for (i = 0; i < 4; i ++) + for (j = 0; j < fonts->num_fonts; j ++) + { + printf("/%s findfont\n", fonts->fonts[j][i]); + printf("dup length 1 add dict begin\n" + " { 1 index /FID ne { def } { pop pop } ifelse } forall\n" + " /Encoding cupsEncoding%02x def\n" + " currentdict\n" + "end\n", j); + printf("/%s%02x exch definefont /%s%02x exch def\n", ps_font_names[i], j, + ps_font_names[i], j); + } + + /* + * Then merge them into composite fonts... + */ + + puts("% Create composite fonts"); + + for (i = 0; i < 4; i ++) + { + puts("8 dict begin"); + puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def" + "/Encoding["); + for (j = 0; j < fonts->num_fonts; j ++) + if (j == (fonts->num_fonts - 1)) + printf("%d", j); + else if ((j & 15) == 15) + printf("%d\n", j); + else + printf("%d ", j); + puts("]def/FDepVector["); + for (j = 0; j < fonts->num_fonts; j ++) + if (j == (fonts->num_fonts - 1)) + printf("%s%02x", ps_font_names[i], j); + else if ((j & 3) == 3) + printf("%s%02x\n", ps_font_names[i], j); + else + printf("%s%02x ", ps_font_names[i], j); + puts("]def currentdict end"); + printf("/%s exch definefont pop\n", ps_font_names[i]); + } + + /* + * Procedures... + */ + + puts("% Procedures to justify text...\n" + "/showcenter{dup stringwidth pop -0.5 mul 0 rmoveto show}bind def\n" + "/showleft{show}bind def\n" + "/showright{dup stringwidth pop neg 0 rmoveto show}bind def"); +} + + +/* + * 'psTextListFonts()' - List PostScript fonts. + */ + +void +psTextListFonts(ps_text_t *fonts) /* I - Font data */ +{ + char *font; /* Current font */ + + + font = (char *)cupsArrayFirst(fonts->unique); + printf("%%%%DocumentSuppliedResources: font %s\n", font); + while ((font = (char *)cupsArrayNext(fonts->unique)) != NULL) + printf("%%%%+ font %s\n", font); +} + + +/* + * 'psTextInitialize()' - Load and embed font data for UTF-8 text. + */ + +ps_text_t * /* O - Font data */ +psTextInitialize(void) +{ + ps_text_t *fonts; /* Font data */ + int i, j; /* Looping vars */ + char filename[1024]; /* Current filename */ + FILE *fp; /* Current file */ + const char *cups_datadir; /* CUPS_DATADIR environment variable */ + char line[1024], /* Line from file */ + *lineptr, /* Pointer into line */ + *valptr; /* Pointer to value in line */ + int unicode; /* Character value */ + int start, end; /* Start and end values for range */ + char glyph[64]; /* Glyph name */ + + + /* + * Get the data directory... + */ + + if ((cups_datadir = getenv("CUPS_DATADIR")) == NULL) + cups_datadir = CUPS_DATADIR; + + /* + * Initialize the PostScript text data... + */ + + fonts = (ps_text_t *)calloc(1, sizeof(ps_text_t)); + fonts->size = -1.0; + fonts->style = -1; + + /* + * Load the PostScript glyph names... + */ + + snprintf(filename, sizeof(filename), "%s/data/psglyphs", cups_datadir); + + if ((fp = fopen(filename, "r")) != NULL) + { + while (fscanf(fp, "%x%63s", &unicode, glyph) == 2) + fonts->glyphs[unicode] = _cupsStrAlloc(glyph); + + fclose(fp); + } + else + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open \"%s\" - %s\n"), filename, + strerror(errno)); + exit(1); + } + + /* + * Open the UTF-8 character set definition... + */ + + snprintf(filename, sizeof(filename), "%s/charsets/utf-8", cups_datadir); + + if ((fp = fopen(filename, "r")) == NULL) + { + /* + * Can't open charset file! + */ + + _cupsLangPrintf(stderr, _("ERROR: Unable to open %s: %s\n"), filename, + strerror(errno)); + exit(1); + } + + if (!fgets(line, sizeof(line), fp) || strncmp(line, "charset utf8", 12)) + { + /* + * Bad/empty charset file! + */ + + fclose(fp); + _cupsLangPrintf(stderr, _("ERROR: Bad charset file %s\n"), filename); + exit(1); + } + + /* + * Read the font descriptions... + */ + + fonts->unique = cupsArrayNew((cups_array_func_t)strcmp, NULL); + + while (fgets(line, sizeof(line), fp) != NULL) + { + /* + * Skip comment and blank lines... + */ + + if (line[0] == '#' || line[0] == '\n') + continue; + + /* + * Read the font descriptions that should look like: + * + * start end direction width normal [bold italic bold-italic] + */ + + lineptr = line; + + start = strtol(lineptr, &lineptr, 16); + end = strtol(lineptr, &lineptr, 16); + + while (isspace(*lineptr & 255)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr & 255) && *lineptr) + lineptr ++; + + if (!*lineptr) + { + /* + * Can't have a font without all required values... + */ + + _cupsLangPrintf(stderr, _("ERROR: Bad font description line: %s\n"), + valptr); + fclose(fp); + exit(1); + } + + *lineptr++ = '\0'; + + if (!strcmp(valptr, "ltor")) + fonts->directions[fonts->num_fonts] = 1; + else if (!strcmp(valptr, "rtol")) + fonts->directions[fonts->num_fonts] = -1; + else + { + _cupsLangPrintf(stderr, _("ERROR: Bad text direction %s\n"), valptr); + fclose(fp); + exit(1); + } + + /* + * Got the direction, now get the width... + */ + + while (isspace(*lineptr & 255)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr & 255) && *lineptr) + lineptr ++; + + if (!*lineptr) + { + /* + * Can't have a font without all required values... + */ + + _cupsLangPrintf(stderr, _("ERROR: Bad font description line: %s\n"), + valptr); + fclose(fp); + exit(1); + } + + *lineptr++ = '\0'; + + if (!strcmp(valptr, "single")) + fonts->widths[fonts->num_fonts] = 1; + else if (!strcmp(valptr, "double")) + fonts->widths[fonts->num_fonts] = 2; + else + { + _cupsLangPrintf(stderr, _("ERROR: Bad text width %s\n"), valptr); + fclose(fp); + exit(1); + } + + /* + * Get the fonts... + */ + + for (i = 0; *lineptr && i < 4; i ++) + { + while (isspace(*lineptr & 255)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr & 255) && *lineptr) + lineptr ++; + + if (*lineptr) + *lineptr++ = '\0'; + + if (lineptr > valptr) + { + if (!cupsArrayFind(fonts->unique, valptr)) + cupsArrayAdd(fonts->unique, _cupsStrAlloc(valptr)); + + fonts->fonts[fonts->num_fonts][i] = _cupsStrAlloc(valptr); + } + } + + /* + * Fill in remaining fonts as needed... + */ + + for (j = i; j < 4; j ++) + fonts->fonts[fonts->num_fonts][j] = + _cupsStrAlloc(fonts->fonts[fonts->num_fonts][0]); + + /* + * Define the character mappings... + */ + + for (i = start, j = fonts->num_fonts * 256; i <= end; i ++, j ++) + { + fonts->chars[i] = j; + fonts->codes[j] = i; + } + + /* + * Move to the next font, stopping if needed... + */ + + fonts->num_fonts ++; + if (fonts->num_fonts >= 256) + break; + } + + fclose(fp); + + if (cupsArrayCount(fonts->unique) == 0) + { + _cupsLangPrintf(stderr, _("ERROR: No fonts in charset file %s\n"), filename); + exit(1); + } + + return (fonts); +} + + +/* + * 'psTextUTF8()' - Output UTF-8 text at the current position. + */ + +void +psTextUTF8(ps_text_t *fonts, /* I - Font data */ + float size, /* I - Size in points */ + int style, /* I - Style */ + int align, /* I - Alignment */ + const char *text) /* I - UTF-8 text */ +{ + cups_utf32_t utf32[2048]; /* Temporary buffer */ + int utf32len; /* Number of characters */ + + + if (!text) + { + puts(""); + return; + } + + if ((utf32len = cupsUTF8ToUTF32(utf32, (cups_utf8_t *)text, + (int)(sizeof(utf32) / sizeof(utf32[0])))) > 0) + psTextUTF32(fonts, size, style, align, utf32, utf32len); +} + + +/* + * 'psTextUTF32()' - Output UTF-32 text at the current position. + */ + +void +psTextUTF32(ps_text_t *fonts, /* I - Font data */ + float size, /* I - Size in points */ + int style, /* I - Font style */ + int align, /* I - Alignment */ + const cups_utf32_t *text, /* I - UTF-32 text */ + int textlen) /* I - Length of text */ +{ + if (size != fonts->size || style != fonts->style) + { + printf("/%s findfont %g scalefont setfont\n", ps_font_names[style], size); + fonts->size = size; + fonts->style = style; + } + + putchar('<'); + while (textlen > 0) + { + printf("%04x", fonts->chars[*text]); + text ++; + textlen --; + } + + if (align == PS_CENTER) + puts(">showcenter"); + else if (align == PS_RIGHT) + puts(">showright"); + else + puts(">showleft"); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/pstext.h b/filter/pstext.h new file mode 100644 index 000000000..fea5b0a75 --- /dev/null +++ b/filter/pstext.h @@ -0,0 +1,75 @@ +/* + * "$Id$" + * + * Common PostScript text definitions for the Common UNIX Printing System + * (CUPS). + * + * Copyright 2008 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/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +/* + * Include necessary headers... + */ + +#include "common.h" +#include <cups/transcode.h> + + +/* + * Constants... + */ + +#define PS_NORMAL 0 /* Normal text */ +#define PS_BOLD 1 /* Bold text */ +#define PS_ITALIC 2 /* Italic text */ +#define PS_BOLDITALIC 3 /* Bold italic text */ + +#define PS_LEFT 1 /* Left-justified text */ +#define PS_CENTER 0 /* Center-justified text */ +#define PS_RIGHT -1 /* Right-justified text */ + + +/* + * Structures... + */ + +typedef struct ps_text_s /**** PostScript font data ****/ +{ + char *glyphs[65536]; /* PostScript glyphs for Unicode */ + int num_fonts; /* Number of fonts to use */ + char *fonts[256][4]; /* Fonts to use */ + cups_array_t *unique; /* Unique fonts */ + unsigned short chars[65536], /* 0xffcc (ff = font, cc = char) */ + codes[65536]; /* Unicode glyph mapping to fonts */ + int widths[256], /* Widths of each font */ + directions[256];/* Text directions for each font */ + float size; /* Current text size */ + int style; /* Current text style */ +} ps_text_t; + + +/* + * Functions... + */ + +extern void psTextEmbedFonts(ps_text_t *fonts); +extern void psTextListFonts(ps_text_t *fonts); +extern ps_text_t *psTextInitialize(void); +extern void psTextUTF8(ps_text_t *fonts, float size, int style, + int align, const char *text); +extern void psTextUTF32(ps_text_t *fonts, float size, int style, + int align, const cups_utf32_t *text, + int textlen); + + +/* + * End of "$Id$". + */ diff --git a/filter/textcommon.c b/filter/textcommon.c index 621e2257d..67a729144 100644 --- a/filter/textcommon.c +++ b/filter/textcommon.c @@ -515,8 +515,9 @@ TextMain(const char *name, /* I - Name of filter */ if (argc < 6 || argc > 7) { - fprintf(stderr, _("Usage: %s job-id user title copies options [file]\n"), - name); + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + name); return (1); } diff --git a/notifier/testnotify.c b/notifier/testnotify.c index 664ddb018..1b8921839 100644 --- a/notifier/testnotify.c +++ b/notifier/testnotify.c @@ -52,6 +52,7 @@ main(int argc, /* I - Number of command-line arguments */ fprintf(stderr, "DEBUG: argc=%d\n", argc); for (i = 0; i < argc; i ++) fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); + fprintf(stderr, "DEBUG: TMPDIR=\"%s\"\n", getenv("TMPDIR")); for (;;) { diff --git a/packaging/cups.list.in b/packaging/cups.list.in index 81805390a..ff313594d 100644 --- a/packaging/cups.list.in +++ b/packaging/cups.list.in @@ -295,6 +295,7 @@ f 0755 root sys $SERVERBIN/daemon/cups-driverd scheduler/cups-driverd f 0755 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld d 0755 root sys $SERVERBIN/driver - d 0755 root sys $SERVERBIN/filter - +f 0755 root sys $SERVERBIN/filter/bannertops filter/bannertops f 0755 root sys $SERVERBIN/filter/commandtoespcx driver/commandtoescpx f 0755 root sys $SERVERBIN/filter/commandtopclx driver/commandtopclx f 0755 root sys $SERVERBIN/filter/commandtops filter/commandtops diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 016a1b1af..23b2c09c4 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -2758,8 +2758,11 @@ add_printer(cupsd_client_t *con, /* I - Client connection */ * (Re)register color profiles... */ - apple_unregister_profiles(printer); - apple_register_profiles(printer); + if (!RunUser) + { + apple_unregister_profiles(printer); + apple_register_profiles(printer); + } #endif /* __APPLE__ */ } else @@ -2820,8 +2823,11 @@ add_printer(cupsd_client_t *con, /* I - Client connection */ * (Re)register color profiles... */ - apple_unregister_profiles(printer); - apple_register_profiles(printer); + if (!RunUser) + { + apple_unregister_profiles(printer); + apple_register_profiles(printer); + } #endif /* __APPLE__ */ } } diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh index 4c341dcc2..c5d671813 100755 --- a/test/run-stp-tests.sh +++ b/test/run-stp-tests.sh @@ -244,6 +244,7 @@ ln -s $root/cgi-bin /tmp/cups-$user/bin ln -s $root/monitor /tmp/cups-$user/bin ln -s $root/notifier /tmp/cups-$user/bin ln -s $root/scheduler /tmp/cups-$user/bin/daemon +ln -s $root/filter/bannertops /tmp/cups-$user/bin/filter ln -s $root/filter/commandtops /tmp/cups-$user/bin/filter ln -s $root/filter/hpgltops /tmp/cups-$user/bin/filter ln -s $root/filter/pstops /tmp/cups-$user/bin/filter |