*ps_lw_cmyk % ** Start user custom prolog for portrait orientation with linewidth % and CMYK color control by AutoCAD color number. ;% Set up a small dictionary for our own use /UserPrologDict 50 dict def UserPrologDict begin ; ;% Save our version in case PSFILLs care /LGP_version 1.5 def % The following section sets up the mapping of AutoCAD color numbers % to line widths. % Note that the linewidths specified below are _minimums_. Explicit % linewidths (for example, a polyline with width) that are larger % than the minimum override the minimum. Also note that if the % coordinate system is distorted, lines in the shorter direction % will be thicker than the minimum (for example, a block inserted % with X and Y scale factors that are not equal in magnitude). On % a system with fewer dots per inch in one direction than the other % this should work, but I haven't tested it. % An array containing the desired line width in inches for any of the % first sixteen colors. May be expanded or contracted if desired. % Colors that are not covered in this array are mapped to the % width specified for the last entry in the array. /LGP_colortowidth [ 0.001 % Color 1 (red) 0.001 % Color 2 (yellow) 0.001 % Color 3 (green) 0.001 % Color 4 (cyan) 0.001 % Color 5 (blue) 0.001 % Color 6 (magenta) 0.001 % Color 7 (white) 0.001 % Color 8 0.001 % Color 9 0.001 % Color 10 0.001 % Color 11 0.001 % Color 12 0.001 % Color 13 0.001 % Color 14 0.001 % Color 15 ] def % Now the map of AutoCAD color numbers to output colors, using the % CMYK (Cyan-Magenta-Yellow-blacK) model. % Each line should have four numbers between the square brackets % on that line. The first number should range from 1 (maximum amount of % cyan) to 0 (no cyan); the second number should range from 1 (maximum % amount of magenta) to 0 (no magenta); the third number should range % from 1 (maximum amount of yellow) to 0 (no yellow); and the fourth % number should range from 1 (maximum amount of black) to 0 (no black). % For example, black is formed by [ 0 0 0 1], white is formed by % [ 0 0 0 0 ], and cyan is formed by [ 1 0 0 0 ]. % The original entries in this array map each of the first fifteen colors % to reasonable approximations of themselves (assuming AutoCAD is in 16 % color mode with no color customization). % This array must have at least as many entries as LGP_colortowidth. If it % has more entries than LGP_colortowidth, the extra entries are ignored. % Colors that are not covered in this array are mapped to the RGB color % specified for the last used entry in the array. /LGP_ACADcolortoPScolor [ [ 0.00 1.00 1.00 0.00 ] % Color 1 (red) [ 0.00 0.00 1.00 0.00 ] % Color 2 (yellow) [ 1.00 0.00 1.00 0.00 ] % Color 3 (green) [ 1.00 0.00 0.00 0.00 ] % Color 4 (cyan) [ 1.00 1.00 0.00 0.00 ] % Color 5 (blue) [ 0.00 1.00 0.00 0.00 ] % Color 6 (magenta) [ 0.00 0.00 0.00 0.00 ] % Color 7 (white) [ 0.00 0.00 0.00 0.50 ] % Color 8 [ 0.00 0.67 0.67 0.33 ] % Color 9 [ 0.00 0.00 0.67 0.33 ] % Color 10 [ 0.67 0.00 0.67 0.33 ] % Color 11 [ 0.67 0.00 0.00 0.33 ] % Color 12 [ 0.67 0.67 0.00 0.33 ] % Color 13 [ 0.00 0.67 0.00 0.33 ] % Color 14 [ 0.00 0.00 0.00 0.33 ] % Color 15 ] def ;% Set up an alias for the function that sets the current color ;% values for the PostScript interpreter. This allows the code section ;% to be independent of the color model. /LGP_setcolor { setcmykcolor } bind def ;% START THE CODE SECTION ; ;% First some preliminary stuff ; ;% A routine to find the square root of the sum of the squares of the top ;% two numbers of the stack ; ;% num1 num2 LGP_SqrtSumSquares sqrt(num1*num1 + num2*num2) ; /LGP_SqrtSumSquares { dup mul exch dup mul add sqrt } bind def ; % A routine to find the minimum non-zero magnitude of either the X scale % factor or the Y scale factor of a given transformation matrix. % Assumes at least one of the scale factor magnitudes is non-zero. ; ;% CTM LGP_MinScaleMag (minimum scale factor, dots per unit) ; /LGP_MinScaleMag { ; % Get the elements of the matrix aload ; % Discard the original matrix and the translation entries pop pop pop ; % Arrange the stack to get the X coefficents and Y coefficients ; % together 4 1 roll exch 4 -1 roll ; % Find the magnitude of the vector defined by the Y coefficients LGP_SqrtSumSquares ; % Bring the X coefficients to the top of the stack 3 1 roll ; % Find the magnitude of the vector defined by the X coefficients LGP_SqrtSumSquares ; % Copy the two magnitudes 2 copy ; % If the Y magnitude is greater than the X magnitude ... gt ; % Swap the X and Y magnitudes { exch } if ; % If the minimum magnitude, now one down in the stack, is zero ; % then swap so the maximum (assumed non-zero) magnitude ; % is one down in the stack exch dup 0.0 ne { exch } if ; % The maximum magnitude is on top of the stack, discard it pop ; % Leaving the minimum magnitude on the stack } bind def ; ;% Get the dot-pitches per inch for this printer (accounting for ;% the possibility that it may be different in X and Y directions; ;% we pick the minimum) ; /LGP_printerdotsperinch matrix defaultmatrix LGP_MinScaleMag 72 mul def ; ;% Convert the array of line widths in inches to line widths in dots ; LGP_colortowidth { LGP_printerdotsperinch mul } forall LGP_colortowidth astore /LGP_colortowidth def ; ;% Initialize the current minimum and desired line widths in current dots. ;% These numbers are arbitrary and will be overriden immediately. ; /LGP_minwidth 1 def /LGP_desiredwidth 1 def ; ;% Set up an array in which to simulate a stack of values of ;% LGP_desirewidth (and, not incidentally, load it with a dummy ;% value to be removed at the final "grestore" of the EPS file) ; /LGP_dw_stack [ LGP_desiredwidth ] def ; end ; ;% Now the routines that really DO things. ; ;% A "front end" for the stroke function. Sets the line width to ;% the desired line width before stroking, so the line width ;% will always be the desired value no matter what machinations ;% have gone on with the scale. NOTE that this procedure and ;% the binding that follows it MUST precede the "front end" ;% for the setlinewidth procedure ; /LGP_strokefrontend { UserPrologDict begin ; % Get the current desired line width in dots LGP_desiredwidth ; % Get the current scale factor in dots per unit matrix currentmatrix LGP_MinScaleMag ; % Divide desired line width in dots by dots per unit to get units div setlinewidth end } bind def ; ;% Bind our front end to the original stroke function for speed ; /stroke { LGP_strokefrontend stroke } bind def ; ;% A front end for the setlinewidth function. If the requested line ;% width in inches is greater than LGP_minwidth, sets the line ;% width to the requested value and sets LGP_desiredwidth to the ;% requested line width in dots. If the requested line width ;% is less than LGP_minwidth, uses LGP_minwidth instead. ;% NOTE that this front end and the binding that follows MUST ;% follow the stroke front end and its binding. ; ;% num setlinewidth - ; /LGP_setlwfrontend { UserPrologDict begin ; % Get the current scale factor in dots per unit matrix currentmatrix LGP_MinScaleMag ; % Save copies of the current dots per unit and requested linewidth 2 copy ; % And convert the requested line width (in units) to dots mul ; % Compare the requested line width to the current minimum line width dup LGP_minwidth gt ; % Here the requested line width is greater than our minimum { ; % Set the current desired line width in dots /LGP_desiredwidth exch def ; % Discard the extra copy of the current inches per unit, leaving ; % the requested line width in units on the stack pop } ; % Here the requested line width is less than our minimum { ; % Discard the requested line width in dots pop ; % Get our minimum line width in dots and save a copy LGP_minwidth dup ; % Save the current desired line width in dots /LGP_desiredwidth exch def ; % Convert the desired line width in dots to units exch div ; % Discard the originally requested line width, leaving our ; % minimum line width in units on the stack exch pop } ifelse end } bind def ; ;% Bind the setlinewidth front end to the setlinewidth function for speed ; /setlinewidth { LGP_setlwfrontend setlinewidth } bind def ; ;% A routine to set desired line width and color or gray scale whenever ;% AutoCAD changes colors. Doesn't actually set the line width (just ;% saves it in LGP_desiredwidth and LGP_minwidth), does actually ;% set the color or gray scale ; ;% (color number) (red value) (green value) (blue value) ACADColor - ; /ACADColor { UserPrologDict begin ; % Discard the RGB values of the color pop pop pop ; % If the color number is greater than the number of elements in the ; % array, use the highest number that's covered in the array dup LGP_colortowidth length gt { pop LGP_colortowidth length } if ; % Convert the color number into a zero-based array index 1 sub ; % Save the index for later (for the gray scale array) dup ; % Get the desired line width in dots and save it both as the minimum ; % and the desired value LGP_colortowidth exch get /LGP_minwidth exch dup /LGP_desiredwidth exch def def ; % Get the desired color or gray scale value array ... LGP_ACADcolortoPScolor exch get ; % Extract the elements of the array and discard the array aload pop ; % Implement the new color or gray scale LGP_setcolor end } bind def ; ;% A "front end" for the gsave function. Simulates pushing LGP_desiredwidth ;% on a stack (really an array). In effect, LGP_desiredwidth is saved ;% along with the graphics state. ; /LGP_gsavefrontend { UserPrologDict begin ; % Put the name of our array on the stack /LGP_dw_stack ; % Start an array [ ; % Put the array itself on the stack, unload its elements onto the stack, ; % and discard the array that "aload" leaves on top LGP_dw_stack aload pop ; % Put the current value of LGP_desiredwidth on the stack LGP_desiredwidth ; % End the array and save it ] def end } bind def ; ;% Bind our front end to the original gsave function for speed ; /gsave { LGP_gsavefrontend gsave} bind def ; ;% A "front end" for the grestore function. Simulates popping ;% LGP_desiredwidth from a stack (really an array). In effect, ;% LGP_desiredwidth is restored along with the graphics state ; /LGP_grestorefrontend { UserPrologDict begin ; % Put the name of our array on the stack /LGP_dw_stack ; % Start an array [ ; % Put the array itself on the stack, unload its elements onto the stack, ; % and discard the array that "aload" leaves on top LGP_dw_stack aload pop ; % Store the last value in the array into LGP_desiredwidth /LGP_desiredwidth exch def ; % End the array and save it ] def end } bind def ; ;% Bind our front end to the original grestore function for speed ; /grestore { LGP_grestorefrontend grestore} bind def ; ;% If the setstrokeadjust procedure is available, activate stroke adjustment ; /setstrokeadjust where { pop true setstrokeadjust } if % ** End user custom prolog