9 static unsigned int cd
[256] = {
10 COLOR0
, COLOR1
, COLOR2
, COLOR3
,
11 COLOR4
, COLOR5
, COLOR6
, COLOR7
,
12 COLOR8
, COLOR9
, COLOR10
, COLOR11
,
13 COLOR12
, COLOR13
, COLOR14
, COLOR15
};
14 static int rows
, cols
;
15 static int fnrows
, fncols
;
16 static struct font
*fonts
[3];
21 if (pad_font(FR
, FI
, FB
))
23 rows
= fb_rows() / fnrows
;
24 cols
= fb_cols() / fncols
;
25 for (r
= 0; r
< 6; r
++) {
26 for (g
= 0; g
< 6; g
++) {
27 for (b
= 0; b
< 6; b
++) {
28 int idx
= 16 + r
* 36 + g
* 6 + b
;
29 int rfin
= r
? (r
* 40 + 55) : 0;
30 int gfin
= g
? (g
* 40 + 55) : 0;
31 int bfin
= b
? (b
* 40 + 55) : 0;
32 cd
[idx
] = (rfin
<< 16) | (gfin
<< 8) | (bfin
);
36 for (r
= 0; r
< 24; r
++)
37 cd
[232 + r
] = ((r
* 10 + 8) << 16) |
38 ((r
* 10 + 8) << 8) | (r
* 10 + 8);
45 for (i
= 0; i
< 3; i
++)
50 #define CR(a) (((a) >> 16) & 0x0000ff)
51 #define CG(a) (((a) >> 8) & 0x0000ff)
52 #define CB(a) ((a) & 0x0000ff)
53 #define COLORMERGE(f, b, c) ((b) + (((f) - (b)) * (c) >> 8u))
55 static unsigned mixed_color(int fg
, int bg
, unsigned val
)
57 unsigned int fore
= cd
[fg
], back
= cd
[bg
];
58 unsigned char r
= COLORMERGE(CR(fore
), CR(back
), val
);
59 unsigned char g
= COLORMERGE(CG(fore
), CG(back
), val
);
60 unsigned char b
= COLORMERGE(CB(fore
), CB(back
), val
);
61 return FB_VAL(r
, g
, b
);
64 static unsigned color2fb(int c
)
66 return FB_VAL(CR(cd
[c
]), CG(cd
[c
]), CB(cd
[c
]));
69 /* glyph bitmap cache */
70 #define GCLCNT (1 << 7) /* glyph cache list count */
71 #define GCLLEN (1 << 4) /* glyph cache list length */
72 #define GCIDX(c) ((c) & (GCLCNT - 1))
74 static fbval_t gc_mem
[GCLCNT
][GCLLEN
][NDOTS
];
75 static int gc_next
[GCLCNT
];
79 } gc_info
[GCLCNT
][GCLLEN
];
81 static fbval_t
*gc_get(int c
, short fg
, short bg
)
83 struct glyph
*g
= gc_info
[GCIDX(c
)];
85 for (i
= 0; i
< GCLLEN
; i
++)
86 if (g
[i
].c
== c
&& g
[i
].fg
== fg
&& g
[i
].bg
== bg
)
87 return gc_mem
[GCIDX(c
)][i
];
91 static fbval_t
*gc_put(int c
, short fg
, short bg
)
94 int pos
= gc_next
[idx
]++;
95 struct glyph
*g
= &gc_info
[idx
][pos
];
96 if (gc_next
[idx
] >= GCLLEN
)
101 return gc_mem
[idx
][pos
];
104 static void bmp2fb(fbval_t
*d
, char *s
, int fg
, int bg
, int nr
, int nc
)
107 for (i
= 0; i
< fnrows
; i
++) {
108 for (j
= 0; j
< fncols
; j
++) {
109 unsigned v
= i
< nr
&& j
< nc
?
110 (unsigned char) s
[i
* nc
+ j
] : 0;
111 d
[i
* fncols
+ j
] = mixed_color(fg
, bg
, v
);
116 static fbval_t
*ch2fb(int fn
, int c
, short fg
, short bg
)
120 if (c
< 0 || (c
< 128 && (!isprint(c
) || isspace(c
))))
122 if ((fbbits
= gc_get(c
, fg
, bg
)))
124 if (font_bitmap(fonts
[fn
], bits
, c
))
126 fbbits
= gc_put(c
, fg
, bg
);
127 bmp2fb(fbbits
, bits
, fg
& FN_C
, bg
& FN_C
,
128 font_rows(fonts
[fn
]), font_cols(fonts
[fn
]));
132 static void fb_set(int r
, int c
, void *mem
, int len
)
134 int bpp
= FBM_BPP(fb_mode());
135 if (r
< 0 || r
>= fb_rows())
137 if (c
+ len
>= fb_cols())
138 len
= MAX(0, fb_cols() - c
);
139 memcpy(fb_mem(r
) + c
* bpp
, mem
, len
* bpp
);
142 static void fb_box(int sr
, int er
, int sc
, int ec
, fbval_t val
)
144 static fbval_t line
[32 * NCOLS
];
146 for (i
= sc
; i
< ec
; i
++)
148 for (i
= sr
; i
< er
; i
++)
149 fb_set(i
, sc
, line
, ec
- sc
);
152 static int fnsel(int fg
, int bg
)
154 if ((fg
| bg
) & FN_B
)
155 return fonts
[2] ? 2 : 0;
156 if ((fg
| bg
) & FN_I
)
157 return fonts
[1] ? 1 : 0;
161 void pad_put(int ch
, int r
, int c
, int fg
, int bg
)
167 if ((fg
& 0xfff8) == FN_B
&& !fonts
[2])
168 fg
|= 8; /* increase intensity of no FB */
169 bits
= ch2fb(fnsel(fg
, bg
), ch
, fg
, bg
);
171 bits
= ch2fb(0, ch
, fg
, bg
);
173 fb_box(sr
, sr
+ fnrows
, sc
, sc
+ fncols
, color2fb(bg
& FN_C
));
175 for (i
= 0; i
< fnrows
; i
++)
176 fb_set(sr
+ i
, sc
, bits
+ (i
* fncols
), fncols
);
179 void pad_fill(int sr
, int er
, int sc
, int ec
, int c
)
181 int fber
= er
>= 0 ? er
* fnrows
: fb_rows();
182 int fbec
= ec
>= 0 ? ec
* fncols
: fb_cols();
183 fb_box(sr
* fnrows
, fber
, sc
* fncols
, fbec
, color2fb(c
& FN_C
));
196 int pad_font(char *fr
, char *fi
, char *fb
)
198 struct font
*r
= fr
? font_open(fr
) : NULL
;
208 fonts
[1] = fi
? font_open(fi
) : NULL
;
209 fonts
[2] = fb
? font_open(fb
) : NULL
;
210 memset(gc_info
, 0, sizeof(gc_info
));
211 fnrows
= font_rows(fonts
[0]);
212 fncols
= font_cols(fonts
[0]);