pad: clear the screen in pad_blank()
[fbpad.git] / pad.c
blob30057b391aa0c77cee0d7dda2891f01dfa574d29
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <ctype.h>
4 #include <ft2build.h>
5 #include FT_FREETYPE_H
6 #include FT_BITMAP_H
7 #include "draw.h"
8 #include "util.h"
10 #define FONTFACE "/home/ali/.fonts/monaco.ttf"
11 #define FONTSIZE 10
12 #define DPI 192
13 #define MAXSQUARES 1 << 15
15 static FT_Library library;
16 static FT_Face face;
17 static int rows, cols;
18 static int row, col;
19 static int char_height, char_width;
20 static int fg, bg;
22 static struct square {
23 int c;
24 int fg;
25 int bg;
26 } screen[MAXSQUARES];
28 static unsigned int cd[] = {
29 0x0a0a0a, 0xc04444, 0x339933, 0xcccc66,
30 0x5566bc, 0xcd66af, 0xa166cd, 0xeeeeee,
31 0x71a3b7, 0xc08888, 0x779977, 0xcccc99,
32 0x8899bc, 0xcd99af, 0xa199cd, 0xdedede};
34 static void init_size(void)
36 char_height = face->size->metrics.height >> 6;
37 char_width = face->size->metrics.max_advance >> 6;
38 rows = fb_rows() / char_height;
39 cols = fb_cols() / char_width;
42 void pad_init(void)
44 FT_Init_FreeType(&library);
45 FT_New_Face(library, FONTFACE, 0, &face);
46 FT_Set_Char_Size(face, 0, FONTSIZE << 6, DPI, DPI);
47 fb_init();
48 init_size();
51 void pad_free(void)
53 fb_free();
56 #define CR(a) (((a) >> 16) & 0x0000ff)
57 #define CG(a) (((a) >> 8) & 0x0000ff)
58 #define CB(a) ((a) & 0x0000ff)
59 #define COLORMERGE(f, b, c) ((b) + (((f) - (b)) * (c) >> 8u))
61 static u16_t mixed_color(int fg, int bg, u8_t val)
63 unsigned int fore = cd[fg], back = cd[bg];
64 u8_t r = COLORMERGE(CR(fore), CR(back), val);
65 u8_t g = COLORMERGE(CG(fore), CG(back), val);
66 u8_t b = COLORMERGE(CB(fore), CB(back), val);
67 return fb_color(r, g, b);
70 static u16_t color2fb(int c)
72 return mixed_color(fg, c, 0);
75 static void draw_bitmap(FT_Bitmap *bitmap, int r, int c, int fg, int bg)
77 int i, j;
78 for (i = 0; i < bitmap->rows; i++) {
79 for (j = 0; j < bitmap->width; j++) {
80 u8_t val = bitmap->buffer[i * bitmap->width + j];
81 fb_put(r + i, c + j, mixed_color(fg, bg, val));
86 void pad_fg(int c)
88 fg = c;
91 void pad_bg(int c)
93 bg = c;
96 static void pad_show(int r, int c, int reverse)
98 int sr = char_height * r;
99 int sc = char_width * c;
100 struct square *sqr = &screen[r * cols + c];
101 int fg = sqr->fg;
102 int bg = sqr->bg;
103 if (reverse) {
104 int t = bg;
105 bg = fg;
106 fg = t;
108 fb_box(sr, sc, sr + char_height, sc + char_width, color2fb(bg));
109 if (isprint(sqr->c)) {
110 FT_Load_Char(face, sqr->c, FT_LOAD_RENDER);
111 if (fg >= 8) {
112 int FT_GlyphSlot_Own_Bitmap(FT_GlyphSlot);
113 FT_GlyphSlot_Own_Bitmap(face->glyph);
114 FT_Bitmap_Embolden(library, &face->glyph->bitmap, 32, 32);
116 sr -= face->glyph->bitmap_top - char_height;
117 sc += face->glyph->bitmap_left / 2;
118 draw_bitmap(&face->glyph->bitmap, sr, sc, fg, bg);
122 void pad_put(int ch, int r, int c)
124 screen[r * cols + c].c = ch;
125 screen[r * cols + c].fg = fg;
126 screen[r * cols + c].bg = bg;
127 pad_show(r, c, 0);
130 static void pad_empty(int sr, int er)
132 memset(&screen[sr * cols], 0, (er - sr) * sizeof(screen[0]) * cols);
135 static void pad_scroll(int n)
137 int s = 0, e = rows;
138 int r;
139 if (n > 0)
140 e -= n;
141 else
142 s = -n;
143 fb_scroll(char_height * n, color2fb(bg));
144 row = rows + n;
145 for (r = s; r < e; r++)
146 memcpy(&screen[(r + n) * cols], &screen[r * cols],
147 rows * sizeof(screen[0]));
148 if (n > 0)
149 pad_empty(0, n);
150 else
151 pad_empty(rows + n, rows);
154 static void advance(int c)
156 switch (c) {
157 case '\n':
158 row++;
159 col = 0;
160 break;
161 case '\t':
162 col = (col / 8 + 1) * 8;
163 break;
164 case '\b':
165 if (col)
166 col--;
167 break;
168 case '\r':
169 col = 0;
170 break;
171 case '\a':
172 case '\f':
173 case '\v':
174 break;
175 default:
176 col++;
178 if (col >= cols) {
179 row++;
180 col = 0;
182 if (row >= rows)
183 pad_scroll(rows - row - 1);
186 void pad_add(int c)
188 pad_put(c, row, col);
189 advance(c);
190 pad_show(row, col, 1);
193 void pad_blank(void)
195 fb_box(0, 0, fb_rows(), fb_cols(), color2fb(bg));
196 memset(screen, 0, sizeof(screen));
199 void pad_move(int r, int c)
201 pad_show(row, col, 0);
202 row = MIN(r, rows - 1);
203 col = MIN(c, cols - 1);
204 pad_show(row, col, 1);
207 int pad_row(void)
209 return row;
212 int pad_col(void)
214 return col;
217 int pad_rows(void)
219 return rows;
222 int pad_cols(void)
224 return cols;