Rev 5981 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5730 | pavelyakov | 1 | #ifndef INCLUDE_FONT_H |
2 | #define INCLUDE_FONT_H |
||
3 | |||
4 | #ifndef INCLUDE_MATH_H |
||
5 | #include "../lib/math.h" |
||
6 | #endif |
||
7 | |||
5933 | pavelyakov | 8 | #ifndef INCLUDE_FS_H |
5885 | pavelyakov | 9 | #include "../lib/obj/fs.h" |
5730 | pavelyakov | 10 | #endif |
11 | |||
5981 | leency | 12 | #define DEFAULT_FONT "/sys/fonts/Tahoma.kf" |
13 | |||
5800 | pavelyakov | 14 | :struct __OFFSET_FONT |
15 | { |
||
16 | signed x,y; |
||
17 | }; |
||
5753 | leency | 18 | :struct __SIZE |
19 | { |
||
5816 | leency | 20 | dword width,height; |
5800 | pavelyakov | 21 | __OFFSET_FONT offset; |
5757 | pavelyakov | 22 | float offset_i,w_italic; |
5753 | leency | 23 | byte text; |
5754 | pavelyakov | 24 | byte TMP_WEIGHT; |
5753 | leency | 25 | }; |
5730 | pavelyakov | 26 | :struct FONT |
27 | { |
||
5753 | leency | 28 | __SIZE size; |
5981 | leency | 29 | int left,top,width,height; |
30 | byte bold,italic,smooth; |
||
31 | dword bg_color; |
||
5753 | leency | 32 | dword color; |
5736 | pavelyakov | 33 | dword file_size; |
5740 | pavelyakov | 34 | dword buffer; |
5741 | pavelyakov | 35 | dword buffer_size; |
5730 | pavelyakov | 36 | word block; |
37 | dword data; |
||
5736 | pavelyakov | 38 | dword begin; |
5730 | pavelyakov | 39 | byte load(...); |
5985 | leency | 40 | byte changeSIZE(); |
41 | byte symbol(signed x,y;byte s;dword c); |
||
5742 | pavelyakov | 42 | byte symbol_size(byte s); |
5753 | leency | 43 | dword getsize(dword text1); |
5985 | leency | 44 | void apply_smooth(); |
45 | int write_center(dword x,y,w,h;dword txt); |
||
46 | int write(int x,y;dword text1); |
||
47 | void write_buf(int x,y,w,h, text1); |
||
48 | void show_buf(); |
||
5730 | pavelyakov | 49 | }; |
50 | FONT font = 0; |
||
5981 | leency | 51 | |
5753 | leency | 52 | :byte FONT::changeSIZE() |
5730 | pavelyakov | 53 | { |
5736 | pavelyakov | 54 | dword TMP_DATA; |
55 | dword ofs; |
||
5753 | leency | 56 | IF(size.text<9) size.text = 8; |
5783 | leency | 57 | TMP_DATA = data = begin; |
58 | TMP_DATA +=size.text-8*4; |
||
5754 | pavelyakov | 59 | ofs = DSDWORD[TMP_DATA]; |
60 | IF(ofs==-1)return false; |
||
5783 | leency | 61 | data += ofs + 156; |
5754 | pavelyakov | 62 | TMP_DATA = data; |
63 | file_size = DSDWORD[TMP_DATA]; |
||
5783 | leency | 64 | TMP_DATA = data + file_size; |
65 | height = DSBYTE[TMP_DATA - 1]; |
||
66 | width = DSBYTE[TMP_DATA - 2]; |
||
5754 | pavelyakov | 67 | block = math.ceil(height*width/32); |
68 | return true; |
||
5736 | pavelyakov | 69 | } |
5753 | leency | 70 | :dword FONT::getsize(dword text1) |
5736 | pavelyakov | 71 | { |
5753 | leency | 72 | size.height = size.width = 0; |
5800 | pavelyakov | 73 | size.offset.x = size.offset.y = -1; |
5753 | leency | 74 | IF(size.text)IF(!changeSIZE())return 0; |
5742 | pavelyakov | 75 | WHILE(DSBYTE[text1]) |
76 | { |
||
5753 | leency | 77 | symbol_size(DSBYTE[text1]); |
5742 | pavelyakov | 78 | text1++; |
79 | } |
||
5800 | pavelyakov | 80 | $neg size.offset.y |
81 | $neg size.offset.x |
||
82 | size.height += size.offset.y; size.height++; |
||
83 | size.width += size.offset.x; size.width++; |
||
5757 | pavelyakov | 84 | IF(italic) |
85 | { |
||
5758 | pavelyakov | 86 | size.w_italic = size.height/3; |
87 | size.offset_i = size.w_italic/size.height; |
||
88 | size.width += size.w_italic; |
||
89 | size.w_italic = -size.w_italic; |
||
5757 | pavelyakov | 90 | } |
5753 | leency | 91 | return size.width; |
5742 | pavelyakov | 92 | } |
93 | :byte FONT::symbol_size(byte s) |
||
94 | { |
||
5981 | leency | 95 | dword xi,yi; |
96 | dword tmp,_; |
||
5985 | leency | 97 | dword iii = 0; |
5981 | leency | 98 | byte rw=0; |
5753 | leency | 99 | byte X; |
5754 | pavelyakov | 100 | size.TMP_WEIGHT = math.ceil(size.text/17); |
5981 | leency | 101 | IF(s==32) |
5753 | leency | 102 | { |
103 | size.width += width/4; |
||
5981 | leency | 104 | IF(bold) size.width+=size.TMP_WEIGHT; |
5753 | leency | 105 | return; |
106 | } |
||
107 | IF(s==9) |
||
108 | { |
||
109 | size.width += width; |
||
5981 | leency | 110 | IF(bold) size.width+=size.TMP_WEIGHT; |
5753 | leency | 111 | return; |
112 | } |
||
5981 | leency | 113 | s = AnsiToCp866(s); |
114 | tmp = 4*block*s + data; |
||
115 | for(yi=0; yi |
||
116 | { |
||
117 | for(xi=0; xi |
||
118 | { |
||
119 | IF(iii%32) _ >>= 1; |
||
5784 | leency | 120 | ELSE |
121 | { |
||
5981 | leency | 122 | tmp += 4; |
123 | _ = DSDWORD[tmp]; |
||
124 | } |
||
125 | IF(_&1) |
||
5784 | leency | 126 | { |
127 | IF(xi>rw)rw=xi; |
||
128 | IF(size.height |
||
5800 | pavelyakov | 129 | IF(size.offset.y<0)size.offset.y = yi; |
130 | ELSE IF(yi |
||
5784 | leency | 131 | IF(!X) X = xi; |
132 | ELSE IF(X>xi)X = xi; |
||
133 | } |
||
5981 | leency | 134 | iii++; |
135 | } |
||
136 | } |
||
5753 | leency | 137 | size.width += rw; |
5981 | leency | 138 | IF(bold) size.width+=size.TMP_WEIGHT; |
5753 | leency | 139 | IF(s=='_') size.width--; |
5800 | pavelyakov | 140 | IF(size.offset.x<0)size.offset.x = X; |
5742 | pavelyakov | 141 | } |
5981 | leency | 142 | :byte FONT::symbol(signed x,y;byte s) |
143 | { |
||
144 | dword xi,yi; |
||
5985 | leency | 145 | dword iii = 0; |
146 | dword offs; |
||
5981 | leency | 147 | float ital = -size.w_italic; |
148 | dword ___x; |
||
149 | byte rw=0; |
||
150 | IF(s==32)return width/4; |
||
151 | IF(s==9)return width; |
||
152 | s = AnsiToCp866(s); |
||
153 | EBX = block*s << 2 + data; |
||
154 | for(yi=0; yi |
||
155 | { |
||
5985 | leency | 156 | EDI = size.offset.y + yi + y * size.width * 3 + buffer; |
5981 | leency | 157 | for(xi=0; xi |
158 | { |
||
159 | IF(iii%32) $shr ecx,1 |
||
160 | ELSE |
||
161 | { |
||
162 | EBX += 4; |
||
163 | ECX = DSDWORD[EBX]; |
||
164 | } |
||
165 | IF(ECX&true) |
||
166 | { |
||
167 | IF(xi>rw)rw=xi; |
||
168 | ___x = x+xi; |
||
169 | IF(italic)___x+=math.ceil(ital); |
||
5985 | leency | 170 | offs = ___x*3 + EDI; |
171 | DSDWORD[offs] = DSDWORD[offs] & 0xFF000000 | color; |
||
172 | IF(bold) DSDWORD[offs+3] = DSDWORD[offs+3] & 0xFF000000 | color; |
||
5981 | leency | 173 | } |
174 | iii++; |
||
175 | } |
||
176 | if (italic) ital-=size.offset_i; |
||
177 | } |
||
178 | return rw; |
||
179 | } |
||
180 | |||
181 | byte AnsiToCp866(byte s) { |
||
182 | IF(s>=128)&&(s<=175)s+=64; |
||
183 | ELSE IF(s>=224)&&(s<=239)s+=16; |
||
184 | ELSE IF(s==241)s=184; //yo |
||
185 | ELSE IF(s==240)s=168; //YO |
||
186 | return s; |
||
187 | } |
||
188 | |||
189 | inline fastcall dword b24(EBX) { return DSDWORD[EBX] << 8; } |
||
5985 | leency | 190 | :void FONT::apply_smooth() |
5981 | leency | 191 | { |
192 | dword i,line_w,to; |
||
5985 | leency | 193 | line_w = font.size.width * 3; |
194 | to = font.size.height - 1 * line_w + font.buffer - 3; |
||
195 | for(i=font.buffer; i < to; i+=3) |
||
196 | { |
||
197 | IF(i-font.buffer%line_w +3 == line_w) continue; |
||
5981 | leency | 198 | IF(b24(i)==0x000000) && (b24(i+3)!=0x000000) && (b24(i+line_w)!=0x000000) && (b24(i+3+line_w)==0x000000) |
199 | { |
||
5985 | leency | 200 | ShadowPixel(i+3, 2); |
201 | ShadowPixel(i+line_w, 2); |
||
5981 | leency | 202 | } |
203 | ELSE IF(b24(i)!=0x000000) && (b24(i+3)==0x000000) && (b24(i+line_w)==0x000000) && (b24(i+3+line_w)!=0x000000) |
||
204 | { |
||
5985 | leency | 205 | ShadowPixel(i, 2); |
206 | ShadowPixel(i+3+line_w, 2); |
||
5981 | leency | 207 | } |
208 | } |
||
209 | } |
||
210 | :byte FONT::load(dword path) |
||
211 | { |
||
212 | lib_init_fs(); |
||
213 | buffer_size = 0; |
||
214 | smooth = true; |
||
215 | IF(data)free(data); |
||
216 | IF(!fs.read(path)) { debug("Error while loading font: "); debugln(path); return false; } |
||
217 | begin = data = EAX; |
||
218 | EBX = begin + ECX; |
||
219 | height = DSBYTE[EBX-1]; |
||
220 | width = DSBYTE[EBX-2]; |
||
221 | block = math.ceil(height*width/32); |
||
222 | return true; |
||
223 | } |
||
224 | |||
5985 | leency | 225 | :int FONT::write_center(dword x,y,w,h;dword txt) |
5742 | pavelyakov | 226 | { |
5985 | leency | 227 | getsize(txt); |
228 | return write(w-size.width/2+x,y,txt); |
||
229 | } |
||
230 | |||
231 | :int FONT::write(int x,y; dword text1) |
||
232 | { |
||
5742 | pavelyakov | 233 | signed len=0; |
5754 | pavelyakov | 234 | IF(!text1)return false; |
235 | IF(size.text)IF(!changeSIZE())return false; |
||
5981 | leency | 236 | left = x; |
5753 | leency | 237 | getsize(text1); |
5800 | pavelyakov | 238 | y -= size.offset.y; |
5814 | pavelyakov | 239 | top = y; |
5754 | pavelyakov | 240 | EDX = size.width*size.height*3; |
5745 | leency | 241 | IF(!buffer_size) |
242 | { |
||
5754 | pavelyakov | 243 | buffer_size = EDX; |
5745 | leency | 244 | buffer = malloc(buffer_size); |
245 | } |
||
5754 | pavelyakov | 246 | ELSE IF(buffer_size |
5745 | leency | 247 | { |
5754 | pavelyakov | 248 | buffer_size = EDX; |
5745 | leency | 249 | buffer = realloc(buffer,buffer_size); |
250 | } |
||
5985 | leency | 251 | // Fill background color { |
252 | EBX = bg_color; |
||
253 | EAX = buffer_size+buffer; |
||
254 | for (EDI=buffer; EDI |
||
255 | // } |
||
5800 | pavelyakov | 256 | len = size.offset.x; |
5730 | pavelyakov | 257 | WHILE(DSBYTE[text1]) |
258 | { |
||
5753 | leency | 259 | IF(DSBYTE[text1]=='_') len--; |
5784 | leency | 260 | len+=symbol(len,0,DSBYTE[text1]); |
5981 | leency | 261 | IF(bold)len+=math.ceil(size.text/17); |
5730 | pavelyakov | 262 | text1++; |
263 | } |
||
5985 | leency | 264 | IF (smooth) apply_smooth(); |
265 | show_buf(left,top); |
||
5730 | pavelyakov | 266 | return len; |
267 | } |
||
268 | |||
5985 | leency | 269 | :void FONT::write_buf(int x,y,w,h; dword text1) |
5782 | leency | 270 | { |
5985 | leency | 271 | dword new_buffer_size; |
5782 | leency | 272 | IF(!text1)return; |
273 | IF(size.text)IF(!changeSIZE())return; |
||
274 | getsize(text1); |
||
5800 | pavelyakov | 275 | y -= size.offset.y; |
5981 | leency | 276 | |
5782 | leency | 277 | size.width = w; |
5783 | leency | 278 | size.height = h; |
5784 | leency | 279 | |
5816 | leency | 280 | new_buffer_size = w*h*3; |
5981 | leency | 281 | IF(buffer_size != w*h*3) |
5782 | leency | 282 | { |
5816 | leency | 283 | buffer_size = new_buffer_size; |
5784 | leency | 284 | free(buffer); |
5816 | leency | 285 | buffer = malloc(buffer_size); |
5985 | leency | 286 | // Fill background color |
5816 | leency | 287 | EBX = bg_color; |
288 | EAX = buffer_size+buffer; |
||
5981 | leency | 289 | for (EDI=buffer; EDI |
5782 | leency | 290 | } |
291 | WHILE(DSBYTE[text1]) |
||
292 | { |
||
5784 | leency | 293 | x+=symbol(x,y,DSBYTE[text1]); |
5981 | leency | 294 | IF(bold)x+=math.ceil(size.text/17); |
5782 | leency | 295 | text1++; |
296 | } |
||
297 | return; |
||
298 | } |
||
299 | |||
5985 | leency | 300 | :void FONT::show_buf(dword left1, top1){ |
301 | _PutImage(left1,top1,size.width,size.height,buffer); |
||
302 | } |
||
303 | |||
304 | |||
305 | |||
306 | |||
5730 | pavelyakov | 307 | #endif |