home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
tex
/
dvivga9.arc
/
DISPCHAR.H
< prev
next >
Wrap
Text File
|
1988-10-22
|
6KB
|
173 lines
/* -*-C-*- dispchar.h */
/*-->dispchar*/
/**********************************************************************/
/****************************** dispchar ******************************/
/**********************************************************************/
void
dispchar(c)
BYTE c; /* character number in current font */
/***********************************************************************
This procedure has the delicate job of OR'ing the current character
raster description into the bitmap, where the character box extends
horizontally from (xcorner .. xcorner+wp-1) and vertically from
(ycorner .. ycorner+hp-1). The lower left corner coordinates
(xcorner, ycorner) are related to the current point (xcp, ycp) as
follows:
<------wp------>
^ ................
| ................
| ................
| ................
| ................
| ................
| ................
hp ................
| ................
| ................
| ................
| .....o.......... <-- (xcp,ycp) at "o"
| ................ ^
| ................ |
| ................ |--- (hp - yoffp - 1)
| ................ |
v +............... v <-- (xcorner,ycorner) at "+"
<--->
|
|
xoffp
The current PXL file format stores character rasters in 32-bit words,
with the rightmost portion of the last word in each line beyond the
edge of the character being all 0 bits. For efficiency, the OR
operation is done a word at a time, and in general, each such word
contributes to two words in the bitmap line.
line line line
|.........word.........|.........word.........|.........word.........|
32-bit chunks--> |.....chrast.....|.....chrast.....|.....chrast.....|
|<---->|<------->|
| |
bits_to_current---^ ^--- bits_to_next
Thus, each 32-bit chunk will be right-shifted (filling vacated
positions at the left with 0 bits) leaving "bits_to_current" bits at
the low end and then OR'd into the current word of the bitmap line.
Since the C language right-shift operator may or may not propagate
the sign bit (which is usually at the left), a compile-time flag,
ARITHRSHIFT, is necessary to include an extra AND operation to remove
them when the right-shift is implemented by an arithmetic
(sign-propagating), rather than a logical, shift.
The 32-bit chunk will then be left-shifted (with 0 bits filling
vacated positions on the right) leaving "bits_to_next" bits at the
high end and OR'd into the next word of the bitmap line.
When the host word size exceeds 32 bits (e.g. DEC-10 or -20 36-bit
word), the first step may in fact require a left shift, and the
second step is then not needed. This is detected in the code below
by "bits_to_next" being negative.
***********************************************************************/
{
register struct char_entry *tcharptr;
COORDINATE x,xcorner,ycorner;
UNSIGN16 ilimit;
register INT16 bits_to_next;
register UNSIGN16 i;
UNSIGN32 word32;
register UNSIGN32 *p;
register UNSIGN32 *raster_word;
register COORDINATE j;
if ((c < FIRSTPXLCHAR) || (LASTPXLCHAR < c)) /* check character range */
return;
tcharptr = &(fontptr->ch[c]);
if (tcharptr->rasters == (UNSIGN32*)NULL)/* if rasters still on file */
loadchar(c); /* go get them */
if (tcharptr->rasters == (UNSIGN32*)NULL)
return; /* character image must be empty */
tcharptr->refcount++; /* update reference count */
raster_word = tcharptr->rasters; /* pointer to first raster word */
xcorner = xcp - tcharptr->xoffp;
ycorner = ycp - (tcharptr->hp - tcharptr->yoffp - 1);
if (DBGOPT(DBG_CHAR_DUMP))
{
NEWLINE(stdout);
(void)printf(
"dispchar(): (xcp,ycp) = (%d,%d) (xcorner,ycorner) = (%d,%d)",
xcp,ycp,xcorner,ycorner);
NEWLINE(stdout);
(void)printf(" (wp,hp) = (%d,%d) (xoffp,yoffp) = (%d,%d)",
tcharptr->wp,tcharptr->hp,tcharptr->xoffp,tcharptr->yoffp);
NEWLINE(stdout);
ilimit = (UNSIGN16)((tcharptr->wp + 31) >> 5);
for (j = tcharptr->hp; j > 0; --j)
{
for (i = 0; i < ilimit; ++i)
(void)printf(" %08lx",*raster_word++);
NEWLINE(stdout);
}
raster_word = tcharptr->rasters;
}
for (j = tcharptr->hp; j > 0; --j) /* loop over hp rasters from */
{ /* top to bottom */
x = xcorner; /* select horizontal position */
if(ycorner+j-1 > 0 && ycorner+j-1 < YBIT)
p = BITMAP(ycorner+j-1,x/HOST_WORD_SIZE);
/* and find word on line */
else
p = BITMAP(YBIT,x/HOST_WORD_SIZE);
ilimit = (UNSIGN16)((tcharptr->wp + 31) >> 5);
for (i = 0; i < ilimit; ++i)
{ /* loop over current line */
word32 = *raster_word++; /* get 32-bit portion of raster */
bits_to_next = (INT16)((x % HOST_WORD_SIZE) - HOST_WORD_SIZE + 32);
#if (HOST_WORD_SIZE > 32)
if (bits_to_next < 0) /* then must left shift character raster */
*p |= (word32 << (-bits_to_next)); /* and OR into line */
else
#endif
{
*p |=
#if (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD)
/* these compilers correctly use a logical right shift for */
/* unsigned values */
#else
#if ARITHRSHIFT /* arithmetic right shift propagates a sign */
/* bit which must be cleared by this AND */
rightones[bits_to_next] &
#endif /* ARITHRSHIFT */
#endif /* (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD) */
(word32 >> bits_to_next); /* OR into line */
if (bits_to_next > 0)
*++p |= (word32 << (HOST_WORD_SIZE - bits_to_next));
/* OR in any spill into next word */
else if (bits_to_next == 0)
++p; /* ended at word boundary, so start new one */
}
x += 32; /* and update horizontal position */
}
}
}