home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QuickDraw GX / GX->PostScript Sample / GXToPostScript / PostScriptFiles / SupportProcs.ps < prev    next >
Encoding:
Text File  |  2000-09-28  |  17.5 KB  |  708 lines  |  [TEXT/MPS ]

  1. %
  2. %    File:        SupportProcs.ps
  3. %
  4. %    Contains:    This file contains the basic support procedure set for the Skia-PostScript 
  5. %        Imaging Engine.
  6. %
  7. %    Version:    Technology:    Quickdraw GX 1.1.x.
  8. %
  9. %    Copyright:    © 1991-7 by Apple Computer, Inc., all rights reserved.
  10. %
  11. %
  12.  
  13. %        File contains the following procedures:
  14. %            FullPath
  15. %            BoxWidths
  16. %            PointsAvailable
  17. %            AvoidLimit
  18. %            SF                    (selectfont)
  19. %            SFy                    (scalefont, scale in y direction only by negative specified size.)
  20. %            RP                    (rectpath)
  21. %            RF                    (rectfill)
  22. %            RStr                 (rectstroke)
  23. %            RCl                 (rectclip)
  24. %            Bdef                (bind def)
  25. %            Xdef                (exch def)
  26. %            Xstore            (exch store)
  27. %            ExecLimChk    (Execute the limit check error from errordict)
  28. %            CopyDict
  29. %            CharPath            (a re-entrant version of charpath)
  30. %            AtanRot
  31. %
  32. %            Max, Min        Max and Min functions.
  33. %            PtNx                for filling arrays.
  34.  
  35. %<FF>
  36. %
  37. %        Define and set a current font if "currentfont setfont" is not valid
  38. %            On most versions of PostScript it is valid, but on 23.0 and some clones
  39. %            it is not. 
  40. %        the function QD2Grestore does a "currentfont grestore setfont" like thing
  41. %            and the following is needed to ensure it doesn't blow up on those printers.
  42. %
  43. currentfont /setfont load stopped not dup                        % See if currentfont setfont doesn't work
  44. /dontDefineDummyFont exch def    {save} {pop} ifelse        % If it did, do a save so we don't waste memory.
  45.                                                                                                         %    If it didn't pop off the null that currentfont pushed.
  46.  
  47. 10 dict dup begin
  48.     /FontType 3 def
  49.     /FontMatrix [1 0 0 1 0 0] def
  50.     /FontBBox [0 0 0 0] def
  51.     /Encoding StandardEncoding def
  52.     /BuildChar {} def
  53.     /FontName /dummyFont def
  54. end
  55.  
  56. /dummyFont exch definefont setfont                            % Make it the current font.
  57.  
  58. dontDefineDummyFont {restore} if                                % Do the restore to deallocate the definition if we didn't need it.
  59.  
  60.  
  61.  
  62.  
  63. %<FF>
  64. % Some basic constant definitions.
  65.  
  66. /maxfloat 32768.0 def                                % Since all things are in fixed point, this is the "biggest"
  67. /minfloat maxfloat neg def
  68. /T true def
  69. /F false def
  70.  
  71. % Define some "Registers in the Imaging Engine Dictionary.
  72. %        This ensures that some definition of them exists so the "store" operator
  73. %        won't try to create an entry in the top-most dictionary (like a style dict)
  74. %        which may not have any available entries.
  75. %
  76. /@1 0 def
  77. /@2 0 def
  78. /@3 0 def
  79. /@4 0 def
  80. /@5 0 def
  81. /@6 0 def
  82. /@7 0 def
  83. /@8 0 def
  84. /aChar 1 string def                                            % We need a character every now and then.
  85. /ScratchMatrix [0 0 0 0 0 0] def                % We need a matrix every now and then too.
  86. /CurrCTM matrix currentmatrix    def                %    Place to hold ctm when needed.
  87.  
  88.  
  89.  
  90. %
  91. %        The Bdef procedure:
  92. %
  93. /Bdef {bind def} bind def
  94.  
  95. %
  96. %        The Xdef procedure:
  97. /Xdef {exch def} Bdef
  98.  
  99. %
  100. %        The Xstore procedure:
  101. /Xstore {exch store} Bdef
  102.  
  103.  
  104. %
  105. %    key Inc -
  106. %        Increment the value pointed at by key.
  107. %
  108. /Inc {dup load 1 add store} Bdef
  109.  
  110.  
  111. %
  112. %    key Dec -
  113. %        Decrement the value pointed at by key.
  114. %
  115. /Dec {dup load 1 sub store} Bdef
  116.  
  117.  
  118. %
  119. %    the ExecLimChk procedure:
  120. %        key ExecLimChk -
  121. %
  122. %        key:        The key that the limitcheck happened on.
  123. /ExecLimChk {
  124.  
  125.     errordict /limitcheck get exec
  126.  
  127. } Bdef
  128.  
  129.  
  130. %<FF>
  131. %    Procedure:    GXCharPath
  132. %        This is the same as the charpath operator, only it keeps a count so it is reentrant.
  133. %            Additionally, it makes sure that userdict is on top of the dictionary stack in case the 
  134. %            TrueType patch has redefined charpath to set the stupid flag.
  135. %
  136. /CharPathCount 0 def
  137. /GXCharPath {
  138.  
  139.     /CharPathCount Inc
  140.     
  141.     userdict begin                        % Look in userdict first and…
  142.         /charpath load exec            % Get the charpath operator from whereever the hell it is defined.
  143.     end
  144.  
  145.     /CharPathCount Dec
  146.  
  147.  
  148. } Bdef
  149.  
  150.  
  151. %<FF>
  152. %    Procedure CopyDict:
  153. %        Copies the values from one dictionary into another dictionary.
  154. %        The dictionaries must have the same keys (such as an AugGstate or a style)
  155. %
  156. %        dict2 dict1 CopyDict             (From dict1 into dict2)  Weird, but saves an exch
  157. %
  158. %            dict2:            Dictionary to copy into
  159. %            dict1:            Dictionary to copy from
  160. /CopyDict {
  161.  
  162.     {
  163.         2 index                % Get dict2
  164.         3 1 roll            % Stack is now dict2 dict2 key value
  165.         put
  166.     } forall
  167.     
  168.     pop                            % Pop dict2 off the stack.    
  169.  
  170. } Bdef
  171.  
  172.  
  173. %<FF>
  174. %
  175. % Procedure takes a rectangle and finds the height and width
  176. %
  177. %    x1 y1 x2 y2 BoxWidhs (x2-x1) (y2-y1)
  178. %
  179. /BoxWidths {
  180.                                                 % Stack is:
  181.         exch                                        % x1 y1 y2 x2
  182.         4 -1 roll                                % y1 y2 x2 x1
  183.         sub                                            % y1 y2 (x2-x1)
  184.         3 1 roll                                % (x2-x1) y1 y2
  185.         exch sub                                % (x2-x1) (y2-y1)
  186.         
  187. } Bdef
  188.  
  189. %
  190. %    The FullPath Proc:
  191. %        this procedure adds to the current path a contour that is essentially wide open.
  192. %
  193. /FullPath {
  194.  
  195.     minfloat minfloat moveto
  196.     maxfloat minfloat lineto
  197.     maxfloat maxfloat lineto
  198.     minfloat maxfloat lineto
  199.     closepath
  200.  
  201. } Bdef
  202.  
  203.  
  204.  
  205. %
  206. %    The EmptyPath Proc:
  207. %        This procedure adds an empty path 
  208. %
  209. /EmptyPath {
  210.     0 0 moveto                % Clipping to this will clip everything out, drawing it will draw nothing.
  211. } Bdef
  212.  
  213. %
  214. %    The TightFullPath Proc:
  215. %        This procedure adds a rectangular contour to the current path that is the bounding
  216. %        box of the current clip  This is only used by PatternFill for inverse filling to 
  217. %        avoid trying to stamp the pattern shape out in infinite land.
  218. %
  219. /TightFullPath {
  220.  
  221.     gsave                                % do this because We're going to use clippath which implicitly does newpath.
  222.         clippath                    % Get the bounding box of the current clipping path.
  223.         pathbbox
  224.     grestore
  225.     
  226.     4 copy                            % Stack is now: x1 y1 x2 y2 x1 y1 x2 y2
  227.     BoxWidths                        %                         : x1 y1 x2 y2 (x2-x1) (y2-y1)
  228.     4 2 roll                        %                            : x1 y1 (x2-x1) (y2-y1) x2 y2
  229.     pop pop                            %                            : x1 y1 W H
  230.     
  231.     RP                                    % Make a rectangular path out of this.
  232.  
  233. } Bdef
  234.  
  235.  
  236. %<FF>
  237. %        The PointsAvailable proc:
  238. %
  239. %        Count the number of points available
  240. %            The Number of points available is left on the stack and the graphics
  241. %            State is restored.
  242. %
  243. /PointsAvailable {
  244.  
  245.     gsave
  246.     newpath
  247.     0.0 0.0 /moveto    load stopped not            % Try to Start a new contour.
  248.     {                                                                            % If we could start one, try to build it.
  249.         1                                                                        % Put initial count on stack.
  250.         {    
  251.                 1.0 1.0 /lineto load stopped        %     Try to add another point to it.
  252.                 {pop pop exit}                                    %   If we failed, pop the point and exit.
  253.                 {1 add    } ifelse                                %        else increment the count on the stack.
  254.         } loop
  255.  
  256.     }
  257.     {pop pop 0}                                                        % Else zero points.
  258.     ifelse
  259.  
  260.     grestore
  261.     
  262. } Bdef
  263.  
  264.  
  265. %<FF>
  266. %
  267. %    Procedure AvoidLimit:
  268. %        Executes the specified function trying to avoid the limitcheck error.
  269. %        It also ensures that the number of points available for use is greater than or equal to
  270. %        the requested amount.  This is accomplished by increasing the curve error (setflat) until
  271. %        These conditions are met.  If the conditions cannot be ment, then the limitcheck error procedure
  272. %        In errordict will be executed, thus causing the same result if the specified operator were
  273. %        simply done and the limitcheck had happened.
  274. %
  275. %        operatorKey minPoints AvoidLimit -
  276. %
  277. %        operatorKey:        The key specifying which function (eg: flattenpath, eoclip, etc…)
  278. %        minPoints:            The minimum number of points that should be left available.
  279. %
  280. /AvoidLimit {
  281.  
  282.     /@1 exch store                                    % Get the number of points we need to leave available
  283.     /@2 exch store                                    % Save the operator key to execute.
  284.     currentflat dup /@3 exch store    % Save the current curve error, Leave copy on stack.
  285.     
  286.     {
  287.         gsave
  288.         @2 load stopped not                                % Try to execute the operator.
  289.         {                                                                    % If successful then
  290.             @1 0 gt {                                                %        make sure we have enough points.
  291.                 PointsAvailable @1 ge
  292.                     {exit} if                                        %          If there were enough points, exit.
  293.             } {exit} ifelse                                    % Also exit, if we didn't need any points.
  294.             
  295.         } if
  296.         
  297.         % The rest of the loop only gets executed if the tests failed.
  298.         
  299.         grestore                                                    % Restore the graphics state before we try again.
  300.         /@3 @3 2 mul dup setflat store        % Increase the error for next try.
  301.         @3 1000 gt {exit} if                            % Don't try flatness bigger than 1000.
  302.         
  303.         %(Trying again with flatness of: ) print @3 ==            % Debugging print-out.
  304.         
  305.     } loop
  306.     
  307.     @3 1000 lt {                                        % If we succeeded in finding a curve error that works:
  308.  
  309.         grestore                                            % Restore the gsave done at beginning of the loop.
  310.         @3 setflat                                        %         Set the error to the necessary value
  311.         @2 load exec                                    %         Do the operator
  312.         
  313.     } {                                                            % Else Execute the limitcheck error on the operator.
  314.     
  315.         pop                                                                        % Pop off the saved value of currentflat,
  316.         @2 ExecLimChk                                    % do the error, this will cause the proc to terminate.
  317.  
  318.     } ifelse
  319.  
  320.     setflat                                                %            Restore the curve error to value saved on stack.
  321.  
  322. } Bdef
  323.  
  324.  
  325.  
  326.  
  327. %<FF>
  328. %
  329. % Procedure SF:   short for selctfont This already exists in level-2, If we are on a level-1 printer,
  330. %        Define it.  See red-book two for definition.
  331. %        Procedure also saves a copy of the font modification matrix in the augmented graphics state.
  332. %
  333. languagelevel 2 lt {
  334.  
  335.     /SF {
  336.     
  337.         exch findfont                                            % Find the font based on the name,
  338.         exch dup type /arraytype eq {            % If the second parameter was a matrix
  339.             dup                                                         %        Save a copy of the matrix 
  340.             AugGstate /FontMapping get            %        in the augmented graphics state.
  341.             copy pop
  342.             makefont                                                %     Apply the matrix to the font.
  343.         }    {                                                                %    Else
  344.             dup                                                            %        Make a matrix for the augmented graphics state
  345.             0 0    2 index 0 0                                    %        Stack is now: scale 0 0 scale 0 0
  346.             AugGstate /FontMapping get
  347.             astore pop
  348.             scalefont                                                %   Then apply it with scalefont
  349.         } ifelse
  350.  
  351.         setfont                                                                % Make it the current font.
  352.         
  353.     } Bdef
  354.  
  355. } {            %%%%% Level-2 definition:
  356.  
  357.     /SF {
  358.     
  359.         dup type /arraytype eq {            % If the second parameter was a matrix
  360.             dup                                                         %        Save a copy of the matrix 
  361.             AugGstate /FontMapping get            %        in the augmented graphics state.
  362.             copy pop
  363.         }    {                                                                %    Else
  364.             dup                                                            %        Make a matrix for the augmented graphics state
  365.             0 0    2 index 0 0                                    %        Stack is now: scale 0 0 scale 0 0
  366.             AugGstate /FontMapping get
  367.             astore pop
  368.         } ifelse
  369.     
  370.         selectfont                                                % Issue level-2 selectfont
  371.     
  372.     } Bdef
  373.  
  374. } ifelse
  375.  
  376. %
  377. % Procedure    SFy:  Does the same as SF does, only the scale is negated and then applied to 
  378. %        only the Y axis.  We need this because PostScript's y axis is reversed from Skia's
  379. %
  380. %            font-key scale  SFy dict
  381. % or
  382. %            font-dict scale SFy dict                (If you already have a dictionary instead of just the name)
  383. %            
  384. %
  385. /SFy {
  386.     
  387.     0 0 2 index neg 0 0                                % Stack is now: font-key(or dict) scale 0 0 
  388.     ScratchMatrix astore                            % Stack is now: font-key(or dict) [scale 0 0 -scale 0 0]
  389.     
  390.     1 index type /dicttype eq {                % If the first parameter was a dictionary then
  391.         makefont setfont                                %        just do makefont and set it.
  392.     } {                                                                % else
  393.         SF                                                            %     Select the font by key.
  394.     } ifelse
  395.  
  396. } Bdef
  397.  
  398.  
  399.  
  400.  
  401. %
  402. %    Procedure SFt:        calls SF (selectfont) but constructs the matrix based on the tangent/size params.
  403. %
  404. %            font-dict a b c d SFy dict                (If you already have a dictionary instead of just the name)
  405. %
  406. %            Where:
  407. %
  408. %            | a        b    |         | Sx  0 |     |  Tx Ty |
  409. %            |             | =  |       | * |        |
  410. %            | c        d |         | 0  Sy |   | -Ty Tx |
  411. %
  412. %            Sx, Sy = scale for font.  (Sy always is Sx or -Sx)
  413. %        and
  414. %            Tx Ty    is the tangent vector from the glyph shape.
  415. %
  416. /SFt {
  417.  
  418.     0 0                                                                % Stack is now: a b c d 0 0
  419.     ScratchMatrix astore                            % Stack is now: [a b c d 0 0]
  420.     makefont setfont                                    % Do a selectfont
  421.     
  422. } Bdef
  423.  
  424.  
  425. %<FF>
  426. %
  427. %            Procedure RP:  Create a path for the specified rectangle.
  428. %            x y w h RP -
  429. %
  430. %            x y:        lower left corner of the rectangle.  (LL in context of normal PS coordinate direction)
  431. %            w h:        The width and height of the rectangle.
  432. %
  433. /RP {
  434.  
  435.     4 2 roll                        % switch order or parameters so we have width height x y
  436.     moveto                            % Move to the lower left of the rectangle.
  437.  
  438.     exch dup 0 rlineto        % Line to x+w, y     stack is: h w
  439.     exch 0 exch rlineto        % Line to x+w, y+h     stack is: w
  440.     neg 0 rlineto                    % Line to x, y+h         stack is:
  441.     closepath                            % Close the contour.
  442.  
  443. } Bdef
  444.  
  445. %<FF>
  446. %        Procedure Pnt:
  447. %            Makes a path for a Skia point shape.
  448. %            PostScript is reluctant to draw paths of length zero, so we will guarentee
  449. %            A length of 1 device-pixel.
  450. %
  451. %            x y Pnt -
  452. %
  453. %            x y:        The point for the line.
  454. %            
  455. /Pnt {
  456.  
  457.     moveto                            % Move to the point on the stack
  458.     1 0 idtransform            % Get a distance of 1 device pixel horizontally.
  459.     rlineto                            % and go there.
  460.  
  461. } Bdef
  462.  
  463.  
  464.  
  465. %<FF>
  466. %        Define rectangle operators for level-1.  They already exist in level-2, abbreviate them.
  467. %            They will act the same way, except implementation of numarray and numstring
  468. %            will not be here.  The definitions are abbreviated becuase they will be found
  469. %`        in the script of the document, keeps script size down.
  470. %
  471. languagelevel 2 lt {
  472.  
  473.     /RF {
  474.         gsave newpath 
  475.         RP    
  476.         fill grestore
  477.     } Bdef
  478.  
  479.     /RStr {
  480.         gsave newpath 
  481.         RP    
  482.         stroke grestore
  483.     } Bdef
  484.  
  485.     /RCl {
  486.         newpath
  487.         RP    
  488.         clip
  489.         newpath
  490.     } Bdef
  491.  
  492. } {                            % Level 2 abbreviations instead.
  493.  
  494.     /RF             /rectfill load def
  495.     /RStr            /rectstroke load def
  496.     /RCl            /rectclip load def
  497.  
  498. } ifelse
  499.  
  500.  
  501. %<FF>
  502. %     Rotate the CTM by the arc-tangent of the specified dy dx.
  503. %            A faster substitute (40% faster) for {atan rotate}
  504. %
  505. %            dy dx AtanRot -
  506. %
  507. /ATanRot {
  508.     2 copy                        % Calculate the length of the vector
  509.     dup mul exch
  510.     dup mul add
  511.     sqrt
  512.     
  513.     % Stack is now dy dx dist
  514.     
  515.     dup 3 1 roll            % dy dist dx dist
  516.     div                                % dy dist dx'
  517.     3 1 roll
  518.     div                                % dx' dy'
  519.     dup                                % dx' dy' dy'
  520.     neg                                % dx' dy' -dy'
  521.     2 index                        % dx' dy' -dy' dx'
  522.     0. 0.
  523.     ScratchMatrix astore concat
  524.     
  525. } Bdef
  526.  
  527.  
  528. %<FF>
  529. %
  530. %        MakeShapeDict:
  531. %        Make a shape dictionary.
  532. %
  533. %        geomProc fillKey x1 y1 x2 y2 shapeType MakeShapeDict dict
  534. %            or
  535. %        colorSet/colorSpace bitStrings bitsPerPixel geomProc fillKey x1 y1 x2 y2 shapeType MakeShapeDict
  536. %
  537. %optional paramters
  538. %
  539. %        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)
  540. %        bitStrings:                            Array of strings containing bitmap data (also required only for bitmaps)
  541. %        bitsPerPixel:                        Bits per pixel (required only for bitmaps)
  542. %required parameters
  543. %        geomProc:                                procedure to execute for shape's geometry
  544. %        fillKey:                                fill key for shape's fill.
  545. %        x1 y1 x2 y2:                        Boudning box of shape.
  546. %        shapeType:                            /g: for geometric shape (polygon, path, rectangle, curve, line, point)
  547. %                                                        /t: for text shape type (text, glyph, layout)
  548. %                                                        /b: for 1 bit bitmap.
  549. %                                                        /i: for image ( > 1 bit bitmap).
  550. % returned on stack
  551. %        dict:                                        A valid shape dictionary is created and left on stack.
  552. %
  553. %
  554. %            A note about shape dictionaries:  Execution of the geomProc may require
  555. %                the shape dictionary to be on the dictionary stack.  It is safest to 
  556. %                make sure this is so before executing a geometry procedure
  557. %
  558. /MakeShapeDict {
  559.     
  560.     dup dup /i eq exch /b eq or {        % For bitmap shapes there are three extra parameters
  561.             12 dict begin                                    % Make a dictionary and put it on dict stack
  562.         } {
  563.             9 dict begin                                    % Make a dictionary and put it on dict stack
  564.         } ifelse
  565.         
  566.         /shapeType Xdef
  567.         /y2 Xdef
  568.         /x2 Xdef
  569.         /y1 Xdef
  570.         /x1 Xdef
  571.         /fillKey Xdef
  572.         /geomProc Xdef
  573.         
  574.         % If the shape is a bitmap, then the stack has:
  575.         % colorSet/colorSpace bitStrings bitsPerPixel, put them in the dictionary as well.
  576.         
  577.         shapeType dup /b eq exch /i eq or {
  578.         
  579.             /BitsPerPixel Xdef
  580.             /BitmapStrings Xdef
  581.             
  582.             /colorSet null def                    % Initialize set and space to be null
  583.             /ColorSpace null def
  584.             
  585.             dup null ne {                                % if the space/set parameter isn't null
  586.                 dup /CSA known {                    %        and it has a CSA field inside then
  587.                     /ColorSpace Xdef                %            it is a GX color space dictionary
  588.                 } {                                                %        else
  589.                     /colorSet Xdef                    %            it must be a GX color set dictionary.
  590.                 }ifelse                                        %
  591.             } {                                                    % else
  592.                 pop                                                %        pop off the null, leave set and space defined to be null                                        
  593.             } ifelse
  594.  
  595.             /HaveDrawnIt false def        % Initialize this shape dictionary as not having been drawn yet.
  596.                                                                 % The portable PostScript RGB bitmap procedure needs to know this.
  597.                 
  598.         } {            % else For non bitmap shapes, just put a null ColorSpace and colorSet
  599.         
  600.             /ColorSpace null def
  601.             /colorSet null def
  602.         
  603.         } ifelse
  604.         
  605.     currentdict end        % Leave the shape dictionary on the stack.
  606.     
  607. } Bdef
  608.  
  609. %<FF>
  610. %
  611. %    ShapeBBox:
  612. %    Get the bounding box of a shape.
  613. %
  614. %    shape ShapeBBox x1 y1 x2 y2
  615. %
  616. %        shape:                A valid shape dictionary.
  617. %        x1 y1 x2 y2:    The bounding box is left as 4 values on stack.
  618. %
  619. /ShapeBBox {
  620.  
  621.     dup /x1 get exch
  622.     dup /y1 get exch
  623.     dup /x2 get exch
  624.             /y2 get
  625.  
  626. } Bdef
  627.  
  628.  
  629.  
  630. %<FF>
  631. %
  632. %    Max and min functions, take two numbers and find the max or min of them.
  633. %
  634. %
  635. /Max {
  636.  
  637.     2 copy
  638.     gt {pop} {exch pop} ifelse
  639.  
  640. } Bdef
  641.  
  642. %
  643. %    Max and min functions, take two numbers and find the max or min of them.
  644. %
  645. %
  646. /Min {
  647.  
  648.     2 copy
  649.     lt {pop} {exch pop} ifelse
  650.  
  651. } Bdef
  652.  
  653. %<FF>
  654. %
  655. %    Grid fit a point
  656. %
  657. %        x y Grid x' y'
  658. %
  659. %        x y:        point to grid fit.
  660. %        x' y':    grid fittend point in user space.
  661. /Grid {
  662.  
  663.     transform                                                    % Transform point to device space.
  664.     round exch round exch                            % Pin it to a pixel.
  665.     itransform                                                % Transform pinned values back.
  666.  
  667. } Bdef
  668.  
  669.  
  670. %<FF>
  671. %
  672. %    PtNx:
  673. %
  674. %        array index value PtNx array index+1
  675. %
  676. %            puts value into array at index and increments the index on the stack.
  677. %
  678. %
  679. /PtNx {
  680.  
  681.     3 copy put                                % Put the value into the array at index.
  682.     pop                                                % Get rid of copy of value
  683.     1 add                                            % Increment the index.
  684.  
  685. } Bdef
  686.  
  687. %<FF>
  688. %
  689. % NotEqual:
  690. %
  691. %        Check if two numbers are not equal, discounting PostScript rounding error.
  692. %
  693. /NotEqual {
  694.  
  695.     sub abs 0.001 ge            % This should be within the precision of PostScript.
  696.                                                 % 1/1000 point in normal user space, (1/72000 inch)
  697.             
  698. } Bdef
  699.  
  700. %<FF>
  701. %
  702. %        Define GX versions of setrgbcolor and colorimage.  These will be overridden if the PortableColorProcs.ps
  703. %        is downloaded after this file.  PortableColorProcs must be downloaded after this file!!
  704. %
  705. /GXSetRGBColor /setrgbcolor load def
  706. /colorimage where {pop /GXColorImage /colorimage load def} if
  707.  
  708.