9 #define NCACHE (1 << 11)
11 static unsigned int cd
[256] = {
12 COLOR0
, COLOR1
, COLOR2
, COLOR3
,
13 COLOR4
, COLOR5
, COLOR6
, COLOR7
,
14 COLOR8
, COLOR9
, COLOR10
, COLOR11
,
15 COLOR12
, COLOR13
, COLOR14
, COLOR15
};
16 static int rows
, cols
;
17 static int fnrows
, fncols
;
18 static struct font
*fonts
[3];
25 if (sizeof(fbval_t
) != FBM_BPP(fb_mode())) {
26 fprintf(stderr
, "pad_init: fbval_t doesn't match fb depth\n");
29 if (pad_font(FR
, FI
, FB
) < 0)
31 fnrows
= font_rows(fonts
[0]);
32 fncols
= font_cols(fonts
[0]);
33 rows
= fb_rows() / fnrows
;
34 cols
= fb_cols() / fncols
;
35 for (r
= 0; r
< 6; r
++) {
36 for (g
= 0; g
< 6; g
++) {
37 for (b
= 0; b
< 6; b
++) {
38 int idx
= 16 + r
* 36 + g
* 6 + b
;
39 cd
[idx
] = ((r
* 40 + 55) << 16) |
40 ((g
* 40 + 55) << 8) |
45 for (r
= 0; r
< 24; r
++)
46 cd
[232 + r
] = ((r
* 10 + 8) << 16) |
47 ((r
* 10 + 8) << 8) | (r
* 10 + 8);
54 for (i
= 0; i
< 3; i
++)
60 #define CR(a) (((a) >> 16) & 0x0000ff)
61 #define CG(a) (((a) >> 8) & 0x0000ff)
62 #define CB(a) ((a) & 0x0000ff)
63 #define COLORMERGE(f, b, c) ((b) + (((f) - (b)) * (c) >> 8u))
65 static unsigned mixed_color(int fg
, int bg
, unsigned val
)
67 unsigned int fore
= cd
[fg
], back
= cd
[bg
];
68 unsigned char r
= COLORMERGE(CR(fore
), CR(back
), val
);
69 unsigned char g
= COLORMERGE(CG(fore
), CG(back
), val
);
70 unsigned char b
= COLORMERGE(CB(fore
), CB(back
), val
);
71 return FB_VAL(r
, g
, b
);
74 static unsigned color2fb(int c
)
76 return FB_VAL(CR(cd
[c
]), CG(cd
[c
]), CB(cd
[c
]));
79 static fbval_t cache
[NCACHE
][NDOTS
];
85 static struct glyph
*glyph_entry(int c
, int fg
, int bg
)
87 return &glyphs
[((c
- 32) ^ (fg
<< 6) ^ (bg
<< 5)) & (NCACHE
- 1)];
90 static fbval_t
*glyph_cache(int c
, short fg
, short bg
)
92 struct glyph
*g
= glyph_entry(c
, fg
, bg
);
93 if (g
->c
== c
&& g
->fg
== fg
&& g
->bg
== bg
)
94 return cache
[g
- glyphs
];
98 static fbval_t
*glyph_add(int c
, short fg
, short bg
)
100 struct glyph
*g
= glyph_entry(c
, fg
, bg
);
104 return cache
[g
- glyphs
];
107 static void bmp2fb(fbval_t
*d
, char *s
, int fg
, int bg
, int nr
, int nc
)
110 for (i
= 0; i
< fnrows
; i
++) {
111 for (j
= 0; j
< fncols
; j
++) {
112 unsigned v
= i
< nr
&& j
< nc
?
113 (unsigned char) s
[i
* nc
+ j
] : 0;
114 d
[i
* fncols
+ j
] = mixed_color(fg
, bg
, v
);
119 static fbval_t
*ch2fb(int fn
, int c
, short fg
, short bg
)
123 if (c
< 0 || (c
< 128 && (!isprint(c
) || isspace(c
))))
125 if ((fbbits
= glyph_cache(c
, fg
, bg
)))
127 if (font_bitmap(fonts
[fn
], bits
, c
))
129 fbbits
= glyph_add(c
, fg
, bg
);
130 bmp2fb(fbbits
, bits
, fg
& FN_C
, bg
& FN_C
,
131 font_rows(fonts
[fn
]), font_cols(fonts
[fn
]));
135 static void fb_box(int sr
, int er
, int sc
, int ec
, fbval_t val
)
137 static fbval_t line
[32 * NCOLS
];
140 for (i
= 0; i
< cn
; i
++)
142 for (i
= sr
; i
< er
; i
++)
143 fb_set(i
, sc
, line
, cn
);
146 static int fnsel(int fg
, int bg
)
148 if ((fg
| bg
) & FN_B
)
149 return fonts
[2] ? 2 : 0;
150 if ((fg
| bg
) & FN_I
)
151 return fonts
[1] ? 1 : 0;
155 void pad_put(int ch
, int r
, int c
, int fg
, int bg
)
161 if ((fg
& 0xfff8) == FN_B
&& !fonts
[2])
162 fg
|= 8; /* increase intensity of no FB */
163 bits
= ch2fb(fnsel(fg
, bg
), ch
, fg
, bg
);
165 bits
= ch2fb(0, ch
, fg
, bg
);
167 fb_box(sr
, sr
+ fnrows
, sc
, sc
+ fncols
, color2fb(bg
& FN_C
));
169 for (i
= 0; i
< fnrows
; i
++)
170 fb_set(sr
+ i
, sc
, bits
+ (i
* fncols
), fncols
);
173 void pad_fill(int sr
, int er
, int sc
, int ec
, int c
)
175 int fber
= er
>= 0 ? er
* fnrows
: fb_rows();
176 int fbec
= ec
>= 0 ? ec
* fncols
: fb_cols();
177 fb_box(sr
* fnrows
, fber
, sc
* fncols
, fbec
, color2fb(c
& FN_C
));
190 int pad_font(char *fr
, char *fi
, char *fb
)
192 char *fns
[] = {fr
, fi
, fb
};
194 for (i
= 0; i
< 3; i
++) {
197 fonts
[i
] = fns
[i
] ? font_open(fns
[i
]) : NULL
;
199 memset(glyphs
, 0, sizeof(glyphs
));
201 fprintf(stderr
, "pad: bad font <%s>\n", fr
);
202 return fonts
[0] ? 0 : -1;