pad: scroll when at the end of screen
[fbpad.git] / pad.c
blob8fbcb2171ffd1e84c17f96112b461230d47f17df
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <ft2build.h>
4 #include FT_FREETYPE_H
5 #include FT_BITMAP_H
6 #include "draw.h"
8 #define FONTFACE "/home/ali/.fonts/monaco.ttf"
9 #define FONTSIZE 10
10 #define DPI 192
11 #define MIN(a, b) ((a) < (b) ? (a) : (b))
12 #define MAX(a, b) ((a) > (b) ? (a) : (b))
14 static FT_Library library;
15 static FT_Face face;
16 static int rows, cols;
17 static int row, col;
18 static int char_height, char_width;
19 static int fg, bg;
21 static unsigned int cd[] = {
22 0x0a0a0a, 0xc04444, 0x339933, 0xcccc66,
23 0x5566bc, 0xcd66af, 0xa166cd, 0xeeeeee,
24 0x71a3b7, 0xc08888, 0x779977, 0xcccc99,
25 0x8899bc, 0xcd99af, 0xa199cd, 0xdedede};
27 static void init_size(void)
29 char_height = face->size->metrics.height >> 6;
30 char_width = face->size->metrics.max_advance >> 6;
31 rows = fb_rows() / char_height;
32 cols = fb_cols() / char_width;
35 void pad_init(void)
37 FT_Init_FreeType(&library);
38 FT_New_Face(library, FONTFACE, 0, &face);
39 FT_Set_Char_Size(face, 0, FONTSIZE << 6, DPI, DPI);
40 fb_init();
41 init_size();
44 void pad_free(void)
46 fb_free();
49 #define CR(a) (((a) >> 16) & 0x0000ff)
50 #define CG(a) (((a) >> 8) & 0x0000ff)
51 #define CB(a) ((a) & 0x0000ff)
52 #define COLORMERGE(f, b, c) ((b) + (((f) - (b)) * (c) >> 8u))
54 static u16_t mixed_color(u8_t val)
56 unsigned int fore = cd[fg], back = cd[bg];
57 u8_t r = COLORMERGE(CR(fore), CR(back), val);
58 u8_t g = COLORMERGE(CG(fore), CG(back), val);
59 u8_t b = COLORMERGE(CB(fore), CB(back), val);
60 return fb_color(r, g, b);
63 static void draw_bitmap(FT_Bitmap *bitmap, int r, int c)
65 int i, j;
66 for (i = 0; i < bitmap->rows; i++) {
67 for (j = 0; j < bitmap->width; j++) {
68 u8_t val = bitmap->buffer[i * bitmap->width + j];
69 fb_put(r + i, c + j, mixed_color(val));
74 void pad_fg(int c)
76 fg = c;
79 void pad_bg(int c)
81 bg = c;
84 void pad_put(int ch, int r, int c)
86 int sr = char_height * r;
87 int sc = char_width * c;
88 FT_Load_Char(face, ch, FT_LOAD_RENDER);
89 if (fg >= 8) {
90 int FT_GlyphSlot_Own_Bitmap(FT_GlyphSlot);
91 FT_GlyphSlot_Own_Bitmap(face->glyph);
92 FT_Bitmap_Embolden(library, &face->glyph->bitmap, 32, 32);
94 fb_box(sr, sc, sr + char_height, sc + char_width, mixed_color(0));
95 sr -= face->glyph->bitmap_top - char_height;
96 sc += face->glyph->bitmap_left / 2;
97 draw_bitmap(&face->glyph->bitmap, sr, sc);
100 static void advance(int c)
102 switch (c) {
103 case '\n':
104 row++;
105 col = 0;
106 break;
107 case '\t':
108 col = (col / 8 + 1) * 8;
109 break;
110 case '\b':
111 if (col)
112 col--;
113 break;
114 case '\r':
115 col = 0;
116 break;
117 case '\a':
118 case '\f':
119 case '\v':
120 break;
121 default:
122 col++;
124 if (col >= cols) {
125 row++;
126 col = 0;
128 if (row >= rows) {
129 fb_scroll(-char_height);
130 row = rows - 1;
131 fb_box(row * char_height, 0, fb_rows(), fb_cols(),
132 mixed_color(0));
136 void pad_add(int c)
138 if (!strchr("\a\b\f\n\r\t\v", c))
139 pad_put(c, row, col);
140 advance(c);
143 void pad_blank(void)
145 fb_box(0, 0, fb_rows(), fb_cols(), mixed_color(0));
148 void pad_move(int r, int c)
150 row = MIN(r, rows - 1);
151 col = MIN(c, cols - 1);
154 int pad_row(void)
156 return row;
159 int pad_col(void)
161 return col;
164 int pad_rows(void)
166 return rows;
169 int pad_cols(void)
171 return cols;