Subversion Repositories Kolibri OS

Rev

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