home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / beebe / h / dispchar < prev    next >
Encoding:
Text File  |  1990-12-18  |  5.7 KB  |  171 lines

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