diff options
Diffstat (limited to 'src/kernel/qpsprinter.ps')
-rw-r--r-- | src/kernel/qpsprinter.ps | 805 |
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 + |