1 /***********************************************************
2 *                      K O U L E S                         *
3 *----------------------------------------------------------*
4 *  C1995 JAHUSOFT                                          *
5 *        Jan Hubicka                                       *
6 *        Dukelskych Bojovniku 1944                         *
7 *        390 03 Tabor                                      *
8 *        Czech Republic                                    *
9 *        Phone: 0041-36-132613                             *
10 *        eMail: hubicka@limax.paru.cas.cz                  *
11 *----------------------------------------------------------*
12 *    Copyright(c)1995,1996 by Jan Hubicka.See README for   *
13 *                    licence details.                      *
14 *----------------------------------------------------------*
15 *  font.c font for the STARWARS SCROLLER                   *
16 ***********************************************************/
17 /* this file was ripped from: */
18 /* Zgv v2.5 - GIF, JPEG and PBM/PGM/PPM viewer, for VGA PCs running Linux.
19  * Copyright (C) 1993-1995 Russell Marks. See README for license details.
20  *
21  * font.c - provides a font of sorts for use via svgalib
22  * modified for starwars scroler by Jan hubicka (hubicka@limaxp.aru.cas.cz)
23  */
24 
25 
26 /* it's all hard-coded a bit ugly and prasarna!, so you probably won't want
27  * much to look at it (hint) :)
28  */
29 
30 
31 #include <stdio.h>
32 #include <string.h>
33 #include "font.h"
34 #include "koules.h"
35 /*following routines are ripped from vgagl library */
36 /* We use the 32-bit to 64-bit multiply and 64-bit to 32-bit divide of the */
37 /* 386 (which gcc doesn't know well enough) to efficiently perform integer */
38 /* scaling without having to worry about overflows. */
39 #ifdef FAST_WIDELINE
40 #define swap(x, y) { int temp = x; x = y; y = temp; }
41 #define setpixel (*(backscreen->ff.driver_setpixel_func))
42 #undef __clipx2
43 #define __clipx2 (MAPWIDTH-3)
44 #undef __clipx1
45 #define __clipx1 0
46 #undef __clipy1
47 #define __clipy1 0
48 #undef __clipy2
49 #define __clipy2 (MAPHEIGHT+19)
50 #if defined(__i386__)&&defined(ASSEMBLY)
51 static INLINE int
muldiv64(int CONST m1,int CONST m2,int CONST d)52 muldiv64 (int CONST m1, int CONST m2, int CONST d)
53 {
54 /* int32 * int32 -> int64 / int32 -> int32 */
55   int             result;
56   __asm__ (
57 	    "imull %%edx\n\t"
58 	    "idivl %3\n\t"
59 :	    "=a" (result)	/* out */
60 :	    "a" (m1), "d" (m2), "g" (d)		/* in */
61 :	    "ax", "dx"		/* mod */
62     );
63   return result;
64 }
65 
66 #define INC_IF_NEG(y)                                  \
67 {                                                       \
68         __asm__("btl $31,%1\n\t"                        \
69                 "adcl $0,%0"                            \
70                 : "=r" ((int) result)                   \
71                 : "rm" ((int) (y)), "0" ((int) result)  \
72                 );                                      \
73 }
74 static INLINE int
gl_regioncode(CONST int x,CONST int y)75 gl_regioncode (CONST int x, CONST int y)
76 {
77   int             dx1, dx2, dy1, dy2;
78   int             result;
79   result = 0;
80   dy2 = __clipy2 - y;
81   INC_IF_NEG (dy2);
82   result <<= 1;
83   dy1 = y - __clipy1;
84   INC_IF_NEG (dy1);
85   result <<= 1;
86   dx2 = __clipx2 - x;
87   INC_IF_NEG (dx2);
88   result <<= 1;
89   dx1 = x - __clipx1;
90   INC_IF_NEG (dx1);
91   return result;
92 }
93 
94 
95 #else
96 
97 static INLINE int
gl_regioncode(CONST int x,CONST int y)98 gl_regioncode (CONST int x, CONST int y)
99 {
100   int             result = 0;
101   if (x < 0)
102     result |= 1;
103   else if (x > __clipx2)
104     result |= 2;
105   if (y < 0)
106     result |= 4;
107   else if (y > __clipy2)
108     result |= 8;
109   return result;
110 }
111 #endif
112 
113 /* Partly based on vgalib by Tommy Frandsen */
114 /* This would be a lot faster if setpixel was inlined */
115 
116 static void
gl_wide_line(int x1,int y1,int x2,int y2,int c)117 gl_wide_line (int x1, int y1, int x2, int y2, int c)
118 {
119   int             dx, dy, ax, ay, sx, sy, x, y;
120   int             syp;
121   char           *point;
122   x1 = (MAPWIDTH / 2 + (x1) * 220 / (1000 - (y1)) / DIV);
123   y1 = (int) (MAPHEIGHT / 3 + MAPWIDTH * 220 / (1000 - (y1)));
124   x2 = (int) (MAPWIDTH / 2 + (x2) * 220 / (1000 - (y2)) / DIV);
125   y2 = (int) (MAPHEIGHT / 3 + MAPWIDTH * 220 / (1000 - (y2)));
126   /* Cohen & Sutherland algorithm */
127   for (;;)
128     {
129       int             r1 = gl_regioncode (x1, y1);
130       int             r2 = gl_regioncode (x2, y2);
131       if (!(r1 | r2))
132 	break;			/* completely inside */
133       if (r1 & r2)
134 	return;			/* completely outside */
135       if (r1 == 0)
136 	{
137 	  swap (x1, x2);	/* make sure first */
138 	  swap (y1, y2);	/* point is outside */
139 	  r1 = r2;
140 	}
141       if (r1 & 1)
142 	{			/* left */
143 #if defined(__i386__)&&defined(ASSEMBLY)
144 	  y1 += muldiv64 (__clipx1 - x1, y2 - y1, x2 - x1);
145 #else
146 	  y1 += (long) (__clipx1 - x1) * (long) (y2 - y1) / (long) (x2 - x1);
147 #endif
148 	  x1 = __clipx1;
149 	}
150       else if (r1 & 2)
151 	{			/* right */
152 #if defined(__i386__)&&defined(ASSEMBLY)
153 	  y1 += muldiv64 (__clipx2 - x1, y2 - y1, x2 - x1);
154 #else
155 	  y1 += (long) (__clipx2 - x1) * (long) (y2 - y1) / (long) (x2 - x1);
156 #endif
157 	  x1 = __clipx2;
158 	}
159       else if (r1 & 4)
160 	{			/* top */
161 #if defined(__i386__)&&defined(ASSEMBLY)
162 	  x1 += muldiv64 (__clipy1 - y1, x2 - x1, y2 - y1);
163 #else
164 	  x1 += (long) (__clipy1 - y1) * (long) (x2 - x1) / (long) (y2 - y1);
165 #endif
166 	  y1 = __clipy1;
167 	}
168       else if (r1 & 8)
169 	{			/* bottom */
170 #if defined(__i386__)&&defined(ASSEMBLY)
171 	  x1 += muldiv64 (__clipy2 - y1, x2 - x1, y2 - y1);
172 #else
173 	  x1 += (long) (__clipy2 - y1) * (long) (x2 - x1) / (long) (y2 - y1);
174 #endif
175 	  y1 = __clipy2;
176 	}
177     }
178   dx = x2 - x1;
179   dy = y2 - y1;
180   ax = abs (dx) << 1;
181   ay = abs (dy) << 1;
182   sx = (dx >= 0) ? 1 : -1;
183   sy = (dy >= 0) ? 1 : -1;
184   x = x1;
185   y = y1;
186 
187   point = VScreenToBuffer (backscreen) + x + y * MAPWIDTH;
188   if (ax > ay)
189     {
190       int             d = ay - (ax >> 1);
191       syp = sy * MAPWIDTH;
192       if (DIV == 1)
193 	while (x != x2)
194 	  {
195 	    *point = c;
196 	    if (y > 3 * MAPHEIGHT / 5)
197 	      {
198 		*(point + 1) = c;
199 		if (y > 3 * MAPHEIGHT / 4)
200 		  *(point + 2) = c;
201 	      }
202 	    if (d > 0 || (d == 0 && sx == 1))
203 	      {
204 		y += sy;
205 		point += syp;
206 		d -= ax;
207 	      }
208 	    x += sx;
209 	    point += sx;
210 	    d += ay;
211 	  }
212       else
213 	while (x != x2)
214 	  {
215 	    *point = c;
216 	    if (y > 4 * MAPHEIGHT / 5)
217 	      *(point + 1) = c;
218 
219 	    if (d > 0 || (d == 0 && sx == 1))
220 	      {
221 		y += sy;
222 		point += syp;
223 		d -= ax;
224 	      }
225 	    x += sx;
226 	    point += sx;
227 	    d += ay;
228 	  }
229     }
230   else
231     {
232       int             sy = (dy >= 0) ? 1 : -1;
233       int             d = ax - (ay >> 1);
234       syp = sy * MAPWIDTH;
235       if (DIV == 1)
236 	while (y != y2)
237 	  {
238 	    *(point) = c;
239 	    if (y > 3 * MAPHEIGHT / 5)
240 	      {
241 		*(point + 1) = c;
242 		if (y > 3 * MAPHEIGHT / 4)
243 		  *(point + 2) = c;
244 	      }
245 	    if (d > 0 || (d == 0 && sy == 1))
246 	      {
247 		x += sx;
248 		point += sx;
249 		d -= ay;
250 	      }
251 	    y += sy;
252 	    point += syp;
253 	    d += ax;
254 	  }
255       else
256 	while (y != y2)
257 	  {
258 	    *(point) = c;
259 	    if (y > 4 * MAPHEIGHT / 5)
260 	      *(point + 1) = c;
261 
262 	    if (d > 0 || (d == 0 && sy == 1))
263 	      {
264 		x += sx;
265 		point += sx;
266 		d -= ay;
267 	      }
268 	    y += sy;
269 	    point += syp;
270 	    d += ax;
271 	  }
272     }
273   if (DIV == 1)
274     {
275       *(point) = c;
276       point++;
277       if (y > 3 * MAPHEIGHT / 5)
278 	{
279 	  *(point) = c, point++;
280 	  if (y > 3 * MAPHEIGHT / 4)
281 	    *(point) = c;
282 	}
283     }
284   else
285     {
286       *(point) = c;
287       point++;
288       if (y > 4 * MAPHEIGHT / 5)
289 	*(point) = c;
290     }
291 }
292 #define gl_putpixel(x,y,c) FillRectangle(x,y,y>3 * MAPHEIGHT / 4 && DIV == 1?2:1,y>3 * MAPHEIGHT / 5 && DIV == 1?2:1,c)
293 
294 
295 
296 #define TABSIZE  64		/* size of a tab, in pixels */
297 #define vga_drawline(x1,y1,x2,y2)\
298 	gl_wide_line(x1,y1,x2,y2,textcolor)
299 #define vga_drawhline(x1,y1,x2,y2)\
300 	gl_hline((int)(MAPWIDTH/2+(x1)*220/(1000-(y1))/DIV),(int)(MAPHEIGHT/3+MAPWIDTH*220/(1000-(y1))),\
301 	        (int)(MAPWIDTH/2+(x2)*220/(1000-(y2))/DIV),\
302 	        textcolor)
303 #define vga_drawpixel(x1,y1)\
304 	gl_putpixel((int)(MAPWIDTH/2+(x1)*220/(1000-(y1))/DIV),(int)(MAPHEIGHT/3+MAPWIDTH*220/(1000-(y1))),textcolor)
305 
306 #endif /*FAST_WIDELINE */
307 
308 
309 
310 #ifdef XSUPPORT
311 #undef Line1
312 #undef HLine
313 #undef SSetPixel
314 XSegment        lines[1000];
315 int             nlines;
316 static void
Line1(int x1,int y1,int x2,int y2,int c)317 Line1 (int x1, int y1, int x2, int y2, int c)
318 {
319 #ifdef MITSHM
320   if (shm)
321     {
322       gl_wide_line (x1, y1, x2, y2, cpixels (c));
323       return;
324     }
325 #endif
326   x1 = (MAPWIDTH / 2 + (x1) * 220 / (1000 - (y1)) / DIV);
327   y1 = (int) (MAPHEIGHT / 3 + MAPWIDTH * 220 / (1000 - (y1)));
328   x2 = (int) (MAPWIDTH / 2 + (x2) * 220 / (1000 - (y2)) / DIV);
329   y2 = (int) (MAPHEIGHT / 3 + MAPWIDTH * 220 / (1000 - (y2)));
330   lines[nlines].x1 = x1;
331   lines[nlines].y1 = y1;
332   lines[nlines].x2 = x2;
333   lines[nlines].y2 = y2;
334   nlines++;
335 }
336 static void
HLine(int x1,int y1,int x2,int c)337 HLine (int x1, int y1, int x2, int c)
338 {
339   x1 = (MAPWIDTH / 2 + (x1) * 220 / (1000 - (y1)) / DIV);
340   x2 = (MAPWIDTH / 2 + (x2) * 220 / (1000 - (y1)) / DIV);
341   y1 = (MAPHEIGHT / 3 + MAPWIDTH * 220 / (1000 - (y1)));
342 #ifdef MITSHM
343   if (shm)
344     {
345       int             i;
346       if (x1 > x2)
347 	i = x1, x1 = x2, x2 = i;
348       if (x1 > MAPWIDTH - 1)
349 	return;
350       if (x2 > MAPWIDTH - 1)
351 	x2 = MAPWIDTH - 1;
352       if (x1 < 0)
353 	x1 = 0;
354       if (x2 < 0)
355 	return;
356       if (y1 > MAPHEIGHT + 19)
357 	return;
358       if (y1 < 0)
359 	return;
360       HLine1 (x1, y1, x2, c);
361       return;
362     }
363 #endif /*MITSHM */
364   lines[nlines].x1 = x1;
365   lines[nlines].y1 = y1;
366   lines[nlines].x2 = x2;
367   lines[nlines].y2 = y1;
368   nlines++;
369 }
370 static void
SSetPixel(int x1,int y1,int c)371 SSetPixel (int x1, int y1, int c)
372 {
373   x1 = (MAPWIDTH / 2 + (x1) * 220 / (1000 - (y1)) / DIV);
374   y1 = (int) (MAPHEIGHT / 3 + MAPWIDTH * 220 / (1000 - (y1)));
375 #ifdef MITSHM
376   if (shm)
377     {
378       if (x1 >= MAPWIDTH - 2)
379 	return;
380       if (x1 < 0)
381 	return;
382       if (y1 >= MAPHEIGHT + 18)
383 	return;
384       if (y1 < 0)
385 	return;
386       SSetPixel1 (x1, y1, c);
387       if (y1 > 3 * MAPHEIGHT / 4 && DIV == 1)
388 	{
389 	  SSetPixel1 (x1, y1 + 1, c);
390 	}
391       if (y1 > 3 * MAPHEIGHT / 5 && DIV == 1)
392 	{
393 	  SSetPixel1 (x1 + 1, y1, c);
394 	  SSetPixel1 (x1 + 1, y1 + 1, c);
395 	}
396 
397       return;
398     }
399 #endif
400   lines[nlines].x1 = x1;
401   lines[nlines].y1 = y1;
402   if (y1 > 3 * MAPHEIGHT / 5 && DIV == 1)
403     x1++;
404   if (y1 > 3 * MAPHEIGHT / 4 && DIV == 1)
405     x1++;
406   lines[nlines].x2 = x1 + 1;
407   lines[nlines].y2 = y1 + 1;
408   nlines++;
409 }
410 #define TABSIZE  64		/* size of a tab, in pixels */
411 #undef vga_drawline
412 #undef vga_drawhline
413 #undef vga_drawpixel
414 #endif /*XSUPPORT */
415 #if defined(XSUPPORT)||!defined(FAST_WIDELINE)
416 #define vga_drawline(x1,y1,x2,y2)\
417 	Line1((int)x1,y1,x2,y2,textcolor);
418 #define vga_drawhline(x1,y1,x2,y2)\
419 	HLine(x1,y1,x2,textcolor)
420 #define vga_drawpixel(x1,y1)\
421 	SSetPixel(x1,y1,textcolor)
422 #endif
423 
424 static int      go_through_the_motions = 0;
425   /* if 1, we don't draw it, just do the width */
426 
427 static int      stop_after_this_x = NO_CLIP_FONT;
428 
429 /* never mind. Character building, wasn't it? (groan) */
430 #if 0
431 #define BEST extern inline
432 #else
433 #define BEST static
434 #endif
435 BEST void
fontc_ul(x,y,r)436 fontc_ul (x, y, r)
437      CONST int       x, y, r;
438 {
439   int             r34;
440 
441   if (go_through_the_motions)
442     return;
443   r34 = ((r * 3) >> 2);
444   vga_drawline (x - r, y, x - r34, y - r34);
445   vga_drawline (x - r34, y - r34, x, y - r);
446 }
447 
448 BEST void
fontc_ur(x,y,r)449 fontc_ur (x, y, r)
450      CONST int       x, y, r;
451 {
452   int             r34;
453 
454   if (go_through_the_motions)
455     return;
456   r34 = ((r * 3) >> 2);
457   vga_drawline (x + r, y, x + r34, y - r34);
458   vga_drawline (x + r34, y - r34, x, y - r);
459 }
460 
461 BEST void
fontc_ll(x,y,r)462 fontc_ll (x, y, r)
463      CONST int       x, y, r;
464 {
465   int             r34;
466 
467   if (go_through_the_motions)
468     return;
469   r34 = ((r * 3) >> 2);
470   vga_drawline (x - r, y, x - r34, y + r34);
471   vga_drawline (x - r34, y + r34, x, y + r);
472 }
473 
474 BEST void
fontc_lr(x,y,r)475 fontc_lr (x, y, r)
476      CONST int       x, y, r;
477 {
478   int             r34;
479 
480   if (go_through_the_motions)
481     return;
482   r34 = ((r * 3) >> 2);
483   vga_drawline (x + r, y, x + r34, y + r34);
484   vga_drawline (x + r34, y + r34, x, y + r);
485 }
486 
487 static void
fontc_l(x,y,r)488 fontc_l (x, y, r)
489      CONST int       x, y, r;
490 {
491   fontc_ll (x, y, r);
492   fontc_lr (x, y, r);
493 }
494 
495 static void
fontc_u(x,y,r)496 fontc_u (x, y, r)
497      CONST int       x, y, r;
498 {
499   fontc_ul (x, y, r);
500   fontc_ur (x, y, r);
501 }
502 
503 static void
fontc_r(x,y,r)504 fontc_r (x, y, r)
505      CONST int       x, y, r;
506 {
507   fontc_ur (x, y, r);
508   fontc_lr (x, y, r);
509 }
510 
511 static void
fontc_left(x,y,r)512 fontc_left (x, y, r)
513      CONST int       x, y, r;
514 {
515   fontc_ul (x, y, r);
516   fontc_ll (x, y, r);
517 }
518 
519 static void
fontcircle(x,y,r)520 fontcircle (x, y, r)
521      CONST int       x, y, r;
522 {
523   fontc_u (x, y, r);
524   fontc_l (x, y, r);
525 }
526 
527 static INLINE char *
myindex(char * s,CONST int c)528 myindex (char *s, CONST int c)
529 {
530   for (; *s != 0; s++)
531     if (*s == c)
532       return (s);
533   return (NULL);
534 }
535 
536 
537 int
vgadrawtext(x,y,siz,str)538 vgadrawtext (x, y, siz, str)
539      CONST int       x, y, siz;
540      CONST char     *str;
541 {
542   int             f, a, b, c, s1, s2, s3, s4, s5, s6, gap;
543   b = y;
544   a = x;
545   s1 = siz;
546   s2 = s1 << 1;
547   s3 = s1 + s2;
548   s4 = s2 << 1;
549   s5 = s4 + s1;
550   s6 = s3 << 1;
551   gap = s1;
552 #ifdef SVGALIBSUPPORT
553   gl_setclippingwindow (0, 0, MAPWIDTH - 1,
554 			MAPHEIGHT + 19);
555 
556 #endif
557   if (gap == 0)
558     gap = 1;
559 #ifdef XSUPPORT
560   {
561     int             pos;
562 #ifdef MITSHM
563     if (!shm)
564 #endif
565       {
566 	pos = (int) (MAPHEIGHT / 3 + MAPWIDTH * 220 / (1000 - (y)));
567 	if (pos > 3 * MAPHEIGHT / 4)
568 	  SetWidth (3);
569 	else if (pos > 3 * MAPHEIGHT / 5)
570 	  SetWidth (2);
571 	else
572 	  SetWidth (1);
573 	SetColor (textcolor);
574       }
575     nlines = 0;
576   }
577 #endif
578   for (f = 0; f < strlen (str); f++)
579     {
580       /* s3+s4 is the size that an ellipsis will take up (s3), plus the
581        * widest possible letter (M = s4).
582        */
583       if (a - x > stop_after_this_x - s3 - s4)
584 	{
585 	  int             tmp;
586 
587 	  /* print an ellipsis... well, three dots :) */
588 	  /* blast the width restriction to stop possible infinite recursion */
589 	  tmp = stop_after_this_x;
590 	  set_max_text_width (NO_CLIP_FONT);
591 	  vgadrawtext (a, y, siz, "...");
592 	  stop_after_this_x = tmp;
593 	  /* now give up */
594 	  break;
595 	}
596       c = str[f];
597 
598 /*** 1st step: cover some common occurances ***/
599       if (!go_through_the_motions) {	/* only draw it if we really want to */
600 	if (myindex ("abdgopq68", c) != NULL)	/* common circle position */
601 	  fontcircle (a + s1, b + s3, siz);
602 	else
603 	  {			/* common part-circle positions */
604 	    if (myindex ("cehmnrs", c) != NULL)
605 	      fontc_ul (a + s1, b + s3, siz);
606 	    if (myindex ("ehmnrBS35", c) != NULL)
607 	      fontc_ur (a + s1, b + s3, siz);
608 	    if (myindex ("cetuyCGJOQSUl035", c) != NULL)
609 	      fontc_ll (a + s1, b + s3, siz);
610 	    if (myindex ("suyBCDGJOQSU035", c) != NULL)
611 	      fontc_lr (a + s1, b + s3, siz);
612 	    /* common line */
613 	    if (myindex ("BDEFHKLMNPR", c) != NULL)
614 	      vga_drawline (a, b, a, b + s4);
615 	  }
616       }
617 /*** 2nd step: fill in rest - this is the *really* long, messy bit :) ***/
618 
619 /*** 2a: lowercase letters ***/
620       if (!go_through_the_motions)
621 	switch (c)
622 	  {
623 	  case 'a':
624 	    vga_drawline (a + s2, b + s2, a + s2, b + s4);
625 	    break;
626 	  case 'b':
627 	    vga_drawline (a, b, a, b + s4);
628 	    break;
629 	  case 'c':
630 	    vga_drawhline (a + s1, b + s2, a + s2, b + s2);
631 	    vga_drawhline (a + s1, b + s4, a + s2, b + s4);
632 	    break;
633 	  case 'd':
634 	    vga_drawline (a + s2, b, a + s2, b + s4);
635 	    break;
636 	  case 'e':
637 	    vga_drawline (a, b + s3, a + s2, b + s3);
638 	    vga_drawhline (a + s1, b + s4, a + s2, b + s4);
639 	    break;
640 	  case 'f':
641 	    fontc_ul (a + s1, b + s1, siz);
642 	    vga_drawline (a, b + s1, a, b + s4);
643 	    vga_drawhline (a, b + s2, a + s1, b + s2);
644 	    break;
645 	  case 'g':
646 	    vga_drawline (a + s2, b + s2, a + s2, b + s5);
647 	    fontc_l (a + s1, b + s5, siz);
648 	    break;
649 	  case 'h':
650 	    vga_drawline (a, b, a, b + s4);
651 	    vga_drawline (a + s2, b + s3, a + s2, b + s4);
652 	    break;
653 	  case 'i':
654 	    vga_drawpixel (a, b + s1);
655 	    vga_drawline (a, b + s2, a, b + s4);
656 	    a += -s1 + 1;
657 	    break;
658 	  case 'j':
659 	    vga_drawline (a + s1, b + s2, a + s1, b + s5);
660 	    fontc_lr (a, b + s5, siz);
661 	    vga_drawpixel (a + s1, b + s1);
662 	    break;
663 	  case 'k':
664 	    vga_drawline (a, b, a, b + s4);
665 	    vga_drawline (a, b + s3, a + s1, b + s2);
666 	    vga_drawline (a, b + s3, a + s1, b + s4);
667 	    break;
668 	  case 'l':
669 	    vga_drawline (a, b, a, b + s3);
670 	    break;
671 	  case 'm':
672 	    vga_drawline (a, b + s2, a, b + s4);
673 	    vga_drawline (a + s2, b + s3, a + s2, b + s4);
674 	    vga_drawline (a + s4, b + s3, a + s4, b + s4);
675 	    fontc_u (a + s3, b + s3, siz);
676 	    break;
677 	  case 'n':
678 	    vga_drawline (a, b + s2, a, b + s4);
679 	    vga_drawline (a + s2, b + s3, a + s2, b + s4);
680 	    break;
681 	  case 'p':
682 	    vga_drawline (a, b + s2, a, b + s6);
683 	    break;
684 	  case 'q':
685 	    vga_drawline (a + s2, b + s2, a + s2, b + s6);
686 	    break;
687 	  case 'r':
688 	    vga_drawline (a, b + s2, a, b + s4);
689 	    break;
690 	  case 's':
691 	    vga_drawhline (a, b + s3, a + s2, b + s3);
692 	    vga_drawhline (a + s1, b + s2, a + s2, b + s2);
693 	    vga_drawhline (a, b + s4, a + s1, b + s4);
694 	    break;
695 	  case 't':
696 	    vga_drawline (a, b + s1, a, b + s3);
697 	    vga_drawhline (a, b + s2, a + s1, b + s2);
698 	    break;
699 	  case 'u':
700 	    vga_drawline (a, b + s2, a, b + s3);
701 	    vga_drawline (a + s2, b + s2, a + s2, b + s4);
702 	    break;
703 	  case 'v':
704 	    vga_drawline (a, b + s2, a + s1, b + s4);
705 	    vga_drawline (a + s1, b + s4, a + s2, b + s2);
706 	    break;
707 	  case 'w':
708 	    vga_drawline (a, b + s2, a + s1, b + s4);
709 	    vga_drawline (a + s1, b + s4, a + s2, b + s3);
710 	    vga_drawline (a + s2, b + s3, a + s3, b + s4);
711 	    vga_drawline (a + s3, b + s4, a + s4, b + s2);
712 	    break;
713 	  case 'x':
714 	    vga_drawline (a, b + s2, a + s2, b + s4);
715 	    vga_drawline (a, b + s4, a + s2, b + s2);
716 	    break;
717 	  case 'y':
718 	    vga_drawline (a, b + s2, a, b + s3);
719 	    vga_drawline (a + s2, b + s2, a + s2, b + s5);
720 	    fontc_l (a + s1, b + s5, siz);
721 	    break;
722 	  case 'z':
723 	    vga_drawhline (a, b + s2, a + s2, b + s2);
724 	    vga_drawline (a + s2, b + s2, a, b + s4);
725 	    vga_drawhline (a, b + s4, a + s2, b + s4);
726 	    break;
727 
728 /*** 2b: uppercase letters ***/
729 
730 	  case 'A':
731 	    vga_drawline (a, b + s4, a + s1, b);
732 	    vga_drawline (a + s1, b, a + s2, b + s4);
733 	    vga_drawline (a + (s1 >> 1), b + s2, a + s2 - (s1 >> 1), b + s2);
734 	    break;
735 	  case 'B':
736 	    fontc_r (a + s1, b + s1, siz);
737 	    vga_drawhline (a, b, a + s1, b);
738 	    vga_drawhline (a, b + s2, a + s1, b + s2);
739 	    vga_drawhline (a, b + s4, a + s1, b + s4);
740 	    break;
741 	  case 'C':
742 	    fontc_u (a + s1, b + s1, siz);
743 	    vga_drawline (a, b + s1, a, b + s3);
744 	    break;
745 	  case 'D':
746 	    vga_drawhline (a, b, a + s1, b);
747 	    vga_drawhline (a, b + s4, a + s1, b + s4);
748 	    fontc_ur (a + s1, b + s1, siz);
749 	    vga_drawline (a + s2, b + s1, a + s2, b + s3);
750 	    break;
751 	  case 'E':
752 	    vga_drawhline (a, b, a + s2, b);
753 	    vga_drawhline (a, b + s2, a + s1, b + s2);
754 	    vga_drawhline (a, b + s4, a + s2, b + s4);
755 	    break;
756 	  case 'F':
757 	    vga_drawhline (a, b, a + s2, b);
758 	    vga_drawhline (a, b + s2, a + s1, b + s2);
759 	    break;
760 	  case 'G':
761 	    fontc_u (a + s1, b + s1, siz);
762 	    vga_drawline (a, b + s1, a, b + s3);
763 	    vga_drawhline (a + s1, b + s2, a + s2, b + s2);
764 	    vga_drawline (a + s2, b + s2, a + s2, b + s3);
765 	    break;
766 	  case 'H':
767 	    vga_drawhline (a, b + s2, a + s2, b + s2);
768 	    vga_drawline (a + s2, b, a + s2, b + s4);
769 	    break;
770 	  case 'I':
771 	    vga_drawhline (a, b, a + s2, b);
772 	    vga_drawline (a + s1, b, a + s1, b + s4);
773 	    vga_drawhline (a, b + s4, a + s2, b + s4);
774 	    break;
775 	  case 'J':
776 	    vga_drawline (a + s2, b, a + s2, b + s3);
777 	    break;
778 	  case 'K':
779 	    vga_drawline (a + s2, b, a, b + s2);
780 	    vga_drawline (a, b + s2, a + s2, b + s4);
781 	    break;
782 	  case 'L':
783 	    vga_drawhline (a, b + s4, a + s2, b + s4);
784 	    break;
785 	  case 'M':
786 	    vga_drawline (a, b, a + s1 + (s1 >> 1), b + s2);
787 	    vga_drawline (a + s1 + (s1 >> 1), b + s2, a + s3, b);
788 	    vga_drawline (a + s3, b, a + s3, b + s4);
789 	    a -= s1;
790 	    break;
791 	  case 'N':
792 	    vga_drawline (a, b, a + s2, b + s4);
793 	    vga_drawline (a + s2, b + s4, a + s2, b);
794 	    break;
795 	  case 'Q':
796 	    vga_drawline (a + s1, b + s3, a + s2, b + s4);
797 	    /* FALLS THROUGH and adds an O, finishing the Q */
798 	  case 'O':
799 	  case '0':		/* all other numbers done later */
800 	    fontc_u (a + s1, b + s1, siz);
801 	    vga_drawline (a, b + s1, a, b + s3);
802 	    vga_drawline (a + s2, b + s1, a + s2, b + s3);
803 	    break;
804 	  case 'R':
805 	    vga_drawline (a + s1, b + s2, a + s2, b + s4);
806 	    /* FALLS THROUGH and adds a P, finishing the R */
807 	  case 'P':
808 	    fontc_r (a + s1, b + s1, siz);
809 	    vga_drawhline (a, b, a + s1, b);
810 	    vga_drawhline (a, b + s2, a + s1, b + s2);
811 	    break;
812 	  case 'S':
813 	    fontc_left (a + s1, b + s1, siz);
814 	    fontc_ur (a + s1, b + s1, siz);
815 	    break;
816 	  case 'T':
817 	    vga_drawhline (a, b, a + s2, b);
818 	    vga_drawline (a + s1, b, a + s1, b + s4);
819 	    break;
820 	  case 'U':
821 	    vga_drawline (a, b, a, b + s3);
822 	    vga_drawline (a + s2, b, a + s2, b + s3);
823 	    break;
824 	  case 'V':
825 	    vga_drawline (a, b, a + s1, b + s4);
826 	    vga_drawline (a + s1, b + s4, a + s2, b);
827 	    break;
828 	  case 'W':
829 	    vga_drawline (a, b, a + s1, b + s4);
830 	    vga_drawline (a + s1, b + s4, a + s2, b + s2);
831 	    vga_drawline (a + s2, b + s2, a + s3, b + s4);
832 	    vga_drawline (a + s3, b + s4, a + s4, b);
833 	    break;
834 	  case 'X':
835 	    vga_drawline (a, b, a + s2, b + s4);
836 	    vga_drawline (a + s2, b, a, b + s4);
837 	    break;
838 	  case 'Y':
839 	    vga_drawline (a, b, a + s1, b + s2);
840 	    vga_drawline (a + s2, b, a + s1, b + s2);
841 	    vga_drawline (a + s1, b + s2, a + s1, b + s4);
842 	    break;
843 	  case 'Z':
844 	    vga_drawhline (a, b, a + s2, b);
845 	    vga_drawline (a + s2, b, a, b + s4);
846 	    vga_drawhline (a, b + s4, a + s2, b + s4);
847 	    break;
848 
849 /*** 2c: numbers ***/
850 
851 	    /* 0 already done */
852 	  case '1':
853 	    vga_drawline (a, b + s1, a + s1, b);
854 	    vga_drawline (a + s1, b, a + s1, b + s4);
855 	    vga_drawhline (a, b + s4, a + s2, b + s4);
856 	    break;
857 	  case '2':
858 	    fontc_u (a + s1, b + s1, siz);
859 	    vga_drawline (a + s2, b + s1, a, b + s4);
860 	    vga_drawline (a, b + s4, a + s2, b + s4);
861 	    break;
862 	  case '3':
863 	    fontc_u (a + s1, b + s1, siz);
864 	    fontc_lr (a + s1, b + s1, siz);
865 	    break;
866 	  case '4':
867 	    vga_drawline (a + s1, b + s4, a + s1, b);
868 	    vga_drawline (a + s1, b, a, b + s2);
869 	    vga_drawhline (a, b + s2, a + s2, b + s2);
870 	    break;
871 	  case '5':
872 	    vga_drawline (a + s2, b, a, b);
873 	    vga_drawline (a, b, a, b + s2);
874 	    vga_drawline (a, b + s2, a + s1, b + s2);
875 	    break;
876 	  case '6':
877 	    fontc_u (a + s1, b + s1, siz);
878 	    vga_drawline (a, b + s1, a, b + s3);
879 	    break;
880 	  case '7':
881 	    vga_drawline (a, b, a + s2, b);
882 	    vga_drawline (a + s2, b, a + s1, b + s4);
883 	    break;
884 	  case '9':
885 	    vga_drawline (a + s2, b, a + s2, b + s4);
886 	    /* FALLS THROUGH and does top circle of 8 to complete the 9 */
887 	  case '8':
888 	    fontcircle (a + s1, b + s1, siz);
889 	    break;
890 
891 	    /* 2d: some punctuation (not much!) */
892 
893 	  case '-':
894 	    vga_drawhline (a, b + s2, a + s1, b + s2);
895 	    break;
896 	  case '+':
897 	    vga_drawhline (a, b + s2, a + s1, b + s2);
898 	    vga_drawline (a + s2, b, a + s2, b + s4);
899 	    break;
900 	  case '.':
901 	    vga_drawpixel (a, b + s4);
902 	    a += -s1 + 1;
903 	    break;
904 	  case ',':
905 	    vga_drawline (a - 1, b + s4 + s1, a, b + s4);
906 	    break;
907 	  case '\'':
908 	    vga_drawline (a, b, a - 1, b + s1);
909 	    break;
910 	  case '(':
911 	    fontc_ul (a + s1, b + s1, siz);
912 	    fontc_ll (a + s1, b + s3, siz);
913 	    vga_drawline (a, b + s1, a, b + s3);
914 	    break;
915 	  case ')':
916 	    fontc_ur (a, b + s1, siz);
917 	    fontc_lr (a, b + s3, siz);
918 	    vga_drawline (a + s1, b + s1, a + s1, b + s3);
919 	    break;
920 	  case '%':
921 	    vga_drawpixel (a, b);
922 	    vga_drawpixel (a + s2, b + s4);
923 	    /* FALLS THROUGH drawing the slash to finish the % */
924 	  case '/':
925 	    vga_drawline (a, b + s4, a + s2, b);
926 	    break;
927 	  case '?':
928 	    fontc_u (a + s1, b + s1, siz);
929 	    vga_drawline (a + s2, b + s1, a + s1, b + s2);
930 	    vga_drawline (a + s1, b + s2, a + s1, b + s3);
931 	    vga_drawpixel (a + s1, b + s4);
932 	    break;
933 	  }
934 /*** 3rd part: finally, move along for the next letter ***/
935 /*** we do this even if go_through_the_motions is set */
936       if (myindex ("ltfijk-. (),'", c) != NULL)
937 	a += s1;
938       else
939 	{
940 	  if (myindex ("?/%abcdeghnopqrsuvxyzABCDEFGHIJKLNOPQRSTUVXYZ0123456789", c) != NULL)
941 	    a += s2;
942 	  else
943 	    {
944 	      if (myindex ("mwMW", c) != NULL)
945 		a += s4;
946 	      else
947 		{
948 		  if (c == 9)
949 		    {
950 		      /* congratulations madam, it's a tab */
951 		      a = ((a / TABSIZE) + 1) * TABSIZE;
952 		    }
953 		  else
954 		    {
955 		      /* oh, don't know this one. do an underscore */
956 		      /* (we don't if go_through_the_motions is set) */
957 		      if (!go_through_the_motions)
958 			vga_drawhline (a, b + s4, a + s2, b + s4);
959 		      a += s2;
960 		    }
961 		}
962 	    }
963 	}
964       a += gap;			/* and add a gap */
965     }
966 
967 #ifdef XSUPPORT
968 #ifdef MITSHM
969   if (!shm)
970 #endif
971     XDrawSegments (dp, current.pixmap, gc, lines, nlines),
972       SetWidth (1);
973 #endif
974   return (a - x);
975 }
976 
977 
978 
979 
980 /* here's a new one - this gets how wide text will be */
981 int
vgatextsize(sizearg,str)982 vgatextsize (sizearg, str)
983      CONST int       sizearg;
984      CONST char     *str;
985 {
986   int             r;
987 
988   go_through_the_motions = 1;
989   r = vgadrawtext (0, 0, sizearg, str);
990   go_through_the_motions = 0;
991   return (r - sizearg);
992 }
993 
994 
995 void
set_max_text_width(width)996 set_max_text_width (width)
997      CONST int       width;
998 {
999   stop_after_this_x = width;
1000 }
1001