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 / HalftoneProcs.ps < prev    next >
Encoding:
Text File  |  2000-09-28  |  8.7 KB  |  389 lines  |  [TEXT/MPS ]

  1. %
  2. %    File:        HalftoneProcs.ps
  3. %
  4. %    Contains:    This file contains Procedures needed do the standard halftone dot types.
  5. %
  6. %    Version:    Technology:    Quickdraw GX 1.1.x.
  7. %
  8. %    Copyright:    © 1991-7 by Apple Computer, Inc., all rights reserved.
  9. %
  10. %
  11.  
  12. %
  13. %    Procedure to generate the standard dispersed dot dither matrix.    
  14. %    Calculates the dither matrix by converting the shade to a base-4 number.
  15. %    Each digit of the base 4 number represents a quadrant in the submatrix.
  16. %    The submatrix for the least significant digit is the whole matrix,
  17. %    this is divided into 4 submatrices for the next least significant and so on
  18. %    down to a 2x2 cell submatrix for the most significant digit, made up of 1 cell
  19. %    quadrants.
  20. %
  21. %             size MakeDispDotMatrix matrix
  22. %
  23. %                    The size is the width of the matrix.  Must be a power of 2.
  24. %
  25. /dispDotDict 12 dict dup begin                % local variable dictionary for making the matrix.
  26.  
  27.     /dx [0 1 1 0] def
  28.     /dy [0 1 0 1] def
  29.     /size 0 def
  30.     /nShades 0 def
  31.     /theMatrix null def
  32.     /lv 0 def
  33.     /ilv 0 def
  34.     /quadSize 0 def
  35.     /quadrant 0 def
  36.     /place 0 def
  37.     /x 0 def
  38.     /y 0 def
  39.  
  40. end def
  41.  
  42. /MakeDispDotMatrix {
  43.  
  44.     dispDotDict begin
  45.     
  46.         /dx [0 1 1 0] def                            % Arrays to determine quadrant position.
  47.         /dy [0 1 0 1] def
  48.     
  49.         /size exch def                                    % Get the size
  50.         /nShades size size mul def            % Get the number of shades we can dither
  51.         /theMatrix nShades array def        % Make an array for the dispersed dot matrix.    
  52.     
  53.         0 1 nShades 1 sub {                            % Loop from 0 to nShades-1
  54.         
  55.             /lv exch def                                    % Get the current loop counter in lv (light-value)
  56.             /ilv lv def                                        % Grab a copy, we will manipulate this one.
  57.             
  58.             /place nShades 4 idiv    def            % Current base-4 place to calculate starts with n/4
  59.             /quadSize 1 def                                % Quadrant size for most significant digit is 1 cell.
  60.             /x 0 def /y 0 def                            % Initialize the matrix position
  61.             
  62.             % Calculate matrix position by offsets for each base-4 digit.
  63.             
  64.             {
  65.                 place 0 eq {exit} if                % While place > 0
  66.                 
  67.                 /quadrant ilv place idiv def                            % The quadrant is the base-4 digit.
  68.                 /ilv ilv quadrant place mul sub def                % Reduce the value to get the next digit later.
  69.                 /x x dx quadrant get quadSize mul add def    % Calculate offset into quadrant (x+=dx[quadrant]*quadSize)
  70.                 /y y dy quadrant get quadSize mul add def    % Do it for y also
  71.                 /place place 4 idiv def                                        % Move to next most significant base-4 digit.
  72.                 /quadSize quadSize 2 mul def                            % Quadrant size doubles for each less significant digit.
  73.             
  74.             } loop
  75.  
  76.             theMatrix                                % Put the value in the matrix:            
  77.             y size mul x add                % Calculate the index into the matrix based on x and y
  78.             lv put
  79.         
  80.         } for
  81.                 
  82.     end
  83.         
  84. } Bdef
  85.  
  86.  
  87. %
  88. %        Function computes a nearest power of two size for a matrix based upon the frequency
  89. %            requested for the halftone.
  90. %
  91. %        freq FrequencyToMatrixSize size
  92. %
  93. %            freq:            The requested frequency
  94. %            size:            the size of the dispersed dot matrix to use.
  95. /FrequencyToMatrixSize {
  96.  
  97.     1 1 matrix defaultmatrix dtransform pop 72 mul abs            % Get the resoultuion.
  98.  
  99.     exch div                % This number is cell size in pixels for this frequency
  100.     
  101.     %
  102.     %        Now find the number that is nearest power of two to the cell size.
  103.     %
  104.     0 5 {                                        % Initialize n to 0, never go greater than 5 (yielding 32x32 cell - no point in doing so)
  105.     
  106.         dup 2 exch exp                % Stack is now cell-size n 2^n
  107.         2 index                                % Stack is now cell-size n 2^n cell-size
  108.         gt {                                    % if 2^n > cellSize then
  109.             exit                                %        stop
  110.         } if
  111.                 
  112.         1 add                                    % increment n
  113.     
  114.     } repeat
  115.     
  116.     % We went one too many, subtract one.
  117.     
  118.     1 sub
  119.     
  120.     exch pop                                % Get rid of the cell-size from the stack, leave the power of two to use.
  121.     
  122.     % raise 2 to the powere of size
  123.     
  124.     2 exch exp cvi
  125.         
  126. } Bdef
  127.  
  128.  
  129.  
  130. %<FF>
  131. %
  132. %        Make dictionary containing each of the 7 standard dot types.
  133. %
  134. /HalftoneDotFunctions 8 dict dup 3 -1 roll Xdef begin
  135.  
  136.     /TriangleDotFunction {
  137.     
  138.         Moby begin                                % Make sure Moby Dict is on stack, in case a postscript synonym executes currentscreen.
  139.  
  140.             2 div /@2 Xdef                                            % y    / 2 (put into -0.5 to 0.5 range)
  141.             dup 0 lt {neg} if 2 div /@1 Xdef        % x = abs(x / 2)
  142.                     
  143.             2 @2 sub 2 @1 mul sub
  144.             
  145.             2.5 div                                                            % Divide by maximum value
  146.         
  147.         end
  148.  
  149.     } Bdef
  150.     
  151.     
  152.     /SpiralDotFunction {
  153.     
  154.         Moby begin                                % Make sure Moby Dict is on stack, in case a postscript synonym executes currentscreen.
  155.  
  156.             2 div /@2 Xdef                            % y    / 2 (put into -0.5 to 0.5 range)
  157.             2 div /@1 Xdef                            % x / 2 (put into -0.5 to 0.5 range)
  158.         
  159.             1 @1 dup mul @2 dup mul @1 16 div @2 8 div add add add sub
  160.             
  161.             1.1 div                                            % The maxima skirts just above 1.0, so make sure PS doesn't
  162.                                                                     %        cause Rangecheck error.
  163.                                                                     
  164.         end
  165.     
  166.     } Bdef
  167.     
  168.     
  169.     /SquareDotFunction {
  170.     
  171.         Moby begin                                % Make sure Moby Dict is on stack, in case a postscript synonym executes currentscreen.
  172.  
  173.             /@2 Xdef /@1 Xdef                        % Get x, y
  174.             
  175.             @1 @2 lt {@2} {@1} ifelse
  176.             
  177.             1 exch sub    
  178.             
  179.             2 div                                    % Divide by maximum value.
  180.             
  181.         end
  182.     
  183.     } Bdef
  184.     
  185.     
  186.     /RoundDotFunction {
  187.     
  188.         Moby begin                                % Make sure Moby Dict is on stack, in case a postscript synonym executes currentscreen.
  189.  
  190.             abs /@2 Xdef                        % Save y
  191.             abs /@1 Xdef                        % Save x
  192.             
  193.             @1 @2 add 1 gt {
  194.             
  195.                 /@1 1 @1 sub def        % subtract 1 from x and y
  196.                 /@2 1 @2 sub def
  197.                 
  198.                 @1 @1 mul
  199.                 @2 @2 mul
  200.                 add
  201.                 1 sub
  202.             
  203.             } {
  204.             
  205.                 1
  206.                 @1 @1 mul
  207.                 @2 @2 mul
  208.                 sub
  209.                 sub
  210.             
  211.             } ifelse
  212.     
  213.             2 div                     % Scale to fit in range.
  214.             
  215.         end        
  216.         
  217.     } Bdef
  218.     
  219.     
  220.     /EllipticDotFunction {
  221.     
  222.         Moby begin                                % Make sure Moby Dict is on stack, in case a postscript synonym executes currentscreen.
  223.  
  224.             /@2 Xdef
  225.             /@1 Xdef
  226.             
  227.             /@2 @2 2 mul abs def                % y = abs(2*y)
  228.             /@1 @1 @1 mul def                        % x = x*x
  229.             /@1 @1 @2 add def                        % x = x + y
  230.             /@1 @1 3 div def                        % x = x/3
  231.             1 @1 sub
  232.             
  233.             2 div                                                % Scale to keep result between 0 and 1.
  234.             
  235.         end
  236.     
  237.     } Bdef
  238.     
  239.  
  240.  
  241.     
  242.     /LineDotFunction {
  243.  
  244.         % This one does not require Moby dict to be on stack.
  245.         
  246.         exch pop    
  247.     
  248.     } Bdef
  249.     
  250.     
  251.     
  252.     /DispersedDotFunction {
  253.     
  254.         Moby begin                                % Make sure Moby Dict is on stack, in case a postscript synonym executes currentscreen.
  255.  
  256.             dispDotDict begin
  257.             
  258.                     % Use the coordintes passed to to index the matrix.
  259.                     
  260.                     1 add 2 div size mul cvi exch            % input is -1 ≤ x < 1, make: 0 ≤ x ≤ (size-1)
  261.                     1 add 2 div size mul cvi exch            % Do the same for y.
  262.                     
  263.                     size mul add                % index = x * size + y
  264.                     theMatrix exch get    % get theMatrix[index]
  265.                     
  266.                     nShades div                    % scale from 0-1 instead of from 0-nShades
  267.             
  268.             end
  269.             
  270.         end
  271.         
  272.     } Bdef
  273.  
  274.  
  275. end             % defined dictionary for all halftone spot functions.
  276.  
  277.  
  278.  
  279.  
  280.  
  281. %<FF>
  282. %
  283. %
  284. %            SetHalftoneParams:
  285. %
  286. %            Set up the current halftone on the printer:
  287. %
  288. %            freq1 angle1 dotFunction1… freqN angleN dotFunctionN N SetHalftoneParams -
  289. %
  290. %                freq1…N:                        Frequencies for components 1 through N
  291. %                angle1…N:                        angles for components 1 through N
  292. %                dotFunction1…N:            names of dot functions 1 through N
  293. %
  294. %                N:                                    Number of color components allowed (1 or 4)
  295. %
  296. /SetHalftoneParams {
  297.  
  298.     1 eq {
  299.                 
  300.         dup /DispersedDotFunction eq {
  301.         
  302.             % Set up to do dispsersed dot function
  303.             
  304.             2 index                                        % Get the frequency
  305.             FrequencyToMatrixSize            % Compute the matrix size to use.
  306.             MakeDispDotMatrix                    % Make the matrix in the dispDotDict dictionary.
  307.         
  308.         } if
  309.  
  310.         HalftoneDotFunctions exch get setscreen
  311.  
  312.     } {                % must be 4 planes
  313.     
  314.         4 {
  315.         
  316.             dup /DispersedDotFunction eq {
  317.             
  318.                 % Set up to do dispersed dot function
  319.                 %        The matrix that will end up being used will actually
  320.                 %        be the one for the first of the components that requested DispersedDotFunction
  321.                 
  322.                 2 index                                        % Get the frequency
  323.                 FrequencyToMatrixSize            % Compute the matrix size to use.
  324.                 MakeDispDotMatrix                    % Make the matrix in the dispDotDict dictionary.
  325.             
  326.             } if
  327.  
  328.             HalftoneDotFunctions exch get
  329.             12 3 roll
  330.             
  331.         } repeat
  332.         
  333.         %
  334.         %    If setcolorscreen exists, use it - else do a setscreen and pop the extra parameters
  335.         %
  336.         systemdict /setcolorscreen known {setcolorscreen} {setscreen 9 {pop} repeat} ifelse
  337.     
  338.     } ifelse
  339.  
  340. } Bdef
  341.  
  342. %<FF>
  343. %
  344. %        Save the set of default halftone parameters.
  345. %
  346. languagelevel 2 lt {                % for level-1, get current screen or color screen
  347.  
  348.     /DefineDefaultHalftone {
  349.     
  350.         /DefaultHalftone [ 
  351.                     
  352.         
  353.             systemdict /setcolorscreen known
  354.                 {currentcolorscreen}                                % If printer has color extensions, get color screen
  355.                 {currentscreen}                                            % else get black and white screen.
  356.             ifelse
  357.                     
  358.         ] def
  359.         
  360.     } Bdef
  361.     
  362.     systemdict /setcolorscreen known {
  363.     
  364.         /SetDefaultHalftone {
  365.         
  366.             DefaultHalftone {} forall setcolorscreen
  367.             
  368.         } Bdef
  369.         
  370.     } {
  371.     
  372.         /SetDefaultHalftone {
  373.         
  374.             DefaultHalftone {} forall setscreen
  375.             
  376.         } Bdef
  377.     
  378.     } ifelse
  379.  
  380. } {        % For level-2, it is much easier, just get and set halftone dictionary.
  381.  
  382.     /DefineDefaultHalftone {/DefaultHalftone currenthalftone def} Bdef
  383.     
  384.     /SetDefaultHalftone {DefaultHalftone sethalftone} Bdef
  385.  
  386. } ifelse
  387.  
  388.  
  389.