home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / tex / dvivga9.arc / DISPCHAR.H < prev    next >
Text File  |  1988-10-22  |  6KB  |  173 lines

  1. /* -*-C-*- dispchar.h */
  2. /*-->dispchar*/
  3. /**********************************************************************/
  4. /****************************** dispchar ******************************/
  5. /**********************************************************************/
  6.  
  7. void
  8. dispchar(c)
  9. BYTE c;        /* character number in current font */
  10.  
  11. /***********************************************************************
  12.  
  13.    This procedure has the delicate  job of OR'ing the current  character
  14.    raster description into the bitmap,  where the character box  extends
  15.    horizontally from  (xcorner  ..  xcorner+wp-1)  and  vertically  from
  16.    (ycorner  ..   ycorner+hp-1).   The  lower  left  corner  coordinates
  17.    (xcorner, ycorner) are  related to  the current point  (xcp, ycp)  as
  18.    follows:
  19.  
  20.     <------wp------>
  21.     ^    ................
  22.     |    ................
  23.     |    ................
  24.     |    ................
  25.     |    ................
  26.     |    ................
  27.     |    ................
  28.     hp  ................
  29.     |    ................
  30.     |    ................
  31.     |    ................
  32.     |    .....o..........       <-- (xcp,ycp) at "o"
  33.     |    ................ ^
  34.     |    ................ |
  35.     |    ................ |--- (hp - yoffp - 1)
  36.     |    ................ |
  37.     v    +............... v     <-- (xcorner,ycorner) at "+"
  38.     <--->
  39.       |
  40.       |
  41.      xoffp
  42.  
  43.    The current PXL file format stores character rasters in 32-bit words,
  44.    with the rightmost portion of the  last word in each line beyond  the
  45.    edge of  the character  being all  0 bits.    For efficiency,  the  OR
  46.    operation is done a word  at a time, and  in general, each such  word
  47.    contributes to two words in the bitmap line.
  48.  
  49.          line            line           line
  50.    |.........word.........|.........word.........|.........word.........|
  51.  
  52.   32-bit chunks--> |.....chrast.....|.....chrast.....|.....chrast.....|
  53.  
  54.            |<---->|<------->|
  55.                |       |
  56.      bits_to_current---^       ^--- bits_to_next
  57.  
  58.    Thus, each  32-bit  chunk  will  be  right-shifted  (filling  vacated
  59.    positions at the left with 0 bits) leaving "bits_to_current" bits  at
  60.    the low end and then OR'd into the current word of the bitmap line.
  61.  
  62.    Since the C language  right-shift operator may  or may not  propagate
  63.    the sign bit  (which is usually  at the left),  a compile-time  flag,
  64.    ARITHRSHIFT, is necessary to include an extra AND operation to remove
  65.    them  when    the  right-shift   is  implemented   by  an   arithmetic
  66.    (sign-propagating), rather than a logical, shift.
  67.  
  68.    The 32-bit  chunk will  then  be left-shifted  (with 0  bits  filling
  69.    vacated positions on  the right) leaving  "bits_to_next" bits at  the
  70.    high end and OR'd into the next word of the bitmap line.
  71.  
  72.    When the host word  size exceeds 32 bits  (e.g. DEC-10 or -20  36-bit
  73.    word), the  first step  may in  fact require  a left  shift, and  the
  74.    second step is then not needed.   This is detected in the code  below
  75.    by "bits_to_next" being negative.
  76.  
  77. ***********************************************************************/
  78. {
  79.     register struct char_entry *tcharptr;
  80.     COORDINATE x,xcorner,ycorner;
  81.     UNSIGN16 ilimit;
  82.     register INT16 bits_to_next;
  83.     register UNSIGN16 i;
  84.     UNSIGN32 word32;
  85.     register UNSIGN32 *p;
  86.     register UNSIGN32 *raster_word;
  87.     register COORDINATE j;
  88.  
  89.     if ((c < FIRSTPXLCHAR) || (LASTPXLCHAR < c)) /* check character range */
  90.     return;
  91.  
  92.     tcharptr = &(fontptr->ch[c]);
  93.  
  94.     if (tcharptr->rasters == (UNSIGN32*)NULL)/* if rasters still on file */
  95.     loadchar(c);            /* go get them */
  96.  
  97.     if (tcharptr->rasters == (UNSIGN32*)NULL)
  98.     return;    /* character image must be empty */
  99.  
  100.     tcharptr->refcount++;        /* update reference count */
  101.     raster_word = tcharptr->rasters;    /* pointer to first raster word */
  102.  
  103.     xcorner = xcp - tcharptr->xoffp;
  104.     ycorner = ycp - (tcharptr->hp - tcharptr->yoffp - 1);
  105.  
  106.     if (DBGOPT(DBG_CHAR_DUMP))
  107.     {
  108.     NEWLINE(stdout);
  109.         (void)printf(
  110.         "dispchar(): (xcp,ycp) = (%d,%d) (xcorner,ycorner) = (%d,%d)",
  111.         xcp,ycp,xcorner,ycorner);
  112.     NEWLINE(stdout);
  113.     (void)printf("            (wp,hp) = (%d,%d)  (xoffp,yoffp) = (%d,%d)",
  114.         tcharptr->wp,tcharptr->hp,tcharptr->xoffp,tcharptr->yoffp);
  115.     NEWLINE(stdout);
  116.     ilimit = (UNSIGN16)((tcharptr->wp + 31) >> 5);
  117.     for (j = tcharptr->hp; j > 0; --j)
  118.     {
  119.         for (i = 0; i < ilimit; ++i)
  120.             (void)printf(" %08lx",*raster_word++);
  121.         NEWLINE(stdout);
  122.     }
  123.     raster_word = tcharptr->rasters;
  124.     }
  125.  
  126.     for (j = tcharptr->hp; j > 0; --j)    /* loop over hp rasters from */
  127.     {                    /* top to bottom */
  128.     x = xcorner;            /* select horizontal position */
  129.  
  130.         if(ycorner+j-1 > 0 && ycorner+j-1 < YBIT)
  131.          p = BITMAP(ycorner+j-1,x/HOST_WORD_SIZE);
  132.                                       /* and find word on line */
  133.         else 
  134.             p = BITMAP(YBIT,x/HOST_WORD_SIZE);
  135.  
  136.     ilimit = (UNSIGN16)((tcharptr->wp + 31) >> 5);
  137.     for (i = 0; i < ilimit; ++i)
  138.     {            /* loop over current line */
  139.         word32 = *raster_word++; /* get 32-bit portion of raster */
  140.         bits_to_next = (INT16)((x % HOST_WORD_SIZE) - HOST_WORD_SIZE + 32);
  141.  
  142. #if    (HOST_WORD_SIZE > 32)
  143.         if (bits_to_next < 0)   /* then must left shift character raster */
  144.         *p |= (word32 << (-bits_to_next));  /* and OR into line */
  145.         else
  146. #endif
  147.  
  148.         {
  149.         *p |=
  150. #if    (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD)
  151. /* these compilers correctly use a logical right shift for */
  152. /* unsigned values */
  153. #else
  154. #if    ARITHRSHIFT        /* arithmetic right shift propagates a sign */
  155.                 /* bit which must be cleared by this AND  */
  156.               rightones[bits_to_next] &
  157. #endif /* ARITHRSHIFT */
  158. #endif /* (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD) */
  159.  
  160.               (word32 >> bits_to_next);     /* OR into line */
  161.  
  162.         if (bits_to_next > 0)
  163.             *++p |= (word32 << (HOST_WORD_SIZE - bits_to_next));
  164.                 /* OR in any spill into next word */
  165.         else if (bits_to_next == 0)
  166.             ++p;    /* ended at word boundary, so start new one */
  167.         }
  168.         x += 32;        /* and update horizontal position */
  169.     }
  170.     }
  171. }
  172.  
  173.