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