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

  1. #include <stdio.h>
  2. #include <gds.h>
  3. #include <prtfont.h>
  4.  
  5. /*==============================================================*
  6.  *                                                              *
  7.  *    This file contain functions for printing.                 *
  8.  *    Only PrintFrame should be used by user.                   *
  9.  *                                                              *
  10.  *    Number of dots per pass (ndot) and number of dots between *
  11.  *      2 pins on the print head are fixed in this file. Use    *
  12.  *      pframe2.c if you want them to be variable.              *
  13.  *                                                              *
  14.  *==============================================================*/
  15.  
  16. #define ERROR (-1)
  17. #define OK 0
  18.  
  19. #define ndot 8  /* number of dots printed per pass */
  20. #define dpp 3   /* number of dots printed between 2 pins on print head
  21.                    in vertical mode 1 */
  22. extern int sixlpi;   /* spacing for six lines per inch */
  23.  
  24. /* main program for printing frame */
  25. PrintFrame(flag,page,line,tlsp,offset)
  26. int flag,line,offset,tlsp;
  27. char **page;
  28. /*
  29.     flag : flag to control vertical and horizontal density
  30.     page : pointer to a array of character pointer containing text data
  31.     line : number of lines of text data
  32.     tlsp : number of point between 2 base lines of text
  33.   offset : position when text data should begin (can be + or -)
  34. */
  35. {
  36.     int hf,vf,remain,count1,count2,y;
  37.  
  38.     MAXPH=FTABLE[CUR_FRAME].vert+1; /* maximum height */
  39.     y=0;
  40.     hf = flag & 0x0f;           /* horizontal flag */
  41.     vf = (flag & 0xf0) >> 4;    /* vertical flag   */
  42.     if (line <= 0) {    /* if line <= 0, no text data */
  43.         if (vf == 1) {
  44.             remain = (MAXPH+dpp-1)/dpp;
  45.         } else {
  46.             remain = MAXPH;
  47.         }
  48.         goto moreg;     /* print graphics data only */
  49.     }
  50.     if (offset != 0) {
  51.         if (offset > 0) {   /* text data are printed first */
  52.             line -= (count1=offset/tlsp);   /* count1 contains lines to print */
  53.             count2 = offset - count1 * tlsp;
  54.             while (count1--) {
  55.                 ptext(*page++);   /* print text data only */
  56.                 skiplong(tlsp); 
  57.             }
  58.             if (count2) {       /* since offset is not multiple of tlsp */
  59.                 ptext(*page++); /* we need to do some adjustment at the end */
  60.                 line--;
  61.                 skiplong(count2);
  62.             }
  63.             count1 = tlsp - count2;
  64.         } else {   /* offset < 0, print graphics data first */
  65.             count1 = -offset;
  66.         }
  67.  
  68.         /* print some graphics data only */
  69.         if (vf == 1) {
  70.             printg1(hf,0,count1);
  71.             y = count1 * dpp;
  72.         } else {
  73.             printg0(hf,0,count1);
  74.             y = count1;
  75.         }
  76.     }
  77.  
  78.     /* begin merge print of text data and graphics data */
  79.     if (vf == 1) {    /* high vertical resolution */
  80.         for (remain=(MAXPH-y+dpp-1)/dpp; remain>0; ) {
  81.             prtg1(hf,y++,remain);   /* print first pass of graphics data */
  82.             ptext(*page++);         /* then test data */
  83.             line--;
  84.             for(count1=dpp-1; count1>0; count1--) {
  85.                 skipdot(1);  /* print remaining graphics data for that line */
  86.                 prtg1(hf,y++,remain);
  87.             }
  88.             skipdot((remain-1)*dpp+1);  /* long skip */
  89.             remain -= ndot;
  90.             y += (ndot-1)*dpp;
  91.             if (remain <= 0) break;
  92.             if (line <= 0) goto moreg;  /* if text data is shorter than */
  93.                                         /* graphics data, goto moreg */
  94.             printg1(hf,y,tlsp-ndot);    /* else fill up the remaining line */
  95.             y+=(tlsp-ndot)*3;
  96.             remain -= tlsp - ndot;
  97.         }
  98.     } else {    /* normal vertical density */
  99.         for (remain=MAXPH-y; remain > 0; ) {
  100.             prtg0(hf,y,remain);    /* graphics data */
  101.             ptext(*page++);        /* text data */
  102.             line--;
  103.             skippt(ndot);          /* skip */
  104.             y+=ndot;
  105.             remain -= ndot;
  106.             if (remain <= 0) break;
  107.             if (line <= 0) goto moreg;  /* no more text data, goto moreg */
  108.             printg0(hf,y,tlsp-ndot);    /* fill up remaining line */
  109.             y += tlsp-ndot;             /* update y coordinate */
  110.             remain -= tlsp-ndot;
  111.         }
  112.     }
  113.     if (line > 0) {                     /* more text data ? */
  114.         while (line--) {                /* yes, print remaining */
  115.             ptext(*page++);
  116.             skiplong(tlsp);
  117.        }
  118.     }
  119.     goto restore;
  120. moreg:
  121.     if (vf == 1) {              /* more graphics data */
  122.         printg1(hf,y,remain);   /* high verical density */
  123.     } else {
  124.         printg0(hf,y,remain);   /* normal vertical density */
  125.     }
  126. restore:
  127.     prtpc(&setp,sixlpi);        /* set back to 6 line per inch */
  128.     pbflush();                  /* flush anything in output buffer */
  129. }
  130.  
  131. /* prints one pass in vertical mode 0 for graphics data only */
  132. static prtg0(option,y,height)
  133. int option,y,height;
  134. {
  135.     int far *ptr[ndot];
  136.     int outw[ndot], length;
  137.     register int loop;
  138.  
  139.     option &= 0x7f;
  140.     if (option >= NHEADER) option=0;
  141. /*    if (y+height > MAXPH)
  142.         height=MAXPH-y; */
  143.     if (height > ndot)
  144.         height=ndot;
  145.  
  146.     /* if frame width larger than printer width */
  147.     if ((length = XLIMIT+1) > MAXPSIZ[option])
  148.         length=MAXPSIZ[option];  /* print up to printer width only */
  149.     length &= ~0x0f;             /* length has to be multiple of 16 */
  150.     prtpc(&header[option],length);     /* print printer control code */
  151.     NULLPRT = header[option].factor-1; /* null print factor, see user manual */
  152.  
  153.     for( loop=0; loop < height; ) {    /* calculate addr. for 1 dot of lines */
  154.         ptr[loop] = calcaddr(0,y++);
  155.         outw[loop++]=0;
  156.     }
  157.     for ( ; loop < ndot ;)
  158.         outw[loop++]=0;          /* clear remaining word to 0 if necessary */
  159.     for (length=length>>4; length > 0; length--) {
  160.         for (loop=0; loop<height; loop++)   /* read one word from every line */
  161.             outw[loop] = exchange(fr_read(ptr[loop]++));
  162.         prt(outw);               /* put them into output buffer */
  163.     }
  164.    length=optprt(option);    /* remove trailing zeros */
  165.    if (length) prtpc(&endg,length);      /* include an carriage return */
  166.    pbflush();         /* flush the buffer */
  167. }
  168.  
  169. /* prints one pass in vertical mode 1 with graphics data only */
  170. static prtg1(option,y,height)
  171. int option,y,height;
  172. {
  173.     int far *ptr[ndot];
  174.     int outw[ndot], length;
  175.     register int loop;
  176.  
  177.     option &= 0x7f;
  178.     if (option >= NHEADER) option=0;
  179. /*    if (y+height*dpp > MAXPH)
  180.         height=(MAXPH-y+dpp-1)/dpp; */
  181.     if (height > ndot)
  182.         height=ndot;
  183.     else if (y+height*dpp-dpp+1 > MAXPH)
  184.         height=(MAXPH-y+dpp-1)/dpp;
  185.     if (height==0) return;
  186.  
  187.     if ((length = XLIMIT+1) > MAXPSIZ[option])
  188.         length=MAXPSIZ[option];
  189.     length &= ~0x0f;
  190.     prtpc(&header[option],length);      /* print control codes */
  191.     NULLPRT = header[option].factor-1;  /* set up null print value */
  192.  
  193.     for( loop=0; loop < height; ) {     /* get one word from each line */
  194.         ptr[loop] = calcaddr(0,y);
  195.         y+=dpp;                         /* skip dpp line */
  196.         outw[loop++]=0;
  197.     }
  198.     for ( ; loop < ndot ;)      /* clear remaining words if necessary */
  199.         outw[loop++]=0;
  200.     for (length=length>>4; length > 0; length--) {
  201.         for (loop=0; loop<height; loop++)
  202.             outw[loop] = exchange(fr_read(ptr[loop]++));
  203.         prt(outw);      /* put them into buffer */
  204.     }
  205.     length=optprt(option);     /* remove trailing zeros */
  206.     if (length) prtpc(&endg,length);
  207.     pbflush();          /* flush the print buffer */
  208. }
  209. /* prints the frame starting from y for height given in vertical mode 0 */
  210. static printg0(option,y,height)
  211. int option;
  212. register int y, height;
  213. {
  214.     int count,pass;
  215.  
  216.     for(; height>0; y+=ndot, height-=ndot) {
  217.         prtg0(option,y,height);
  218.         skippt(height);
  219.     }
  220. }
  221.  
  222. /* prints the frame starting from y for height given for vertical mode 1 */
  223. static printg1(option,y,height)
  224. int option;
  225. register int y,height;
  226. {
  227.     int count1;
  228.  
  229.     for (; height>0 ; height-=ndot, y+=(ndot-1)*dpp) {
  230.         prtg1(option,y++,height);
  231.         for(count1=dpp-1; count1>0; count1--) {
  232.             skipdot(1); /* skip a little */
  233.             prtg1(option,y++,height);
  234.         }
  235.         skipdot((height-1)*dpp+1);      /* big skip */
  236.     }
  237. }
  238.  
  239. /* skip desire number of dots */
  240. skiplong(number)
  241. int number;
  242. {
  243.     prtpc(&skp,number);
  244.     pbflush();
  245. }
  246.  
  247. /* skip not more than ndot of dots */
  248. skippt(number)
  249. int number;
  250. {
  251.     if (number > ndot) number=ndot;
  252.     prtpc(&skp,number);
  253.     pbflush();
  254. }
  255.  
  256. skipdot(number)
  257. int number;
  258. {
  259.     if (number > (ndot-1)*dpp+1) number=(ndot-1)*dpp+1;
  260.     prtpc(&skd,number);
  261.     pbflush();
  262. }
  263.  
  264. /* print a line of text */
  265. ptext(cptr)
  266. register char *cptr;
  267. {
  268.     while (*cptr) {
  269.         if (*cptr==0x80) *cptr=0;
  270.         prtc(*cptr++);
  271.     }
  272.     prtc(0x0d);
  273.     pbflush();
  274. }
  275.  
  276. /* print control codes */
  277. static prtpc(pcptr,number)
  278. struct prtcmd *pcptr;
  279. int number;
  280. {
  281.     int loop,temph,templ,len;
  282.  
  283.     number *= pcptr->factor;
  284.     temph = pcptr->numh;
  285.     templ = pcptr->numl;
  286.     len = pcptr->length;
  287.     for (loop=0; loop<len; loop++) {
  288.         if (loop==temph)
  289.             prtc((number>>8) & 0xff);
  290.         else if (loop==templ)
  291.             prtc(number & 0xff);
  292.         else
  293.             prtc(pcptr->code[loop]);
  294.     }
  295. }
  296.  
  297. /* optimize print length */
  298. static optprt(option)
  299. int option;
  300. {
  301.     int tlen, temp;
  302.  
  303.     tlen=header[option].length;
  304.     if ((tlen=rmv0(tlen)) == 0) return(0);      /* remove trailing zero */
  305.     if ((temp=header[option].numh) >= 0) {
  306.         CFBUF[temp] = (tlen >> 8) & 0xff;
  307.     }
  308.     if ((temp=header[option].numl) >= 0) {
  309.         CFBUF[temp] = tlen & 0xff;
  310.     }
  311.     return(PBCOUNT);    /* number of characters in buffer */
  312. }
  313.  
  314.