Subversion Repositories Kolibri OS

Rev

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