Subversion Repositories Kolibri OS

Rev

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