Go to most recent revision | Details | 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 | |||
8 | #ifndef INCLUDE_IO_H |
||
9 | #include "../lib/io.h" |
||
10 | #endif |
||
11 | |||
5800 | pavelyakov | 12 | :struct __OFFSET_FONT |
13 | { |
||
14 | signed x,y; |
||
15 | }; |
||
5753 | leency | 16 | :struct __SIZE |
17 | { |
||
5816 | leency | 18 | dword width,height; |
5800 | pavelyakov | 19 | __OFFSET_FONT offset; |
5757 | pavelyakov | 20 | float offset_i,w_italic; |
5753 | leency | 21 | byte text; |
5754 | pavelyakov | 22 | byte TMP_WEIGHT; |
5753 | leency | 23 | }; |
5730 | pavelyakov | 24 | :struct FONT |
25 | { |
||
5753 | leency | 26 | __SIZE size; |
5784 | leency | 27 | byte r,g,b,weight,italic, smooth; |
5783 | leency | 28 | byte width,height; |
5814 | pavelyakov | 29 | word left,top; |
5759 | pavelyakov | 30 | byte encoding; |
5753 | leency | 31 | dword color; |
5736 | pavelyakov | 32 | dword file_size; |
5740 | pavelyakov | 33 | dword buffer; |
5741 | pavelyakov | 34 | dword buffer_size; |
5730 | pavelyakov | 35 | word block; |
36 | dword data; |
||
5736 | pavelyakov | 37 | dword begin; |
5730 | pavelyakov | 38 | byte load(...); |
5784 | leency | 39 | byte symbol(word x,y;byte s;dword c); |
5742 | pavelyakov | 40 | byte symbol_size(byte s); |
5776 | leency | 41 | dword prepare(word x,y;dword text1); |
5816 | leency | 42 | void prepare_buf(dword x,y,w,h, text1); |
5814 | pavelyakov | 43 | void show(); |
5757 | pavelyakov | 44 | byte textcenter(word x,y,w,h;dword txt); |
5753 | leency | 45 | dword getsize(dword text1); |
46 | byte changeSIZE(); |
||
5816 | leency | 47 | void PixelRGB(dword x,y); |
5782 | leency | 48 | //dword GetPixel(word x,y); |
5745 | leency | 49 | byte no_bg_copy; |
50 | dword bg_color; |
||
5730 | pavelyakov | 51 | }; |
52 | FONT font = 0; |
||
5782 | leency | 53 | /* |
5757 | pavelyakov | 54 | :dword FONT::GetPixel(word x,y) |
55 | { |
||
5782 | leency | 56 | dword tmp = y*size.width*3; |
57 | tmp += x*3 + buffer; |
||
5783 | leency | 58 | r = DSBYTE[tmp]; tmp++; |
59 | g = DSBYTE[tmp]; tmp++; |
||
60 | b = DSBYTE[tmp]; |
||
5782 | leency | 61 | }*/ |
5740 | pavelyakov | 62 | :void FONT::PixelRGB(dword x,y) |
63 | { |
||
5816 | leency | 64 | dword offs = y*size.width+x*3 + buffer; |
65 | DSBYTE[offs] = r; offs++; |
||
66 | DSBYTE[offs] = g; offs++; |
||
67 | DSBYTE[offs] = b; |
||
5740 | pavelyakov | 68 | } |
5753 | leency | 69 | :byte FONT::changeSIZE() |
5730 | pavelyakov | 70 | { |
5736 | pavelyakov | 71 | dword TMP_DATA; |
72 | dword ofs; |
||
5753 | leency | 73 | IF(size.text<9) size.text = 8; |
5783 | leency | 74 | TMP_DATA = data = begin; |
75 | TMP_DATA +=size.text-8*4; |
||
5754 | pavelyakov | 76 | ofs = DSDWORD[TMP_DATA]; |
77 | IF(ofs==-1)return false; |
||
5783 | leency | 78 | data += ofs + 156; |
5754 | pavelyakov | 79 | TMP_DATA = data; |
80 | file_size = DSDWORD[TMP_DATA]; |
||
5783 | leency | 81 | TMP_DATA = data + file_size; |
82 | height = DSBYTE[TMP_DATA - 1]; |
||
83 | width = DSBYTE[TMP_DATA - 2]; |
||
5754 | pavelyakov | 84 | block = math.ceil(height*width/32); |
85 | return true; |
||
5736 | pavelyakov | 86 | } |
5757 | pavelyakov | 87 | :byte FONT::textcenter(word x,y,w,h;dword txt) |
88 | { |
||
89 | getsize(txt); |
||
90 | EDX = w/2; |
||
91 | ECX = size.width/2; |
||
92 | EDX -= ECX; |
||
93 | x += EDX; |
||
5814 | pavelyakov | 94 | prepare(x,y,txt); |
5757 | pavelyakov | 95 | } |
5753 | leency | 96 | :dword FONT::getsize(dword text1) |
5736 | pavelyakov | 97 | { |
5753 | leency | 98 | size.height = size.width = 0; |
5800 | pavelyakov | 99 | size.offset.x = size.offset.y = -1; |
5753 | leency | 100 | IF(size.text)IF(!changeSIZE())return 0; |
5742 | pavelyakov | 101 | WHILE(DSBYTE[text1]) |
102 | { |
||
5753 | leency | 103 | symbol_size(DSBYTE[text1]); |
5742 | pavelyakov | 104 | text1++; |
105 | } |
||
5800 | pavelyakov | 106 | $neg size.offset.y |
107 | $neg size.offset.x |
||
108 | size.height += size.offset.y; size.height++; |
||
109 | size.width += size.offset.x; size.width++; |
||
5757 | pavelyakov | 110 | IF(italic) |
111 | { |
||
5758 | pavelyakov | 112 | size.w_italic = size.height/3; |
113 | size.offset_i = size.w_italic/size.height; |
||
114 | size.width += size.w_italic; |
||
115 | size.w_italic = -size.w_italic; |
||
5757 | pavelyakov | 116 | } |
5753 | leency | 117 | return size.width; |
5742 | pavelyakov | 118 | } |
119 | :byte FONT::symbol_size(byte s) |
||
120 | { |
||
121 | dword xi,yi; |
||
122 | dword tmp,_; |
||
123 | dword iii; |
||
124 | byte rw=0; |
||
5753 | leency | 125 | byte X; |
5754 | pavelyakov | 126 | size.TMP_WEIGHT = math.ceil(size.text/17); |
5753 | leency | 127 | IF(s==32) |
128 | { |
||
129 | size.width += width/4; |
||
5754 | pavelyakov | 130 | IF(weight) size.width+=size.TMP_WEIGHT; |
5753 | leency | 131 | return; |
132 | } |
||
133 | IF(s==9) |
||
134 | { |
||
135 | size.width += width; |
||
5754 | pavelyakov | 136 | IF(weight) size.width+=size.TMP_WEIGHT; |
5753 | leency | 137 | return; |
138 | } |
||
5759 | pavelyakov | 139 | IF(!encoding){ |
140 | IF(s>=128)&&(s<=175)s+=64; |
||
141 | ELSE IF(s>=224)&&(s<=239)s+=16; |
||
5778 | leency | 142 | ELSE IF(s==241)s=184; //yo |
143 | ELSE IF(s==240)s=168; //YO |
||
5759 | pavelyakov | 144 | } |
5742 | pavelyakov | 145 | iii = 0; |
5782 | leency | 146 | tmp = 4*block*s + data; |
5784 | leency | 147 | for(yi=0; yi |
5742 | pavelyakov | 148 | { |
5784 | leency | 149 | for(xi=0; xi |
150 | { |
||
151 | IF(iii%32) _ >>= 1; |
||
152 | ELSE |
||
153 | { |
||
154 | tmp += 4; |
||
155 | _ = DSDWORD[tmp]; |
||
5742 | pavelyakov | 156 | } |
5784 | leency | 157 | IF(_&1) |
158 | { |
||
159 | IF(xi>rw)rw=xi; |
||
160 | IF(size.height |
||
5800 | pavelyakov | 161 | IF(size.offset.y<0)size.offset.y = yi; |
162 | ELSE IF(yi |
||
5784 | leency | 163 | IF(!X) X = xi; |
164 | ELSE IF(X>xi)X = xi; |
||
165 | } |
||
166 | iii++; |
||
167 | } |
||
5742 | pavelyakov | 168 | } |
5753 | leency | 169 | size.width += rw; |
5754 | pavelyakov | 170 | IF(weight) size.width+=size.TMP_WEIGHT; |
5753 | leency | 171 | IF(s=='_') size.width--; |
5800 | pavelyakov | 172 | IF(size.offset.x<0)size.offset.x = X; |
5742 | pavelyakov | 173 | } |
5776 | leency | 174 | :dword FONT::prepare(word x,y;dword text1) |
5742 | pavelyakov | 175 | { |
176 | signed len=0; |
||
5783 | leency | 177 | proc_info Form_SELF_FONTS; |
5753 | leency | 178 | dword c; |
179 | c = color; |
||
5814 | pavelyakov | 180 | left = x; |
5754 | pavelyakov | 181 | IF(!text1)return false; |
182 | IF(size.text)IF(!changeSIZE())return false; |
||
5783 | leency | 183 | AX = c; r = AL; g = AH; c>>=16; AX = c; b = AL; |
5753 | leency | 184 | getsize(text1); |
5800 | pavelyakov | 185 | y -= size.offset.y; |
5814 | pavelyakov | 186 | top = y; |
5754 | pavelyakov | 187 | EDX = size.width*size.height*3; |
5745 | leency | 188 | IF(!buffer_size) |
189 | { |
||
5754 | pavelyakov | 190 | buffer_size = EDX; |
5745 | leency | 191 | buffer = malloc(buffer_size); |
192 | } |
||
5754 | pavelyakov | 193 | ELSE IF(buffer_size |
5745 | leency | 194 | { |
5754 | pavelyakov | 195 | buffer_size = EDX; |
5745 | leency | 196 | buffer = realloc(buffer,buffer_size); |
197 | } |
||
198 | IF (no_bg_copy) |
||
199 | { |
||
200 | EBX = bg_color; |
||
201 | EDI = buffer; |
||
5754 | pavelyakov | 202 | EAX = buffer_size+EDI; |
5745 | leency | 203 | WHILE (EDI |
204 | { |
||
205 | ESDWORD[EDI] = EBX; |
||
206 | $add edi,3 |
||
207 | } |
||
208 | } |
||
5783 | leency | 209 | ELSE |
210 | { |
||
211 | GetProcessInfo(#Form_SELF_FONTS, SelfInfo); |
||
212 | CopyScreen(buffer,x+Form_SELF_FONTS.left+5,y+Form_SELF_FONTS.top+GetSkinHeight(),size.width,size.height); |
||
213 | } |
||
5800 | pavelyakov | 214 | len = size.offset.x; |
5730 | pavelyakov | 215 | WHILE(DSBYTE[text1]) |
216 | { |
||
5753 | leency | 217 | IF(DSBYTE[text1]=='_') len--; |
5784 | leency | 218 | len+=symbol(len,0,DSBYTE[text1]); |
5754 | pavelyakov | 219 | IF(weight)len+=math.ceil(size.text/17); |
5730 | pavelyakov | 220 | text1++; |
221 | } |
||
5761 | leency | 222 | IF (no_bg_copy) && (!color) SmoothFont(buffer, size.width, size.height); |
5730 | pavelyakov | 223 | return len; |
224 | } |
||
5814 | pavelyakov | 225 | :void FONT::show() |
5776 | leency | 226 | { |
5814 | pavelyakov | 227 | _PutImage(left,top,size.width,size.height,buffer); |
5776 | leency | 228 | } |
5761 | leency | 229 | inline fastcall dword b24(EBX) { return DSDWORD[EBX] << 8; } |
5776 | leency | 230 | :void SmoothFont(dword image, w, h) |
5761 | leency | 231 | { |
232 | byte rr,gg,bb; |
||
233 | dword i,line_w,to, pixel; |
||
234 | line_w = w * 3; |
||
5776 | leency | 235 | to = w*h*3 + image - line_w - 3; |
5802 | pavelyakov | 236 | for(i = image; i < to; i+=3) { |
237 | IF(i-image%line_w +3 == line_w) continue; |
||
238 | IF(b24(i)==0x000000) && (b24(i+3)!=0x000000) && (b24(i+line_w)!=0x000000) && (b24(i+3+line_w)==0x000000) |
||
5761 | leency | 239 | { |
240 | ShadowImage(i+3, 1, 1, 2); |
||
241 | ShadowImage(i+line_w, 1, 1, 2); |
||
242 | } |
||
5802 | pavelyakov | 243 | ELSE IF(b24(i)!=0x000000) && (b24(i+3)==0x000000) && (b24(i+line_w)==0x000000) && (b24(i+3+line_w)!=0x000000) |
5761 | leency | 244 | { |
245 | ShadowImage(i, 1, 1, 2); |
||
246 | ShadowImage(i+3+line_w, 1, 1, 2); |
||
247 | } |
||
248 | } |
||
249 | } |
||
5784 | leency | 250 | :byte FONT::symbol(signed x,y;byte s) |
5730 | pavelyakov | 251 | { |
5736 | pavelyakov | 252 | dword xi,yi; |
253 | dword iii; |
||
5757 | pavelyakov | 254 | float ital = -size.w_italic; |
5741 | pavelyakov | 255 | dword ___x; |
5814 | pavelyakov | 256 | //byte _TMP_WEIGHT; |
5736 | pavelyakov | 257 | byte rw=0; |
5814 | pavelyakov | 258 | //_TMP_WEIGHT=2; |
5736 | pavelyakov | 259 | IF(s==32)return width/4; |
260 | IF(s==9)return width; |
||
5759 | pavelyakov | 261 | IF(!encoding) |
262 | { |
||
263 | IF(s>=128)&&(s<=175)s+=64; |
||
264 | ELSE IF(s>=224)&&(s<=239)s+=16; |
||
5778 | leency | 265 | ELSE IF(s==241)s=184; //yo |
266 | ELSE IF(s==240)s=168; //YO |
||
5759 | pavelyakov | 267 | } |
5736 | pavelyakov | 268 | iii = 0; |
5802 | pavelyakov | 269 | EBX = block*s; |
270 | $shl ebx,2 |
||
271 | $add ebx,data |
||
272 | yi = 0; |
||
273 | while(yi |
||
5736 | pavelyakov | 274 | { |
5802 | pavelyakov | 275 | EDI = size.offset.y; |
276 | $add edi,yi |
||
277 | $add edi,y |
||
5784 | leency | 278 | for(xi=0; xi |
5782 | leency | 279 | { |
5802 | pavelyakov | 280 | IF(iii%32) $shr ecx,1 |
5782 | leency | 281 | ELSE |
282 | { |
||
5802 | pavelyakov | 283 | $add ebx,4 |
284 | ECX = DSDWORD[EBX]; |
||
5782 | leency | 285 | } |
5802 | pavelyakov | 286 | IF(ECX&true) |
5782 | leency | 287 | { |
288 | IF(xi>rw)rw=xi; |
||
289 | ___x = x+xi; |
||
290 | IF(italic)___x+=math.ceil(ital); |
||
5802 | pavelyakov | 291 | PixelRGB(___x,EDI); |
5814 | pavelyakov | 292 | //_TMP_WEIGHT = 2; |
293 | //WHILE(_TMP_WEIGHT) |
||
294 | //{ |
||
295 | // _TMP_WEIGHT--; |
||
296 | IF(weight) PixelRGB(___x+1,EDI); |
||
297 | //} |
||
5782 | leency | 298 | } |
299 | iii++; |
||
300 | } |
||
301 | IF(italic) ital-=size.offset_i; |
||
5802 | pavelyakov | 302 | $inc yi |
5736 | pavelyakov | 303 | } |
304 | return rw; |
||
5730 | pavelyakov | 305 | } |
306 | :byte FONT::load(dword path) |
||
307 | { |
||
5745 | leency | 308 | buffer_size = 0; |
5730 | pavelyakov | 309 | IF(data)free(data); |
5802 | pavelyakov | 310 | IF(!io.read(path)) { debug("Error while loading font: "); debugln(path); return false; } |
5782 | leency | 311 | begin = data = io.buffer_data; |
5784 | leency | 312 | EBX = begin + io.FILES_SIZE; |
5802 | pavelyakov | 313 | $dec ebx |
314 | height = DSBYTE[EBX]; |
||
315 | $dec ebx |
||
316 | width = DSBYTE[EBX]; |
||
5730 | pavelyakov | 317 | block = math.ceil(height*width/32); |
5754 | pavelyakov | 318 | return true; |
5730 | pavelyakov | 319 | } |
320 | |||
5816 | leency | 321 | :void FONT::prepare_buf(dword x,y,w,h; dword text1) |
5782 | leency | 322 | { |
5816 | leency | 323 | dword c, new_buffer_size; |
5782 | leency | 324 | c = color; |
325 | IF(!text1)return; |
||
326 | IF(size.text)IF(!changeSIZE())return; |
||
327 | AX = c; r = AL; g = AH; c>>=16; AX = c; b = AL; |
||
328 | getsize(text1); |
||
5800 | pavelyakov | 329 | y -= size.offset.y; |
5782 | leency | 330 | |
331 | size.width = w; |
||
5783 | leency | 332 | size.height = h; |
5784 | leency | 333 | |
5816 | leency | 334 | new_buffer_size = w*h*3; |
335 | IF(buffer_size!=new_buffer_size) |
||
5782 | leency | 336 | { |
5816 | leency | 337 | buffer_size = new_buffer_size; |
5784 | leency | 338 | free(buffer); |
5816 | leency | 339 | buffer = malloc(buffer_size); |
340 | EBX = bg_color; |
||
341 | EDI = buffer; |
||
342 | EAX = buffer_size+buffer; |
||
5782 | leency | 343 | WHILE (EDI |
344 | { |
||
345 | ESDWORD[EDI] = EBX; |
||
346 | $add edi,3 |
||
347 | } |
||
348 | } |
||
349 | WHILE(DSBYTE[text1]) |
||
350 | { |
||
5784 | leency | 351 | x+=symbol(x,y,DSBYTE[text1]); |
5782 | leency | 352 | IF(weight)x+=math.ceil(size.text/17); |
353 | text1++; |
||
354 | } |
||
355 | return; |
||
356 | } |
||
357 | |||
5730 | pavelyakov | 358 | #endif |