Rev 7853 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6808 | leency | 1 | // Сам шрифт представляет. |
2 | |||
3 | // Голова: |
||
4 | // [2 байта символы:KF] |
||
5 | // [4 байта:указатель на название шрифта] |
||
6 | // [1 байт:размер массива указателей на размеры шрифтов, указатель 4 байта, т.е. размер = размер массива*4] |
||
7 | // [размер массива*4 байт:указатели..] |
||
8 | |||
9 | // Тело файла: |
||
10 | // [4 байта:масштаб ширина][4 байта:масштаб высота][255*4 байт:указатели на символы][масштаб ширина*масштаб высота байт: данные символов..] |
||
11 | |||
12 | // Конец: |
||
13 | // [Название шрифта:"Times New Roman"] |
||
14 | |||
15 | |||
7286 | leency | 16 | #ifndef INCLUDE_KFONT_H |
17 | #define INCLUDE_KFONT_H |
||
5730 | pavelyakov | 18 | |
19 | #ifndef INCLUDE_MATH_H |
||
20 | #include "../lib/math.h" |
||
21 | #endif |
||
22 | |||
6784 | leency | 23 | #ifndef INCLUDE_IO_H |
8383 | leency | 24 | #include "../lib/fs.h" |
5730 | pavelyakov | 25 | #endif |
26 | |||
6021 | leency | 27 | #include "../lib/patterns/rgb.h" |
28 | |||
29 | |||
5981 | leency | 30 | #define DEFAULT_FONT "/sys/fonts/Tahoma.kf" |
31 | |||
6808 | leency | 32 | #ifndef KFONT_BPP |
33 | #define KFONT_BPP 4 |
||
34 | #endif |
||
35 | |||
7286 | leency | 36 | int kfont_char_width[255]; |
37 | |||
5753 | leency | 38 | :struct __SIZE |
39 | { |
||
5816 | leency | 40 | dword width,height; |
5987 | leency | 41 | signed offset_x, offset_y; |
5988 | leency | 42 | byte pt; |
5753 | leency | 43 | }; |
7286 | leency | 44 | :struct KFONT |
5730 | pavelyakov | 45 | { |
5753 | leency | 46 | __SIZE size; |
5987 | leency | 47 | int width,height; |
6803 | leency | 48 | byte bold,smooth; |
5997 | leency | 49 | dword color, background; |
5987 | leency | 50 | dword font,font_begin; |
5730 | pavelyakov | 51 | word block; |
6803 | leency | 52 | dword raw; |
53 | dword raw_size; |
||
54 | |||
6806 | leency | 55 | bool init(); |
6803 | leency | 56 | bool changeSIZE(); |
5987 | leency | 57 | byte symbol(); |
58 | byte symbol_size(); |
||
59 | dword getsize(); |
||
7286 | leency | 60 | int get_label_width(); |
5987 | leency | 61 | |
6803 | leency | 62 | void ApplySmooth(); |
63 | int WriteIntoWindow(); |
||
64 | int WriteIntoWindowCenter(); |
||
7853 | leency | 65 | dword WriteIntoBuffer(); |
6805 | leency | 66 | void ShowBuffer(); |
6808 | leency | 67 | void ShowBufferPart(); |
6806 | leency | 68 | } kfont; |
5981 | leency | 69 | |
7286 | leency | 70 | :bool KFONT::init(dword font_path) |
6808 | leency | 71 | { |
8383 | leency | 72 | dword fsize_notused; |
6808 | leency | 73 | if(font)free(font); |
8383 | leency | 74 | read_file(font_path, #font_begin, #fsize_notused); |
6808 | leency | 75 | if(!EAX) { |
8383 | leency | 76 | RunProgram("/sys/@notify", "'Error: KFONT is not loaded.' -E"); |
6808 | leency | 77 | return false; |
78 | } |
||
79 | changeSIZE(); |
||
80 | smooth = true; |
||
81 | return true; |
||
82 | } |
||
83 | |||
7286 | leency | 84 | :bool KFONT::changeSIZE() |
5730 | pavelyakov | 85 | { |
7286 | leency | 86 | int i; |
5987 | leency | 87 | dword file_size; |
5736 | pavelyakov | 88 | dword ofs; |
6805 | leency | 89 | if(size.pt<9) size.pt = 9; |
6803 | leency | 90 | font = font_begin; |
91 | ofs = DSDWORD[calc(size.pt-8<<2+font_begin)]; |
||
92 | if(ofs==-1)return false; |
||
5987 | leency | 93 | font += ofs + 156; |
6803 | leency | 94 | file_size = DSDWORD[calc(font)]; |
95 | height = DSBYTE[calc(font+file_size) - 1]; |
||
96 | width = DSBYTE[calc(font+file_size) - 2]; |
||
5754 | pavelyakov | 97 | block = math.ceil(height*width/32); |
7286 | leency | 98 | for (i=0; i<256; i++) { |
99 | kfont_char_width[i] = symbol_size((byte) i); |
||
100 | } |
||
5754 | pavelyakov | 101 | return true; |
5736 | pavelyakov | 102 | } |
6806 | leency | 103 | |
7769 | leency | 104 | :dword KFONT::getsize(byte font_size, dword text1) |
5736 | pavelyakov | 105 | { |
5753 | leency | 106 | size.height = size.width = 0; |
5987 | leency | 107 | size.offset_x = size.offset_y = -1; |
7769 | leency | 108 | if (size.pt != font_size) { |
109 | size.pt = font_size; |
||
7286 | leency | 110 | if(!changeSIZE())return 0; |
111 | } |
||
5742 | pavelyakov | 112 | WHILE(DSBYTE[text1]) |
113 | { |
||
6806 | leency | 114 | size.width += symbol_size(DSBYTE[text1]); |
5742 | pavelyakov | 115 | text1++; |
116 | } |
||
5987 | leency | 117 | $neg size.offset_y |
118 | $neg size.offset_x |
||
5996 | leency | 119 | size.height += size.offset_y+1; |
120 | size.width += size.offset_x+1; |
||
5753 | leency | 121 | return size.width; |
5742 | pavelyakov | 122 | } |
6806 | leency | 123 | |
7769 | leency | 124 | //WILL NOT WORK if requested font_size |
7286 | leency | 125 | //is differ from precalculated kfont_char_width[] |
126 | :int KFONT::get_label_width(dword _label) |
||
5742 | pavelyakov | 127 | { |
7286 | leency | 128 | int len=0; |
129 | while (ESBYTE[_label]) { |
||
130 | len += kfont_char_width[ ESBYTE[_label] ]; |
||
131 | _label++; |
||
132 | } |
||
133 | return len; |
||
134 | } |
||
135 | |||
136 | :byte KFONT::symbol_size(byte s) |
||
137 | { |
||
6806 | leency | 138 | int chaw_width; |
139 | chaw_width = symbol(0,0, s, 0); |
||
140 | if(bold) chaw_width += math.ceil(size.pt/17); |
||
141 | return chaw_width; |
||
5742 | pavelyakov | 142 | } |
6806 | leency | 143 | |
7286 | leency | 144 | :byte KFONT::symbol(signed x,y; byte s; dword image_raw) |
5981 | leency | 145 | { |
6805 | leency | 146 | dword xi,yi; |
147 | dword iii = 0; |
||
148 | dword offs; |
||
6806 | leency | 149 | dword tmp, _; |
150 | byte X; |
||
151 | byte chaw_width=0; |
||
7798 | leency | 152 | if(s==32)return width/4+1; |
6805 | leency | 153 | if(s==9)return width; |
154 | s = Cp866ToAnsi(s); |
||
6806 | leency | 155 | tmp = block*s << 2 + font; |
6805 | leency | 156 | for(yi=0; yi |
157 | { |
||
6808 | leency | 158 | EDI = size.offset_y + yi + y * size.width * KFONT_BPP + image_raw; |
6805 | leency | 159 | for(xi=0; xi |
5981 | leency | 160 | { |
6806 | leency | 161 | if(iii%32) _ >>= 1; |
6805 | leency | 162 | else |
5981 | leency | 163 | { |
6806 | leency | 164 | tmp += 4; |
165 | _ = DSDWORD[tmp]; |
||
5981 | leency | 166 | } |
6806 | leency | 167 | if(_&1) //check does the pixel set |
6805 | leency | 168 | { |
6806 | leency | 169 | if(xi>chaw_width)chaw_width=xi; |
6808 | leency | 170 | //in case of image_raw!=0 draw font into bug |
171 | //in case of image_raw==0 calculate size |
||
6806 | leency | 172 | if (image_raw) |
173 | { |
||
6808 | leency | 174 | offs = x + xi * KFONT_BPP + EDI; |
175 | DSDWORD[offs] = color; |
||
176 | if(bold) DSDWORD[offs+KFONT_BPP] = color; |
||
6806 | leency | 177 | } |
178 | else |
||
179 | { |
||
180 | if(size.height |
||
181 | if(size.offset_y<0)size.offset_y = yi; else if(yi |
||
182 | if(!X) X = xi; else if(X>xi)X = xi; |
||
183 | if(size.offset_x<0)size.offset_x = X; |
||
184 | } |
||
6805 | leency | 185 | } |
186 | iii++; |
||
5981 | leency | 187 | } |
6805 | leency | 188 | } |
6806 | leency | 189 | return chaw_width; |
5981 | leency | 190 | } |
191 | |||
6803 | leency | 192 | inline fastcall Cp866ToAnsi(AL) { |
193 | if (AL>=128)&&(AL<=175) return AL+64; |
||
194 | if (AL>=224)&&(AL<=239) return AL+16; |
||
195 | if (AL==241) return 184; //e ruAL with dotAL (yo) |
||
196 | if (AL==240) return 168; //E ruAL with dotAL (yo) |
||
197 | if (AL==242) return 'E'; //E ukr (ye) |
||
198 | if (AL==243) return 186; //e ukr (ye) |
||
199 | if (AL==244) return 'I'; //I ukr (yi) |
||
200 | if (AL==245) return 191; //i ukr (yi) |
||
201 | return AL; |
||
5981 | leency | 202 | } |
203 | |||
5987 | leency | 204 | /*===================================================================================== |
205 | =========================== =========================== |
||
206 | =========================== RAW =========================== |
||
207 | =========================== =========================== |
||
208 | =====================================================================================*/ |
||
209 | |||
6808 | leency | 210 | inline fastcall dword b32(EAX) { return DSDWORD[EAX]; } |
7286 | leency | 211 | :void KFONT::ApplySmooth() |
5981 | leency | 212 | { |
6053 | leency | 213 | dword i,line_w,to,dark_background; |
6808 | leency | 214 | line_w = size.width * KFONT_BPP; |
215 | to = size.height - 1 * line_w + raw - KFONT_BPP; |
||
216 | for(i=raw; i < to; i+=KFONT_BPP) |
||
5985 | leency | 217 | { |
6808 | leency | 218 | if(i-raw%line_w +KFONT_BPP == line_w) continue; |
6021 | leency | 219 | // pixels position, where b - black, w - write |
220 | // bw |
||
221 | // wb |
||
6808 | leency | 222 | if(b32(i)!=background) { |
223 | if (b32(i+KFONT_BPP)==background) |
||
224 | && (b32(i+line_w)==background) && (b32(i+KFONT_BPP+line_w)!=background) |
||
225 | { |
||
226 | dark_background = MixColors(background,b32(i),200); |
||
227 | DSDWORD[i+KFONT_BPP] = dark_background; |
||
228 | DSDWORD[i+line_w] = dark_background; |
||
229 | } |
||
5981 | leency | 230 | } |
6021 | leency | 231 | // wb |
232 | // bw |
||
6808 | leency | 233 | else if (b32(i+KFONT_BPP)!=background) |
234 | && (b32(i+line_w)!=background) && (b32(i+KFONT_BPP+line_w)==background) |
||
5981 | leency | 235 | { |
6808 | leency | 236 | dark_background = MixColors(background,b32(i+KFONT_BPP),200); |
237 | DSDWORD[i] = dark_background; |
||
238 | DSDWORD[i+KFONT_BPP+line_w] = dark_background; |
||
5981 | leency | 239 | } |
240 | } |
||
241 | } |
||
242 | |||
7853 | leency | 243 | :dword KFONT::WriteIntoBuffer(int x,y,w,h; dword _background, _color; byte font_size; dword text1) |
5782 | leency | 244 | { |
5987 | leency | 245 | dword new_raw_size; |
6803 | leency | 246 | if(!text1)return; |
5987 | leency | 247 | |
7769 | leency | 248 | if (size.pt != font_size) { |
249 | getsize(font_size, text1); |
||
6021 | leency | 250 | y -= size.offset_y; |
251 | } |
||
5997 | leency | 252 | color = _color; |
253 | background = _background; |
||
5981 | leency | 254 | |
5782 | leency | 255 | size.width = w; |
5783 | leency | 256 | size.height = h; |
5784 | leency | 257 | |
6808 | leency | 258 | new_raw_size = w*h*KFONT_BPP; |
6803 | leency | 259 | if(raw_size != new_raw_size) |
5782 | leency | 260 | { |
5987 | leency | 261 | raw_size = new_raw_size; |
262 | free(raw); |
||
263 | raw = malloc(raw_size); |
||
5985 | leency | 264 | // Fill background color |
5987 | leency | 265 | EBX = background; |
266 | EAX = raw_size+raw; |
||
6808 | leency | 267 | for (EDI=raw; EDI |
5782 | leency | 268 | } |
269 | WHILE(DSBYTE[text1]) |
||
270 | { |
||
5987 | leency | 271 | x+=symbol(x,y,DSBYTE[text1], raw); |
6803 | leency | 272 | if(bold)x+=math.ceil(size.pt/17); |
5782 | leency | 273 | text1++; |
274 | } |
||
7853 | leency | 275 | return x; |
5782 | leency | 276 | } |
277 | |||
7769 | leency | 278 | :int KFONT::WriteIntoWindow(int x,y; dword _background, _color; byte font_size; dword text1) |
6805 | leency | 279 | { |
280 | if(!text1)return 0; |
||
7769 | leency | 281 | getsize(font_size, text1); |
6805 | leency | 282 | raw_size = NULL; |
283 | WriteIntoBuffer(0, -size.offset_y, size.width-size.offset_x, |
||
7769 | leency | 284 | size.height-size.offset_y, _background, _color, font_size, text1); |
6805 | leency | 285 | if (smooth) ApplySmooth(); |
286 | ShowBuffer(x,y); |
||
287 | return size.offset_x + size.width; |
||
288 | } |
||
289 | |||
7769 | leency | 290 | :int KFONT::WriteIntoWindowCenter(dword x, _y,w,h, _background, _color; byte font_size; dword text1) |
6805 | leency | 291 | { |
7769 | leency | 292 | getsize(font_size, text1); |
293 | return WriteIntoWindow(w-size.width/2+x-1, _y, _background, _color, font_size, text1); |
||
6805 | leency | 294 | } |
295 | |||
7286 | leency | 296 | :void KFONT::ShowBuffer(dword _x, _y) |
6808 | leency | 297 | { |
298 | if (4==KFONT_BPP) PutPaletteImage(raw, size.width, size.height, _x, _y, 32, 0); |
||
299 | //if (1==KFONT_BPP) PutPaletteImage(raw, size.width, size.height, _x, _y, 8, #palette); |
||
5985 | leency | 300 | } |
301 | |||
7286 | leency | 302 | :void KFONT::ShowBufferPart(dword _x, _y, _w, _h, _buf_offset) |
6808 | leency | 303 | { |
304 | if (4==KFONT_BPP) PutPaletteImage(_buf_offset * KFONT_BPP + raw, _w, _h, _x, _y, 32, 0); |
||
305 | //if (1==KFONT_BPP) PutPaletteImage(_buf_offset * KFONT_BPP + raw, _w, _h, _x, _y, 8, #palette); |
||
306 | } |
||
5985 | leency | 307 | |
5730 | pavelyakov | 308 | #endif>=239)>=175)>0)size.offset_x>0)size.offset_y>><>256;>2+font_begin)]; |