home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 286_02 / rotate.c < prev    next >
Text File  |  1989-05-25  |  7KB  |  234 lines

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <sys\types.h>
  4. #include <io.h>
  5. #include <sys\stat.h>
  6. #include <stdlib.h>
  7.  
  8. /*==============================================================*
  9.  *                                                              *
  10.  *    This is a program to rotate the characters in a font      *
  11.  *    file by 90 degree in anti-clockwise direction.            *
  12.  *                                                              *
  13.  *    Usage : rotate infilename outfilename                     *
  14.  *                                                              *
  15.  *    Input file and output file must have different name.      *
  16.  *                                                              *
  17.  *==============================================================*/
  18.  
  19. #define ERROR (-1)
  20. #define FONTID 51
  21.  
  22. struct fontspec {
  23.     unsigned char width,inkwidth,height;
  24.       signed char leftmargin;
  25.     unsigned char topline,cellheight;
  26. };
  27.  
  28. /* maximum number of characters in the font file is 256 */
  29. struct fontspec fontinfo[256], outinfo[256];
  30.  
  31. unsigned char DOTVALUE[] =
  32.     0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001
  33. };
  34.  
  35. /* maximum size of a character is 4096 bytes. approx 180 by 180 */
  36. unsigned char bufi[4096], bufo[4096];
  37. int infn,outfn;
  38.  
  39. main(argc,argv)
  40. int argc;
  41. char *argv[];
  42. {
  43.     int loop,count;
  44.  
  45.     if (argc != 3) {
  46.         fprintf(stderr,"usage: rotate infilename outfilename\n");
  47.         exit(1);
  48.     }
  49.     if ((infn=open(argv[1],O_RDONLY | O_BINARY)) == ERROR) {
  50.         fprintf(stderr,"\nrotate: Cannot open input file\n");
  51.         exit(1);
  52.         }
  53.     if ((outfn=open(argv[2],O_CREAT | O_BINARY | O_TRUNC |O_WRONLY,
  54.                           S_IREAD | S_IWRITE))
  55.            == ERROR) {
  56.         fprintf(stderr,"\nrotate: Cannot create output\n");
  57.         exit(1);
  58.         }
  59.     if ((count=read(infn,bufi,256)) <= 0) {
  60. errorexit:
  61.         fprintf(stderr,"Bad Font File\n");
  62.     }
  63.     /* first byte has to be equal to FONTID */
  64.     if (bufi[0]!=FONTID) goto errorexit;
  65.  
  66.     /* Look for the end of comment string */
  67.     for (loop=1; loop<=count; loop++) {
  68.         if (bufi[loop]==0) goto cont;
  69.     }
  70.     goto errorexit;
  71. cont:
  72.     loop++;
  73.     /* seek to begining of font information */
  74.     lseek(infn,(long) loop, SEEK_SET);
  75.     loop+=16;
  76.     if (read(infn,bufi,16) != 16) {
  77.         fprintf(stderr,"\n\nPremature EOF!\n");
  78.         goto cleanup;
  79.     }
  80.     switch(bufi[0]) {
  81.     case 0:     /* type 0 font file */
  82.         process0();
  83.         break;
  84.     case 1:     /* type 1 font file */
  85.         process1();
  86.         break;
  87.     default:
  88.         fprintf(stderr,"Invalid Font Type\n!");
  89.     }
  90. cleanup:
  91.     close(infn);
  92.     close(outfn);
  93. }
  94.  
  95. /* process type 0 font file */
  96. process0()
  97. {
  98.     unsigned char temp1,temp2;
  99.     int loop1,loop2,nochar,charsize,outsize;
  100.     struct fontspec inspec;
  101.  
  102.     /* see the appendix in user manual about font file format */
  103.     inspec.width=bufi[5];
  104.     inspec.inkwidth=bufi[6];
  105.     inspec.height=bufi[7];
  106.     inspec.leftmargin=bufi[8];
  107.     inspec.topline=bufi[9];
  108.     inspec.cellheight=bufi[10];
  109.     bufo[0]=FONTID;
  110.  
  111.     /* Allocate 14 bytes for comment */
  112.     for (loop1=1;loop1<15;) bufo[loop1++]=' ';
  113.     for (loop1=15; loop1<32;) bufo[loop1++]=0;
  114.     for (loop1=16;loop1<21;loop1++) bufo[loop1]=bufi[loop1-16];
  115.     bufo[21]=inspec.cellheight;
  116.     bufo[22]=inspec.height;
  117.     bufo[23]=inspec.inkwidth;
  118.     bufo[24]=inspec.cellheight-inspec.topline-1;
  119.     bufo[25]=inspec.inkwidth+inspec.leftmargin-1;
  120.     bufo[26]=inspec.width;
  121.  
  122.     /* write out the header */
  123.     write(outfn,bufo,32);
  124.     nochar=bufi[1]+(bufi[2]<<8);
  125.     /* calculate input character size in byte */
  126.     charsize=((inspec.inkwidth+7)>>3)*inspec.height;
  127.     /* calculate output character size in byte */
  128.     outsize=((inspec.height+7)>>3)*inspec.inkwidth;
  129.  
  130.     /* loop until all characters are processed */
  131.     while (nochar--) {
  132.         if (read(infn,bufi,charsize)!=charsize) {
  133.             fprintf(stderr,"\n\nPremature EOF!\n");
  134.             goto cleanup;
  135.         }    
  136.         rotate(&inspec,bufi,bufo);
  137.         write(outfn,bufo,outsize);
  138.     }
  139. cleanup: ;
  140. }
  141.  
  142. /* process type 1 font file */
  143. process1()
  144. {
  145.     unsigned char temp1,temp2;
  146.     int loop1,loop2,nochar,charsize,outsize;
  147.     long size;
  148.  
  149.     bufo[0]=FONTID;
  150.     /* allocate 14 bytes for comment */
  151.     for (loop1=1;loop1<15;) bufo[loop1++]=' ';
  152.     for (loop1=15;loop1<32;) bufo[loop1++]=0;
  153.     for (loop1=16;loop1<24;loop1++) bufo[loop1]=bufi[loop1-16];
  154.     nochar=bufi[1]+(bufi[2]<<8);
  155.  
  156.     /* read characters information */
  157.     if (read(infn,fontinfo,6*nochar)!=6*nochar) {
  158.         fprintf(stderr,"\n\nPremature EOF!\n");
  159.         goto cleanup;
  160.     }
  161.     size=0L;
  162.     for (loop1=0; loop1<nochar; loop1++) {
  163.         size+=(long) ((fontinfo[loop1].height+7)>>3)*fontinfo[loop1].inkwidth;
  164.         /* transform the character information */
  165.         rotspec(&fontinfo[loop1],&outinfo[loop1]);
  166.     }
  167.     bufo[21]=(unsigned char) (size & 0xff);
  168.     bufo[22]=(unsigned char) ((size>>8) & 0xff);
  169.     bufo[23]=(unsigned char) ((size>>16) & 0xff);
  170.     write(outfn,bufo,32);
  171.     if (write(outfn,outinfo,6*nochar)!=6*nochar) {
  172.         fprintf(stderr,"\nError writing the output file!\n");
  173.         goto cleanup;
  174.     }
  175.     for (loop1=0; loop1<nochar; loop1++) {
  176.         charsize=((fontinfo[loop1].inkwidth+7)>>3)*fontinfo[loop1].height;
  177.         outsize=((fontinfo[loop1].height+7)>>3)*fontinfo[loop1].inkwidth;
  178.         if (read(infn,bufi,charsize)!=charsize) {
  179.             fprintf(stderr,"\n\nPremature EOF!\n");
  180.             goto cleanup;
  181.         }    
  182.         rotate(&fontinfo[loop1],bufi,bufo);
  183.         write(outfn,bufo,outsize);
  184.     }
  185. cleanup: ;
  186. }
  187.  
  188. /* rotate the pattern given in bufi and stored output in bufo */
  189. rotate(spec,bufi,bufo)
  190. struct fontspec *spec;
  191. char bufi[], bufo[];
  192. {
  193.     int wb, tw, loop1, loop2, loop3, outptr,count;
  194.     unsigned char out;
  195.  
  196.     outptr=0;
  197.  
  198.     /* Hard to describe. You will understand it after tracing once */
  199.     wb=(spec->inkwidth+7)>>3;
  200.     tw=(spec->inkwidth-1) & 0x07;
  201.     for (loop1=wb-1; loop1>=0 ; loop1--) {
  202.         for (loop2=tw; loop2>=0 ; loop2--) {
  203.             out=count=0;
  204.             for (loop3=loop1; loop3<(wb*spec->height); loop3+=wb) {
  205.                 if (count++ == 8) {
  206.                     bufo[outptr++]=out;
  207.                     out=0;
  208.                     count=1;
  209.                 }
  210.                 out <<= 1;
  211.                 if (bufi[loop3] & DOTVALUE[loop2])
  212.                     out |= 1;
  213.             }
  214.         if (count<8) out <<= 8-count;
  215.         bufo[outptr++]=out;
  216.         }
  217.     tw=7;
  218.     }
  219. }
  220.  
  221. /* transform the character information */
  222. rotspec(in,out)
  223. struct fontspec *in, *out;
  224. {
  225.     out->width=in->cellheight;
  226.     out->inkwidth=in->height;
  227.     out->height=in->inkwidth;
  228.     out->topline=in->inkwidth+in->leftmargin-1;
  229.     out->cellheight=in->width;
  230.     out->leftmargin=in->cellheight-in->topline-1;
  231. }
  232.  
  233.