Subversion Repositories Kolibri OS

Rev

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