home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 13 / 13.iso / p / p024 / 12.img / ADS2.LIB / SLD2PS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-17  |  27.6 KB  |  1,011 lines

  1. /* Next available MSG number is  32 */
  2.  
  3. /*    SLD2PS.C
  4.       ¬⌐┼v (C) 1990-1992  Autodesk ñ╜Ñq
  5.  
  6.       Ñ╗│n┼ΘºK╢O¿╤▒z╢iªµÑ⌠ª≤Ñ╬│~╗▌¿D¬║½■¿⌐íB¡╫º∩ñ╬╡oªµ, ª²¼O░╚╜╨┐φ┤`ñU¡z
  7.       ¡∞½h :
  8.  
  9.       1)  ñWªC¬║¬⌐┼v│qºi░╚╗▌ÑX▓{ªb¿Cñ@Ñ≈½■¿⌐∙╪íC
  10.       2)  ¼█├÷¬║╗í⌐·ñσÑ≤ñ]Ñ▓╢╖⌐·╕ⁿ¬⌐┼v│qºiñ╬Ñ╗╢╡│\Ñi│qºiíC
  11.  
  12.       Ñ╗│n┼Θ╢╚┤ú¿╤º@¼░└│Ñ╬ñW¬║░╤ª╥, ª╙Ñ╝┴n⌐·⌐╬┴⌠ºtÑ⌠ª≤½O├╥; ╣∩⌐≤Ñ⌠ª≤»S«φ
  13.       Ñ╬│~ñº╛A║┘⌐╩, ÑHñ╬░╙╖~╛P░Γ⌐╥┴⌠ºtÑX¿π¬║½O├╥, ªbª╣ñ@╖ºñ⌐ÑHº_╗{íC
  14.  
  15.  
  16.  
  17.       DESCRIPTION:
  18.  
  19.  
  20.       SLD2PS.C - Converts AutoCAD Slide files to PostScript files
  21.       Optionally outputs full color and Encapsulated PS files.
  22.  
  23.       Designed and implemented by Amar Hanspal, Autodesk Product Support
  24.  
  25.       Originally developed as a DOS stand-alone program - January 89
  26.       Converted to Release 11 ADS application           - March 90
  27.  
  28. */
  29.  
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <ctype.h>
  33.  
  34. #include "adslib.h"
  35.  
  36. #define ushort unsigned short
  37. #define uchar  unsigned char
  38.  
  39. /* Hardcopy parameters */
  40.  
  41. #define PSIZEX 8.50                   /* X Paper size in inches */
  42. #define PSIZEY 11.00                  /* Y Paper size in inches */
  43. #define HCLIP 0.125                   /* Printer's hardclip limits */
  44.  
  45. #define DPI 72.0                      /* PostScript's Units per inch */
  46.  
  47. #define PLOWX 0.5                     /* Half-inch border around plot */
  48. #define PLOWY 0.5
  49. #define PHIGHX (PSIZEX - 0.5)
  50. #define PHIGHY (PSIZEY - 0.5)
  51.  
  52. #define LOWXDOT PLOWX*DPI             /* Convert to PostScript units */
  53. #define LOWYDOT PLOWY*DPI
  54. #define HIXDOT  PHIGHX*DPI
  55. #define HIYDOT  PHIGHY*DPI
  56. #define HCLIPADJ HCLIP*DPI
  57.  
  58. /* Define the record types present in a Slide file */
  59.  
  60. #define MINVEC          0x0000        /* Plain vector - minimum value */
  61. #define MAXVEC          0x7F00        /* Plain vector - maximum value */
  62. #define OFFSETVEC       0xFB00        /* Offset from last vector */
  63. #define ENDOFSLD        0XFC00        /* End of Slide File marker */
  64. #define SOLIDFILL       0xFD00        /* Solid Fill */
  65. #define COMMONEND       0xFE00        /* Common endpoint with last vector */
  66. #define NEWCOLOR        0xFF00        /* New color begins */
  67.  
  68. /* Declare global variables */
  69.  
  70. unsigned short lowx = 0, lowy = 0 ;   /* Drawing limits */
  71. unsigned short highx= 0, highy = 0;   /* Ditto */
  72. unsigned short plastx = 0, plasty = 0;/* PostScript's last X & Y point */
  73. FILE *in = NULL, *out = NULL;         /* Input and output file pointers */
  74. char *exfun = /*MSG0*/"C:SLD2PS";     /* AutoCAD Command name */
  75.  
  76. /* Declare global flags */
  77.  
  78. char lptok = 0;                       /* Last point OK flag */
  79. char scrout = 0;                      /* = 1 if printing the screen */
  80. char colorout = 0;                    /* = 1 if color */
  81. char epsout = 0;                      /* = 1 if encapsulated */
  82. char boxout = 0;                      /* = 1 if drawing a plotbox */
  83. char rotate = 0;                      /* = 1 if landscape */
  84. char oldformat = 0;                   /* = 1 if pre-R9 style slide file */
  85. char backwards = 0;                   /* = 1 if file needs byte swapping */
  86. char usrcanc = 0;                     /* = 0 if user cancels the function */
  87. char intel = 0 ;                      /* = 1 if running on an Intel chip */
  88.  
  89. /* Forward Function declarations */
  90.  
  91. void main _((int argc, char **argv));         /* ADS link */
  92. void clearopts _((void));             /* Clear old options */
  93. int funcload _((void));               /* ADS function load routine */
  94. int funcunload _((void));             /* ADS function unload routine */
  95. int dofun _((void));                  /* ADS function dispatcher */
  96. int sld2ps _((void));                 /* Main routine */
  97. void endplot _((void));               /* Closes PostScript file */
  98. void drawbox _((void));               /* Draws a border */
  99.  
  100. #ifdef __ZTC__
  101. void initplot _((double pscfx, double pscfy));
  102. void swap_pen _((int pen));
  103. int drawvec _((int x1, int y1, int x2, int y2));
  104. int contvec _((int x2, int y2));
  105. void raisepen _((int curx, int cury));
  106. int sfill _((int sx2, int sy2, int fillstat));
  107. short fixchar _((int ch));
  108. #else  /* __ZTC__ */
  109. #if defined(__WATCOMC__) || (defined(TURBOC) && defined(RMADS))
  110. void initplot _((double pscfx, double pscfy));
  111. #else
  112. void initplot _((float pscfx, float pscfy));         /* Opens PostScript file */
  113. #endif
  114. void swap_pen _((short pen));         /* Handles color output */
  115. int drawvec _((ushort x1, ushort y1, ushort x2, ushort y2));
  116. int contvec _((ushort x2, ushort y2));
  117. void raisepen _((ushort curx, ushort cury));
  118. int sfill _((short sx2, short sy2, char fillstat));  /* Handles solid fill */
  119. short fixchar _((unsigned char ch));  /* Simple read routine to help out */
  120. #endif  /* __ZTC__ */
  121.  
  122. short fetch2bytes _((void));          /* Simple read routine to help out */
  123. short fetchoffset _((void));          /* Ditto */
  124. int formshort _((unsigned char *ptr));  /* The short of portability */
  125. int formlong _((unsigned char *ptr));   /* The long of portability */
  126. int testlong _((unsigned char *ptr));   /* Tests CPU storage of long integers */
  127. int printscr _((void));               /* Creates a temporary slide file */
  128. int getopt _((char *question));       /* Asks questions, sets global flags */
  129.  
  130.  
  131. void main(argc,argv)
  132.   int argc;
  133.   char *argv[];
  134. {
  135.  
  136.     /* Local declarations */
  137.  
  138.     short scode = RSRSLT;             /* normal result code */
  139.     int stat;
  140.  
  141.     /* Actual Code begins here */
  142.  
  143.     ads_init(argc, argv);
  144.  
  145.     for ( ;; ) {
  146.  
  147.         if ((stat = ads_link(scode)) < 0)  {
  148.             ads_printf(/*MSG1*/"Ñ╤ ads_link() ╢╟ª^¬║ñú¿╬¬¼║A = %d\n", stat);
  149.             fflush(stdout);
  150.             ads_exit(1);
  151.         }
  152.  
  153.         scode = RSRSLT;               /* default return code */
  154.  
  155.         switch (stat)  {
  156.  
  157.         case RQXLOAD:
  158.             scode = funcload() ? -RSRSLT : -RSERR;
  159.             continue;
  160.  
  161.         case RQXUNLD:                 /* Unloading */
  162.             scode = (funcunload() ? RSRSLT : RSERR);
  163.             break;
  164.  
  165.         case RQSUBR:
  166.             dofun();
  167.             ads_retvoid();            /* Exit queitly */
  168.             break;
  169.  
  170.         default:
  171.             break;
  172.  
  173.         }                             /* End switch */
  174.  
  175.     }                                 /* End for */
  176.  
  177. }                                     /* End main */
  178.  
  179. /* FUNCLOAD - Load external functions  */
  180.  
  181. int funcload()
  182. {
  183.     if (ads_defun(exfun,0) != RTNORM)
  184.         return 0;
  185.     else
  186.         return 1;
  187. }
  188.  
  189. /* FUNCUNLOAD - Unload external functions */
  190.  
  191. int funcunload()
  192. {
  193.     ads_undef(exfun,0);
  194.  
  195.     return 1;
  196. }
  197.  
  198. /* DOFUN - Process the RQSUBR call from AutoCAD */
  199.  
  200. int dofun()
  201. {
  202.     int val;
  203.  
  204.     if ( (val = ads_getfuncode()) < 0)
  205.         return 0;
  206.     else {
  207.         switch (val) {
  208.  
  209.         case 0:
  210.             return sld2ps();
  211.  
  212.         default:
  213.             break;
  214.         }
  215.  
  216.     }
  217.  
  218.     return 1;
  219.  
  220. }
  221.  
  222. /* SLD2PS - Reads and process the slide file */
  223.  
  224. int sld2ps()
  225. {
  226.  
  227.     /* Slide file header fields */
  228.  
  229.     char id[17];                      /* Slide file banner */
  230.     char typeind, levlind;            /* Header information */
  231.     short hfill, testno;              /* Hardware fill & test number */
  232.     long aspect;                      /* Aspect Ratio encoded as long */
  233.  
  234.     /* Alternate fields for OLD format slide files */
  235.  
  236.     double oldasp;                    /* Old format aspect ratio */
  237.     short oldhfill;                   /* Old hardware fill */
  238.     char fillbyte;                    /* Padding around old format file */
  239.  
  240.     /* Local variables */
  241.  
  242.     static char sldfile[132], plotfile[132];  /* Filename strings */
  243.  
  244.     float gscf;                       /* PostScript Scale Factor */
  245.     float xscf, yscf, scly;           /* X, Y & Scaled Y Scale factors */
  246.  
  247.     unsigned short fromx, fromy, tox, toy;    /* Vector co-ordinates */
  248.     unsigned short lastx = 0, lasty = 0;      /* Last point saved */
  249.     short sfx, sfy  = 0;              /* Running Solid fill co-ords */
  250.  
  251.     unsigned short rtype = 0x00;      /* Slide file record type flag */
  252.     short color = 0x07;               /* Initialize color to white or black */
  253.     short offset;                     /* +/- 127 Offset buffer */
  254.  
  255.     char fillon = 0;                  /* Fill in progress ? */
  256.     char firstpass = 0;               /* First time through ? */
  257.  
  258.     char lobyte;                      /* Low byte value */
  259.     unsigned short cword;             /* 2 byte integer from "    */
  260.  
  261.     register unsigned short j = 0;    /* Processing vector counter */
  262.  
  263.     /* Begin */
  264.  
  265.     clearopts ();                     /* Clear previous flags */
  266.  
  267.     scrout = getopt(/*MSG2*/"\n╣w│╞▒Níu┼πÑ▄╡e¡▒ív├╕ÑX ? <No>: ");
  268.  
  269.     if (usrcanc)                      /* We're aborting */
  270.         return 0 ;
  271.  
  272.     if (scrout) {
  273.         if (!printscr()) {
  274.             ads_fail(/*MSG3*/"íuñ█┐Oñ∙ív╝╚ªs└╔½╪Ñ▀┐∙╗~íC");
  275.             return 0;
  276.         }
  277.         strcpy(sldfile,/*MSG0*/"sld2ps");
  278.     }
  279.     else {
  280.         ads_getstring (0,/*MSG4*/"\n┐ΘñJíuñ█┐Oñ∙ív└╔ªW¿╙╢iªµ: ",
  281.                        sldfile);
  282.     }
  283.  
  284.     if (sldfile[0] == 0) {
  285.         ads_fail (/*MSG5*/"Ñ▓╢╖½ⁿ⌐wíuñ█┐Oñ∙ív└╔ªWíC\n");
  286.         return 0;
  287.     }
  288.  
  289.     strcpy (plotfile, sldfile);
  290.     strcat (sldfile,/*MSG0*/".sld");
  291.  
  292.     if ((in = fopen (sldfile,/*MSG0*/"rb")) == NULL)  {
  293.         ads_fail (/*MSG6*/"íuñ█┐Oñ∙ív└╔«╫íu╢}▒╥ív┐∙╗~íC\n");
  294.         return 0;
  295.     }
  296.  
  297.     /* Get answers to some major questions about life */
  298.  
  299.     colorout = getopt
  300.                (/*MSG7*/"\n¼Oº_¡níu▒mªΓ PostScriptív┬αÑX ? <No>: ");
  301.     if (usrcanc) return 0 ;
  302.  
  303.     epsout = getopt
  304.              (/*MSG8*/"\n¼Oº_¡níuEncapsulated PostScriptív┬αÑX ? <No>: ");
  305.     if (usrcanc) return 0 ;
  306.  
  307.     rotate = getopt
  308.              (/*MSG9*/"\n¼Oº_¡n▒N┐ΘÑXñ⌐ÑHíu▒█┬αív? <No>: ");
  309.     if (usrcanc) return 0 ;
  310.  
  311.     boxout = getopt
  312.              (/*MSG10*/"\nÑX╣╧¼Oº_Ñ[ñWíu├Σ«╪ív ? <No>: ");
  313.     if (usrcanc) return 0;
  314.  
  315.     if (epsout == 1)
  316.         strcat (plotfile,/*MSG0*/".eps");
  317.     else
  318.         strcat (plotfile,/*MSG0*/".ps" );
  319.  
  320.     ads_printf (/*MSG11*/"\n┬αñJíuñ█┐Oñ∙└╔«╫íví╨ %s, ┬αÑXíuPostScript └╔«╫íví╨ %s íC\n",
  321.                 sldfile, plotfile);
  322.  
  323.     if (colorout == 1)
  324.         ads_printf (/*MSG12*/"\nÑ■▒m: RGB ┬αÑXíC");
  325.     else
  326.         ads_printf (/*MSG13*/"\n░▓⌐wÑHíu│µªΓív┬αÑXíC");
  327.  
  328.     if (epsout == 1)
  329.         ads_printf (/*MSG14*/"\n▓úÑ═íuEncapsulated PostScriptív└╔íC");
  330.  
  331.     if (rotate == 1)
  332.         ads_printf (/*MSG15*/"\n▒NÑX╣╧▒█┬α¼░íulandscapeívñΦª∞íC");
  333.  
  334.     if ((out = fopen(plotfile,/*MSG0*/"wb")) == NULL) {
  335.         ads_fail (/*MSG16*/"íuÑX╣╧ív║╧║╨└╔╢}▒╥┐∙╗~íC\n");
  336.         return 0;
  337.     }
  338.  
  339.     /* Read in from slide file: Assume Release 9 Slide file format */
  340.  
  341.     fread (id,17,1,in);
  342.     fread (&typeind,sizeof(typeind),1,in);
  343.     fread (&levlind,sizeof(levlind),1,in);
  344.     fread (&highx,sizeof(highx),1,in);
  345.     fread (&highy,sizeof(highy),1,in);
  346.  
  347.     if (levlind == 1)
  348.         oldformat = 1;
  349.  
  350.     if (!oldformat) {
  351.         fread (&aspect,sizeof(aspect),1,in);
  352.         fread (&hfill,sizeof(hfill),1,in);
  353.         fread (&testno,sizeof(testno),1,in);
  354.     }
  355.     else {
  356.         fread (&oldasp,sizeof(oldasp),1,in);
  357.         fread (&oldhfill,sizeof(oldhfill),1,in);
  358.         fread (&fillbyte,sizeof(fillbyte),1,in);
  359.     }
  360.  
  361.     if ( (strncmp(id,/*MSG0*/"AutoCAD Slide", 13)) != 0) {
  362.         ads_fail (/*MSG17*/"íuñ█┐Oñ∙ív└╔«╫íu╝╨└Y (header)ívª│╗~! ⌐±▒≤íC\n");
  363.         return 0;
  364.     }
  365.  
  366.     if (testno != 0x1234)
  367.         backwards = 1;                /* File written in reverse byte order */
  368.  
  369.     if (!oldformat) {
  370.         formshort ((unsigned char *)&highx);
  371.         formshort ((unsigned char *)&highy);
  372.         formshort ((unsigned char *)&hfill);
  373.         formlong  ((unsigned char *)&aspect);
  374.     }
  375.  
  376.  
  377.     if (oldformat) {
  378.         ads_printf (/*MSG18*/"\n\níuñ█┐Oñ∙ív└╔«╫½YÑH┬┬«µªí½╪Ñ▀íC");
  379.         ads_printf (/*MSG19*/"\nñúÑi»α╢iªµíubyte-orderingív└╦«╓íC");
  380.     }
  381.     else {
  382.         ads_printf (/*MSG20*/"\n\níuñ█┐Oñ∙ív└╔«╫½YÑHíuR9 «µªíív½╪Ñ▀íC");
  383.  
  384.         if (backwards)
  385.             ads_printf (/*MSG21*/"\n┼¬¿·└╔«╫«╔íu╛▄┤½ byteívíC");
  386.         else
  387.             ads_printf (/*MSG22*/"\nñú╗▌╢iªµíubyte-╛▄┤½ívíC");
  388.     }
  389.  
  390.     ads_printf (/*MSG23*/"\níuñ█┐Oñ∙ív└╔«╫¬║íu╕╤¬R½╫ív¼░íu%u x %uívÑ·┬IíC",
  391.                 highx + 1, highy + 1);
  392.  
  393.     ads_printf ("\n\n");
  394.  
  395.     /* Calculate X & Y scale factors as: Paper size/Highest X or Y pixel */
  396.     /* If plots are rotated, the X & Y PAPER directions are reversed */
  397.  
  398.     if (rotate == 1)  {
  399.         xscf =  (HIYDOT - LOWYDOT - 2*HCLIPADJ)/highx;
  400.         yscf =  (HIXDOT - LOWXDOT - 2*HCLIPADJ)/highy;
  401.     }
  402.     else {
  403.         xscf =  (HIXDOT - LOWXDOT - 2*HCLIPADJ)/highx;
  404.         yscf =  (HIYDOT - LOWYDOT - 2*HCLIPADJ)/highy;
  405.     }
  406.  
  407.     gscf =  (xscf < yscf) ? xscf : yscf;  /* Global scale is higher of 2 */
  408.  
  409.     if (!oldformat)
  410.         scly =  aspect/1e7*highy;     /* Scale Y using aspect ratio */
  411.     else
  412.         scly = oldasp*highy;
  413.  
  414.     yscf =  gscf*highx/scly;          /* Scale the Y factor by global factor */
  415.  
  416.     /* Start plot */
  417.  
  418.     initplot (xscf, yscf);
  419.  
  420.     if (boxout == 1)
  421.         drawbox();
  422.  
  423.     /* Start parsing data */
  424.  
  425.     while ( (cword = (ushort)fetch2bytes() ) != ENDOFSLD) {
  426.  
  427.         lobyte = (cword & 0x00FF);
  428.         rtype = (cword & 0xFF00);     /* High order byte marks record type */
  429.  
  430.         switch (rtype) {
  431.  
  432.         case OFFSETVEC:
  433.  
  434.             offset = fixchar((uchar)lobyte);
  435.             fromx = lastx + offset;
  436.  
  437.             offset = fetchoffset();
  438.             fromy = lasty + offset;
  439.  
  440.             offset = fetchoffset();
  441.             tox = lastx + offset;
  442.  
  443.             offset = fetchoffset();
  444.             toy = lasty + offset;
  445.  
  446.             /* Output vector */
  447.  
  448.             drawvec (fromx, fromy, tox, toy);
  449.  
  450.             /* Save last point */
  451.  
  452.             lastx = fromx;
  453.             lasty = fromy;
  454.  
  455.             break;
  456.  
  457.         case ENDOFSLD:
  458.             /* Nothing to do */
  459.             break;
  460.  
  461.         case SOLIDFILL:
  462.  
  463.             sfx = fetch2bytes();
  464.             sfy = fetch2bytes();
  465.  
  466.             /* Toggle fill on/off if negative Y value */
  467.  
  468.             if (sfy < 0)
  469.                 fillon = (fillon == 0) ? 1 : 0;
  470.  
  471.             /* Output point to fill routine */
  472.  
  473.             sfill (sfx, sfy, fillon);
  474.  
  475.             /* Last point is no longer OK ! */
  476.  
  477.             lptok = 1;
  478.  
  479.             break;
  480.  
  481.         case COMMONEND:
  482.  
  483.             fromx = lastx;
  484.             fromy = lasty;
  485.  
  486.             offset = fixchar(lobyte);
  487.             tox = lastx + offset;
  488.  
  489.             offset = fetchoffset();
  490.             toy = lasty + offset;
  491.  
  492.             /* Output vector */
  493.  
  494.             drawvec (fromx, fromy, tox, toy);
  495.  
  496.             /* Save point */
  497.  
  498.             lastx = tox;
  499.             lasty = toy;
  500.  
  501.             break;
  502.  
  503.         case NEWCOLOR:
  504.  
  505.             color = lobyte;
  506.  
  507.             if (colorout == 1) {
  508.                 if (firstpass != 0)
  509.                     raisepen (lastx,lasty);
  510.                 swap_pen(color);
  511.                 firstpass = 1;
  512.             }
  513.  
  514.             break;
  515.  
  516.         default:
  517.             /* Should be vector def; else oops ! */
  518.  
  519.             if (rtype <= MAXVEC)  {
  520.  
  521.                 fromx = cword;
  522.                 fromy = fetch2bytes();
  523.                 tox   = fetch2bytes();
  524.                 toy   = fetch2bytes();
  525.  
  526.                 drawvec (fromx, fromy, tox, toy);
  527.  
  528.                 lastx = fromx;
  529.                 lasty = fromy;
  530.             }
  531.             else
  532.                 ads_printf(/*MSG24*/"\níuñ█┐Oñ∙ív└╔«╫ññª│ñú⌐·¬║íu╜X %xív! ", rtype);
  533.  
  534.             break;
  535.  
  536.  
  537.         }                             /* End switch */
  538.  
  539.         j++;
  540.  
  541.  
  542.         if (j % 32 == 0)  {
  543.             ads_printf(/*MSG25*/"\r│B▓zíuªV╢q %uív", j );
  544.             if ( ads_usrbrk() ) {
  545.                 ads_fail(/*MSG30*/"Ñ\134»α¿·«°íC") ;
  546.                 endplot () ;
  547.                 return 0 ;
  548.             }
  549.         }
  550.  
  551.         if (j % 150 == 0 && fillon == 0 )
  552.             raisepen (lastx, lasty);
  553.  
  554.  
  555.     }                                 /* End while */
  556.  
  557.     endplot ();
  558.     ads_printf (/*MSG26*/"\n\nº╣ª¿ ! ┐ΘÑXíu%sív└╔«╫!\n", plotfile);
  559.  
  560.     return 1;
  561. }
  562.  
  563. /* INITPLOT - Opens and constructs the Header of the PostScript file */
  564.  
  565. void initplot(pscfx, pscfy)
  566.   float pscfx;
  567.   float pscfy;
  568. {
  569.     if (epsout == 1) {                /* Special header for Encapsulated file */
  570.         fprintf (out,/*MSG0*/"%%!PS-Adobe-2.0 EPSF-1.2\n");
  571.         fprintf (out,/*MSG0*/"%%%%Bounding Box: %u %u %u %u\n",
  572.                  lowx, lowy, highx, highy) ;
  573.         fprintf (out,/*MSG0*/"%%%%Creator: File from SLD2PS\n");
  574.         fprintf (out,/*MSG0*/"%%%%EndComments\n");
  575.     }
  576.     else {
  577.         fprintf (out,/*MSG0*/"%%!PS-Adobe-1.0\n");
  578.         fprintf (out,/*MSG0*/"%%%%Creator: File from SLD2PS\n");
  579.         fprintf (out,/*MSG0*/"%%%%EndComments\n");
  580.     }
  581.  
  582.     fprintf (out,/*MSG0*/"/m {moveto} def\n");
  583.     fprintf (out,/*MSG0*/"/l {lineto} def\n");
  584.     fprintf (out,/*MSG0*/"/s {stroke} def\n");
  585.     fprintf (out,/*MSG0*/"/f {fill} def\n");
  586.     fprintf (out,/*MSG0*/"/n {newpath} def\n");
  587.     fprintf (out,/*MSG0*/"1 setlinejoin\n");
  588.     fprintf (out,/*MSG0*/"0.5 setlinewidth\n");
  589.     fprintf (out,/*MSG0*/"1 setlinecap\n");
  590.  
  591.     if (rotate == 1)  {               /* Reset origin & re-align co-ords */
  592.         fprintf (out,/*MSG0*/"90 rotate\n");
  593.         fprintf (out,/*MSG0*/"0 %f translate\n", -1.0*DPI*PSIZEX);
  594.         fprintf (out,/*MSG0*/"%f %f translate\n", LOWXDOT, LOWYDOT);
  595.     }
  596.     else
  597.         fprintf (out,/*MSG0*/"%f %f translate\n", LOWXDOT, LOWYDOT);
  598.  
  599.     fprintf (out,/*MSG0*/"%5.3f %5.3f scale\n", pscfx, pscfy);
  600.     fprintf (out,/*MSG0*/"n\n");
  601.  
  602.     return;
  603. }
  604.  
  605. /* ENDPLOT - Completes PostScript file */
  606.  
  607. void endplot()
  608. {
  609.     fprintf (out,/*MSG0*/"s\n");
  610.  
  611.     if (epsout != 1)
  612.         fprintf (out,/*MSG0*/"%%%%Bounding Box %u %u %u %u\n",
  613.                  lowx, lowy, highx, highy);
  614.  
  615.     fprintf (out,/*MSG0*/"showpage\n");
  616.  
  617.     fclose (in) ;
  618.     fclose (out) ;
  619.  
  620.     return;
  621. }
  622.  
  623. /* DRAWBOX - Draws a nice rectangular border around plot */
  624.  
  625. void drawbox()
  626. {
  627.     fprintf (out,/*MSG0*/"%u %u m\n", lowx, lowy);
  628.     fprintf (out,/*MSG0*/"%u %u l\n", highx, lowy);
  629.     fprintf (out,/*MSG0*/"%u %u l\n", highx, highy);
  630.     fprintf (out,/*MSG0*/"%u %u l\n", lowx, highy);
  631.     fprintf (out,/*MSG0*/"%u %u l\n", lowx, lowy);
  632.     fprintf (out,/*MSG0*/"s\n");
  633.     return;
  634. }
  635.  
  636. /* SWAP_PEN - Outputs PostScript RGB triple from AutoCAD HSV color */
  637. /* Adapted from Foley and Van Dam and some ADI documentation */
  638.  
  639. void swap_pen(pen)
  640.   short pen;
  641. {
  642.     unsigned char acadclr;                      /* AutoCAD color number */
  643.     float red = 0.0, green = 0.0, blue = 0.0;   /* RGB triplet values */
  644.     float hue, sat, val;                        /* HSV components */
  645.     static float bright[5] = {
  646.             1.0, 0.65, 0.5, 0.3, 0.15       };
  647.     int i, vs;
  648.     float f;
  649.     float p,q,t;
  650.     int visible = 0;                  /* Force white visibility is off */
  651.  
  652.  
  653.     /* Begin */
  654.  
  655.     acadclr = pen ;
  656.  
  657.     if (acadclr >= 250 && acadclr <= 255)  {
  658.         red = 1;
  659.         green = 0.5;                  /* These RGB choices are arbitrary */
  660.         blue = 0.35;
  661.         visible = 1;                  /* Make sure it comes out ; force black */
  662.     }
  663.     else {
  664.  
  665.         switch (acadclr) {
  666.  
  667.         case 1 :                      /* Red */
  668.             red = 1;
  669.             blue = 0;
  670.             green = 0;
  671.             break;
  672.  
  673.         case 2 :                      /* Yellow */
  674.             red = 1;
  675.             green = 1;
  676.             blue = 0;
  677.             break;
  678.  
  679.         case 3 :                      /* Green */
  680.             red = 0;
  681.             green = 1;
  682.             blue = 0;
  683.             break;
  684.  
  685.         case 4 :                      /* Cyan */
  686.             red = 0;
  687.             green = 1;
  688.             blue = 1;
  689.             break;
  690.  
  691.         case 5:                       /* Blue */
  692.             red = 0;
  693.             green = 0;
  694.             blue = 1;
  695.             break;
  696.  
  697.         case 6:                       /* Magenta */
  698.             red = 1;
  699.             green = 0;
  700.             blue = 1;
  701.             break;
  702.  
  703.         case 0 :                      /* Just in case someone screws up */
  704.  
  705.         case 7 :                      /* White */
  706.         case 8 :
  707.         case 9 :
  708.             red = 1;
  709.             green = 1;
  710.             blue = 1;
  711.             visible = 1;              /* Force black output on paper */
  712.             break;
  713.  
  714.         default :                     /* For colors between 10 & 250 */
  715.  
  716.             hue =  (acadclr - 10) / 10.0; /* 240 maps to 0 - 6 */
  717.  
  718.             if (hue >= 24)
  719.                 hue -= 24;
  720.             hue = hue / 4.0;
  721.  
  722.             vs =   acadclr % 10;      /* Encoded Saturation and Value */
  723.  
  724.             val =  bright[vs >> 1];   /* this should be 0,2,4,6,8 */
  725.             sat =  vs & 1 ? 0.5 : 1.0;    /* if odd, set it to 0.5, else 1 */
  726.  
  727.             i = (int)hue;
  728.             f = hue - i;              /* Fractional part of Hue */
  729.  
  730.             p = val*(1 - sat);
  731.             q = val*(1 - (sat*f));
  732.             t = val*(1 - (sat*(1 - f)));
  733.  
  734.             switch (i)        {
  735.  
  736.             case 0 :
  737.                 red = val;
  738.                 green = t;
  739.                 blue = p;
  740.                 break;
  741.  
  742.             case 1 :
  743.                 red = q;
  744.                 green = val;
  745.                 blue = p;
  746.                 break;
  747.  
  748.             case 2 :
  749.                 red = p;
  750.                 green = val;
  751.                 blue = t;
  752.                 break;
  753.  
  754.             case 3 :
  755.                 red = p;
  756.                 green = q;
  757.                 blue = val;
  758.                 break;
  759.  
  760.             case 4 :
  761.                 red = t;
  762.                 green = p;
  763.                 blue = val;
  764.                 break;
  765.  
  766.             case 5 :
  767.                 red = val;
  768.                 green = p;
  769.                 blue = q;
  770.                 break;
  771.  
  772.             default :
  773.                 ads_printf (/*MSG27*/"ñú⌐·¬║íu├CªΓ╜Xív: %d %f %f %f %f\n",
  774.                             acadclr, hue,sat, val);
  775.  
  776.             }                         /* Switch (i) */
  777.  
  778.         }                             /* Switch (acadclr) */
  779.  
  780.     }                                 /* Else (acadclr < 250) */
  781.  
  782.     if (visible == 1)
  783.         fprintf (out,/*MSG0*/"0 0 0 setrgbcolor\n");    /* Pure black ! */
  784.     else
  785.         fprintf (out,/*MSG0*/"%f %f %f setrgbcolor\n", red, green, blue);
  786.  
  787.     return;
  788. }
  789.  
  790. /* DRAWVEC - Outputs PostScript vector to file */
  791.  
  792. int drawvec(x1, y1, x2, y2)
  793.   unsigned short x1, y1, x2, y2;
  794. {
  795.  
  796.     /*   See if from point is the same as the last saved point
  797.          If so, continue the vector, rather than output a full one
  798.          Note that PostScript's "last point" is the exact opposite of
  799.          the slide file's last point. PostScript uses the "to" point
  800.          Also avoid continuing a vector if lastpoint is invalid following
  801.          a fill.
  802.     */
  803.  
  804.     if (x1 == plastx && y1 == plasty && lptok == 0)
  805.         contvec (x2, y2);
  806.     else {
  807.         fprintf (out,/*MSG0*/"%u %u m\n", x1, y1);
  808.         fprintf (out,/*MSG0*/"%u %u l\n", x2, y2);
  809.     }
  810.  
  811.     plastx = x2;
  812.     plasty = y2;
  813.  
  814.     lptok = 0;
  815.  
  816.     return 1;
  817. }
  818.  
  819. /* CONTVEC - Continues last vector */
  820.  
  821. int contvec(x2, y2)
  822.   unsigned short x2, y2;
  823. {
  824.     fprintf (out,/*MSG0*/"%u %u l\n", x2, y2);
  825.  
  826.     return 1;
  827. }
  828.  
  829. /* RAISEPEN - Strokes current path when PostScript path has reached max points */
  830.  
  831. void raisepen(curx, cury)
  832.   unsigned short curx, cury;
  833. {
  834.     fprintf (out,/*MSG0*/"s\n");
  835.     fprintf (out,/*MSG0*/"%u %u m\n", curx, cury);
  836.  
  837.     lptok = 1;                        /* Warn vector drawing function */
  838.  
  839.     return;
  840. }
  841.  
  842. /* SFILL - Generates Solid Fill Polygon */
  843.  
  844. int sfill(sx2, sy2, fillstat)
  845.   short sx2, sy2;                     /* Fill polygon co-ordinates */
  846.   char fillstat;                      /* Is fill beginning or ending ? */
  847. {
  848.     static int call;
  849.  
  850.     if (sy2 < 0 && fillstat == 1)
  851.         call = 1;                     /* Start of fill, nothing to do */
  852.     else
  853.     if (sy2 > 0) {
  854.         if (call == 1) {              /* First fill point. End current path
  855.                                          and move to start point */
  856.             fprintf (out,/*MSG0*/"s\n");
  857.             fprintf (out,/*MSG0*/"%d %d m\n", sx2, sy2);
  858.             call++;
  859.         }                             /* Output fill polygon point */
  860.         else
  861.             fprintf (out,/*MSG0*/"%d %d l\n", sx2, sy2);
  862.     }
  863.  
  864.     if (sy2 < 0 && fillstat == 0) {   /* End of fill */
  865.         call = 0;
  866.         fprintf (out,/*MSG0*/"f\n");
  867.     }
  868.  
  869.     return 1;
  870.  
  871. }
  872.  
  873. /* FETCH2BYTES - Read a 2 byte integer in a portable fashion */
  874.  
  875. short fetch2bytes()
  876. {
  877.     short wd = 0 ;
  878.  
  879.     fread (&wd, sizeof(wd), 1, in) ;
  880.  
  881.     if (!oldformat) {
  882.         if (backwards)
  883.             wd = ((wd >> 8) & 0xFF) | (wd << 8) ;
  884.     }
  885.  
  886.     return wd ;
  887. }
  888.  
  889. /* FETCHOFFSET - Fetches a 1 byte short */
  890.  
  891. short fetchoffset()
  892. {
  893.     unsigned char ch = 0;
  894.  
  895.     fread (&ch, sizeof(ch) , 1, in);
  896.  
  897.     return fixchar(ch);
  898. }
  899.  
  900. /* FIXCHAR - Converts a char to a short, hammers in sign bit */
  901.  
  902. short fixchar(ch)
  903.   unsigned char ch;
  904. {
  905.     return ( (short) ((ch & 0x80) ? ch | ~0xFF : ch));
  906. }
  907.  
  908. /* FORMSHORT - Swaps bytes of a short depending on machine type */
  909.  
  910. int formshort(ptr)
  911.   unsigned char *ptr;                 /* Pointer to data array */
  912. {
  913.     register unsigned char swap;
  914.  
  915.     if (backwards) {
  916.         swap   = ptr[0];
  917.         ptr[0] = ptr[1];
  918.         ptr[1] = swap;                /* Swap those bytes ! */
  919.     }
  920.  
  921.     return 1;
  922. }
  923.  
  924. /* FORMLONG - Form a 4 byte long integer */
  925.  
  926. int formlong(ptr)
  927.   unsigned char *ptr;                 /* Pointer to data array */
  928. {
  929.     unsigned long testval = 1L;       /* Test value */
  930.     register unsigned char swap;
  931.  
  932.     testlong ((unsigned char *)&testval);      /* Test to check CPU type */
  933.  
  934.     if (!intel) {
  935.         swap   = ptr[0];
  936.         ptr[0] = ptr[3];
  937.         ptr[3] = swap;
  938.         swap   = ptr[1];
  939.         ptr[1] = ptr[2];
  940.         ptr[2] = swap;
  941.     }                                 /* AutoCAD always writes longs with LSB */
  942.                                       /* first, so Intel CPUs don't need help */
  943.  
  944.     return 1;
  945. }
  946.  
  947. /* TESTLONG - Checks to see if the CPU stores longs with LSB first or HSB first */
  948.  
  949. int testlong(ptr)
  950.   unsigned char *ptr;
  951. {
  952.     char lsb = 0;
  953.  
  954.     lsb = ptr[0];                     /* Get first byte */
  955.  
  956.     if (lsb == 1)
  957.         intel = 1;                    /* Intel style CPUs store LSB first */
  958.  
  959.     return 1 ;
  960.  
  961. }
  962.  
  963. /* PRINTSCR - Creates a temporary slide file of the current display */
  964.  
  965. int printscr()
  966. {
  967.     ads_printf (/*MSG28*/"\n½╪Ñ▀íuñ█┐Oñ∙ív╝╚ªs└╔ í╨ SLD2PS.SLD\n");
  968.  
  969.     if ( (ads_command (RTSTR,/*MSG29*/"MSLIDE", RTSTR,/*MSG0*/"sld2ps",
  970.                        RTNONE) ) < 0)
  971.         return 0;
  972.     else
  973.         return 1;
  974. }
  975.  
  976. /* GETOPT - Gets a simple yes or no from the user, to set a global flag */
  977.  
  978. int getopt(question)
  979.   char *question;
  980. {
  981.     static char opt, optstr[132];
  982.  
  983.     opt = /*MSG0*/'n';                /* Set default option */
  984.  
  985.     if ( (ads_getstring (0,question,optstr)) == RTCAN)  {
  986.         usrcanc = 1 ;
  987.         ads_fail (/*MSG31*/"Ñ\134»α¿·«°íC") ;
  988.         return 0 ;
  989.     }
  990.  
  991.     opt = optstr[0];
  992.  
  993.     if (toupper(opt) == /*MSG0*/'Y')
  994.         return 1;
  995.     else
  996.         return 0;
  997. }
  998.  
  999. /* CLEAROPTS - Clears previously set flags and options from last RQSUBR */
  1000. /* The application is loaded and initialized only once, but could be executed */
  1001. /* several times.  Flags not cleared would be affect the next execution */
  1002.  
  1003. void clearopts()
  1004. {
  1005.     backwards = lptok = scrout = colorout = 0;
  1006.     epsout = boxout = rotate = oldformat = 0;
  1007.     usrcanc = 0 ;
  1008.  
  1009.     return;
  1010. }
  1011.