00001 #include "bctheme.h"
00002 #include "bcwindowbase.h"
00003 #include "clip.h"
00004 #include "language.h"
00005 #include "vframe.h"
00006
00007 #include <errno.h>
00008 #include <stdio.h>
00009 #include <string.h>
00010
00011 BC_Theme::BC_Theme()
00012 {
00013 data_ptr = 0;
00014 contents_ptr = 0;
00015 last_image = 0;
00016 last_pointer = 0;
00017 }
00018
00019 BC_Theme::~BC_Theme()
00020 {
00021 image_sets.remove_all_objects();
00022 }
00023
00024 void BC_Theme::dump()
00025 {
00026 printf("BC_Theme::dump 1 image_sets=%d contents=%d\n",
00027 image_sets.total,
00028 contents.total);
00029 for(int i = 0; i < contents.total; i++)
00030 printf(" %s %p\n", contents.values[i], pointers.values[i]);
00031 }
00032
00033 BC_Resources* BC_Theme::get_resources()
00034 {
00035 return BC_WindowBase::get_resources();
00036 }
00037
00038
00039
00040 VFrame* BC_Theme::new_image(char *title, char *path)
00041 {
00042 VFrame *existing_image = title[0] ? get_image(title, 0) : 0;
00043 if(existing_image) return existing_image;
00044
00045 BC_ThemeSet *result = new BC_ThemeSet(1, 0, title);
00046 result->data[0] = new VFrame(get_image_data(path));
00047 image_sets.append(result);
00048 return result->data[0];
00049 }
00050
00051 VFrame* BC_Theme::new_image(char *path)
00052 {
00053 return new_image("", path);
00054 }
00055
00056
00057
00058
00059 VFrame** BC_Theme::new_image_set(char *title, int total, va_list *args)
00060 {
00061 VFrame **existing_image_set = title[0] ? get_image_set(title, 0) : 0;
00062 if(existing_image_set) return existing_image_set;
00063
00064 BC_ThemeSet *result = new BC_ThemeSet(total, 1, title);
00065 image_sets.append(result);
00066 for(int i = 0; i < total; i++)
00067 {
00068 char *path = va_arg(*args, char*);
00069 result->data[i] = new_image(path);
00070 }
00071 return result->data;
00072 }
00073
00074 VFrame** BC_Theme::new_image_set_images(char *title, int total, ...)
00075 {
00076 va_list list;
00077 va_start(list, total);
00078 BC_ThemeSet *existing_image_set = title[0] ? get_image_set_object(title) : 0;
00079 if(existing_image_set)
00080 {
00081 image_sets.remove_object(existing_image_set);
00082 }
00083
00084 BC_ThemeSet *result = new BC_ThemeSet(total, 0, title);
00085 image_sets.append(result);
00086 for(int i = 0; i < total; i++)
00087 {
00088 result->data[i] = va_arg(list, VFrame*);
00089 }
00090 return result->data;
00091 }
00092
00093 VFrame** BC_Theme::new_image_set(char *title, int total, ...)
00094 {
00095 va_list list;
00096 va_start(list, total);
00097 VFrame **result = new_image_set(title, total, &list);
00098 va_end(list);
00099
00100 return result;
00101 }
00102
00103 VFrame** BC_Theme::new_image_set(int total, ...)
00104 {
00105 va_list list;
00106 va_start(list, total);
00107 VFrame **result = new_image_set("", total, &list);
00108 va_end(list);
00109
00110 return result;
00111 }
00112
00113 VFrame* BC_Theme::get_image(char *title, int use_default)
00114 {
00115 for(int i = 0; i < image_sets.total; i++)
00116 {
00117 if(!strcmp(image_sets.values[i]->title, title))
00118 {
00119 return image_sets.values[i]->data[0];
00120 }
00121 }
00122
00123
00124
00125
00126 if(use_default)
00127 {
00128 printf("BC_Theme::get_image: image \"%s\" not found.\n",
00129 title);
00130 if(image_sets.total)
00131 {
00132 return image_sets.values[0]->data[0];
00133 }
00134 }
00135
00136
00137 return 0;
00138 }
00139
00140 VFrame** BC_Theme::get_image_set(char *title, int use_default)
00141 {
00142 for(int i = 0; i < image_sets.total; i++)
00143 {
00144 if(!strcmp(image_sets.values[i]->title, title))
00145 {
00146 return image_sets.values[i]->data;
00147 }
00148 }
00149
00150
00151 if(use_default)
00152 {
00153 printf("BC_Theme::get_image_set: image set \"%s\" not found.\n",
00154 title);
00155 int max_total = 0;
00156 int max_number = -1;
00157 for(int i = 0; i < image_sets.total; i++)
00158 {
00159 if(image_sets.values[i]->total > max_total)
00160 {
00161 max_total = image_sets.values[i]->total;
00162 max_number = i;
00163 }
00164 }
00165
00166 if(max_number >= 0)
00167 return image_sets.values[max_number]->data;
00168 }
00169
00170
00171 return 0;
00172 }
00173
00174 BC_ThemeSet* BC_Theme::get_image_set_object(char *title)
00175 {
00176 for(int i = 0; i < image_sets.total; i++)
00177 {
00178 if(!strcmp(image_sets.values[i]->title, title))
00179 {
00180 return image_sets.values[i];
00181 }
00182 }
00183 return 0;
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 VFrame** BC_Theme::new_button(char *overlay_path,
00197 char *up_path,
00198 char *hi_path,
00199 char *dn_path,
00200 char *title)
00201 {
00202 VFrame default_data(get_image_data(overlay_path));
00203 BC_ThemeSet *result = new BC_ThemeSet(3, 1, title ? title : (char*)"");
00204 if(title) image_sets.append(result);
00205
00206 result->data[0] = new_image(up_path);
00207 result->data[1] = new_image(hi_path);
00208 result->data[2] = new_image(dn_path);
00209 for(int i = 0; i < 3; i++)
00210 {
00211 overlay(result->data[i], &default_data, -1, -1, (i == 2));
00212 }
00213 return result->data;
00214 }
00215
00216
00217 VFrame** BC_Theme::new_button4(char *overlay_path,
00218 char *up_path,
00219 char *hi_path,
00220 char *dn_path,
00221 char *disabled_path,
00222 char *title)
00223 {
00224 VFrame default_data(get_image_data(overlay_path));
00225 BC_ThemeSet *result = new BC_ThemeSet(4, 1, title ? title : (char*)"");
00226 if(title) image_sets.append(result);
00227
00228 result->data[0] = new_image(up_path);
00229 result->data[1] = new_image(hi_path);
00230 result->data[2] = new_image(dn_path);
00231 result->data[3] = new_image(disabled_path);
00232 for(int i = 0; i < 4; i++)
00233 {
00234 overlay(result->data[i], &default_data, -1, -1, (i == 2));
00235 }
00236 return result->data;
00237 }
00238
00239
00240 VFrame** BC_Theme::new_button(char *overlay_path,
00241 VFrame *up,
00242 VFrame *hi,
00243 VFrame *dn,
00244 char *title)
00245 {
00246 VFrame default_data(get_image_data(overlay_path));
00247 BC_ThemeSet *result = new BC_ThemeSet(3, 0, title ? title : (char*)"");
00248 if(title) image_sets.append(result);
00249
00250 result->data[0] = new VFrame(*up);
00251 result->data[1] = new VFrame(*hi);
00252 result->data[2] = new VFrame(*dn);
00253 for(int i = 0; i < 3; i++)
00254 overlay(result->data[i], &default_data, -1, -1, (i == 2));
00255 return result->data;
00256 }
00257
00258
00259 VFrame** BC_Theme::new_toggle(char *overlay_path,
00260 char *up_path,
00261 char *hi_path,
00262 char *checked_path,
00263 char *dn_path,
00264 char *checkedhi_path,
00265 char *title)
00266 {
00267 VFrame default_data(get_image_data(overlay_path));
00268 BC_ThemeSet *result = new BC_ThemeSet(5, 1, title ? title : (char*)"");
00269 if(title) image_sets.append(result);
00270
00271 result->data[0] = new_image(up_path);
00272 result->data[1] = new_image(hi_path);
00273 result->data[2] = new_image(checked_path);
00274 result->data[3] = new_image(dn_path);
00275 result->data[4] = new_image(checkedhi_path);
00276 for(int i = 0; i < 5; i++)
00277 overlay(result->data[i], &default_data, -1, -1, (i == 3));
00278 return result->data;
00279 }
00280
00281 VFrame** BC_Theme::new_toggle(char *overlay_path,
00282 VFrame *up,
00283 VFrame *hi,
00284 VFrame *checked,
00285 VFrame *dn,
00286 VFrame *checkedhi,
00287 char *title)
00288 {
00289 VFrame default_data(get_image_data(overlay_path));
00290 BC_ThemeSet *result = new BC_ThemeSet(5, 0, title ? title : (char*)"");
00291 if(title) image_sets.append(result);
00292
00293 result->data[0] = new VFrame(*up);
00294 result->data[1] = new VFrame(*hi);
00295 result->data[2] = new VFrame(*checked);
00296 result->data[3] = new VFrame(*dn);
00297 result->data[4] = new VFrame(*checkedhi);
00298 for(int i = 0; i < 5; i++)
00299 overlay(result->data[i], &default_data, -1, -1, (i == 3));
00300 return result->data;
00301 }
00302
00303 void BC_Theme::overlay(VFrame *dst, VFrame *src, int in_x1, int in_x2, int shift)
00304 {
00305 int w;
00306 int h;
00307 unsigned char **in_rows;
00308 unsigned char **out_rows;
00309
00310 if(in_x1 < 0)
00311 {
00312 w = MIN(src->get_w(), dst->get_w());
00313 h = MIN(dst->get_h(), src->get_h());
00314 in_x1 = 0;
00315 in_x2 = w;
00316 }
00317 else
00318 {
00319 w = in_x2 - in_x1;
00320 h = MIN(dst->get_h(), src->get_h());
00321 }
00322 in_rows = src->get_rows();
00323 out_rows = dst->get_rows();
00324
00325 switch(src->get_color_model())
00326 {
00327 case BC_RGBA8888:
00328 switch(dst->get_color_model())
00329 {
00330 case BC_RGBA8888:
00331 for(int i = shift; i < h; i++)
00332 {
00333 unsigned char *in_row = 0;
00334 unsigned char *out_row;
00335
00336 if(!shift)
00337 {
00338 in_row = in_rows[i] + in_x1 * 4;
00339 out_row = out_rows[i];
00340 }
00341 else
00342 {
00343 in_row = in_rows[i - 1] + in_x1 * 4;
00344 out_row = out_rows[i] + 4;
00345 }
00346
00347 for(int j = shift; j < w; j++)
00348 {
00349 int opacity = in_row[3];
00350 int transparency = 0xff - opacity;
00351
00352 out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
00353 out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
00354 out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
00355 out_row[3] = MAX(in_row[3], out_row[3]);
00356 out_row += 4;
00357 in_row += 4;
00358 }
00359 }
00360 break;
00361
00362 case BC_RGB888:
00363 for(int i = shift; i < h; i++)
00364 {
00365 unsigned char *in_row;
00366 unsigned char *out_row = out_rows[i];
00367
00368 if(!shift)
00369 {
00370 in_row = in_rows[i] + in_x1 * 3;
00371 out_row = out_rows[i];
00372 }
00373 else
00374 {
00375 in_row = in_rows[i - 1] + in_x1 * 3;
00376 out_row = out_rows[i] + 3;
00377 }
00378
00379 for(int j = shift; j < w; j++)
00380 {
00381 int opacity = in_row[3];
00382 int transparency = 0xff - opacity;
00383 out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
00384 out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
00385 out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
00386 out_row += 3;
00387 in_row += 4;
00388 }
00389 }
00390 break;
00391 }
00392 break;
00393 }
00394 }
00395
00396 void BC_Theme::set_data(unsigned char *ptr)
00397 {
00398 contents_ptr = (char*)(ptr + sizeof(int));
00399 int contents_size = *(int*)ptr - sizeof(int);
00400 data_ptr = contents_ptr + contents_size;
00401
00402 for(int i = 0; i < contents_size; )
00403 {
00404 used.append(0);
00405 contents.append(contents_ptr + i);
00406 while(contents_ptr[i] && i < contents_size)
00407 i++;
00408 if(i < contents_size)
00409 {
00410 i++;
00411 pointers.append((unsigned char*)data_ptr +
00412 *(unsigned int*)(contents_ptr + i));
00413 i += 4;
00414 }
00415 else
00416 {
00417 pointers.append((unsigned char*)data_ptr);
00418 break;
00419 }
00420 }
00421 }
00422
00423 unsigned char* BC_Theme::get_image_data(char *title)
00424 {
00425 if(!data_ptr)
00426 {
00427 fprintf(stderr, "BC_Theme::get_image_data: no data set\n");
00428 return 0;
00429 }
00430
00431
00432 if(last_image && !strcasecmp(last_image, title))
00433 {
00434 return last_pointer;
00435 }
00436 else
00437
00438 for(int i = 0; i < contents.total; i++)
00439 {
00440 if(!strcasecmp(contents.values[i], title))
00441 {
00442 last_pointer = pointers.values[i];
00443 last_image = contents.values[i];
00444 used.values[i] = 1;
00445 return pointers.values[i];
00446 }
00447 }
00448
00449 fprintf(stderr, _("Theme::get_image: %s not found.\n"), title);
00450 return 0;
00451 }
00452
00453 void BC_Theme::check_used()
00454 {
00455
00456 return;
00457 int got_it = 0;
00458 for(int i = 0; i < used.total; i++)
00459 {
00460 if(!used.values[i])
00461 {
00462 if(!got_it)
00463 printf(_("BC_Theme::check_used: Images aren't used.\n"));
00464 printf("%s ", contents.values[i]);
00465 got_it = 1;
00466 }
00467 }
00468 if(got_it) printf("\n");
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 BC_ThemeSet::BC_ThemeSet(int total, int is_reference, char *title)
00483 {
00484 this->total = total;
00485 this->title = new char[strlen(title) + 1];
00486 strcpy(this->title, title);
00487 this->is_reference = is_reference;
00488 data = new VFrame*[total];
00489 }
00490
00491 BC_ThemeSet::~BC_ThemeSet()
00492 {
00493 if(data)
00494 {
00495 if(!is_reference)
00496 {
00497 for(int i = 0; i < total; i++)
00498 delete data[i];
00499 }
00500
00501 delete [] data;
00502 }
00503
00504 delete [] title;
00505 }
00506
00507
00508
00509
00510