Subversion Repositories Kolibri OS

Rev

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