Subversion Repositories Kolibri OS

Rev

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