summaryrefslogtreecommitdiff
path: root/dviware/beebe/src/dispchar.h
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/beebe/src/dispchar.h')
-rw-r--r--dviware/beebe/src/dispchar.h166
1 files changed, 166 insertions, 0 deletions
diff --git a/dviware/beebe/src/dispchar.h b/dviware/beebe/src/dispchar.h
new file mode 100644
index 0000000000..aa7c26a009
--- /dev/null
+++ b/dviware/beebe/src/dispchar.h
@@ -0,0 +1,166 @@
+/* -*-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 */
+ p = BITMAP(ycorner+j-1,x/HOST_WORD_SIZE); /* and find word on line */
+ 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 */
+ }
+ }
+}
+