char *ps_filter[] = {
  "%/setglobal where\n",
  "% { pop currentglobal /setglobal load true setglobal }\n",
  "% { { } }\n",
  "%ifelse\n",
  "NOBIND\n",
  " { systemdict begin /bind /.bind load def end }\n",
  "if\n",
  "\n",
  "40 dict begin			% following stuff is private\n",
  "\n",
  "/redef { systemdict begin odef end } bind def\n",
  "/privateDict currentdict def	% for lastFontNum and lastEncoding\n",
  "/fonts 200 dict def		% maps font to integer \"n\"\n",
  "/fontsUnit 200 dict def 	% (1000,0) and (0,1000) transformed, per font\n",
  "/encodings 200 dict def		% maps encoding array to integer \"e\"\n",
  "/encodingSpace 200 dict def	% space char for each encoding\n",
  "/metrics 200 dict def		% maps font UniqueID to integer  \"m\"\n",
  "/lastFontNum 0 def		% last integer used for a font\n",
  "/lastEncoding 0 def		% last integer used for an encoding\n",
  "/lastMetrics 0 def		% last integer used for a metrics table\n",
  "/minLeft 90000 def		% initializing min left coordinate\n",
  "/maxRight 0 def			% initializing max right coordinate \n",
  "/tempFile (/tmp/minmax.tmp) (w) file def % defining a temporary file\n",
  "/tempString 20 string def	% scratch for printing integers\n",
  "/reportMatrix matrix identmatrix def % maps device coords to reporting coords\n",
  "/inUse false def		% prevents recursive invokcation of \"report\"\n",
  "\n",
  "/dvipsGlyphs [\n",
  "  % Self-named glyphs for dvitops type 3 fonts ...\n",
  "  % 284\n",
  "  0 1 255 { 1 string dup 0 4 -1 roll put cvn } for\n",
  "  % 540\n",
  "  ] def\n",
  "\n",
  "/oldDviGlyphs [\n",
  "  % More self-named glyphs for old dvitops type 3 fonts ...\n",
  "  % 1052\n",
  "  0 1 127 { 10 3 string cvrs cvn } for\n",
  "  % 1180\n",
  "  ] def\n",
  "\n",
  "/StandardGlyphs 256 128 add array def\n",
  "//StandardGlyphs 0 //dvipsGlyphs putinterval\n",
  "//StandardGlyphs 256 //oldDviGlyphs putinterval\n",
  "\n",
  "/standardMap StandardGlyphs length dict\n",
  "  % Maps names to indices in StandardGlyphs.\n",
  "  0 StandardGlyphs {\n",
  "    2 index exch\n",
  "    2 copy known { pop pop } { 2 index put } ifelse\n",
  "    1 add\n",
  "    } forall\n",
  "  pop def\n",
  "\n",
  "/printInt {			% stack: n\n",
  "  % Prints an integer followed by a space on stdout\n",
  "  //tempString cvs print ( ) print\n",
  "  } bind def\n",
  "\n",
  "/showxy {			%stack:  x y\n",
  "  % prints a pair of integers on stdout, converting to 1/100th's\n",
  "  exch\n",
  "  100 mul round cvi //printInt exec\n",
  "  100 mul round cvi //printInt exec\n",
  "  } bind def\n",
  "\n",
  "/characterToReporting {		% stack: x y -> x' y'\n",
  "  % Transforms a vector in currentfont's character coordinate\n",
  "  % system to the reporting coordinate system\n",
  "  currentfont /FontMatrix get\n",
  "  dtransform			% to current user coordinates\n",
  "  dtransform			% to device coordinates\n",
  "  //reportMatrix idtransform	% to reporting coordinates\n",
  "  } def\n",
  "\n",
  "/printCharacterOrigin {\n",
  "  % Prints the position in the reporting coordinate system at which a\n",
  "  % character origin would be painted using currentfont\n",
  "  0 0 currentfont /FontMatrix get transform\n",
  "  currentpoint exch 4 -1 roll add 3 1 roll add\n",
  "  transform //reportMatrix itransform\n",
  "  1 index 100 mul round cvi \n",
  "  dup minLeft lt\n",
  "  { /minLeft 1 index def\n",
  "    //tempFile (ML ) writestring\n",
  "    //tempFile minLeft //tempString cvs writestring\n",
  "    //tempFile (\n) writestring\n",
  "  } if \n",
  "  dup maxRight gt\n",
  "  { /maxRight 1 index def\n",
  "    //tempFile (MR ) writestring\n",
  "    //tempFile maxRight //tempString cvs writestring\n",
  "    //tempFile (\n) writestring\n",
  "  } if\n",
  "  pop\n",
  "  //showxy exec\n",
  "  } bind def\n",
  "\n",
  "/printMap {\n",
  "  % Print map from indices in currentfont/Encoding to StandardEncoding indices\n",
  "  16 currentfont /Encoding get dup length //printInt exec {\n",
  "    exch dup 16 eq { () = pop 1 } { 1 add } ifelse exch\n",
  "    //standardMap exch\n",
  "    2 copy known {\n",
  "      get //printInt exec\n",
  "      } {\n",
  "      pop pop (9999 ) print\n",
  "      } ifelse\n",
  "    } forall\n",
  "  pop () =\n",
  "  } bind def\n",
  "\n",
  "/metricsString (X) def\n",
  "\n",
  "/printMetrics {\n",
  "  % Print bounding box and character metrics for currentfont\n",
  "  % Sadly, dvitops produces illegal type 3 fonts with no /.notdef entry. The\n",
  "  % use of \"stopped\" deals with that and any other silliness.\n",
  "  currentfont /FontBBox get aload pop 4 2 roll\n",
  "  //showxy exec\n",
  "  //showxy exec\n",
  "  currentfont /FontMatrix get\n",
  "  currentfont /FontType get 3 eq {\n",
  "    //privateDict /pm.dictCount countdictstack put\n",
  "    count //privateDict exch /pm.count exch put\n",
  "    //privateDict /pm.save save put\n",
  "    0 1 255 {\n",
  "      dup 8 mod 0 eq { () = } if\n",
  "      //metricsString exch 0 exch put\n",
  "      { //metricsString //stringwidth exec\n",
  "        2 index idtransform		% to font's character coordinates\n",
  "        } stopped {\n",
  "        count //privateDict /pm.count get sub { pop } repeat\n",
  "        countdictstack //privateDict /pm.dictCount get sub { end } repeat\n",
  "        //privateDict /pm.save get restore\n",
  "        //privateDict /pm.save save put\n",
  "        0 0\n",
  "        } if\n",
  "      //showxy exec\n",
  "      } for\n",
  "    //privateDict /pm.save get restore % necessary to balance the \"save\"\n",
  "    }{\n",
  "    currentfont /CharStrings get\n",
  "    currentfont /Encoding get\n",
  "    0 1 255 {\n",
  "      dup 8 mod 0 eq { () = } if\n",
  "      2 copy get 3 index exch known {\n",
  "        //metricsString exch 0 exch put\n",
  "        //metricsString //stringwidth exec\n",
  "        4 index idtransform		% to font's character coordinates\n",
  "        } {\n",
  "        pop 0 0\n",
  "        } ifelse\n",
  "      //showxy exec\n",
  "      } for\n",
  "      pop pop				% encoding, charstrings\n",
  "    } ifelse\n",
  "  pop				% fontmatrix\n",
  "  } bind def\n",
  "\n",
  "\n",
  "%\n",
  "% The main work: reportMetrics, reportEncoding, reportFont and report\n",
  "%\n",
  "\n",
  "/reportMetrics {		% stack: -> m\n",
  "				% privateDict is open\n",
  "  % Print new \"m\" directive for currentfont\n",
  "  (QM ) print\n",
  "  lastMetrics 1 add /lastMetrics 1 index def\n",
  "  dup //printInt exec\n",
  "  //printMetrics exec\n",
  "  () =\n",
  "  } bind def\n",
  "\n",
  "/reportEncoding {		% stack: -> e\n",
  "				% privateDict is open\n",
  "  % Print new \"e\" directive for currentfont\n",
  "  (QE ) print\n",
  "  lastEncoding 1 add /lastEncoding 1 index def\n",
  "  dup //printInt exec\n",
  "  //printMap exec\n",
  "  } bind def\n",
  "\n",
  "/spaceString (X) def		% for space char from current encoding\n",
  "\n",
  "/reportFont {			% stack: any -> unchanged\n",
  "  % Report currentfont to the user and record its number\n",
  "  % //privateDict is open\n",
  "  % Sets //privateDict/spaceString to font's encoding's space string, if any,\n",
  "  % and sets //privateDict/hasSpace to indicate whether there's a space char.\n",
  "  currentfont /UniqueID known not {\n",
  "    //reportMetrics exec\n",
  "    } {\n",
  "    //metrics currentfont /UniqueID get\n",
  "    2 copy known {\n",
  "      get\n",
  "      } {\n",
  "      //reportMetrics exec\n",
  "      dup 4 1 roll put		% define in /metrics\n",
  "      } ifelse\n",
  "    } ifelse			% stack: m\n",
  "  //encodings currentfont /Encoding get\n",
  "  2 copy known {\n",
  "    get\n",
  "    } {\n",
  "    //reportEncoding exec	% leaves e on stack\n",
  "    dup 4 1 roll put		% define in /encodings\n",
  "    //encodingSpace 1 index\n",
  "    0 currentfont /Encoding get {\n",
  "      dup /space eq exch /G20 eq or { exit } if\n",
  "      1 add\n",
  "      } forall\n",
  "    put				% put in /encodingSpace\n",
  "    } ifelse			% stack: m e\n",
  "  //encodingSpace 1 index get	% font's space character (256 if none)\n",
  "  /hasSpace 1 index 256 lt def\n",
  "  hasSpace { //spaceString exch 0 exch put } { pop } ifelse\n",
  "  (QF ) print\n",
  "  lastFontNum 1 add /lastFontNum 1 index def\n",
  "  //fonts currentfont 2 index put % record fontNum in /fonts\n",
  "  dup //printInt exec		% print fontNum\n",
  "				% stack: m e f\n",
  "  1000 0 //characterToReporting exec 2 copy //showxy exec\n",
  "  0 1000 //characterToReporting exec 2 copy //showxy exec\n",
  "  4 array astore		% stack: m e f array\n",
  "  //fontsUnit 3 1 roll put	% stack: m e\n",
  "  //printInt exec		% print encoding number\n",
  "  //printInt exec		% print metrics number\n",
  "  currentfont /FontName		% check font dict for /FontName\n",
  "  2 copy known {\n",
  "    get				% if found ...\n",
  "    dup type /stringtype eq	% ... and is actually a string\n",
  "    { print }			% print it.\n",
  "    { == } ifelse		% else print whatever we've found\n",
  "    }\n",
  "    { pop pop			% pop out the 2 copies\n",
  "      (UserDef) print		% FontName does not exist\n",
  "    } ifelse\n",
  "  () =\n",
  "  } bind def\n",
  "\n",
  "/reportFontCreation {		% stack: font\n",
  "  % Report a newly created font. Called now so that if later uses are\n",
  "  % inside a save/restore we don't forget it.\n",
  "  % NOTE: this is currently not used, since it actually slows things down\n",
  "  //privateDict begin\n",
  "  inUse not {\n",
  "    /inUse true def\n",
  "    dup currentfont exch setfont //reportFont exec setfont\n",
  "    /inUse false def\n",
  "    } if\n",
  "  end\n",
  "  } bind def\n",
  "\n",
  "/reportSubString {		% stack: args string -> args\n",
  "  % Report the rendering of a string, assumed to be a single word.\n",
  "  % privateDict is open.  /n is font number, /p is call-back\n",
  "  dup length 0 eq {\n",
  "    p\n",
  "    } {\n",
  "    (QS ) print\n",
  "    n //printInt exec\n",
  "    //printCharacterOrigin exec\n",
  "    dup length //printInt exec\n",
  "    dup print ( ) print\n",
  "    /p load end			% close privateDict during the call-back\n",
  "    exec			% render the string; leaves args on stack\n",
  "    //privateDict begin\n",
  "    //printCharacterOrigin exec\n",
  "    () =\n",
  "    } ifelse\n",
  "  } bind def\n",
  "\n",
  "/report {			% stack: args string proc -> args\n",
  "  % Report the rendering of a string.\n",
  "  % Calls proc for each word and space.  The call-back should expect \"args\"\n",
  "  % on the stack followed by a string, and should leave \"args\" on the stack.\n",
  "  //privateDict begin\n",
  "  inUse {\n",
  "    end exec\n",
  "    } {\n",
  "    /inUse true def\n",
  "    //fonts currentfont\n",
  "    2 copy known not { //reportFont exec } if\n",
  "    get				% stack: probable font-number\n",
  "    % check if points transform as before ...\n",
  "    //fontsUnit 1 index get\n",
  "    1000 0 //characterToReporting exec\n",
  "    0 1000 //characterToReporting exec\n",
  "    4 index 3 get ne 4 1 roll\n",
  "    4 index 2 get ne 4 1 roll\n",
  "    4 index 1 get ne 4 1 roll\n",
  "    4 index 0 get ne 5 -1 roll pop\n",
  "    or or or {			% if transformed points differ\n",
  "      //reportFont exec\n",
  "      pop //fonts currentfont get\n",
  "      } if			% stack: args string proc n\n",
  "    /n exch def\n",
  "    /p exch def		% stack: args string\n",
  "    hasSpace {\n",
  "      {			% begin loop\n",
  "        //spaceString search {\n",
  "          exch pop exch /s exch def\n",
  "          //reportSubString exec\n",
  "          //spaceString p\n",
  "          s\n",
  "          } {\n",
  "          //reportSubString exec\n",
  "          exit\n",
  "          } ifelse\n",
  "        } loop\n",
  "      } {\n",
  "      //reportSubString exec\n",
  "      } ifelse\n",
  "    /inUse false def\n",
  "    end\n",
  "    } ifelse\n",
  "  } bind def\n",
  "\n",
  "/dontReport {			% stack: proc\n",
  "  % Call \"proc\" with //privateDict/inUse set to true\n",
  "  //privateDict /inUse get {\n",
  "    exec\n",
  "    } {\n",
  "    //privateDict /inUse true put\n",
  "    exec\n",
  "    //privateDict /inUse false put\n",
  "    } ifelse\n",
  "  } bind def\n",
  "\n",
  "/kshow.temp (X) def		% scratch space for kshow\n",
  "\n",
  "userdict begin			% subsequent definitions are publicly visible\n",
  "\n",
  "\n",
  "%\n",
  "% Redefine the character rendering operations to call \"report\"\n",
  "%\n",
  "\n",
  "/show { { show } //report exec } bind redef\n",
  "\n",
  "/ashow { {3 copy ashow pop} //report exec pop pop } bind redef\n",
  "\n",
  "/widthshow { {4 copy widthshow pop} //report exec pop pop pop } bind redef\n",
  "\n",
  "/awidthshow { {6 copy awidthshow pop} //report exec 5 {pop} repeat } bind redef\n",
  "\n",
  "/kshow {			% stack: proc string\n",
  "  exch //privateDict exch /kshow.proc exch put\n",
  "  false exch			% stack: false string\n",
  "  {				% stack: false next | prev true next\n",
  "    //kshow.temp 0 2 index put\n",
  "    exch { //privateDict /kshow.proc get exec } { pop } ifelse\n",
  "    //kshow.temp //show exec\n",
  "    //kshow.temp 0 get true	% stack: this true\n",
  "    } forall\n",
  "				% stack: false | last true\n",
  "  { pop } if\n",
  "  } bind redef\n",
  "\n",
  "%\n",
  "% Redefine the painting operators\n",
  "% in order to indicate the presence of a shape.\n",
  "%\n",
  "\n",
  "% We only want to redefine operators if they are defined already.\n",
  "\n",
  "/codef { 1 index where { pop def } { pop pop } ifelse } def\n",
  "\n",
  "% Redefine the fill operators to detect rectangles.\n",
  "\n",
  "/.orderrect	% <llx> <lly> <urx> <ury> .orderrect <llx> <lly> <w> <h>\n",
  " {	% Ensure llx <= urx, lly <= ury.\n",
  "   1 index 4 index lt { 4 2 roll } if\n",
  "   dup 3 index lt { 3 1 roll exch } if\n",
  "   exch 3 index sub exch 2 index sub\n",
  " } odef\n",
  "/.fillcomplex\n",
  " {	% Do a first pass to see if the path is all rectangles in\n",
  "	% the output coordinate system.  We don't worry about overlapping\n",
  "	% rectangles that might be partially not filled.\n",
  "	% Stack: mark llx0 lly0 urx0 ury0 ... true mark x0 y0 ...\n",
  "   mark true mark\n",
  "	% Add a final moveto so we pick up any trailing unclosed subpath.\n",
  "   0 0 itransform moveto\n",
  "    { .coord counttomark 2 gt\n",
  "       { counttomark 4 gt { .fillcheckrect } { 4 2 roll pop pop }  ifelse }\n",
  "      if\n",
  "    }\n",
  "    { .coord }\n",
  "    { cleartomark not mark exit }\n",
  "    { counttomark -2 roll 2 copy counttomark 2 roll .fillcheckrect }\n",
  "   pathforall cleartomark\n",
  "    { counttomark 4 idiv\n",
  "       { counttomark -4 roll .orderrect\n",
  "	 (QL ) //print .show==4\n",
  "       }\n",
  "      repeat pop\n",
  "    }\n",
  "    { cleartomark\n",
  "    }\n",
  "   ifelse\n",
  " } odef\n",
  "/.fillcheckrect\n",
  " {	% Check whether the current subpath is a rectangle.\n",
  "	% If it is, add it to the list of rectangles being accumulated;\n",
  "	% if not exit the .fillcomplex loop.\n",
  "	% The subpath has not been closed.\n",
  "	% Stack: as in .fillcomplex, + newx newy\n",
  "   counttomark 10 eq { 9 index 9 index 4 2 roll } if\n",
  "   counttomark 12 ne { cleartomark not mark exit } if\n",
  "   12 2 roll\n",
  "	% Check for the two possible forms of rectangles:\n",
  "	%	x0 y0  x0 y1  x1 y1  x1 y0  x0 y0\n",
  "	%	x0 y0  x1 y0  x1 y1  x0 y1  x0 y0\n",
  "   9 index 2 index eq 9 index 2 index eq and\n",
  "   10 index 9 index eq\n",
  "    {	% Check for first form.\n",
  "      7 index 6 index eq and 6 index 5 index eq and 3 index 2 index eq and\n",
  "    }\n",
  "    {	% Check for second form.\n",
  "      9 index 8 index eq and\n",
  "      8 index 7 index eq and 5 index 4 index eq and 4 index 3 index eq and\n",
  "    }\n",
  "   ifelse not { cleartomark not mark exit } if\n",
  "	% We have a rectangle.\n",
  "   pop pop pop pop 4 2 roll pop pop 8 4 roll\n",
  " } odef\n",
  "/eofill { .fillcomplex newpath } codef\n",
  "/fill { .fillcomplex newpath } codef\n",
  "/rectfill { gsave newpath .rectappend fill grestore } codef\n",
  "/ueofill { gsave newpath uappend eofill grestore } codef\n",
  "/ufill { gsave newpath uappend fill grestore } codef\n",
  "\n",
  "% Redefine the stroke operators to detect rectangles.\n",
  "\n",
  "/rectstroke\n",
  " { gsave newpath\n",
  "   dup type dup /arraytype eq exch /packedarraytype eq or\n",
  "    { dup length 6 eq { exch .rectappend concat } { .rectappend } ifelse }\n",
  "    { .rectappend }\n",
  "   ifelse stroke grestore\n",
  " } codef\n",
  "/.strokeline	% <fromx> <fromy> <tox> <toy> .strokeline <tox> <toy>\n",
  "		% Note: fromx and fromy are in output coordinates;\n",
  "		% tox and toy are in user coordinates.\n",
  " { .coord 2 copy 6 2 roll .orderrect\n",
  "	% Add in the line width.  Assume square or round caps.\n",
  "   currentlinewidth 2 div dup .dcoord add abs 1 max 5 1 roll\n",
  "   4 index add 4 1 roll 4 index add 4 1 roll\n",
  "   4 index sub 4 1 roll 5 -1 roll sub 4 1 roll\n",
  "   (QR ) //print .show==4\n",
  " } odef\n",
  "/.strokecomplex\n",
  " {	% Do a first pass to see if the path is all horizontal and vertical\n",
  "	% lines in the output coordinate system.\n",
  "	% Stack: true mark origx origy curx cury\n",
  "   true mark null null null null\n",
  "    { .coord 6 2 roll pop pop pop pop 2 copy }\n",
  "    { .coord 1 index 4 index eq 1 index 4 index eq or\n",
  "       { 4 2 roll pop pop }\n",
  "       { cleartomark not mark exit }\n",
  "      ifelse\n",
  "    }\n",
  "    { cleartomark not mark exit }\n",
  "    { counttomark -2 roll 2 copy counttomark 2 roll\n",
  "      1 index 4 index eq 1 index 4 index eq or\n",
  "       { pop pop 2 copy }\n",
  "       { cleartomark not mark exit }\n",
  "      ifelse\n",
  "    }\n",
  "   pathforall cleartomark\n",
  "   0 currentlinewidth .dcoord 0 eq exch 0 eq or and\n",
  "	% Do the second pass to write out the rectangles.\n",
  "	% Stack: origx origy curx cury\n",
  "    { null null null null\n",
  "       { 6 2 roll pop pop pop pop 2 copy .coord }\n",
  "       { .strokeline }\n",
  "       { }\n",
  "       { 3 index 3 index .strokeline }\n",
  "      pathforall pop pop pop pop\n",
  "    }\n",
  "   if\n",
  " } odef\n",
  "/stroke { .strokecomplex newpath } codef\n",
  "/ustroke\n",
  " { gsave newpath\n",
  "   dup length 6 eq { exch uappend concat } { uappend } ifelse\n",
  "   stroke grestore\n",
  " } codef\n",
  "\n",
  "% Set things up so our output will be in tenths of a point, with origin at\n",
  "% lower left.  This isolates us from the peculiarities of individual devices.\n",
  "\n",
  "/.show.ident.matrix matrix def\n",
  "/.show.ident\n",
  "% { //.show.ident.matrix defaultmatrix\n",
  "%		% Assume the original transformation is well-behaved.\n",
  "%   0.1 0 2 index dtransform abs exch abs .max /.show.scale exch def\n",
  "%   0.1 dup 3 -1 roll scale\n",
  " { gsave initmatrix\n",
  "		% Assume the original transformation is well-behaved.\n",
  "   0.1 0 dtransform abs exch abs .max /.show.scale exch def\n",
  "   0.1 dup scale .show.ident.matrix currentmatrix\n",
  "   grestore\n",
  " } bind def\n",
  "/.coord\n",
  " { transform .show.ident itransform\n",
  "   exch round cvi exch round cvi\n",
  " } odef\n",
  "/.dcoord\n",
  " {		% Transforming distances is trickier, because\n",
  "		% the coordinate system might be rotated.\n",
  "   .show.ident pop\n",
  "   exch 0 dtransform\n",
  "     dup mul exch dup mul add sqrt\n",
  "     .show.scale div round cvi\n",
  "   exch 0 exch dtransform\n",
  "     dup mul exch dup mul add sqrt\n",
  "     .show.scale div round cvi\n",
  " } odef\n",
  "\n",
  "% We have to redirect stdout somehow....\n",
  "/.show.stdout { (%stdout) (w) file } bind def\n",
  "\n",
  "% Make sure writing will work even if a program uses =string.\n",
  "/.show.string =string length string def\n",
  "/.show.=string =string length string def\n",
  "/.show==only\n",
  " { //=string //.show.=string copy pop\n",
  "   dup type /stringtype eq\n",
  "    { dup length //.show.string length le\n",
  "       { dup rcheck { //.show.string copy } if\n",
  "       } if\n",
  "    } if\n",
  "   .show.stdout exch write==only\n",
  "   //.show.=string //=string copy pop\n",
  " } odef\n",
  "/.show==4\n",
  " { 4 -1 roll 10 mul .show==only ( ) //print\n",
  "   3 -1 roll 10 mul .show==only ( ) //print\n",
  "   exch 10 mul .show==only ( ) //print\n",
  "   10 mul .show==only (\n) //print\n",
  " } odef\n",
  "\n",
  "%\n",
  "% Redefine the image and colorimage operators\n",
  "% so that they report about their path box\n",
  "%\n",
  "\n",
  "/image {\n",
  "  image\n",
  "  (QI ) print\n",
  "  (\n) print\n",
  "  } bind redef\n",
  "\n",
  "/colortogray {  % define an RGB->I function\n",
  "  /rgbdata exch store    % call input 'rgbdata'\n",
  "  rgbdata length 3 idiv\n",
  "  /npixls exch store\n",
  "  /rgbindx 0 store\n",
  "  0 1 npixls 1 sub {\n",
  "    grays exch\n",
  "    rgbdata rgbindx       get 20 mul    % Red\n",
  "    rgbdata rgbindx 1 add get 32 mul    % Green\n",
  "    rgbdata rgbindx 2 add get 12 mul    % Blue\n",
  "    add add 64 idiv      % I = .5G + .31R + .18B\n",
  "    put\n",
  "    /rgbindx rgbindx 3 add store\n",
  "  } for\n",
  "  grays 0 npixls getinterval\n",
  "} bind def\n",
  "\n",
  "% Utility procedure for colorimage operator.\n",
  "% This procedure takes two procedures off the\n",
  "% stack and merges them into a single procedure.\n",
  "\n",
  "/mergeprocs { % def\n",
  "  dup length\n",
  "  3 -1 roll\n",
  "  dup\n",
  "  length\n",
  "  dup\n",
  "  5 1 roll\n",
  "  3 -1 roll\n",
  "  add\n",
  "  array cvx\n",
  "  dup\n",
  "  3 -1 roll\n",
  "  0 exch\n",
  "  putinterval\n",
  "  dup\n",
  "  4 2 roll\n",
  "  putinterval\n",
  "} bind def\n",
  "\n",
  "/colorimage { % def\n",
  "  pop pop     % remove 'false 3' operands\n",
  "  {colortogray} mergeprocs\n",
  "  image\n",
  "} bind def\n",
  "\n",
  "%\n",
  "% Redefine non-rendering operations so that they don't report\n",
  "%\n",
  "\n",
  "/stringwidth { {stringwidth} //dontReport exec } bind redef\n",
  "\n",
  "/charpath { {charpath} //dontReport exec } bind redef\n",
  "\n",
  "\n",
  "%\n",
  "% Intercept and report the page operations\n",
  "%\n",
  "\n",
  "/copypage { (QC) = flush copypage } bind redef\n",
  "\n",
  "/erasepage { (QZ) = flush erasepage } bind redef\n",
  "\n",
  "/showpage { (QP) = flush showpage } bind redef\n",
  "\n",
  "\n",
  "%\n",
  "% Intercept font creation so as to record the font inside less save/restore's\n",
  "% NOTE: disabled, because it actually slows things down\n",
  "%\n",
  "\n",
  "% /definefont { definefont //reportFontCreation exec } bind redef\n",
  "\n",
  "% /makefont { makefont //reportFontCreation exec } bind redef\n",
  "\n",
  "% /scalefont { scalefont //reportFontCreation exec } bind redef\n",
  "\n",
  "\n",
  "%\n",
  "% Clean-up\n",
  "%\n",
  "\n",
  "end				% close nested userdict begin\n",
  "end				% close private dictionary\n",
  "\n",
  "% Bind the operators we just defined, and all the others if we didn't\n",
  "% do it before.  Also reenable 'bind' for future files.\n",
  "\n",
  ".bindoperators\n",
  "NOBIND currentdict systemdict ne and\n",
  " { systemdict begin .bindoperators end }\n",
  "if\n",
  "\n",
  "systemdict readonly pop\n",
  "% Restore the current local/global VM mode.\n",
  "% exec\n",
  "\n",
  "\n",
  "%\n",
  "% Testing\n",
  "%\n",
  "\n",
  "false {\n",
  "  100 dict begin\n",
  "  (Times 12, two strings; second one sloping up with ashow:)=\n",
  "  /Times-Roman findfont 12 scalefont dup /t12 exch def setfont\n",
  "  72 300 moveto (Hello world) show\n",
  "  72 280 moveto 10 1 (Hello world once more) ashow\n",
  "  (Times 10 two strings:)=\n",
  "  /Times-Roman findfont 10 scalefont setfont\n",
  "  72 260 moveto (Third) show\n",
  "  72 240 moveto (Fourth) show\n",
  "  (Symbol 12, one string:)=\n",
  "  /Symbol findfont 12 scalefont setfont\n",
  "  72 220 moveto (symbol string) show\n",
  "  (Helvetica 12, two strings:)=\n",
  "  /Helvetica findfont 12 scalefont setfont\n",
  "  72 200 moveto (Fifth) show\n",
  "  72 180 moveto (Sixth) show\n",
  "  (Times 12 again, two strings; second one with kshow:)=\n",
  "  t12 setfont\n",
  "  72 160 moveto (Seventh) show\n",
  "  end\n",
  "  72 140 moveto\n",
  "  gsave\n",
  "    /dx 1.0 def\n",
  "    { pop pop\n",
  "      dx 1 add /dx 1 index def\n",
  "      0 rmoveto } (Accelerated letter spacing) kshow\n",
  "    grestore\n",
  "  (Times 12 scaled by 2:)=\n",
  "  72 100 moveto\n",
  "  gsave\n",
  "    2 2 scale\n",
  "    (Ninth) show\n",
  "    grestore\n",
  "  count 0 ne { (Left on stack:)= pstack } if\n",
  "  flush\n",
  "  } if\n",
  0
};
