src/gui/painting/qpsprinter.ps
author Alex Gilkes <alex.gilkes@nokia.com>
Mon, 11 Jan 2010 14:00:40 +0000
changeset 0 1918ee327afb
permissions -rw-r--r--
Revision: 200952

% the postscript header we use for our qpsprinter in uncompressed and commented form.
% use the makepsheader perl script to generate a compressed version of this header
% you can then paste into qpsprinter.cpp
%
% some compression of the code is done by the makepsheader script, so we don't need to 
% write too criptically here. 

/BD  {bind def} bind def
/d2 {dup dup} BD
/ED {exch def} BD
/D0 {0 ED} BD

/F  {setfont} BD
/RL {rlineto} BD
/CM {currentmatrix} BD
/SM {setmatrix} BD
/TR {translate} BD
/SD {setdash} BD
/SC {aload pop setrgbcolor} BD
/CR {currentfile read pop} BD
/i  {index} BD
/scs {setcolorspace} BD
/DB {dict dup begin} BD
/DE {end def} BD
/ie {ifelse} BD
/gs {gsave} BD
/gr {grestore} BD

% these use PDF syntax
/w {setlinewidth} BD
/d {setdash} BD
/J {setlinecap} BD
/j {setlinejoin} BD
/scn {3 array astore /BCol exch def} BD
/SCN {3 array astore /PCol exch def} BD
/cm {6 array astore concat} BD

/m  {moveto} BD
/l  {lineto} BD
/c  {curveto} BD
/h  {closepath} BD

/W  {clip} BD
/W* {eoclip} BD
/n {newpath} BD
% ENDUNCOMPRESSED: Warning: leave this line in. 
% Everything before this line will be left untouched by the compression

/q  {gsave 10 dict begin} BD
/Q  {end grestore} BD

% PDF operators
/re { % PDF re operator
  4 2 roll  % w h x y
  moveto % w h
  dup % w h h
  0 exch rlineto % w h
  exch 0 rlineto % h
  0 exch neg rlineto
  closepath
} bind def

/S {
  gsave
    PCol SC stroke
  grestore
  newpath
} BD

% PDF text operators
/BT {gsave 10 dict begin /_m matrix currentmatrix def BCol SC} BD
/ET {end grestore} BD
/Tf {
  /_fs exch def
  findfont
  [ _fs 0 0 _fs 0 0 ]  
  makefont
  setfont
} BD
/Tm {6 array astore concat} BD
/Td {translate} BD
/Tj {0 0 moveto show} BD
/BDC {pop pop} BD
/EMC {} BD

% old operators

/BSt 0 def                             % brush style
/WFi false def                 % winding fill

/BCol  [ 1 1 1 ] def                   % brush color
/PCol  [ 0 0 0 ] def                   % pen color
/BDArr [                             % Brush dense patterns
  0.94
  0.88
  0.63
  0.50
  0.37 
  0.12 
  0.06 
] def

% -- level3 true/false
/level3 {
  /languagelevel where {
    pop
    languagelevel 3 ge 
  } { false } ifelse
} bind def


%% image drawing routines

% defines for QCI
/QCIgray D0 /QCIcolor D0 /QCIindex D0

% this method prints color images if colorimage is available, otherwise
% converts the string to a grayscale image and uses the reular postscript image
% operator for printing.
% Arguments are the same as for the image operator:
% 
%     width height bits/sample matrix datasrc QCI -
/QCI {
  /colorimage where {
    pop
    false 3 colorimage
  }{  % the hard way, based on PD code by John Walker <kelvin@autodesk.com>
    exec /QCIcolor exch def
    /QCIgray QCIcolor length 3 idiv string def
    0 1 QCIcolor length 3 idiv 1 sub
    { /QCIindex exch def
      /_x QCIindex 3 mul def
      QCIgray QCIindex
      QCIcolor _x       get 0.30 mul
      QCIcolor _x 1 add get 0.59 mul
      QCIcolor _x 2 add get 0.11 mul
      add add cvi
      put
    } for
    QCIgray image
  } ifelse
} bind def

% general image drawing routine, used from the postscript driver
%
% Draws images with and without mask with 1, 8 and 24(rgb) bits depth.
%
%     width height matrix image 1|8|24 mask|false x y di
%
% width and height specify the width/height of the image,
% matrix a transformation matrix, image a procedure holding the image data
% (same for mask) and x/y an additional translation.
%
% ### should move the translation into the matrix!!!
/di 
{
  gsave
    translate
    1 index 1 eq { % bitmap
      pop pop % get rid of mask and depth
      false 3 1 roll % width height false matrix image
      BCol SC
      imagemask
    } { 
      dup false ne { 
	% have a mask, see if we can use it
	level3
      } { 
	false 
      } ifelse

      {
	% languagelevel3, we can use image mask and dicts

	% store the image mask
	/_ma exch def
	% select colorspace according to 8|24 bit depth and set the decode array /dc
	8 eq {
	  /_dc [0 1] def
	  /DeviceGray
	} {
	  /_dc [0 1 0 1 0 1] def
	  /DeviceRGB
	} ifelse
	setcolorspace
	% the image data
	/_im exch def
	% transformation matrix
	/_mt exch def
	% width and height
	/_h exch def
	/_w exch def
	% and the combined image dict
	<<
	  /ImageType 3
	  % the image dict
	  /DataDict <<
              /ImageType 1
	      /Width _w
	      /Height _h
	      /ImageMatrix _mt
	      /DataSource _im
	      /BitsPerComponent 8
	      /Decode _dc
	  >> 
	  % the mask dictionary
	  /MaskDict <<
             /ImageType 1
	     /Width _w
	     /Height _h
	     /ImageMatrix _mt
	     /DataSource _ma
	     /BitsPerComponent 1
	     /Decode [0 1]
	  >> 
	  /InterleaveType 3
	>> 
	image
      } {
	pop % no mask or can't use it, get rid of it
	8 % width height image 8|24 8 matrix
	4 1 roll
	8 eq { % grayscale
	  image
	} { %color
	  QCI
	} ifelse
      } ifelse
    } ifelse
  grestore    
} bind def


/BF {                                % brush fill
  gsave
    BSt 1 eq                          % solid brush?
    {
      BCol SC
      WFi { fill } { eofill } ifelse
    } if
    BSt 2 ge BSt 8 le and             % dense pattern?
    {
      BDArr BSt 2 sub get /_sc exch def 
      % the following line scales the brush color according to the pattern. the higher the pattern the lighter the color.
      BCol 
      { 
	1. exch sub _sc mul 1. exch sub 
      } forall 
      3 array astore
      SC 
      WFi { fill } { eofill } ifelse
    } if
    BSt 9 ge BSt 14 le and            % brush pattern?
    {
      WFi { clip } { eoclip } ifelse
      pathbbox                        % left upper right lower
      3 index 3 index translate
      4 2 roll                        % right lower left upper
      3 2 roll                        % right left upper lower
      exch                            % left right lower upper
      sub /_h exch def
      sub /_w exch def
      BCol SC
      0.3 setlinewidth
      newpath
      BSt 9 eq BSt 11 eq or           % horiz or cross pattern
      { 0 4 _h
	{ dup 0 exch moveto _w exch lineto } for
      } if
      BSt 10 eq BSt 11 eq or          % vert or cross pattern
      { 0 4 _w
	{ dup 0 moveto _h lineto } for
      } if
      BSt 12 eq BSt 14 eq or          % F-diag or diag cross
      { _w _h gt
	{ 0 6 _w _h add
	  { dup 0 moveto _h sub _h lineto } for
	} { 0 6 _w _h add
	  { dup 0 exch moveto _w sub _w exch lineto } for
	} ifelse
      } if
      BSt 13 eq BSt 14 eq or          % B-diag or diag cross
      { _w _h gt
	{ 0 6 _w _h add
	  { dup _h moveto _h sub 0 lineto } for
	} { 0 6 _w _h add
	  { dup _w exch moveto _w sub 0 exch lineto } for
	} ifelse
      } if
      stroke
    } if
    BSt 15 eq
    {
    } if
    BSt 24 eq                         % TexturePattern
    {
    } if
  grestore
} bind def

% more PDF operators
/f { /WFi true def BF newpath } bind def
/f* { /WFi false def BF newpath } bind def
/B { /WFi true def BF S newpath } bind def
/B* { /WFi false def BF S newpath } bind def

%% start of page
/QI {
  /C save def
  pageinit
  q
  newpath
} bind def

%% end of page
/QP {
  Q                                % show page
  C restore
  showpage
} bind def

% merges one key value pair into the page device dict
%
%    key value SPD -
/SPD {
  /setpagedevice where {
    << 3 1 roll >>
    setpagedevice
  } { pop pop } ifelse
} bind def


% font handling

/T1AddMapping { % basefont [glyphname ...] T1AddMapping -
  10 dict begin
    /glyphs exch def
    /fnt exch def
    /current fnt /NumGlyphs get def
    /CMap fnt /CMap get def

    0 1 glyphs length 1 sub % 0 1 (num glyphs - 1)
    {
      glyphs exch get /gn exch def

      current dup                                 % glyph_index glyph_index
      256 mod /min exch def                       % glyph_index
      256 idiv /maj exch def                      % -
      CMap dup maj get dup                        % cmap cmap_maj cmap_maj
      null eq {
	pop 256 array 
	0 1 255 {1 index exch /.notdef put} for
      } if
      dup                                         % cmap cmap_maj cmap_maj
      min gn put                                  % cmap cmap_maj
      maj exch put                                % -

      /current current 1 add def
    } for

    fnt /CMap CMap put
    fnt /NumGlyphs current put
  end 
} def

/T1AddGlyphs { % basefont [glyphname charstring ...] T1AddGlyphs -
  10 dict begin
    /glyphs exch def
    /fnt exch def
    /current fnt /NumGlyphs get def
    /CMap fnt /CMap get def
    /CharStrings fnt /CharStrings get def

    0 1 glyphs length 2 idiv 1 sub % 0 1 (num glyphs - 1)
    {
      2 mul dup
      glyphs exch get /gn exch def
      1 add
      glyphs exch get /cs exch def

      current dup                                 % glyph_index glyph_index
      256 mod /min exch def                       % glyph_index
      256 idiv /maj exch def                      % -
      CMap dup maj get dup                        % cmap cmap_maj cmap_maj
      null eq {
	pop 256 array 
	0 1 255 {1 index exch /.notdef put} for
      } if
      dup                                         % cmap cmap_maj cmap_maj
      min gn put                                  % cmap cmap_maj
      maj exch put                                % -

      CharStrings gn cs put
      /current current 1 add def
    } for

    fnt /CharStrings CharStrings put
    fnt /CMap CMap put
    fnt /NumGlyphs current put
  end 
} def



/StringAdd { % string1 string2 stringadd result
  1 index length 1 index length add
  string
  3 1 roll
  2 index 0 3 index putinterval
  2 index 2 index length 2 index putinterval 
  pop pop
} def


/T1Setup { % fontname T1Setup -
10 dict begin
  dup /FontName exch def
  (-Base) StringAdd cvx cvn /Font exch def
  /MaxPage Font /NumGlyphs get 1 sub 256 idiv def

  /FDepVector MaxPage 1 add array def
  /Encoding MaxPage 1 add array def

  0 1 MaxPage {
    dup Encoding exch dup put
 

    dup /Page exch def
    FontName (-) StringAdd 
    exch 
    20 string cvs StringAdd % page fontname
    cvn

    Font 0 dict copy dup dup /CMap get 
    Page get 
    /Encoding exch put definefont 
    FDepVector exch Page exch put
  } for 

  FontName cvn <<
    /FontType 0
    /FMapType 2
    /FontMatrix[1 0 0 1 0 0]
    /Encoding Encoding
    /FDepVector FDepVector
    >> definefont pop
  end
} def