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 }
bool isUTF(char c)
Проверяет, является ли символ формата UTF-8.
Definition: string.c:27
uint16_t psf1_rupatch(uint16_t c, uint16_t c2)
252
Definition: psf.c:76
bool text_init(char *psf)
Инициализация шрифта PSF.
Definition: psf.c:32
ssize_t fseek(FILE *stream, ssize_t offset, uint8_t whence)
Установка позиции в потоке данных относительно текущей позиции
Definition: stdio.c:315
void fclose(FILE *stream)
Закончить работу с файлом
Definition: stdio.c:213
FILE * fopen(const char *filename, const char *_mode)
Открывает файл
Definition: stdio.c:166
int ftell(FILE *stream)
Текущая позиция считывания в файле
Definition: stdio.c:287
int fread(FILE *stream, size_t count, size_t size, void *buffer)
Чтение файла
Definition: stdio.c:250
Структура файла. Требуется для работы с VFS.
Definition: stdio.h:21