Subversion Repositories Kolibri OS

Rev

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