home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / education / a / autopcb / !AutoPCB / c / PCBPRINT < prev    next >
Text File  |  1991-03-17  |  18KB  |  409 lines

  1. /*
  2. ** printed circuit board printer, Copyright (C) Randy Nevin 1989.
  3. **
  4. ** you may give this software to anyone, make as many copies as you like, and
  5. ** post it on public computer bulletin boards and file servers. you may not
  6. ** sell it or charge any fee for distribution (except for media and postage),
  7. ** remove this comment or the copyright notice from the code, or claim that
  8. ** you wrote this code or anything derived from it. you may modify the code as
  9. ** much as you want (please document clearly with comments, and maintain the
  10. ** coding style), but programs which are derived from this one are subject to
  11. ** the conditions stated here. i am providing this code so that people can
  12. ** learn from it, so if you distribute it, please include source code, not
  13. ** just executables. contact me to report bugs or suggest enhancements; i do
  14. ** not guarantee support, but i will make an effort in good faith to help you,
  15. ** and i want to act as a central clearing house for future versions. you
  16. ** should contact me before undertaking a significant development effort, to
  17. ** avoid reinventing the wheel. if you come up with an enhancement you
  18. ** consider particularly useful, i would appreciate being informed so that it
  19. ** can be incorporated in future versions. my address is: Randy Nevin,
  20. ** 1731 211th PL NE, Redmond, WA 98053. this code is available directly from
  21. ** the author; just send a floppy and a self-addressed floppy mailer with
  22. ** sufficient postage.
  23. **
  24. ** HISTORY
  25. ** (name                date            description)
  26. ** ----------------------------------------------------
  27. ** randy nevin          3/4/89          initial version
  28. ** randy nevin          3/4/89          released version 1.00
  29. */
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include "cell.h"
  35.  
  36. /*
  37. ** usage: PCBPRINT [/P] [/L] [/Rn] [/Zm] infile
  38. **
  39. ** /P indicates portrait orientation (paper is longer from top to bottom), and
  40. ** /L indicates landscape orientation (paper is longer side-to-side). only one
  41. ** of /P and /L can be present. n is the laser printer resolution (75, 100,
  42. ** 150, or 300) and m is the zoom factor (0, 1, 2, or 3 ). the defaults are:
  43. ** /P /R150 /Z1. this program creates 6 output files (H, T, B, HT, HB, and
  44. ** HTB). each of these files can be fed to a hewlett-packard laser printer to
  45. ** produce a picture of part or all of the routed printed circuit board. H
  46. ** contains commands to print only the holes and routing holes. T and B
  47. ** contain commands to print only the top-side or bottom-side traces,
  48. ** respectively. HT and HB are the same, but also include the holes, and HTB
  49. ** contains everything (holes, top-side traces, and bottom-side traces).
  50. */
  51.  
  52. #define MAXZOOM 3       /* maximum zoom number; minimum is 0 */
  53.  
  54. #define ZOOM0   3       /* 3x3 dots per cell    */
  55. #define ZOOM1   6       /* 6x6 dots per cell    */
  56. #define ZOOM2   10      /* 10x10 dots per cell  */
  57. #define ZOOM3   18      /* 18x18 dots per cell  */
  58.  
  59. static int size[MAXZOOM+1] = { ZOOM0, ZOOM1, ZOOM2, ZOOM3 };
  60.  
  61. #define H       1       /* holes                                */
  62. #define T       2       /* top-side traces                      */
  63. #define B       4       /* bottom-side traces                   */
  64. #define HT      (H+T)   /* holes and top-side traces            */
  65. #define HB      (H+B)   /* holes and bottom-side traces         */
  66. #define HTB     (H+T+B) /* holes, top- and bottom-side traces   */
  67.  
  68. static int currnt;      /* current image type (one of the six above)    */
  69. static int orient;      /* 0=portrait, 1=landscape                      */
  70. static int resol;       /* resolution (one of 75,100,150,300)           */
  71. static int zoom;        /* 0=3x3, 1=6x6, 2=10x10, 3=18x18               */
  72. static int nbytes;      /* number of bytes per image row                */
  73.  
  74. int justboard = 1; /* only need the board data structure */
  75.  
  76. /* board dimensions */
  77. extern int Nrows;
  78. extern int Ncols;
  79.  
  80. extern void InitBoard( void );
  81. extern long GetCell( int, int, int );
  82. extern void SetCell( int, int, int, long );
  83.  
  84. void main( int, char *[] );
  85. static void dofile( char *, int );
  86. static void prolog( FILE * );
  87. static void epilog( FILE * );
  88. static void doimage( FILE * );
  89. static void map( long, long, int, FILE * );
  90. static void initbit( void );
  91. static void flushbit( FILE * );
  92. static void outbit( int, FILE * );
  93.  
  94. void main ( argc, argv ) /* input routed board, output laser printer files */
  95.         int argc;
  96.         char *argv[];
  97.         {
  98.         char *self, *p;
  99.         register int r, c;
  100.         int i1, i2, i3, i4, i, j;
  101.         FILE *fp;
  102.         long x;
  103.         char oset, rset, zset;
  104.  
  105.         printf( "Copyright (C) Randy Nevin, 1989. Version 1.00\n" );
  106.         printf( "See source code for rights granted.\n\n" );
  107.         orient = 0; /* portrait mode */
  108.         resol = 150; /* 150 dots per inch */
  109.         zoom = 1; /* 6x6 cells */
  110.         oset = rset = zset = 0; /* so far, just defaults */
  111.         self = argv[0];
  112.         /* get rid of initial part of path */
  113.         if ((p = strrchr( self, '\\' )) || (p = strrchr( self, ':' )))
  114.                 self = ++p;
  115.         if (argc < 2 || argc > 5) { /* need infile and up to 4 switches */
  116.                 fprintf( stderr, "usage: %s [/P] [/L] [/Rn] [/Zm] infile\n",
  117.                         self );
  118.                 fprintf( stderr, " P = portrait orientation\n" );
  119.                 fprintf( stderr, " L = landscape orientation\n" );
  120.                 fprintf( stderr, " n = resolution (75,100,150,300)\n" );
  121.                 fprintf( stderr, " m = zoom (0,1,2,3)\n" );
  122.                 exit( -1 );
  123.                 }
  124.         for (i = 1; i < argc-1; i++) { /* process switches */
  125.                 if (*argv[i] == '/' && (*(argv[i]+1) == 'P'
  126.                         || *(argv[i]+1) == 'p') && *(argv[i]+2) == 0) {
  127.                         if (oset)
  128.                                 fprintf( stderr, "duplicate orientation %s\n",
  129.                                         argv[i] );
  130.                         else {
  131.                                 oset = 1;
  132.                                 orient = 0;
  133.                                 }
  134.                         }
  135.                 else if (*argv[i] == '/' && (*(argv[i]+1) == 'L'
  136.                         || *(argv[i]+1) == 'l') && *(argv[i]+2) == 0) {
  137.                         if (oset)
  138.                                 fprintf( stderr, "duplicate orientation %s\n",
  139.                                         argv[i] );
  140.                         else {
  141.                                 oset = 1;
  142.                                 orient = 1;
  143.                                 }
  144.                         }
  145.                 else if (*argv[i] == '/' && (*(argv[i]+1) == 'R'
  146.                         || *(argv[i]+1) == 'r')) {
  147.                         if (rset)
  148.                                 fprintf( stderr, "duplicate resolution %s\n",
  149.                                         argv[i] );
  150.                         else {
  151.                                 rset = 1;
  152.                                 resol = atoi( argv[i]+2 );
  153.                                 }
  154.                         }
  155.                 else if (*argv[i] == '/' && (*(argv[i]+1) == 'Z'
  156.                         || *(argv[i]+1) == 'z')) {
  157.                         if (zset)
  158.                                 fprintf( stderr, "duplicate zoom %s\n",
  159.                                         argv[i] );
  160.                         else {
  161.                                 zset = 1;
  162.                                 zoom = atoi( argv[i]+2 );
  163.                                 }
  164.                         }
  165.                 else
  166.                         fprintf( stderr, "unknown option %s\n", argv[i] );
  167.                 }
  168.         if (!(fp = fopen( argv[argc-1], "rb" ))) {
  169.                 fprintf( stderr, "can't open %s\n", argv[argc-1] );
  170.                 exit( -1 );
  171.                 }
  172.         /* fetch the board dimensions */
  173.         if ((i = getc( fp )) == EOF || (j = getc( fp )) == EOF) {
  174.                 fprintf( stderr, "premature eof\n" );
  175.                 exit( -1 );
  176.                 }
  177.         Nrows = (i & 0xFF) | ((j << 8) & 0xFF00);
  178.         if ((i = getc( fp )) == EOF || (j = getc( fp )) == EOF) {
  179.                 fprintf( stderr, "premature eof\n" );
  180.                 exit( -1 );
  181.                 }
  182.         Ncols = (i & 0xFF) | ((j << 8) & 0xFF00);
  183.         InitBoard(); /* allocate memory for data structures */
  184.         for (r = 0; r < Nrows; r++) { /* read in the board, row by column */
  185.                 for (c = 0; c < Ncols; c++) {
  186.                         /* first do top-side */
  187.                         if ((i1 = getc( fp )) == EOF
  188.                                 || (i2 = getc( fp )) == EOF
  189.                                 || (i3 = getc( fp )) == EOF
  190.                                 || (i4 = getc( fp )) == EOF) {
  191.                                 fprintf( stderr, "premature eof\n" );
  192.                                 exit( -1 );
  193.                                 }
  194.                         x = (long)i1 | (((long)i2) << 8)
  195.                                 | (((long)i3) << 16) | (((long)i4) << 24);
  196.                         SetCell( r, c, TOP, x );
  197.                         /* then do bottom-side */
  198.                         if ((i1 = getc( fp )) == EOF
  199.                                 || (i2 = getc( fp )) == EOF
  200.                                 || (i3 = getc( fp )) == EOF
  201.                                 || (i4 = getc( fp )) == EOF) {
  202.                                 fprintf( stderr, "premature eof\n" );
  203.                                 exit( -1 );
  204.                                 }
  205.                         x = (long)i1 | (((long)i2) << 8)
  206.                                 | (((long)i3) << 16) | (((long)i4) << 24);
  207.                         SetCell( r, c, BOTTOM, x );
  208.                         }
  209.                 }
  210.         nbytes = (Ncols * size[zoom] + 7) / 8;
  211.         dofile( "print.H",   H   );
  212.         dofile( "print.T",   T   );
  213.         dofile( "print.B",   B   );
  214.         dofile( "print.HT",  HT  );
  215.         dofile( "print.HB",  HB  );
  216.         dofile( "print.HTB", HTB );
  217.         exit( 0 );
  218.         }
  219.  
  220. static void dofile ( p, i ) /* create a board image file */
  221.         char *p;
  222.         int i;
  223.         {
  224.         FILE *fp;
  225.  
  226.         printf( "producing %s image file\n", p );
  227.         currnt = i;
  228.         if (!(fp = fopen( p, "wb" ))) {
  229.                 fprintf( stderr, "can't open %s\n", p );
  230.                 exit( -1 );
  231.                 }
  232.         prolog( fp ); /* initial laser printer commands */      
  233.         doimage( fp ); /* create the board image */
  234.         epilog( fp ); /* final laser printer commands */
  235.         if (fclose( fp )) {
  236.                 fprintf( stderr, "can't close %s\n", p );
  237.                 exit( -1 );
  238.                 }
  239.         }
  240.  
  241. static void prolog ( fp ) /* output initial laser printer commands */
  242.         register FILE *fp;
  243.         {
  244.         putc( 0x1B, fp );               /* <esc> */
  245.         putc( 'E', fp );                /* reset */
  246.         putc( 0x1B, fp );               /* <esc> */
  247.         fprintf( fp, "&l%dO", orient ); /* set image orientation */
  248.         putc( 0x1B, fp );               /* <esc> */
  249.         fprintf( fp, "&a10R" );         /* cursor to row 10 */
  250.         putc( 0x1B, fp );               /* <esc> */
  251.         fprintf( fp, "&a10C" );         /* cursor to column 10 */
  252.         putc( 0x1B, fp );               /* <esc> */
  253.         fprintf( fp, "*t%dR", resol );  /* set resolution in dots per inch */
  254.         putc( 0x1B, fp );               /* <esc> */
  255.         fprintf( fp, "*r1A" );          /* start graphics at cursor */
  256.         }
  257.  
  258. static void epilog ( fp ) /* output final laser printer commands */
  259.         register FILE *fp;
  260.         {
  261.         putc( 0x1B, fp );       /* <esc> */
  262.         fprintf( fp, "*rB" );   /* end graphics */
  263.         putc( 0x12, fp );       /* formfeed to eject paper */
  264.         putc( 0x1B, fp );       /* <esc> */
  265.         putc( 'E', fp );        /* reset */
  266.         }
  267.  
  268. static void doimage ( fp ) /* create the board image, row by column */
  269.         FILE *fp;
  270.         {
  271.         register int r, c;
  272.         int ir;
  273.         long x, y;
  274.  
  275.         for (r = Nrows-1; r >= 0; r--) { /* each row */
  276.                 for (ir = size[zoom]-1; ir >= 0; ir--) { /* each scan line */
  277.                         putc( 0x1B, fp );       /* <esc> */
  278.                         fprintf( fp, "*b%dW", nbytes );
  279.                         initbit();
  280.                         for (c = 0; c < Ncols; c++) {
  281.                                 x = GetCell( r, c, TOP );
  282.                                 y = GetCell( r, c, BOTTOM );
  283.                                 map( x, y, ir, fp );
  284.                                 }
  285.                         flushbit( fp );
  286.                         }
  287.                 }
  288.         }
  289.  
  290. struct x { /* group the bit templates for an object */
  291.         long t;                 /* the object type      */
  292.         char t0[ZOOM0][ZOOM0];  /* tiny zoom template   */
  293.         char t1[ZOOM1][ZOOM1];  /* small zoom template  */
  294.         char t2[ZOOM2][ZOOM2];  /* medium zoom template */
  295.         char t3[ZOOM3][ZOOM3];  /* large zoom template  */
  296.         };
  297.  
  298. extern struct x y1[];  /* hole templates                */
  299. extern struct x y2[];  /* hole-related templates        */
  300. extern struct x y3[];  /* non-hole-related templates    */
  301.  
  302. extern int z1;  /* number of hole types                 */
  303. extern int z2;  /* number of hole-related types         */
  304. extern int z3;  /* number of non-hole-related types     */
  305.  
  306. #define domap1(v)       { int i; \
  307.                           for (i = 0; i < z1; i++) { \
  308.                                 if (v & (y1[i].t)) { \
  309.                                         if (zoom == 0) \
  310.                                                 bit |= y1[i].t0[ir][ic]; \
  311.                                         else if (zoom == 1) \
  312.                                                 bit |= y1[i].t1[ir][ic]; \
  313.                                         else if (zoom == 2) \
  314.                                                 bit |= y1[i].t2[ir][ic]; \
  315.                                         else if (zoom == 3) \
  316.                                                 bit |= y1[i].t3[ir][ic]; \
  317.                                         } \
  318.                                 if (bit) \
  319.                                         break; \
  320.                                 } }
  321.  
  322. #define domap2(v)       { int i; \
  323.                           for (i = 0; i < z2; i++) { \
  324.                                 if (v & (y2[i].t)) { \
  325.                                         if (zoom == 0) \
  326.                                                 bit |= y2[i].t0[ir][ic]; \
  327.                                         else if (zoom == 1) \
  328.                                                 bit |= y2[i].t1[ir][ic]; \
  329.                                         else if (zoom == 2) \
  330.                                                 bit |= y2[i].t2[ir][ic]; \
  331.                                         else if (zoom == 3) \
  332.                                                 bit |= y2[i].t3[ir][ic]; \
  333.                                         } \
  334.                                 if (bit) \
  335.                                         break; \
  336.                                 } }
  337.  
  338. #define domap3(v)       { int i; \
  339.                           for (i = 0; i < z3; i++) { \
  340.                                 if (v & (y3[i].t)) { \
  341.                                         if (zoom == 0) \
  342.                                                 bit |= y3[i].t0[ir][ic]; \
  343.                                         else if (zoom == 1) \
  344.                                                 bit |= y3[i].t1[ir][ic]; \
  345.                                         else if (zoom == 2) \
  346.                                                 bit |= y3[i].t2[ir][ic]; \
  347.                                         else if (zoom == 3) \
  348.                                                 bit |= y3[i].t3[ir][ic]; \
  349.                                         } \
  350.                                 if (bit) \
  351.                                         break; \
  352.                                 } }
  353.  
  354. static void map ( v0, v1, ir, fp ) /* map a cell to the image */
  355.         long v0, v1;
  356.         int ir;
  357.         FILE *fp;
  358.         {
  359.         register int ic, bit;
  360.  
  361.         for (ic = 0; ic < size[zoom]; ic++) { /* do each scan column */
  362.                 bit = 0;
  363.                 if (v0 & HOLE) {
  364.                         if (currnt & H) /* plot holes? */
  365.                                 domap1( v0 );
  366.                         if (!bit && (currnt & T)) /* plot top-side? */
  367.                                 domap2( v0 );
  368.                         if (!bit && (currnt & B)) /* plot bottom-side? */
  369.                                 domap2( v1 );
  370.                         }
  371.                 else {
  372.                         if (v0 && (currnt & T)) /* plot top-side? */
  373.                                 domap3( v0 );
  374.                         if (!bit && v1 && (currnt & B)) /* plot bottom-side? */
  375.                                 domap3( v1 );
  376.                         }
  377.                 outbit( bit, fp );
  378.                 }
  379.         }
  380.  
  381. static int shift; /* how far to shift next bit */
  382. static char byte; /* the byte buffer */
  383.  
  384. static void initbit () { /* initialize bit output */
  385.         byte = 0;
  386.         shift = 7;
  387.         }
  388.  
  389. static void flushbit ( fp ) /* flush bit output */
  390.         FILE *fp;
  391.         {
  392.         if (shift != 7) /* buffer empty? */
  393.                 putc( byte, fp ); /* no, output partial byte */
  394.         }
  395.  
  396. static void outbit( bit, fp ) /* output a bit using byte buffering */
  397.         int bit;
  398.         FILE *fp;
  399.         {
  400.         byte |= ((char)bit << shift);
  401.         if (!shift) {
  402.                 putc( byte, fp );
  403.                 byte = 0;
  404.                 shift = 7;
  405.                 }
  406.         else
  407.                 shift--;
  408.         }
  409.