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