Rev 5997 | Rev 6053 | 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 | |||
5981 | leency | 213 | inline fastcall dword b24(EBX) { return DSDWORD[EBX] << 8; } |
5987 | leency | 214 | :void LABEL::apply_smooth() |
5981 | leency | 215 | { |
216 | dword i,line_w,to; |
||
6021 | leency | 217 | rgb.DwordToRgb(ShadowPixel(background,2)); //get shadowed pixel |
5987 | leency | 218 | line_w = size.width * 3; |
219 | to = size.height - 1 * line_w + raw - 3; |
||
220 | for(i=raw; i < to; i+=3) |
||
5985 | leency | 221 | { |
5997 | leency | 222 | if(i-raw%line_w +3 == line_w) continue; |
6021 | leency | 223 | // pixels position, where b - black, w - write |
224 | // bw |
||
225 | // wb |
||
5997 | leency | 226 | if(b24(i)==0x000000) && (b24(i+3)!=0x000000) && (b24(i+line_w)!=0x000000) && (b24(i+3+line_w)==0x000000) |
227 | { |
||
6021 | leency | 228 | ESBYTE[i+3] = rgb.b; |
229 | ESBYTE[i+4] = rgb.g; |
||
230 | ESBYTE[i+5] = rgb.r; |
||
231 | ESBYTE[i+line_w ] = rgb.b; |
||
232 | ESBYTE[i+line_w+1] = rgb.g; |
||
233 | ESBYTE[i+line_w+2] = rgb.r; |
||
234 | // // I don't know why but underneath code works slower then beneath |
||
235 | // DSDWORD[i] = DSDWORD[i] & 0xFF000000 | dark_background; |
||
236 | // DSDWORD[i+line_w] = DSDWORD[i+3+line_w] & 0xFF000000 | dark_background; |
||
5981 | leency | 237 | } |
6021 | leency | 238 | // wb |
239 | // bw |
||
5997 | leency | 240 | else if(b24(i)!=0x000000) && (b24(i+3)==0x000000) && (b24(i+line_w)==0x000000) && (b24(i+3+line_w)!=0x000000) |
5981 | leency | 241 | { |
6021 | leency | 242 | ESBYTE[i ] = rgb.b; |
243 | ESBYTE[i+1] = rgb.g; |
||
244 | ESBYTE[i+2] = rgb.r; |
||
245 | ESBYTE[i+line_w+3] = rgb.b; |
||
246 | ESBYTE[i+line_w+4] = rgb.g; |
||
247 | ESBYTE[i+line_w+5] = rgb.r; |
||
248 | // // I don't know why but underneath code works slower then beneath |
||
249 | // DSDWORD[i] = DSDWORD[i] & 0xFF000000 | dark_background; |
||
250 | // DSDWORD[i+3+line_w] = DSDWORD[i+3+line_w] & 0xFF000000 | dark_background; |
||
5981 | leency | 251 | } |
252 | } |
||
253 | } |
||
254 | |||
5997 | leency | 255 | :int LABEL::write_center(dword x,y,w,h; dword _background, _color; byte fontSizePoints; dword txt) |
5742 | pavelyakov | 256 | { |
5987 | leency | 257 | size.pt = fontSizePoints; |
5985 | leency | 258 | getsize(txt); |
5997 | leency | 259 | return write(w-size.width/2+x,y, _background, _color, fontSizePoints, txt); |
5985 | leency | 260 | } |
261 | |||
5997 | leency | 262 | :int LABEL::write(int x,y; dword _background, _color; byte fontSizePoints; dword text1) |
5985 | leency | 263 | { |
5742 | pavelyakov | 264 | signed len=0; |
5754 | pavelyakov | 265 | IF(!text1)return false; |
5987 | leency | 266 | IF(size.pt)IF(!changeSIZE())return false; |
267 | size.pt = fontSizePoints; |
||
5753 | leency | 268 | getsize(text1); |
5997 | leency | 269 | color = _color; |
270 | background = _background; |
||
5987 | leency | 271 | y -= size.offset_y; |
5754 | pavelyakov | 272 | EDX = size.width*size.height*3; |
5987 | leency | 273 | IF(!raw_size) |
5745 | leency | 274 | { |
5987 | leency | 275 | raw_size = EDX; |
276 | raw = malloc(raw_size); |
||
5745 | leency | 277 | } |
5987 | leency | 278 | ELSE IF(raw_size |
5745 | leency | 279 | { |
5987 | leency | 280 | raw_size = EDX; |
281 | raw = realloc(raw,raw_size); |
||
5745 | leency | 282 | } |
5985 | leency | 283 | // Fill background color { |
5987 | leency | 284 | EBX = background; |
285 | EAX = raw_size+raw; |
||
286 | for (EDI=raw; EDI |
||
5985 | leency | 287 | // } |
5987 | leency | 288 | len = size.offset_x; |
5730 | pavelyakov | 289 | WHILE(DSBYTE[text1]) |
290 | { |
||
5753 | leency | 291 | IF(DSBYTE[text1]=='_') len--; |
5987 | leency | 292 | len+=symbol(len,0,DSBYTE[text1], raw); |
293 | IF(bold)len+=math.ceil(size.pt/17); |
||
5730 | pavelyakov | 294 | text1++; |
295 | } |
||
5985 | leency | 296 | IF (smooth) apply_smooth(); |
5987 | leency | 297 | show_buf(x,y); |
5730 | pavelyakov | 298 | return len; |
299 | } |
||
300 | |||
5997 | leency | 301 | :void LABEL::write_buf(int x,y,w,h; dword _background, _color; byte fontSizePoints; dword text1) |
5782 | leency | 302 | { |
5987 | leency | 303 | dword new_raw_size; |
5782 | leency | 304 | IF(!text1)return; |
5987 | leency | 305 | IF(size.pt)IF(!changeSIZE())return; |
306 | |||
6021 | leency | 307 | if (size.pt != fontSizePoints) { |
308 | size.pt = fontSizePoints; |
||
309 | getsize(text1); |
||
310 | y -= size.offset_y; |
||
311 | } |
||
5997 | leency | 312 | color = _color; |
313 | background = _background; |
||
5981 | leency | 314 | |
5782 | leency | 315 | size.width = w; |
5783 | leency | 316 | size.height = h; |
5784 | leency | 317 | |
5987 | leency | 318 | new_raw_size = w*h*3; |
319 | IF(raw_size != new_raw_size) |
||
5782 | leency | 320 | { |
5987 | leency | 321 | raw_size = new_raw_size; |
322 | free(raw); |
||
323 | raw = malloc(raw_size); |
||
5985 | leency | 324 | // Fill background color |
5987 | leency | 325 | EBX = background; |
326 | EAX = raw_size+raw; |
||
327 | for (EDI=raw; EDI |
||
5782 | leency | 328 | } |
329 | WHILE(DSBYTE[text1]) |
||
330 | { |
||
5987 | leency | 331 | x+=symbol(x,y,DSBYTE[text1], raw); |
332 | IF(bold)x+=math.ceil(size.pt/17); |
||
5782 | leency | 333 | text1++; |
334 | } |
||
335 | return; |
||
336 | } |
||
337 | |||
5987 | leency | 338 | :void LABEL::show_buf(dword x, y){ |
339 | _PutImage(x, y, size.width, size.height, raw); |
||
5985 | leency | 340 | } |
341 | |||
342 | |||
343 | |||
5730 | pavelyakov | 344 | #endif |