SayoriOS 0.3.3

psf.c
См. документацию.
1
10 #include <drv/psf.h>
11 #include <lib/stdio.h>
12 #include <io/ports.h>
13 #include "mem/vmm.h"
14 #include "io/serial_port.h"
15 #include "io/screen.h"
16
17 uint32_t psf_font_version = 0;
18
19 static psf_t *_font_ptr = nullptr;
20 static bool _init = false;
21 static uint8_t _w = 8;
22 static uint8_t _h = 0;
23 uint8_t* first_glyph = 0;
24
25 uint16_t *unicode;
26
32 bool text_init(char* psf){
33 ON_NULLPTR(psf, {
34 qemu_log("Filename is nullptr!");
35 return false;
36 });
37
38 FILE* psf_file = fopen(psf, "r");
39 if (!psf_file) {
40 qemu_log("[Core] [PSF] Не удалось найти файл `%s`. \n",psf);
41 return false;
42 }
43
44 fseek(psf_file, 0, SEEK_END);
45 size_t rfsize = ftell(psf_file);
46 fseek(psf_file, 0, SEEK_SET);
47
48 char* buffer = kmalloc(rfsize);
49 fread(psf_file, rfsize, 1, buffer);
50 fclose(psf_file);
51
52 psf_t *header = (psf_t*)buffer;
53 _init = false;
54 _w = 0;
55 _h = 0;
56 if (header->magic[0] != PSF1_MAGIC0 || header->magic[1] != PSF1_MAGIC1){
57 qemu_log("PSF Header Error");
58 return false;
59 }
60 _font_ptr = (psf_t*)buffer;
61 _w = 8;
62 _h = header->charHeight;
63 _init = true;
64 first_glyph = (uint8_t*)_font_ptr+sizeof(psf_t);
65 return _init;
66 }
67
68 size_t psf1_get_w(){
69 return _w;
70 }
71
72 size_t psf1_get_h(){
73 return _h;
74 }
76 uint16_t psf1_rupatch(uint16_t c,uint16_t c2){
77 if (!isUTF(c)) return c;
78 if ((c & 0x1F) != 16 && (c & 0x1F) != 17) return c;
79 uint16_t x = (c2 & 0x3F);
80 uint16_t lS = 224;
81 uint16_t bS = 128;
82 switch(x){
83 case 1: return ((c & 0x1F) == 16?lS+16:lS+1);
84 case 17: return ((c & 0x1F) == 17?lS+17:bS+1);
85 case 0: return lS+0; case 22: return bS+6; case 42: return bS+26;
86 case 2: return lS+2; case 23: return bS+7; case 43: return bS+27;
87 case 3: return lS+3; case 24: return bS+8; case 44: return bS+28;
88 case 4: return lS+4; case 25: return bS+9; case 45: return bS+29;
89 case 5: return lS+5; case 26: return bS+10; case 46: return bS+30;
90 case 6: return lS+6; case 27: return bS+11; case 47: return bS+31;
91 case 7: return lS+7; case 28: return bS+12; case 48: return bS+32;
92 case 8: return lS+8; case 29: return bS+13; case 49: return bS+33;
93 case 9: return lS+9; case 30: return bS+14; case 50: return bS+34;
94 case 10: return lS+10; case 31: return bS+15; case 51: return bS+35;
95 case 11: return lS+11; case 32: return bS+16; case 52: return bS+36;
96 case 12: return lS+12; case 33: return bS+17; case 53: return bS+37;
97 case 13: return lS+13; case 34: return bS+18; case 54: return bS+38;
98 case 14: return lS+14; case 35: return bS+19; case 55: return bS+39;
99 case 15: return lS+15; case 36: return bS+20; case 56: return bS+40;
100 case 16: return bS+0; case 37: return bS+21; case 57: return bS+41;
101 case 18: return bS+2; case 38: return bS+22; case 58: return bS+42;
102 case 19: return bS+3; case 39: return bS+23; case 59: return bS+43;
103 case 20: return bS+4; case 40: return bS+24; case 60: return bS+44;
104 case 21: return bS+5; case 41: return bS+25; case 61: return bS+45;
105 case 62: return bS+46; case 63: return bS+47;
106 default: return 1;
107 }
108 }
109
110 uint8_t *psf1_get_glyph(uint16_t ch){
111 psf_t *header = (psf_t*)_font_ptr;
112
113 if ((ch > 511) || (ch > 255 && (header->mode == 0 || header->mode == 2))){
114 qemu_log("[PSF] DEAD >>> %d (returning nullptr)", ch);
115 return 0;
116 }
117 //qemu_log("\t\t >[PSF] C:%c=%d p:%d h:%d a:%d",ch,ch,ch*_h,_h,((ch*_h)/8));
118 return ((uint8_t*)_font_ptr+sizeof(psf_t)+(ch*_h));
119 }
120
121 void draw_vga_ch(uint16_t c, uint16_t c2, size_t pos_x, size_t pos_y, size_t color) {
122 char mask[8] = {128,64,32,16,8,4,2,1};
123 if (isUTF(c) && false) { // Ideal method to disable code block LOL
124 __com_formatString(PORT_COM1,"||||||||||||||\n");
125 qemu_log("Is UTF8 C1:%c => %s%s",(char)c, c,c2);
126 __com_formatString(PORT_COM1,"%d\n",c);
127 __com_formatString(PORT_COM1,"%d\n",c2);
128 __com_formatString(PORT_COM1,"%d\n",(c & 0x1F));
129 __com_formatString(PORT_COM1,"%d\n",(c & 0x1F)<<6);
130 __com_formatString(PORT_COM1,"%d\n",(c2 & 0x3F));
131 __com_formatString(PORT_COM1,"%d\n",((c & 0x1F)<<6)+(c2 & 0x3F));
132 __com_formatString(PORT_COM1,"%d\n",(((c & 0x1F)<<6)+(c2 & 0x3F)) & 128);
133 __com_formatString(PORT_COM1,"||||||||||||||\n");
134 //int sdaqsd = ((c & 0x1F)<<6)+(c2 & 0x3F);
135 //glyph = psf1_rupatch(c,c2);
136 }
137
138 uint8_t *glyph = psf1_get_glyph(psf1_rupatch(c, c2));
139
140 if(!glyph)
141 return;
142
143 // size_t ph = _h; //psf1_get_h();
144 // size_t pw = _w; //psf1_get_w();
145 for (size_t y = 0; y < _h; y++){
146 for (size_t x = 0; x < _w; x++){
147 if (glyph[y] & mask[x]) {
148 // qemu_log("DRAWFONT: X: %d Y: %d", x, y);
149 set_pixel(pos_x+x, pos_y+y, color);
150 }
151 }
152 // qemu_log("LINE");
153 }
154 // qemu_log("OK");
155
156 // __com_formatString(PORT_COM1,"||||||||||||||\n");
157 }
158
159 void draw_vga_str(const char* text, size_t len, int x, int y, uint32_t color){
160 ON_NULLPTR(text, {
161 return;
162 });
163
164 size_t scrwidth = getScreenWidth();
165 for(int i = 0; i < len; i++){
166 if (x + _w <= scrwidth){
167 if (isUTF(text[i])){
168 draw_vga_ch(text[i], text[i+1], x, y, color);
169 i++;
170 } else {
171 if(!text[i])
172 return;
173 draw_vga_ch(text[i], 0, x, y, color);
174 }
175 x += _w;
176 } else {
177 break;
178 }
179 }
180 }
isUTF
bool isUTF(char c)
Проверяет, является ли символ формата UTF-8.
Definition: string.c:27
psf1_rupatch
uint16_t psf1_rupatch(uint16_t c, uint16_t c2)
252
Definition: psf.c:76
text_init
bool text_init(char *psf)
Инициализация шрифта PSF.
Definition: psf.c:32
fseek
ssize_t fseek(FILE *stream, ssize_t offset, uint8_t whence)
Установка позиции в потоке данных относительно текущей позиции
Definition: stdio.c:315
fclose
void fclose(FILE *stream)
Закончить работу с файлом
Definition: stdio.c:213
fopen
FILE * fopen(const char *filename, const char *_mode)
Открывает файл
Definition: stdio.c:166
ftell
int ftell(FILE *stream)
Текущая позиция считывания в файле
Definition: stdio.c:287
fread
int fread(FILE *stream, size_t count, size_t size, void *buffer)
Чтение файла
Definition: stdio.c:250
FILE
Структура файла. Требуется для работы с VFS.
Definition: stdio.h:21