home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2000-09-28 | 17.5 KB | 708 lines | [ TEXT/MPS ]
% % File: SupportProcs.ps % % Contains: This file contains the basic support procedure set for the Skia-PostScript % Imaging Engine. % % Version: Technology: Quickdraw GX 1.1.x. % % Copyright: © 1991-7 by Apple Computer, Inc., all rights reserved. % % % File contains the following procedures: % FullPath % BoxWidths % PointsAvailable % AvoidLimit % SF (selectfont) % SFy (scalefont, scale in y direction only by negative specified size.) % RP (rectpath) % RF (rectfill) % RStr (rectstroke) % RCl (rectclip) % Bdef (bind def) % Xdef (exch def) % Xstore (exch store) % ExecLimChk (Execute the limit check error from errordict) % CopyDict % CharPath (a re-entrant version of charpath) % AtanRot % % Max, Min Max and Min functions. % PtNx for filling arrays. %<FF> % % Define and set a current font if "currentfont setfont" is not valid % On most versions of PostScript it is valid, but on 23.0 and some clones % it is not. % the function QD2Grestore does a "currentfont grestore setfont" like thing % and the following is needed to ensure it doesn't blow up on those printers. % currentfont /setfont load stopped not dup % See if currentfont setfont doesn't work /dontDefineDummyFont exch def {save} {pop} ifelse % If it did, do a save so we don't waste memory. % If it didn't pop off the null that currentfont pushed. 10 dict dup begin /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [0 0 0 0] def /Encoding StandardEncoding def /BuildChar {} def /FontName /dummyFont def end /dummyFont exch definefont setfont % Make it the current font. dontDefineDummyFont {restore} if % Do the restore to deallocate the definition if we didn't need it. %<FF> % Some basic constant definitions. /maxfloat 32768.0 def % Since all things are in fixed point, this is the "biggest" /minfloat maxfloat neg def /T true def /F false def % Define some "Registers in the Imaging Engine Dictionary. % This ensures that some definition of them exists so the "store" operator % won't try to create an entry in the top-most dictionary (like a style dict) % which may not have any available entries. % /@1 0 def /@2 0 def /@3 0 def /@4 0 def /@5 0 def /@6 0 def /@7 0 def /@8 0 def /aChar 1 string def % We need a character every now and then. /ScratchMatrix [0 0 0 0 0 0] def % We need a matrix every now and then too. /CurrCTM matrix currentmatrix def % Place to hold ctm when needed. % % The Bdef procedure: % /Bdef {bind def} bind def % % The Xdef procedure: /Xdef {exch def} Bdef % % The Xstore procedure: /Xstore {exch store} Bdef % % key Inc - % Increment the value pointed at by key. % /Inc {dup load 1 add store} Bdef % % key Dec - % Decrement the value pointed at by key. % /Dec {dup load 1 sub store} Bdef % % the ExecLimChk procedure: % key ExecLimChk - % % key: The key that the limitcheck happened on. /ExecLimChk { errordict /limitcheck get exec } Bdef %<FF> % Procedure: GXCharPath % This is the same as the charpath operator, only it keeps a count so it is reentrant. % Additionally, it makes sure that userdict is on top of the dictionary stack in case the % TrueType patch has redefined charpath to set the stupid flag. % /CharPathCount 0 def /GXCharPath { /CharPathCount Inc userdict begin % Look in userdict first and… /charpath load exec % Get the charpath operator from whereever the hell it is defined. end /CharPathCount Dec } Bdef %<FF> % Procedure CopyDict: % Copies the values from one dictionary into another dictionary. % The dictionaries must have the same keys (such as an AugGstate or a style) % % dict2 dict1 CopyDict (From dict1 into dict2) Weird, but saves an exch % % dict2: Dictionary to copy into % dict1: Dictionary to copy from /CopyDict { { 2 index % Get dict2 3 1 roll % Stack is now dict2 dict2 key value put } forall pop % Pop dict2 off the stack. } Bdef %<FF> % % Procedure takes a rectangle and finds the height and width % % x1 y1 x2 y2 BoxWidhs (x2-x1) (y2-y1) % /BoxWidths { % Stack is: exch % x1 y1 y2 x2 4 -1 roll % y1 y2 x2 x1 sub % y1 y2 (x2-x1) 3 1 roll % (x2-x1) y1 y2 exch sub % (x2-x1) (y2-y1) } Bdef % % The FullPath Proc: % this procedure adds to the current path a contour that is essentially wide open. % /FullPath { minfloat minfloat moveto maxfloat minfloat lineto maxfloat maxfloat lineto minfloat maxfloat lineto closepath } Bdef % % The EmptyPath Proc: % This procedure adds an empty path % /EmptyPath { 0 0 moveto % Clipping to this will clip everything out, drawing it will draw nothing. } Bdef % % The TightFullPath Proc: % This procedure adds a rectangular contour to the current path that is the bounding % box of the current clip This is only used by PatternFill for inverse filling to % avoid trying to stamp the pattern shape out in infinite land. % /TightFullPath { gsave % do this because We're going to use clippath which implicitly does newpath. clippath % Get the bounding box of the current clipping path. pathbbox grestore 4 copy % Stack is now: x1 y1 x2 y2 x1 y1 x2 y2 BoxWidths % : x1 y1 x2 y2 (x2-x1) (y2-y1) 4 2 roll % : x1 y1 (x2-x1) (y2-y1) x2 y2 pop pop % : x1 y1 W H RP % Make a rectangular path out of this. } Bdef %<FF> % The PointsAvailable proc: % % Count the number of points available % The Number of points available is left on the stack and the graphics % State is restored. % /PointsAvailable { gsave newpath 0.0 0.0 /moveto load stopped not % Try to Start a new contour. { % If we could start one, try to build it. 1 % Put initial count on stack. { 1.0 1.0 /lineto load stopped % Try to add another point to it. {pop pop exit} % If we failed, pop the point and exit. {1 add } ifelse % else increment the count on the stack. } loop } {pop pop 0} % Else zero points. ifelse grestore } Bdef %<FF> % % Procedure AvoidLimit: % Executes the specified function trying to avoid the limitcheck error. % It also ensures that the number of points available for use is greater than or equal to % the requested amount. This is accomplished by increasing the curve error (setflat) until % These conditions are met. If the conditions cannot be ment, then the limitcheck error procedure % In errordict will be executed, thus causing the same result if the specified operator were % simply done and the limitcheck had happened. % % operatorKey minPoints AvoidLimit - % % operatorKey: The key specifying which function (eg: flattenpath, eoclip, etc…) % minPoints: The minimum number of points that should be left available. % /AvoidLimit { /@1 exch store % Get the number of points we need to leave available /@2 exch store % Save the operator key to execute. currentflat dup /@3 exch store % Save the current curve error, Leave copy on stack. { gsave @2 load stopped not % Try to execute the operator. { % If successful then @1 0 gt { % make sure we have enough points. PointsAvailable @1 ge {exit} if % If there were enough points, exit. } {exit} ifelse % Also exit, if we didn't need any points. } if % The rest of the loop only gets executed if the tests failed. grestore % Restore the graphics state before we try again. /@3 @3 2 mul dup setflat store % Increase the error for next try. @3 1000 gt {exit} if % Don't try flatness bigger than 1000. %(Trying again with flatness of: ) print @3 == % Debugging print-out. } loop @3 1000 lt { % If we succeeded in finding a curve error that works: grestore % Restore the gsave done at beginning of the loop. @3 setflat % Set the error to the necessary value @2 load exec % Do the operator } { % Else Execute the limitcheck error on the operator. pop % Pop off the saved value of currentflat, @2 ExecLimChk % do the error, this will cause the proc to terminate. } ifelse setflat % Restore the curve error to value saved on stack. } Bdef %<FF> % % Procedure SF: short for selctfont This already exists in level-2, If we are on a level-1 printer, % Define it. See red-book two for definition. % Procedure also saves a copy of the font modification matrix in the augmented graphics state. % languagelevel 2 lt { /SF { exch findfont % Find the font based on the name, exch dup type /arraytype eq { % If the second parameter was a matrix dup % Save a copy of the matrix AugGstate /FontMapping get % in the augmented graphics state. copy pop makefont % Apply the matrix to the font. } { % Else dup % Make a matrix for the augmented graphics state 0 0 2 index 0 0 % Stack is now: scale 0 0 scale 0 0 AugGstate /FontMapping get astore pop scalefont % Then apply it with scalefont } ifelse setfont % Make it the current font. } Bdef } { %%%%% Level-2 definition: /SF { dup type /arraytype eq { % If the second parameter was a matrix dup % Save a copy of the matrix AugGstate /FontMapping get % in the augmented graphics state. copy pop } { % Else dup % Make a matrix for the augmented graphics state 0 0 2 index 0 0 % Stack is now: scale 0 0 scale 0 0 AugGstate /FontMapping get astore pop } ifelse selectfont % Issue level-2 selectfont } Bdef } ifelse % % Procedure SFy: Does the same as SF does, only the scale is negated and then applied to % only the Y axis. We need this because PostScript's y axis is reversed from Skia's % % font-key scale SFy dict % or % font-dict scale SFy dict (If you already have a dictionary instead of just the name) % % /SFy { 0 0 2 index neg 0 0 % Stack is now: font-key(or dict) scale 0 0 ScratchMatrix astore % Stack is now: font-key(or dict) [scale 0 0 -scale 0 0] 1 index type /dicttype eq { % If the first parameter was a dictionary then makefont setfont % just do makefont and set it. } { % else SF % Select the font by key. } ifelse } Bdef % % Procedure SFt: calls SF (selectfont) but constructs the matrix based on the tangent/size params. % % font-dict a b c d SFy dict (If you already have a dictionary instead of just the name) % % Where: % % | a b | | Sx 0 | | Tx Ty | % | | = | | * | | % | c d | | 0 Sy | | -Ty Tx | % % Sx, Sy = scale for font. (Sy always is Sx or -Sx) % and % Tx Ty is the tangent vector from the glyph shape. % /SFt { 0 0 % Stack is now: a b c d 0 0 ScratchMatrix astore % Stack is now: [a b c d 0 0] makefont setfont % Do a selectfont } Bdef %<FF> % % Procedure RP: Create a path for the specified rectangle. % x y w h RP - % % x y: lower left corner of the rectangle. (LL in context of normal PS coordinate direction) % w h: The width and height of the rectangle. % /RP { 4 2 roll % switch order or parameters so we have width height x y moveto % Move to the lower left of the rectangle. exch dup 0 rlineto % Line to x+w, y stack is: h w exch 0 exch rlineto % Line to x+w, y+h stack is: w neg 0 rlineto % Line to x, y+h stack is: closepath % Close the contour. } Bdef %<FF> % Procedure Pnt: % Makes a path for a Skia point shape. % PostScript is reluctant to draw paths of length zero, so we will guarentee % A length of 1 device-pixel. % % x y Pnt - % % x y: The point for the line. % /Pnt { moveto % Move to the point on the stack 1 0 idtransform % Get a distance of 1 device pixel horizontally. rlineto % and go there. } Bdef %<FF> % Define rectangle operators for level-1. They already exist in level-2, abbreviate them. % They will act the same way, except implementation of numarray and numstring % will not be here. The definitions are abbreviated becuase they will be found %` in the script of the document, keeps script size down. % languagelevel 2 lt { /RF { gsave newpath RP fill grestore } Bdef /RStr { gsave newpath RP stroke grestore } Bdef /RCl { newpath RP clip newpath } Bdef } { % Level 2 abbreviations instead. /RF /rectfill load def /RStr /rectstroke load def /RCl /rectclip load def } ifelse %<FF> % Rotate the CTM by the arc-tangent of the specified dy dx. % A faster substitute (40% faster) for {atan rotate} % % dy dx AtanRot - % /ATanRot { 2 copy % Calculate the length of the vector dup mul exch dup mul add sqrt % Stack is now dy dx dist dup 3 1 roll % dy dist dx dist div % dy dist dx' 3 1 roll div % dx' dy' dup % dx' dy' dy' neg % dx' dy' -dy' 2 index % dx' dy' -dy' dx' 0. 0. ScratchMatrix astore concat } Bdef %<FF> % % MakeShapeDict: % Make a shape dictionary. % % geomProc fillKey x1 y1 x2 y2 shapeType MakeShapeDict dict % or % colorSet/colorSpace bitStrings bitsPerPixel geomProc fillKey x1 y1 x2 y2 shapeType MakeShapeDict % %optional paramters % % colorSet/colorSpace: null or GX color set dictionary (required only for bitmaps, type b or i) or GX Color Space dictionary (for level-2 bitmaps, type i) % bitStrings: Array of strings containing bitmap data (also required only for bitmaps) % bitsPerPixel: Bits per pixel (required only for bitmaps) %required parameters % geomProc: procedure to execute for shape's geometry % fillKey: fill key for shape's fill. % x1 y1 x2 y2: Boudning box of shape. % shapeType: /g: for geometric shape (polygon, path, rectangle, curve, line, point) % /t: for text shape type (text, glyph, layout) % /b: for 1 bit bitmap. % /i: for image ( > 1 bit bitmap). % returned on stack % dict: A valid shape dictionary is created and left on stack. % % % A note about shape dictionaries: Execution of the geomProc may require % the shape dictionary to be on the dictionary stack. It is safest to % make sure this is so before executing a geometry procedure % /MakeShapeDict { dup dup /i eq exch /b eq or { % For bitmap shapes there are three extra parameters 12 dict begin % Make a dictionary and put it on dict stack } { 9 dict begin % Make a dictionary and put it on dict stack } ifelse /shapeType Xdef /y2 Xdef /x2 Xdef /y1 Xdef /x1 Xdef /fillKey Xdef /geomProc Xdef % If the shape is a bitmap, then the stack has: % colorSet/colorSpace bitStrings bitsPerPixel, put them in the dictionary as well. shapeType dup /b eq exch /i eq or { /BitsPerPixel Xdef /BitmapStrings Xdef /colorSet null def % Initialize set and space to be null /ColorSpace null def dup null ne { % if the space/set parameter isn't null dup /CSA known { % and it has a CSA field inside then /ColorSpace Xdef % it is a GX color space dictionary } { % else /colorSet Xdef % it must be a GX color set dictionary. }ifelse % } { % else pop % pop off the null, leave set and space defined to be null } ifelse /HaveDrawnIt false def % Initialize this shape dictionary as not having been drawn yet. % The portable PostScript RGB bitmap procedure needs to know this. } { % else For non bitmap shapes, just put a null ColorSpace and colorSet /ColorSpace null def /colorSet null def } ifelse currentdict end % Leave the shape dictionary on the stack. } Bdef %<FF> % % ShapeBBox: % Get the bounding box of a shape. % % shape ShapeBBox x1 y1 x2 y2 % % shape: A valid shape dictionary. % x1 y1 x2 y2: The bounding box is left as 4 values on stack. % /ShapeBBox { dup /x1 get exch dup /y1 get exch dup /x2 get exch /y2 get } Bdef %<FF> % % Max and min functions, take two numbers and find the max or min of them. % % /Max { 2 copy gt {pop} {exch pop} ifelse } Bdef % % Max and min functions, take two numbers and find the max or min of them. % % /Min { 2 copy lt {pop} {exch pop} ifelse } Bdef %<FF> % % Grid fit a point % % x y Grid x' y' % % x y: point to grid fit. % x' y': grid fittend point in user space. /Grid { transform % Transform point to device space. round exch round exch % Pin it to a pixel. itransform % Transform pinned values back. } Bdef %<FF> % % PtNx: % % array index value PtNx array index+1 % % puts value into array at index and increments the index on the stack. % % /PtNx { 3 copy put % Put the value into the array at index. pop % Get rid of copy of value 1 add % Increment the index. } Bdef %<FF> % % NotEqual: % % Check if two numbers are not equal, discounting PostScript rounding error. % /NotEqual { sub abs 0.001 ge % This should be within the precision of PostScript. % 1/1000 point in normal user space, (1/72000 inch) } Bdef %<FF> % % Define GX versions of setrgbcolor and colorimage. These will be overridden if the PortableColorProcs.ps % is downloaded after this file. PortableColorProcs must be downloaded after this file!! % /GXSetRGBColor /setrgbcolor load def /colorimage where {pop /GXColorImage /colorimage load def} if