-------- VERSION 1
Date: Mon, 11 Mar 2002 22:02:06 -0800
From: Stuart Marshall <stuart@igpp.ucllnl.org>
Subject: Re: LPRng: Inserting a watermark

Hi,

I have the following in a .tex file:

%-------- specials to put DRAFT across the page
\special{!userdict begin /bop-hook{gsave 200 30 translate 65 rotate
        /Times-Roman findfont 216 scalefont setfont 0 0 moveto 0.9
	setgray (DRAFT) show grestore}def end}

As long as you are sending postscript to the printer, I think some
variant on that will do what you want.  Obviously you'll want to
do something smaller than a bit "DRAFT" diagonally across the page.

hope that helps,
Stuart

----------- VERSION2

From: Rick Cochran [mailto:rcc2@cornell.edu]
Sent: Friday, November 07, 2003 2:26 PM
To: Darin Stephenson
Cc: Michael Q. Hojnowski
Subject: Cornell LPRng needs

Darin and Patrick,

As promised, I have attached the relevant code for the watermark.
The code snippit at the begining is what determines where the
PostScript gets inserted (depends on printer model).  This code is
part of my final "if".  Not pretty, but that's life.  Saves us
printing about a million banner pages per year.

Yours,
-Rick

--
|Rick Cochran                                   phone: 607-255-7618|
|Cornell CIT - Systems & Operations - Net-Print   FAX: 607-255-8521|
|730 Rhodes Hall, Ithaca, N.Y. 14853        email: rcc2@cornell.edu|

############################################################################
# Copyright (c) 2003 by Cornell University.  All rights reserved.
#
# Permission to use and redistribute this software is granted with the
# following two conditions:
#
# This Copyright notice must be retained in the code.
#
# The user or redistributor understands that this software is being
# provided "as is," without any express or implied warranties,  including,
# without limitation, the implied warranties of merchantability and
# fitness for a particular purpose.
############################################################################

...

# Print watermark or banner page if required
my($banner_printed) = 0;
if ( $qinfo->{banner} eq 'Y' ) {
    if ( $ainfo->{banner} eq 'W' ) {
        if ( not ($qinfo->{model} =~ /^Lexmark/) ) {
	    $line = find_line('^%%EndSetup', $PRINT);
	    sockwrite($line);
	    my_log_line($qname, $lineno, $line);
	}
	print_watermark($ainfo, $jobinfo);
    }
    else {
	print_banner($dbh, $qinfo, $ainfo, $jobinfo, { 'errno' => 0 }, undef);
	$banner_printed++;
    }
}

...

############################################################################
# Print a watermark prolog
sub print_watermark {
    my($ainfo, $jobinfo) = @_;

    my($netid) = psclean($ainfo->{usernetid});
    my($queued_time_display) = psclean($jobinfo->{queued_time_display});
    my($jobname) = psclean($jobinfo->{name});

    # start ps file
    my($b) = '';
    $b .= "%%BeginNetPrintWatermark\n";

# EndPage is called at the begining of showpage, copypage and setpagedevice.
# It is also called at a few other times. For complete details see pages
# 251-255 of the Red Book 2nd edition. 
#
# It is passed two integers on the the stack (which it is expected to consume):
#  # of executions of 'showpage' (starting with 0)
#  who called: 0 => showpage; 1 => copypage; 2 => setpagedevice
# It should generate a boolean which indictaes whether the current page should
# be rasterized (true) or erased (false). 

# The Bad News: The Lexmark EndPage operator _doesn't check for
# setpagedevice_.  Therefore, if we define our EndPage while theirs is
# defined, the 'setpagedevice' causes the Lexmark EndPage to execute once,
# creating a blank page.
# The Worse News: 'EndPage' is a _special_ name in the currentpagedevice
# dictionary.  If we try renaming the definition to 'OldEndPage', it disappears
# without a trace when 'setpagedevice' is executed.
# Even Worse News: The Lexmark EndPage operator seems to need to be called even
# if the caller code is neither 0 nor 1.
# Sad News: Because of its poor design, the 'setpagedevice' which defines the
# Lexmark EndPage operator must be the very last 'setpagedevice' in the code.
# Therefore, it may occur in the page 1 preamble instead of the document
# preamble.

# There is similar Bad News for HP - especially using the Adobe driver.  If our
# EndPage code is placed after a particular piece of driver code, it will
# cause a blank page to be printed.  Also, HP has its own watermark code which
# is implemented as a 'Feature' in its PPD files.  This will supersede our
# watermark.

# Conclusions:
# We put the watermark code at the begining for Lexmark queues and after
# '%%EndSetup' for HP (and other) queues.
# It is simply too complicated to try to fix the Lexmark driver N-up/watermark
# problem.  If people _must_ use the Lexmark driver, then they will not get
# watermarks on N-up output.

    $b .= "<<\n";
    $b .= "  /EndPage\n";
    $b .= "  {\n";

# On stack: (#showpages) (code)
# Duplicate EndPage arguments

    $b .= "    2 copy\n";
    $b .= "    dup 0 eq exch 1 eq or exch 0 eq and\n";   # (showpage or copypage) and (page == 0)
    $b .= "    {\n";
    $b .= "      save\n";

# Create a dictionary large enough to hold our operators
    $b .= "      10 dict begin\n";
    $b .= "      /rvideo { currentpoint 1 sub 2 index stringwidth pop 6 0 setgray rectfill 1 setgray show 0 setgray } bind def\n";
    $b .= "      initmatrix\n";

# Get printable area
    $b .= "      initclip clippath pathbbox /ymax exch def /xmax exch def /ymin exch def /xmin exch def\n";
    $b .= "      /fontsize 6 def\n";

# Next line moves to top of page
    $b .= "      /ymin ymax fontsize sub 1 sub def\n";
    $b .= "      /ybase ymin 2 add def\n";
    $b .= "      initclip\n";
    $b .= "      1 setgray xmin ymin xmax fontsize 1 add rectfill 0 setgray\n";
    $b .= "      xmin ybase moveto\n";
    $b .= "      /TimesNewRoman-BoldItalic findfont [8 0 0 6 0 0] makefont setfont\n";
    $b .= "      ( Net-Print ) rvideo\n";
    $b .= "      xmax ( Net-Print ) stringwidth pop sub ybase moveto\n";
    $b .= "      ( Net-Print ) rvideo\n";
    $b .= "      64 ybase moveto\n";
    $b .= "      /Helvetica-Bold findfont fontsize scalefont setfont \n";
    $b .= "      ( $netid ) rvideo\n";
    $b .= "      100 ybase moveto\n";
    $b .= "      ( $jobname) show\n";
    $b .= "      527 ybase moveto\n";
    $b .= "      ( $queued_time_display) show\n";
    $b .= "      end\n";
    $b .= "      restore\n";
    $b .= "    } if\n";

# A simple EndPage operator.
    $b .= "    exch pop dup 0 eq exch 1 eq or\n";

    $b .= "  }\n";
    $b .= ">> setpagedevice\n";
    $b .= "%%EndNetPrintWatermark\n";
    sockwrite($b);
}

--------------- VERSION 3

This goes in a PPD file so you can use the Watermark with Foomatic-RIP
See the notes about StartPage and EndPage


 *DefaultWatermark: True
 *OrderDependency: 99 PaeeSetup *Watermark
 *Watermark True: "
 <<
   /EndPage
   {
     2 copy
     dup 0 eq exch 1 eq or exch 0 eq and
     {
       save
       10 dict begin
       /rvideo { currentpoint 1 sub 2 index
         stringwidth pop 6 0 setgray rectfill 1
         setgray show 0 setgray } bind def
       initmatrix initclip clippath pathbbox /ymax exch def
         /xmax exch def /ymin exch def /xmin exch def
       /fontsize 6 def /ymin ymax fontsize sub 1 sub def /ybase ymin 2 add def
       initclip 1 setgray xmin ymin xmax fontsize 1 add rectfill 0 setgray
       xmin ybase moveto /TimesNewRoman-BoldItalic findfont
         [8 0 0 6 0 0] makefont setfont
       ( Net-Print ) rvideo xmax ( Net-Print ) stringwidth pop sub ybase moveto
       ( Net-Print ) rvideo 64 ybase moveto /Helvetica-Bold findfont
        fontsize scalefont setfont
       ( \%s{cmd.P} \%s{cmd.L} ) rvideo
       100 ybase moveto
       ( \%s{cmd.J} ) show
       527 ybase moveto
       ( \%s{DATE} ) show
       end
       restore
     } if
     exch pop dup 0 eq exch 1 eq or
   } >> setpagedevice
 *End
