1 /**
2 ** buildaux.c ---- generate and store a rotated character for a font
3 **
4 ** Copyright (c) 1995 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
5 ** [e-mail: csaba@vuse.vanderbilt.edu]
6 **
7 ** This file is part of the GRX graphics library.
8 **
9 ** The GRX graphics library is free software; you can redistribute it
10 ** and/or modify it under some conditions; see the "copying.grx" file
11 ** for details.
12 **
13 ** This library is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 **
17 **/
18
19 #include "libgrx.h"
20 #include "allocate.h"
21 #include "arith.h"
22 #include "memfill.h"
23
GrBuildAuxiliaryBitmap(GrFont * f,int chr,int dir,int ul)24 char far *GrBuildAuxiliaryBitmap(GrFont *f,int chr,int dir,int ul)
25 {
26 unsigned int idx = (unsigned int)chr - f->h.minchar;
27 unsigned int bpos,rbpos,size,rsize,w,h;
28 int boff,rboff,rbinc;
29 char far *stdmap,far *cvtmap;
30 if(idx >= f->h.numchars) return(NULL);
31 stdmap = &f->bitmap[f->chrinfo[idx].offset];
32 dir = (dir & 3) + ((ul && (f->h.ulheight > 0)) ? 4 : 0);
33 if(dir == GR_TEXT_RIGHT) return(stdmap);
34 if(f->auxoffs[--dir] != NULL) {
35 unsigned int offs = f->auxoffs[dir][idx];
36 if(offs > 0) return(&f->auxmap[offs - 1]);
37 }
38 else {
39 size = sizeof(f->auxoffs[0][0]) * f->h.numchars;
40 f->auxoffs[dir] = farmalloc(size);
41 if(f->auxoffs[dir] == NULL) return(NULL);
42 memzero(f->auxoffs[dir],size);
43 }
44 h = f->h.height;
45 w = f->chrinfo[idx].width;
46 size = h * (boff = (w + 7) & ~7);
47 rsize = w * (rboff = (h + 7) & ~7);
48 switch(dir) {
49 case (GR_TEXT_RIGHT - 1 + 4):
50 rboff = boff;
51 rsize = size;
52 rbpos = 0;
53 rbinc = 1;
54 break;
55 case (GR_TEXT_DOWN - 1): /* downward */
56 case (GR_TEXT_DOWN - 1 + 4):
57 rbpos = h - 1;
58 rbinc = rboff;
59 rboff = -1;
60 break;
61 case (GR_TEXT_LEFT - 1): /* upside down, right to left */
62 case (GR_TEXT_LEFT - 1 + 4):
63 rboff = boff;
64 rsize = size;
65 rbpos = rsize - rboff + w - 1;
66 rbinc = -1;
67 rboff = -rboff;
68 break;
69 case (GR_TEXT_UP - 1): /* upward */
70 case (GR_TEXT_UP - 1 + 4):
71 rbpos = rsize - rboff;
72 rbinc = -rboff;
73 rboff = 1;
74 break;
75 default:
76 return(NULL);
77 }
78 if((rsize >>= 3) == 0) return(NULL);
79 if(rsize > (f->auxsize - f->auxnext)) {
80 /* add space for 32 (average) characters */
81 unsigned int newsize = (((f->h.width + 7) >> 3) * f->h.height) << 6;
82 newsize = umax(newsize,(rsize << 2));
83 newsize = umin(newsize,((unsigned int)(-4) - f->auxsize));
84 newsize += f->auxsize;
85 if(rsize > (newsize - f->auxnext)) return(NULL);
86 cvtmap = farmalloc(newsize);
87 if(cvtmap == NULL) return(NULL);
88 if(f->auxsize > 0) {
89 memcpy(cvtmap,f->auxmap,f->auxsize);
90 farfree(f->auxmap);
91 }
92 f->auxmap = cvtmap;
93 f->auxsize = newsize;
94 }
95 cvtmap = &f->auxmap[f->auxnext];
96 f->auxoffs[dir][idx] = f->auxnext + 1;
97 f->auxnext += rsize;
98 memfill_b(cvtmap,0,rsize);
99 for(h = bpos = 0; bpos < size; bpos += boff,rbpos += rboff,h++) {
100 unsigned int bp = bpos;
101 unsigned int bptop = bpos + w;
102 unsigned int rbp = rbpos;
103 unsigned int ulrow = ul && ((h - f->h.ulpos) < f->h.ulheight);
104 for( ; bp < bptop; bp++,rbp += rbinc) {
105 if(stdmap[bp >> 3] & (0x80 >> (bp & 7)) || ulrow) {
106 cvtmap[rbp >> 3] |= (0x80 >> (rbp & 7));
107 }
108 }
109 }
110 return(cvtmap);
111 }
112
113