Subversion Repositories Kolibri OS

Rev

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