Subversion Repositories Kolibri OS

Rev

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