Subversion Repositories Kolibri OS

Rev

Rev 6021 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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