summaryrefslogtreecommitdiffstats
path: root/src/kernel/qpsprinter.ps
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/qpsprinter.ps')
-rw-r--r--src/kernel/qpsprinter.ps805
1 files changed, 805 insertions, 0 deletions
diff --git a/src/kernel/qpsprinter.ps b/src/kernel/qpsprinter.ps
new file mode 100644
index 000000000..4fbd98546
--- /dev/null
+++ b/src/kernel/qpsprinter.ps
@@ -0,0 +1,805 @@
+% 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.
+
+/d /def load def
+/D {bind d} bind d
+/d2 {dup dup} D
+/B {0 d2} D
+/W {255 d2} D
+/ED {exch d} D
+/D0 {0 ED} D
+/LT {lineto} D
+/MT {moveto} D
+/S {stroke} D
+/F {setfont} D
+/SW {setlinewidth} D
+/CP {closepath} D
+/RL {rlineto} D
+/NP {newpath} D
+/CM {currentmatrix} D
+/SM {setmatrix} D
+/TR {translate} D
+/SD {setdash} D
+/SC {aload pop setrgbcolor} D
+/CR {currentfile read pop} D
+/i {index} D
+/bs {bitshift} D
+/scs {setcolorspace} D
+/DB {dict dup begin} D
+/DE {end d} D
+/ie {ifelse} D
+/sp {astore pop} D
+
+% ENDUNCOMPRESSED: Warning: leave this line in.
+% Everything before this line will be left untouched by the compression
+
+
+
+/BSt 0 d % brush style
+/LWi 1 d % line width
+/PSt 1 d % pen style
+/Cx 0 d % current x position
+/Cy 0 d % current y position
+/WFi false d % winding fill
+/OMo false d % opaque mode (not transparent)
+
+/BCol [ 1 1 1 ] d % brush color
+/PCol [ 0 0 0 ] d % pen color
+/BkCol [ 1 1 1 ] d % background color
+/BDArr [ % Brush dense patterns
+ 0.94
+ 0.88
+ 0.63
+ 0.50
+ 0.37
+ 0.12
+ 0.06
+] d
+/defM matrix d
+
+/nS 0 d % number of saved painter states
+
+% LArr for the Pen styles is defined in emitHeader because of scaling
+
+% GPS: GetPenStyle
+% Returns the line pattern (from pen style PSt).
+%
+% bool GPS pattern
+% true : returns draw pattern
+% false: returns fill pattern
+/GPS {
+ PSt 1 ge PSt 5 le and % valid pen pattern?
+ {
+ { LArr PSt 1 sub 2 mul get } % draw pattern
+ { LArr PSt 2 mul 1 sub get } ifelse % opaque pattern
+ }
+ { [] } ifelse % out of range => solid line
+} D
+
+% QS: QtStroke
+% draw and fill current path
+%
+% - QS -
+/QS { % stroke command
+ PSt 0 ne % != NO_PEN
+ {
+ gsave
+ LWi SW % set line width
+ true GPS 0 setdash S % draw line pattern
+ OMo PSt 1 ne and % opaque mode and not solid line?
+ {
+ BkCol SC
+ false GPS dup 0 get setdash S % fill in opaque pattern
+ } if
+ grestore
+ } if
+} D
+
+
+
+
+%% The following operations are used to read compressed data from the file
+%% Until now this is only used for image compression
+
+% read 28 bits and leave them on tos
+%
+% - r28 num
+/r28 {
+ % skip past whitespace and read one character
+ { currentfile read pop
+ dup 32 gt { exit } if
+ pop
+ } loop
+ % read three more
+ 3 {
+ currentfile read pop
+ } repeat
+ % make an accumulator
+ 0
+ % for each character, shift the accumulator and add in the character
+ 4 {
+ 7 bitshift exch
+ dup 128 gt { 84 sub } if 42 sub 127 and
+ add
+ } repeat
+} D
+
+/rA 0 d % accumulator
+/rL 0 d % bits left
+
+% takes number of bits, leaves number
+%
+% num rB num
+/rB {
+ rL 0 eq {
+ % if we have nothing, let's get something
+ /rA r28 d
+ /rL 28 d
+ } if
+ dup rL gt {
+ % if we don't have enough, take what we have and get more
+ rA exch rL sub rL exch
+ /rA 0 d /rL 0 d
+ rB exch bitshift add
+ } {
+ % else take some of what we have
+ dup rA 16#fffffff 3 -1 roll bitshift not and exch
+ % ... and update rL and rA
+ dup rL exch sub /rL ED
+ neg rA exch bitshift /rA ED
+ } ifelse
+} D
+
+% uncompresses image data from currentfile until the string on the
+% stack is full; leaves the string there.
+% assumes that nothing could conceivably go wrong, ie. the compressed data has
+% to be in the correct format and the length of the string has to be exactly right
+% to hold the compressed data
+%
+% string uc string
+%
+%%% Warning: if you change the method here, change the table in qpsprinter.cpp:compress()!
+/uc {
+ /rL 0 d
+ 0
+ { % string pos
+ dup 2 index length ge { exit } if
+ 1 rB
+ 1 eq { % compressed
+ 3 rB % string pos bits
+ dup 3 ge {
+ 1 add dup rB % string pos bits extra
+ 1 index 5 ge {
+ 1 index 6 ge {
+ 1 index 7 ge {
+ 1 index 8 ge {
+ 128 add
+ } if
+ 64 add
+ } if
+ 32 add
+ } if
+ 16 add
+ } if
+ 3 add
+ exch pop
+ } if
+ 3 add
+ % string pos length
+ exch 10 rB 1 add
+ % string length pos dist
+ {
+ dup 3 index lt {
+ dup
+ } {
+ 2 index
+ } ifelse % string length pos dist length-this-time
+ 4 index 3 index 3 index sub 2 index getinterval
+ 5 index 4 index 3 -1 roll putinterval
+ dup 4 -1 roll add 3 1 roll
+ 4 -1 roll exch sub
+ dup 0 eq { exit } if
+ 3 1 roll
+ } loop % string pos dist length
+ pop pop
+ } { % uncompressed
+ 3 rB 1 add
+ {
+ 2 copy 8 rB put 1 add
+ } repeat
+ } ifelse
+ } loop
+ pop
+} D
+
+%% image drawing routines
+
+/sl D0 % ### is this needed ?
+
+% 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 ED
+ /QCIgray QCIcolor length 3 idiv string d
+ 0 1 QCIcolor length 3 idiv 1 sub
+ { /QCIindex ED
+ /x QCIindex 3 mul d
+ 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
+} D
+
+% 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
+ false eq { % no mask, draw solid background
+ pop
+ true 3 1 roll % width height false matrix image
+ 4 index
+ 4 index
+ false
+ 4 index
+ 4 index
+ imagemask
+ BkCol SC
+ imagemask
+ } {
+ pop
+ false 3 1 roll % width height false matrix image
+ imagemask
+ } ifelse
+ } {
+ dup false ne {
+ % have a mask, see if we can use it
+ /languagelevel where {
+ pop
+ languagelevel 3 ge
+ } { false } ifelse
+ } {
+ false
+ } ifelse
+
+ {
+ % languagelevel3, we can use image mask and dicts
+
+ % store the image mask
+ /ma exch d
+ % select colorspace according to 8|24 bit depth and set the decode array /dc
+ 8 eq {
+ /dc [0 1] d
+ /DeviceGray
+ } {
+ /dc [0 1 0 1 0 1] d
+ /DeviceRGB
+ } ifelse
+ setcolorspace
+ % the image data
+ /im exch d
+ % transformation matrix
+ /mt exch d
+ % width and height
+ /h exch def
+ /w exch def
+ % the image dict
+ /id
+ 7 dict dup begin
+ /ImageType 1 d
+ /Width w d
+ /Height h d
+ /ImageMatrix mt d
+ /DataSource im d
+ /BitsPerComponent 8 d
+ /Decode dc d
+ end d
+ % the mask dictionary
+ /md
+ 7 dict dup begin
+ /ImageType 1 d
+ /Width w d
+ /Height h d
+ /ImageMatrix mt d
+ /DataSource ma d
+ /BitsPerComponent 1 d
+ /Decode [0 1] d
+ end d
+ % and the combined image dict
+ 4 dict dup begin
+ /ImageType 3 d
+ /DataDict id d
+ /MaskDict md d
+ /InterleaveType 3 d
+ end
+ 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
+} d
+
+
+
+
+/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 ED
+ % 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
+ defM SM
+ 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 ED
+ sub /w ED
+ OMo {
+ NP
+ 0 0 MT
+ 0 h RL
+ w 0 RL
+ 0 h neg RL
+ CP
+ BkCol SC
+ fill
+ } if
+ BCol SC
+ 0.3 SW
+ NP
+ BSt 9 eq BSt 11 eq or % horiz or cross pattern
+ { 0 4 h
+ { dup 0 exch MT w exch LT } for
+ } if
+ BSt 10 eq BSt 11 eq or % vert or cross pattern
+ { 0 4 w
+ { dup 0 MT h LT } for
+ } if
+ BSt 12 eq BSt 14 eq or % F-diag or diag cross
+ { w h gt
+ { 0 6 w h add
+ { dup 0 MT h sub h LT } for
+ } { 0 6 w h add
+ { dup 0 exch MT w sub w exch LT } 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 MT h sub 0 LT } for
+ } { 0 6 w h add
+ { dup w exch MT w sub 0 exch LT } for
+ } ifelse
+ } if
+ S
+ } if
+ BSt 24 eq % CustomPattern
+
+ {
+ } if
+ grestore
+} D
+
+% for arc
+/mat matrix d
+/ang1 D0 /ang2 D0
+/w D0 /h D0
+/x D0 /y D0
+
+/ARC { % Generic ARC function [ X Y W H ang1 ang2 ]
+ /ang2 ED /ang1 ED /h ED /w ED /y ED /x ED
+ mat CM pop
+ x w 2 div add y h 2 div add TR
+ 1 h w div neg scale
+ ang2 0 ge
+ {0 0 w 2 div ang1 ang1 ang2 add arc }
+ {0 0 w 2 div ang1 ang1 ang2 add arcn} ifelse
+ mat SM
+} D
+
+/C D0
+
+/P { % PdcDrawPoint [x y]
+ NP
+ MT
+ 0.5 0.5 rmoveto
+ 0 -1 RL
+ -1 0 RL
+ 0 1 RL
+ CP
+ fill
+} D
+
+/M { % PdcMoveTo [x y]
+ /Cy ED /Cx ED
+} D
+
+/L { % PdcLineTo [x y]
+ NP
+ Cx Cy MT
+ /Cy ED /Cx ED
+ Cx Cy LT
+ QS
+} D
+
+/DL { % PdcDrawLine [x1 y1 x0 y0]
+ NP
+ MT
+ LT
+ QS
+} D
+
+/HL { % PdcDrawLine [x1 y x0]
+ 1 index DL
+} D
+
+/VL { % PdcDrawLine [x y1 y0]
+ 2 index exch DL
+} D
+
+/R { % PdcDrawRect [x y w h]
+ /h ED /w ED /y ED /x ED
+ NP
+ x y MT
+ 0 h RL
+ w 0 RL
+ 0 h neg RL
+ CP
+ BF
+ QS
+} D
+
+/ACR { % add clip rect
+ /h ED /w ED /y ED /x ED
+ x y MT
+ 0 h RL
+ w 0 RL
+ 0 h neg RL
+ CP
+} D
+
+/xr D0 /yr D0
+/rx D0 /ry D0 /rx2 D0 /ry2 D0
+
+/RR { % PdcDrawRoundRect [x y w h xr yr]
+ /yr ED /xr ED /h ED /w ED /y ED /x ED
+ xr 0 le yr 0 le or
+ {x y w h R} % Do rect if one of rounding values is less than 0.
+ {xr 100 ge yr 100 ge or
+ {x y w h E} % Do ellipse if both rounding values are larger than 100
+ {
+ /rx xr w mul 200 div d
+ /ry yr h mul 200 div d
+ /rx2 rx 2 mul d
+ /ry2 ry 2 mul d
+ NP
+ x rx add y MT
+ x y rx2 ry2 180 -90
+ x y h add ry2 sub rx2 ry2 270 -90
+ x w add rx2 sub y h add ry2 sub rx2 ry2 0 -90
+ x w add rx2 sub y rx2 ry2 90 -90
+ ARC ARC ARC ARC
+ CP
+ BF
+ QS
+ } ifelse
+ } ifelse
+} D
+
+/E { % PdcDrawEllipse [x y w h]
+ /h ED /w ED /y ED /x ED
+ mat CM pop
+ x w 2 div add y h 2 div add translate
+ 1 h w div scale
+ NP
+ 0 0 w 2 div 0 360 arc
+ mat SM
+ BF
+ QS
+} D
+
+/A { % PdcDrawArc [x y w h ang1 ang2]
+ 16 div exch 16 div exch
+ NP
+ ARC
+ QS
+} D
+
+/PIE { % PdcDrawPie [x y w h ang1 ang2]
+ /ang2 ED /ang1 ED /h ED /w ED /y ED /x ED
+ NP
+ x w 2 div add y h 2 div add MT
+ x y w h ang1 16 div ang2 16 div ARC
+ CP
+ BF
+ QS
+} D
+
+/CH { % PdcDrawChord [x y w h ang1 ang2]
+ 16 div exch 16 div exch
+ NP
+ ARC
+ CP
+ BF
+ QS
+} D
+
+/BZ { % PdcDrawCubicBezier [4 points]
+ curveto
+ QS
+} D
+
+/CRGB { % Compute RGB [R G B] => R/255 G/255 B/255
+ 255 div 3 1 roll
+ 255 div 3 1 roll
+ 255 div 3 1 roll
+} D
+
+
+/BC { % PdcSetBkColor [R G B]
+ CRGB
+ BkCol astore pop
+} D
+
+/BR { % PdcSetBrush [style R G B]
+ CRGB
+ BCol astore pop
+ /BSt ED
+} D
+
+/WB { % set white solid brush
+ 1 W BR
+} D
+
+/NB { % set nobrush
+ 0 B BR
+} D
+
+/PE { % PdcSetPen [style width R G B Cap Join]
+ setlinejoin setlinecap
+ CRGB
+ PCol astore pop
+ /LWi ED
+ /PSt ED
+ LWi 0 eq { 0.25 /LWi ED } if % ### 3.0 remove this line
+ PCol SC
+} D
+
+/P1 { % PdcSetPen [R G B]
+ 1 0 5 2 roll 0 0 PE
+} D
+
+/ST { % SET TRANSFORM [matrix]
+ defM setmatrix
+ concat
+} D
+
+%% Font handling
+
+% the next three commands are for defining fonts. The first one
+% tries to find the most suitable printer font out of a fontlist.
+% if encoding is false the default one will be used.
+/MF { % newname encoding fontlist
+ % this function tries to find a suitable postscript font.
+ % We try tquite hard not to get courier for a
+ % proportional font. The following takes an array of fonts.
+ % The algorithm will take the first font that
+ % gives a match (defined as not resulting in a courier font).
+ % each entry in the table is an array of the form [ /Fontname x-stretch slant ]
+ % x-strtch can be used to stretch/squeeze the font in x direction.
+ % This gives better results when eg substituting helvetica for arial
+ % slant is an optional slant. 0 is non slanted, 0.2 is a typical value for a syntetic oblique.
+ % encoding can be either an encoding vector of false if the default font encoding is requested.
+ true exch true exch % push a dummy on the stack,
+ { % so the loop over the array will leave a font in any case when exiting.
+ exch pop exch pop % (dummy | oldfont) (dummy | fontdict) fontarray
+ dup 0 get dup findfont % get the fontname from the array and load it
+ dup /FontName get % see if the font exists
+ 3 -1 roll eq { % see if fontname and the one provided are equal
+ exit
+ } if
+ } forall
+ exch % font fontarray
+
+ % newname encoding font fontarray defines a postscript font
+ dup
+ 1 get /fxscale exch def % define scale, sland and encoding
+ 2 get /fslant exch def
+ exch /fencoding exch def
+ [ fxscale 0 fslant 1 0 0 ] makefont % transform font accordingly
+ fencoding false eq { % check if we have an encoding and use it if available
+ } {
+ dup maxlength dict begin % copy font
+ {
+ 1 index /FID ne % don't copy FID, as it's not allowed in PS Level 1
+ {def}{pop pop}ifelse
+ } forall
+ /Encoding fencoding def % replace encoding
+ currentdict
+ end
+ } ifelse
+ definefont pop
+} D
+
+% an embedded font. This is used for the base fonts of the composite font used later on.
+/MFEmb { % newname encoding fontname
+ findfont dup length dict
+ begin
+ {
+ 1 index /FID ne
+ {d}{pop pop}ifelse
+ } forall
+ /Encoding ED currentdict
+ end
+ definefont pop
+} D
+
+% DF: define font
+% used to get a scaled version of an already loaded font
+%
+% newname pointsize fontmame DF -
+/DF {
+ findfont
+ % get the fontsize on top of the stack and define font matrix
+ /fs 3 -1 roll d [ fs 0 0 fs -1 mul 0 0 ]
+ makefont
+ d
+} D
+
+/ty 0 d
+/Y {
+ /ty ED
+} D
+
+/Tl { % draw underline/strikeout line: () w x y lw ->Tl-> () w x
+ gsave
+ setlinewidth
+ NP 1 index exch MT
+ 1 index 0 rlineto stroke
+ grestore
+} D
+
+/XYT { % [string [x/y displacement array] width x]
+ ty MT % pops x
+
+ /xyshow where { % interpreter has xyshow
+ pop pop
+ xyshow
+ } { % use ashow
+ exch pop % string cwidth
+ 1 index % string cwidth string
+ dup length 2 div exch % string cwidth length string !have to divide by 2 since we use unicode!
+ stringwidth pop % string cwidth length pwidth
+ 3 -1 roll % string length pwidth cwidth
+ exch sub exch div % string extraperchar
+ exch 0 exch % extraperchar 0 string
+ ashow
+ } ifelse
+} D
+
+/AT {
+ ty MT % pops x
+ 1 index % string cwidth string
+ dup length 2 div exch % string cwidth length string !have to divide by 2 since we use unicode!
+ stringwidth pop % string cwidth length pwidth
+ 3 -1 roll % string length pwidth cwidth
+ exch sub exch div % string extraperchar
+ exch 0 exch % extraperchar 0 string
+ ashow
+} D
+
+%% start of page
+/QI {
+ /C save d
+ pageinit
+ /Cx 0 d % reset current x position
+ /Cy 0 d % reset current y position
+ /OMo false d
+} D
+
+%% end of page
+/QP { % show page
+ C restore
+ showpage
+} D
+
+% merges one key value pair into the page device dict
+%
+% key value SPD -
+/SPD {
+ /setpagedevice where {
+ 1 dict dup begin 3 1 roll def end
+ setpagedevice
+ } { pop pop } ifelse
+} D
+
+/SV { % Save painter state
+ BSt LWi PSt Cx Cy WFi OMo BCol PCol BkCol
+ /nS nS 1 add d
+ gsave
+} D
+
+/RS { % Restore painter state
+ nS 0 gt
+ { grestore
+ /BkCol ED /PCol ED /BCol ED /OMo ED /WFi ED
+ /Cy ED /Cx ED /PSt ED /LWi ED /BSt ED
+ /nS nS 1 sub d
+ } if
+} D
+
+/CLSTART { % clipping start
+ /clipTmp matrix CM d % save current matrix
+ defM SM % Page default matrix
+ NP
+} D
+
+/CLEND { % clipping end
+ clip
+ NP
+ clipTmp SM % restore the current matrix
+} D
+
+/CLO { % clipping off
+ grestore % restore top of page state
+ gsave % save it back again
+ defM SM % set coordsys (defensive progr.)
+} D
+