00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #undef LOCAL_DEBUG
00023 #ifdef _WIN32
00024 #include "win32/config.h"
00025 #else
00026 #include "config.h"
00027 #endif
00028
00029 #include <ctype.h>
00030 #include <math.h>
00031 #ifdef HAVE_UNISTD_H
00032 #include <unistd.h>
00033 #endif
00034 #ifdef HAVE_STDLIB_H
00035 #include <stdlib.h>
00036 #endif
00037 #ifdef HAVE_STDARG_H
00038 #include <stdarg.h>
00039 #endif
00040 #include <string.h>
00041 #if TIME_WITH_SYS_TIME
00042 # include <sys/time.h>
00043 # include <time.h>
00044 #else
00045 # if HAVE_SYS_TIME_H
00046 # include <sys/time.h>
00047 # else
00048 # include <time.h>
00049 # endif
00050 #endif
00051 #ifndef _WIN32
00052 #include <sys/times.h>
00053 #endif
00054
00055 #ifdef _WIN32
00056 # include "win32/afterbase.h"
00057 #else
00058 # include "afterbase.h"
00059 #endif
00060 #include "afterimage.h"
00061 #include "imencdec.h"
00062
00063 static char* cdata_str = XML_CDATA_STR;
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 static ASImageManager *_as_xml_image_manager = NULL ;
00143 static ASFontManager *_as_xml_font_manager = NULL ;
00144
00145 void set_xml_image_manager( ASImageManager *imman )
00146 {
00147 _as_xml_image_manager = imman ;
00148 }
00149 void set_xml_font_manager( ASFontManager *fontman )
00150 {
00151 _as_xml_font_manager = fontman ;
00152 }
00153
00154
00155
00156
00157 ASImageManager *create_generic_imageman(const char *path)
00158 {
00159 ASImageManager *my_imman = NULL ;
00160 char *path2 = copy_replace_envvar( getenv( ASIMAGE_PATH_ENVVAR ) );
00161 show_progress("image path is \"%s\".", path2?path2:"(null)" );
00162 if( path != NULL )
00163 my_imman = create_image_manager( NULL, SCREEN_GAMMA, path, path2, NULL );
00164 else
00165 my_imman = create_image_manager( NULL, SCREEN_GAMMA, path2, NULL );
00166 LOCAL_DEBUG_OUT( "created image manager %p with search path \"%s\"", my_imman, my_imman->search_path[0] );
00167 if( path2 )
00168 free( path2 );
00169 return my_imman;
00170 }
00171
00172 ASFontManager *create_generic_fontman(Display *dpy, const char *path)
00173 {
00174 ASFontManager *my_fontman ;
00175 char *path2 = copy_replace_envvar( getenv( ASFONT_PATH_ENVVAR ) );
00176 if( path != NULL )
00177 {
00178 if( path2 != NULL )
00179 {
00180 int path_len = strlen(path);
00181 char *full_path = safemalloc( path_len+1+strlen(path2)+1);
00182 strcpy( full_path, path );
00183 full_path[path_len] = ':';
00184 strcpy( &(full_path[path_len+1]), path2 );
00185 free( path2 );
00186 path2 = full_path ;
00187 }else
00188 path2 = (char*)path ;
00189 }
00190 my_fontman = create_font_manager( dpy, path2, NULL );
00191 if( path2 && path2 != path )
00192 free( path2 );
00193
00194 return my_fontman;
00195 }
00196
00197 ASImage *
00198 compose_asimage_xml_from_doc(ASVisual *asv, ASImageManager *imman, ASFontManager *fontman, xml_elem_t* doc, ASFlagType flags, int verbose, Window display_win, const char *path, int target_width, int target_height)
00199 {
00200
00201 ASImage* im = NULL;
00202 ASImageManager *my_imman = imman, *old_as_xml_imman = _as_xml_image_manager ;
00203 ASFontManager *my_fontman = fontman, *old_as_xml_fontman = _as_xml_font_manager ;
00204 int my_imman_curr_dir_path_idx = MAX_SEARCH_PATHS ;
00205
00206 if (doc)
00207 {
00208 int old_target_width = -1;
00209 int old_target_height = -1;
00210 xml_elem_t* ptr;
00211 Bool local_dir_included = False ;
00212
00213 asxml_var_init();
00214 #if (HAVE_AFTERBASE_FLAG==1)
00215 if (verbose > 1)
00216 {
00217 xml_print(doc);
00218 fprintf(stderr, "\n");
00219 }
00220 #endif
00221
00222 if( my_imman == NULL )
00223 {
00224 if( _as_xml_image_manager == NULL )
00225 {
00226 local_dir_included = True ;
00227 _as_xml_image_manager = create_generic_imageman( path );
00228 }
00229 my_imman = _as_xml_image_manager ;
00230 }
00231
00232 if( !local_dir_included )
00233 {
00234 register int i = 0;
00235 char **paths = my_imman->search_path ;
00236 while( i < MAX_SEARCH_PATHS && paths[i] != NULL ) ++i;
00237 if( i < MAX_SEARCH_PATHS )
00238 {
00239 paths[i] = mystrdup(path) ;
00240 paths[i+1] = NULL ;
00241 my_imman_curr_dir_path_idx = i ;
00242 }
00243 }
00244
00245 if( my_fontman == NULL )
00246 {
00247 if( _as_xml_font_manager == NULL )
00248 _as_xml_font_manager = create_generic_fontman( asv->dpy, path );
00249 my_fontman = _as_xml_font_manager ;
00250 }
00251
00252
00253 old_target_width = asxml_var_get(ASXMLVAR_TargetWidth);
00254 old_target_height = asxml_var_get(ASXMLVAR_TargetHeight);
00255
00256 asxml_var_insert(ASXMLVAR_TargetWidth, target_width);
00257 asxml_var_insert(ASXMLVAR_TargetHeight, target_height);
00258
00259 for (ptr = doc->child ; ptr ; ptr = ptr->next) {
00260 ASImage* tmpim = build_image_from_xml(asv, my_imman, my_fontman, ptr, NULL, flags, verbose, display_win);
00261 if (tmpim && im) safe_asimage_destroy(im);
00262 if (tmpim) im = tmpim;
00263 }
00264 if (im && (target_width > 0 || target_height > 0) )
00265 {
00266 int scale_width = (target_width>0)?target_width:im->width;
00267 int scale_height = (target_height>0)?target_height:im->height;
00268 if (im->width != scale_width || im->height != scale_height)
00269 {
00270 ASImage *tmp = scale_asimage( asv, im, scale_width, scale_height, ASA_ASImage, 100, ASIMAGE_QUALITY_DEFAULT );
00271 if (tmp != NULL)
00272 {
00273 safe_asimage_destroy(im);
00274 im = tmp;
00275 }
00276 }
00277 }
00278
00279 asxml_var_insert(ASXMLVAR_TargetWidth, old_target_width);
00280 asxml_var_insert(ASXMLVAR_TargetHeight, old_target_height);
00281
00282 LOCAL_DEBUG_OUT( "result im = %p, im->imman = %p, my_imman = %p, im->magic = %8.8lX", im, im?im->imageman:NULL, my_imman, im?im->magic:0 );
00283
00284 if( my_imman_curr_dir_path_idx < MAX_SEARCH_PATHS && my_imman->search_path[my_imman_curr_dir_path_idx])
00285 {
00286 free(my_imman->search_path[my_imman_curr_dir_path_idx]);
00287 my_imman->search_path[my_imman_curr_dir_path_idx] = NULL ;
00288 }
00289
00290 if( my_imman != imman && my_imman != old_as_xml_imman )
00291 {
00292 if( im && im->imageman == my_imman )
00293 forget_asimage( im );
00294 destroy_image_manager(my_imman, False);
00295 }
00296
00297 if( my_fontman != fontman && my_fontman != old_as_xml_fontman )
00298 destroy_font_manager(my_fontman, False);
00299
00300 _as_xml_image_manager = old_as_xml_imman ;
00301 _as_xml_font_manager = old_as_xml_fontman ;
00302
00303 }
00304 LOCAL_DEBUG_OUT( "returning im = %p, im->imman = %p, im->magic = %8.8lX", im, im?im->imageman:NULL, im?im->magic:0 );
00305 return im;
00306 }
00307
00308 ASImage *
00309 compose_asimage_xml_at_size(ASVisual *asv, ASImageManager *imman, ASFontManager *fontman, char *doc_str, ASFlagType flags, int verbose, Window display_win, const char *path, int target_width, int target_height)
00310 {
00311 xml_elem_t* doc = xml_parse_doc(doc_str, NULL);
00312 ASImage *im = compose_asimage_xml_from_doc(asv, imman, fontman, doc, flags, verbose, display_win, path, target_width, target_height);
00313 if (doc)
00314 xml_elem_delete(NULL, doc);
00315 return im;
00316 }
00317
00318 inline ASImage *
00319 compose_asimage_xml(ASVisual *asv, ASImageManager *imman, ASFontManager *fontman, char *doc_str, ASFlagType flags, int verbose, Window display_win, const char *path)
00320 {
00321 xml_elem_t* doc = xml_parse_doc(doc_str, NULL);
00322 ASImage *im = compose_asimage_xml_from_doc(asv, imman, fontman, doc, flags, verbose, display_win, path, -1, -1);
00323 if (doc)
00324 xml_elem_delete(NULL, doc);
00325 return im;
00326 }
00327
00328
00329 Bool save_asimage_to_file(const char *file2bsaved, ASImage *im,
00330 const char *strtype,
00331 const char *compress,
00332 const char *opacity,
00333 int delay, int replace)
00334 {
00335 ASImageExportParams params ;
00336
00337 memset( ¶ms, 0x00, sizeof(params) );
00338 params.gif.flags = EXPORT_ALPHA ;
00339 if (strtype == NULL || !mystrcasecmp(strtype, "jpeg") || !mystrcasecmp(strtype, "jpg")) {
00340 params.type = ASIT_Jpeg;
00341 params.jpeg.quality = (compress==NULL)?-1:100-atoi(compress);
00342 if( params.jpeg.quality > 100 )
00343 params.jpeg.quality = 100;
00344 } else if (!mystrcasecmp(strtype, "bitmap") || !mystrcasecmp(strtype, "bmp")) {
00345 params.type = ASIT_Bmp;
00346 } else if (!mystrcasecmp(strtype, "png")) {
00347 params.type = ASIT_Png;
00348 params.png.compression = (compress==NULL)?-1:atoi(compress);
00349 if( params.png.compression > 99 )
00350 params.png.compression = 99;
00351 } else if (!mystrcasecmp(strtype, "xcf")) {
00352 params.type = ASIT_Xcf;
00353 } else if (!mystrcasecmp(strtype, "ppm")) {
00354 params.type = ASIT_Ppm;
00355 } else if (!mystrcasecmp(strtype, "pnm")) {
00356 params.type = ASIT_Pnm;
00357 } else if (!mystrcasecmp(strtype, "ico")) {
00358 params.type = ASIT_Ico;
00359 } else if (!mystrcasecmp(strtype, "cur")) {
00360 params.type = ASIT_Cur;
00361 } else if (!mystrcasecmp(strtype, "gif")) {
00362 params.type = ASIT_Gif;
00363 params.gif.flags |= EXPORT_APPEND ;
00364 params.gif.opaque_threshold = (opacity==NULL)?127:atoi(opacity) ;
00365 params.gif.dither = (compress==NULL)?3:atoi(compress)/17;
00366 if( params.gif.dither > 6 )
00367 params.gif.dither = 6;
00368 params.gif.animate_delay = delay ;
00369 } else if (!mystrcasecmp(strtype, "xpm")) {
00370 params.type = ASIT_Xpm;
00371 params.xpm.opaque_threshold = (opacity==NULL)?127:atoi(opacity) ;
00372 params.xpm.dither = (compress==NULL)?3:atoi(compress)/17;
00373 if( params.xpm.dither > 6 )
00374 params.xpm.dither = 6;
00375 } else if (!mystrcasecmp(strtype, "xbm")) {
00376 params.type = ASIT_Xbm;
00377 } else if (!mystrcasecmp(strtype, "tiff")) {
00378 params.type = ASIT_Tiff;
00379 params.tiff.compression_type = TIFF_COMPRESSION_NONE ;
00380 if( compress )
00381 {
00382 if( mystrcasecmp( compress, "deflate" ) == 0 )
00383 params.tiff.compression_type = TIFF_COMPRESSION_DEFLATE ;
00384 else if( mystrcasecmp( compress, "jpeg" ) == 0 )
00385 params.tiff.compression_type = TIFF_COMPRESSION_JPEG ;
00386 else if( mystrcasecmp( compress, "ojpeg" ) == 0 )
00387 params.tiff.compression_type = TIFF_COMPRESSION_OJPEG ;
00388 else if( mystrcasecmp( compress, "packbits" ) == 0 )
00389 params.tiff.compression_type = TIFF_COMPRESSION_PACKBITS ;
00390 }
00391 } else {
00392 show_error("File type not found.");
00393 return(0);
00394 }
00395
00396 if( replace && file2bsaved )
00397 unlink( file2bsaved );
00398
00399 return ASImage2file(im, NULL, file2bsaved, params.type, ¶ms);
00400
00401 }
00402
00403 void show_asimage(ASVisual *asv, ASImage* im, Window w, long delay)
00404 {
00405 #ifndef X_DISPLAY_MISSING
00406 if ( im && w && asv)
00407 {
00408 Pixmap p = asimage2pixmap(asv, w, im, NULL, False);
00409 struct timeval value;
00410
00411 XSetWindowBackgroundPixmap( asv->dpy, w, p );
00412 XClearWindow( asv->dpy, w );
00413 XFlush( asv->dpy );
00414 XFreePixmap( asv->dpy, p );
00415 p = None ;
00416 value.tv_usec = delay % 10000;
00417 value.tv_sec = delay / 10000;
00418 PORTABLE_SELECT (1, 0, 0, 0, &value);
00419 }
00420 #endif
00421 }
00422
00423 typedef struct ASImageXMLState
00424 {
00425 ASFlagType flags ;
00426 ASVisual *asv;
00427 ASImageManager *imman ;
00428 ASFontManager *fontman ;
00429
00430 int verbose ;
00431 Window display_win ;
00432
00433 }ASImageXMLState;
00434
00435
00436 ASImage *commit_xml_image_built( ASImageXMLState *state, char *id, ASImage *result )
00437 {
00438 if (state && id && result)
00439 {
00440 char* buf = NEW_ARRAY(char, strlen(id) + 1 + 6 + 1);
00441 if( state->verbose > 1 )
00442 show_progress("Storing image id [%s] with image manager %p .", id, state->imman);
00443 sprintf(buf, "%s.width", id);
00444 asxml_var_insert(buf, result->width);
00445 sprintf(buf, "%s.height", id);
00446 asxml_var_insert(buf, result->height);
00447 free(buf);
00448 if( result->imageman != NULL )
00449 {
00450 ASImage *tmp = clone_asimage(result, SCL_DO_ALL );
00451 safe_asimage_destroy(result );
00452 result = tmp ;
00453 }
00454 if( result )
00455 {
00456 if( !store_asimage( state->imman, result, id ) )
00457 {
00458 show_warning("Failed to store image id [%s].", id);
00459
00460
00461
00462 }else
00463 {
00464
00465
00466 dup_asimage( result );
00467 }
00468 }
00469 }
00470 return result;
00471 }
00472
00473 static void
00474 translate_tag_size( const char *width_str, const char *height_str, ASImage *imtmp, ASImage *refimg, int *width_ret, int *height_ret )
00475 {
00476 int width_ref = 0;
00477 int height_ref = 0;
00478 int width = 0, height = 0 ;
00479 LOCAL_DEBUG_OUT("width_str = \"%s\", height_str = \"%s\", imtmp = %p, refimg = %p", width_str?width_str:"(null)", height_str?height_str:"(null)", imtmp, refimg );
00480
00481 if( imtmp )
00482 {
00483 width_ref = width = imtmp->width ;
00484 height_ref = height = imtmp->height ;
00485 }
00486 if (refimg)
00487 {
00488 width_ref = refimg->width;
00489 height_ref = refimg->height;
00490 }
00491 if( width_str )
00492 {
00493 if( width_str[0] == '$' || isdigit( (int)width_str[0] ) )
00494 width = (int)parse_math(width_str, NULL, width);
00495 }
00496 if( height_str )
00497 {
00498 if( height_str[0] == '$' || isdigit( (int)height_str[0] ) )
00499 height = (int)parse_math(height_str, NULL, height);
00500 }
00501 if( width_str && height_ref > 0 && mystrcasecmp(width_str,"proportional") == 0 )
00502 width = (width_ref * height) / height_ref ;
00503 else if( height_str && width_ref > 0 && mystrcasecmp(height_str,"proportional") == 0 )
00504 height = (height_ref * width) / width_ref ;
00505 if( width_ret )
00506 *width_ret = (width==0)?(imtmp?imtmp->width:(refimg?refimg->width:0)):width;
00507 if( height_ret )
00508 *height_ret = (height==0)?(imtmp?imtmp->height:(refimg?refimg->height:0)):height;
00509
00510 LOCAL_DEBUG_OUT("width = %d, height = %d", *width_ret, *height_ret );
00511
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 static ASImage *
00540 handle_asxml_tag_text( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm )
00541 {
00542 ASImage *result = NULL ;
00543 xml_elem_t* ptr ;
00544 const char* text = NULL;
00545 const char* font_name = "fixed";
00546 const char* fgimage_str = NULL;
00547 const char* bgimage_str = NULL;
00548 const char* fgcolor_str = NULL;
00549 const char* bgcolor_str = NULL;
00550 ARGB32 fgcolor = ARGB32_White, bgcolor = ARGB32_Black;
00551 int point = 12, spacing = 0, type = AST_Plain;
00552 unsigned int width = 0;
00553 LOCAL_DEBUG_OUT("doc = %p, parm = %p", doc, parm );
00554 for (ptr = parm ; ptr ; ptr = ptr->next) {
00555 if (!strcmp(ptr->tag, "font")) font_name = ptr->parm;
00556 else if (!strcmp(ptr->tag, "point")) point = strtol(ptr->parm, NULL, 0);
00557 else if (!strcmp(ptr->tag, "spacing")) spacing = strtol(ptr->parm, NULL, 0);
00558 else if (!strcmp(ptr->tag, "fgimage")) fgimage_str = ptr->parm;
00559 else if (!strcmp(ptr->tag, "bgimage")) bgimage_str = ptr->parm;
00560 else if (!strcmp(ptr->tag, "fgcolor")) fgcolor_str = ptr->parm;
00561 else if (!strcmp(ptr->tag, "bgcolor")) bgcolor_str = ptr->parm;
00562 else if (!strcmp(ptr->tag, "type")) type = strtol(ptr->parm, NULL, 0);
00563 else if (!strcmp(ptr->tag, "width")) width = strtol(ptr->parm, NULL, 0);
00564 }
00565 for (ptr = doc->child ; ptr && text == NULL ; ptr = ptr->next)
00566 if (!strcmp(ptr->tag, cdata_str)) text = ptr->parm;
00567
00568 if (text && point > 0)
00569 {
00570 struct ASFont *font = NULL;
00571 if( state->verbose > 1 )
00572 show_progress("Rendering text [%s] with font [%s] size [%d].", text, font_name, point);
00573 if (state->fontman) font = get_asfont(state->fontman, font_name, 0, point, ASF_GuessWho);
00574 if (font != NULL)
00575 {
00576 ASTextAttributes attr = {ASTA_VERSION_INTERNAL, 0, 0, ASCT_Char, 8, 0, NULL, 0, ARGB32_White, width};
00577 attr.type = type ;
00578 if( IsUTF8Locale() )
00579 attr.char_type = ASCT_UTF8 ;
00580 set_asfont_glyph_spacing(font, spacing, 0);
00581 if( fgcolor_str )
00582 parse_argb_color(fgcolor_str, &(attr.fore_color) );
00583
00584 result = draw_fancy_text( text, font, &attr, 0, 0 );
00585 if (result && fgcolor_str) {
00586 #if 0
00587 result->back_color = attr.fore_color ;
00588 #else
00589 ASImage* fgimage = create_asimage(result->width, result->height, ASIMAGE_QUALITY_TOP);
00590 parse_argb_color(fgcolor_str, &fgcolor);
00591 fill_asimage(state->asv, fgimage, 0, 0, result->width, result->height, fgcolor);
00592 move_asimage_channel(fgimage, IC_ALPHA, result, IC_ALPHA);
00593 safe_asimage_destroy(result);
00594 result = fgimage ;
00595 #endif
00596 }
00597 if (result && fgimage_str) {
00598 ASImage* fgimage = NULL;
00599 fgimage = get_asimage(state->imman, fgimage_str, 0xFFFFFFFF, 100 );
00600 if( state->verbose > 1 )
00601 show_progress("Using image [%s](%p) as foreground. Text size is %dx%d", fgimage_str, fgimage, result->width, result->height);
00602 if (fgimage) {
00603 ASImage *tmp = tile_asimage(state->asv, fgimage, 0, 0, result->width, result->height, 0, ASA_ASImage, 100, ASIMAGE_QUALITY_TOP);
00604 if( tmp )
00605 {
00606 release_asimage( fgimage );
00607 fgimage = tmp ;
00608 }
00609 move_asimage_channel(fgimage, IC_ALPHA, result, IC_ALPHA);
00610 safe_asimage_destroy(result);
00611 result = fgimage;
00612 }
00613 }
00614 if (result && (bgcolor_str || bgimage_str)) {
00615 ASImageLayer layers[2];
00616 init_image_layers(&(layers[0]), 2);
00617 if (bgimage_str) layers[0].im = fetch_asimage(state->imman, bgimage_str);
00618 if (bgcolor_str)
00619 if( parse_argb_color(bgcolor_str, &bgcolor) != bgcolor_str )
00620 {
00621 if( layers[0].im != NULL )
00622 layers[0].im->back_color = bgcolor ;
00623 else
00624 layers[0].solid_color = bgcolor ;
00625 }
00626 result->back_color = fgcolor ;
00627 layers[0].dst_x = 0;
00628 layers[0].dst_y = 0;
00629 layers[0].clip_width = result->width;
00630 layers[0].clip_height = result->height;
00631 layers[0].bevel = NULL;
00632 layers[1].im = result;
00633 layers[1].dst_x = 0;
00634 layers[1].dst_y = 0;
00635 layers[1].clip_width = result->width;
00636 layers[1].clip_height = result->height;
00637 result = merge_layers(state->asv, layers, 2, result->width, result->height, ASA_ASImage, 0, ASIMAGE_QUALITY_DEFAULT);
00638 safe_asimage_destroy( layers[0].im );
00639 }
00640 }
00641 }
00642
00643 return result;
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 static ASImage *
00707 handle_asxml_tag_composite( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm )
00708 {
00709 ASImage *result = NULL ;
00710 xml_elem_t* ptr ;
00711 const char* pop = "alphablend";
00712 int keep_trans = 0;
00713 int merge = 0;
00714 int num = 0;
00715 int width = 0, height = 0;
00716 ASImageLayer *layers;
00717 #define ASXML_ALIGN_LEFT (0x01<<0)
00718 #define ASXML_ALIGN_RIGHT (0x01<<1)
00719 #define ASXML_ALIGN_TOP (0x01<<2)
00720 #define ASXML_ALIGN_BOTTOM (0x01<<3)
00721 int *align ;
00722 int i ;
00723 merge_scanlines_func op_func = NULL ;
00724
00725 LOCAL_DEBUG_OUT("doc = %p, parm = %p", doc, parm );
00726 for (ptr = parm ; ptr ; ptr = ptr->next) {
00727 if (!strcmp(ptr->tag, "op")) { pop = ptr->parm; op_func = blend_scanlines_name2func(pop); }
00728 else if (!strcmp(ptr->tag, "keep-transparency")) keep_trans = strtol(ptr->parm, NULL, 0);
00729 else if (!strcmp(ptr->tag, "merge") && !mystrcasecmp(ptr->parm, "clip")) merge = 1;
00730 }
00731
00732 for (ptr = doc->child ; ptr ; ptr = ptr->next)
00733 if (strcmp(ptr->tag, cdata_str)) num++;
00734
00735 if( num == 0 )
00736 {
00737 show_warning( "composite tag with no subimages to compose from specified!");
00738 return NULL;
00739 }
00740
00741
00742 if( op_func == NULL )
00743 {
00744 LOCAL_DEBUG_OUT( "defaulting to alpha-blending%s","");
00745 op_func = alphablend_scanlines ;
00746 }
00747
00748 layers = create_image_layers( num );
00749 align = safecalloc( num, sizeof(int));
00750
00751 for (num = 0, ptr = doc->child ; ptr ; ptr = ptr->next)
00752 {
00753 int x = 0, y = 0;
00754 int clip_x = 0, clip_y = 0;
00755 int clip_width = 0, clip_height = 0;
00756 ARGB32 tint = 0;
00757 Bool tile = False ;
00758 xml_elem_t* sparm = NULL;
00759 if (!strcmp(ptr->tag, cdata_str)) continue;
00760 if( (layers[num].im = build_image_from_xml(state->asv, state->imman, state->fontman, ptr, &sparm, state->flags, state->verbose, state->display_win)) != NULL )
00761 {
00762 clip_width = layers[num].im->width;
00763 clip_height = layers[num].im->height;
00764 }
00765 if (sparm)
00766 {
00767 xml_elem_t* tmp;
00768 const char* x_str = NULL;
00769 const char* y_str = NULL;
00770 const char* clip_x_str = NULL;
00771 const char* clip_y_str = NULL;
00772 const char* clip_width_str = NULL;
00773 const char* clip_height_str = NULL;
00774 const char* refid = NULL;
00775 for (tmp = sparm ; tmp ; tmp = tmp->next) {
00776 if (!strcmp(tmp->tag, "crefid")) refid = tmp->parm;
00777 else if (!strcmp(tmp->tag, "x")) x_str = tmp->parm;
00778 else if (!strcmp(tmp->tag, "y")) y_str = tmp->parm;
00779 else if (!strcmp(tmp->tag, "clip_x")) clip_x_str = tmp->parm;
00780 else if (!strcmp(tmp->tag, "clip_y")) clip_y_str = tmp->parm;
00781 else if (!strcmp(tmp->tag, "clip_width")) clip_width_str = tmp->parm;
00782 else if (!strcmp(tmp->tag, "clip_height")) clip_height_str = tmp->parm;
00783 else if (!strcmp(tmp->tag, "tint")) parse_argb_color(tmp->parm, &tint);
00784 else if (!strcmp(tmp->tag, "tile")) tile = True;
00785 else if (!strcmp(tmp->tag, "align"))
00786 {
00787 if (!strcmp(tmp->parm, "left"))set_flags( align[num], ASXML_ALIGN_LEFT);
00788 else if (!strcmp(tmp->parm, "right"))set_flags( align[num], ASXML_ALIGN_RIGHT);
00789 else if (!strcmp(tmp->parm, "center"))set_flags( align[num], ASXML_ALIGN_LEFT|ASXML_ALIGN_RIGHT);
00790 }else if (!strcmp(tmp->tag, "valign"))
00791 {
00792 if (!strcmp(tmp->parm, "top"))set_flags( align[num], ASXML_ALIGN_TOP) ;
00793 else if (!strcmp(tmp->parm, "bottom"))set_flags( align[num], ASXML_ALIGN_BOTTOM);
00794 else if (!strcmp(tmp->parm, "middle"))set_flags( align[num], ASXML_ALIGN_TOP|ASXML_ALIGN_BOTTOM);
00795 }
00796 }
00797 if (refid) {
00798 ASImage* refimg = fetch_asimage(state->imman, refid);
00799 if (refimg) {
00800 x = refimg->width;
00801 y = refimg->height;
00802 }
00803 safe_asimage_destroy(refimg );
00804 }
00805 x = x_str ? (int)parse_math(x_str, NULL, x) : 0;
00806 y = y_str ? (int)parse_math(y_str, NULL, y) : 0;
00807 clip_x = clip_x_str ? (int)parse_math(clip_x_str, NULL, x) : 0;
00808 clip_y = clip_y_str ? (int)parse_math(clip_y_str, NULL, y) : 0;
00809 if( clip_width_str )
00810 clip_width = (int)parse_math(clip_width_str, NULL, clip_width);
00811 else if( tile )
00812 clip_width = 0 ;
00813 if( clip_height_str )
00814 clip_height = (int)parse_math(clip_height_str, NULL, clip_height);
00815 else if( tile )
00816 clip_height = 0 ;
00817 }
00818 if (layers[num].im) {
00819 layers[num].dst_x = x;
00820 layers[num].dst_y = y;
00821 layers[num].clip_x = clip_x;
00822 layers[num].clip_y = clip_y;
00823 layers[num].clip_width = clip_width ;
00824 layers[num].clip_height = clip_height ;
00825 layers[num].tint = tint;
00826 layers[num].bevel = 0;
00827 layers[num].merge_scanlines = op_func;
00828 if( clip_width + x > 0 )
00829 {
00830 if( width < clip_width + x )
00831 width = clip_width + x;
00832 }else
00833 if (width < (int)(layers[num].im->width)) width = layers[num].im->width;
00834 if( clip_height + y > 0 )
00835 {
00836 if( height < clip_height + y )
00837 height = clip_height + y ;
00838 }else
00839 if (height < (int)(layers[num].im->height)) height = layers[num].im->height;
00840 num++;
00841 }
00842 if (sparm) xml_elem_delete(NULL, sparm);
00843 }
00844
00845 if (num && merge && layers[0].im ) {
00846 width = layers[0].im->width;
00847 height = layers[0].im->height;
00848 }
00849
00850
00851 for (i = 0 ; i < num ; i++)
00852 {
00853 if( get_flags(align[i], ASXML_ALIGN_LEFT|ASXML_ALIGN_RIGHT ) )
00854 {
00855 int im_width = ( layers[i].clip_width == 0 )? layers[i].im->width : layers[i].clip_width ;
00856 int x = 0 ;
00857 if( get_flags( align[i], ASXML_ALIGN_RIGHT ) )
00858 x = width - im_width ;
00859 if( get_flags( align[i], ASXML_ALIGN_LEFT ) )
00860 x /= 2;
00861 layers[i].dst_x = x;
00862 }
00863 if( get_flags(align[i], ASXML_ALIGN_TOP|ASXML_ALIGN_BOTTOM ) )
00864 {
00865 int im_height = ( layers[i].clip_height == 0 )? layers[i].im->height : layers[i].clip_height;
00866 int y = 0 ;
00867 if( get_flags( align[i], ASXML_ALIGN_BOTTOM ) )
00868 y = height - im_height ;
00869 if( get_flags( align[i], ASXML_ALIGN_TOP ) )
00870 y /= 2;
00871 layers[i].dst_y = y;
00872 }
00873 if( layers[i].clip_width == 0 )
00874 layers[i].clip_width = width - layers[i].dst_x;
00875 if( layers[i].clip_height == 0 )
00876 layers[i].clip_height = height - layers[i].dst_y;
00877 }
00878
00879 if (state->verbose > 1) {
00880 show_progress("Compositing [%d] image(s) with op [%s]. Final geometry [%dx%d].", num, pop, width, height);
00881 if (keep_trans) show_progress(" Keeping transparency.");
00882
00883 for (i = 0 ; i < num ; i++) {
00884 show_progress(" Image [%d] geometry [%dx%d+%d+%d]", i, layers[i].clip_width, layers[i].clip_height, layers[i].dst_x, layers[i].dst_y);
00885 if (layers[i].tint) show_progress(" tint (#%08x)", (unsigned int)layers[i].tint);
00886 }
00887 }
00888
00889 result = merge_layers( state->asv, layers, num, width, height,
00890 ASA_ASImage, 0, ASIMAGE_QUALITY_DEFAULT);
00891 if (keep_trans && result && layers[0].im)
00892 copy_asimage_channel(result, IC_ALPHA, layers[0].im, IC_ALPHA);
00893
00894 while (--num >= 0 )
00895 safe_asimage_destroy( layers[num].im );
00896
00897 free(align);
00898 free(layers);
00899
00900 return result;
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916 static ASImage *
00917 handle_asxml_tag_img( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, int dst_width, int dst_height)
00918 {
00919 ASImage *result = NULL ;
00920 const char* src = NULL;
00921 xml_elem_t* ptr ;
00922 LOCAL_DEBUG_OUT("doc = %p, parm = %p", doc, parm );
00923 for (ptr = parm ; ptr ; ptr = ptr->next) {
00924 if (!strcmp(ptr->tag, "src")) src = ptr->parm;
00925 }
00926 if (src && !strcmp(src, "xroot:")) {
00927 unsigned int width, height;
00928 Pixmap rp = GetRootPixmap(None);
00929 if( state->verbose > 1 )
00930 show_progress("Getting root pixmap.");
00931 if (rp) {
00932 get_dpy_drawable_size( state->asv->dpy, rp, &width, &height);
00933 result = pixmap2asimage(state->asv, rp, 0, 0, width, height, 0xFFFFFFFF, False, 100);
00934 if( dst_width == 0 ) dst_width = width ;
00935 if( dst_height == 0 ) dst_height = height ;
00936 if( dst_width != (int)width || dst_height != (int)height )
00937 {
00938 ASImage *tmp = scale_asimage( NULL, result, dst_width, dst_height, ASA_ASImage, 100, ASIMAGE_QUALITY_DEFAULT );
00939 if( tmp )
00940 {
00941 safe_asimage_destroy( result );
00942 result = tmp ;
00943 }
00944 }
00945 }
00946 } else if (src) {
00947 if( state->verbose > 1 )
00948 show_progress("Loading image [%s] using imman (%p) with search path \"%s\" (dst_size = %dx%d).", src, state->imman, state->imman?state->imman->search_path[0]:"", dst_width, dst_height);
00949 if( dst_width != 0 || dst_height != 0 )
00950 result = get_thumbnail_asimage( state->imman, src, dst_width, dst_height, (dst_width==0||dst_height==0)?AS_THUMBNAIL_PROPORTIONAL:0 );
00951 else
00952 result = get_asimage( state->imman, src, 0xFFFFFFFF, 100 );
00953 }
00954 return result;
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967 static ASImage *
00968 handle_asxml_tag_recall( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm)
00969 {
00970 ASImage *result = NULL ;
00971 xml_elem_t* ptr = parm ;
00972 LOCAL_DEBUG_OUT("doc = %p, parm = %p", doc, parm );
00973 while ( ptr && !result )
00974 {
00975 if (!strcmp(ptr->tag, "srcid"))
00976 {
00977 if( state->verbose > 1 )
00978 show_progress("Recalling image id [%s] from imman %p.", ptr->parm, state->imman);
00979 result = fetch_asimage(state->imman, ptr->parm );
00980 if (!result)
00981 show_warning("Image recall failed for id [%s].", ptr->parm);
00982 }
00983 ptr = ptr->next ;
00984 }
00985 if( result == NULL )
00986 {
00987 for( ptr = parm ; ptr && !result ; ptr = ptr->next )
00988 if (!strcmp(ptr->tag, "default_src"))
00989 {
00990 if( state->verbose > 1 )
00991 show_progress("loading default image [%s] from imman %p.", ptr->parm, state->imman);
00992 result = get_asimage( state->imman, ptr->parm, 0xFFFFFFFF, 100 );
00993 }
00994 }
00995 return result;
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007 static ASImage *
01008 handle_asxml_tag_release( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm)
01009 {
01010 xml_elem_t* ptr ;
01011 LOCAL_DEBUG_OUT("doc = %p, parm = %p", doc, parm );
01012 for (ptr = parm ; ptr ; ptr = ptr->next)
01013 if (!strcmp(ptr->tag, "srcid"))
01014 {
01015 if( state->verbose > 1 )
01016 show_progress("Releasing image id [%s] from imman %p.", ptr->parm, state->imman);
01017 release_asimage_by_name(state->imman, (char*)ptr->parm );
01018 break;
01019 }
01020 return NULL;
01021 }
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039 static ASImage *
01040 handle_asxml_tag_color( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm)
01041 {
01042 xml_elem_t* ptr ;
01043 char* name = NULL;
01044 const char* argb_text = NULL;
01045 const char* var_domain = NULL;
01046 LOCAL_DEBUG_OUT("doc = %p, parm = %p", doc, parm );
01047 for (ptr = parm ; ptr ; ptr = ptr->next) {
01048 if (!strcmp(ptr->tag, "name")) name = ptr->parm;
01049 else if (!strcmp(ptr->tag, "argb")) argb_text = ptr->parm;
01050 else if (!strcmp(ptr->tag, "domain")) var_domain = ptr->parm;
01051 }
01052 if (name && argb_text)
01053 {
01054 ARGB32 argb = ARGB32_Black;
01055 if( parse_argb_color( argb_text, &argb ) != argb_text )
01056 {
01057 char *tmp;
01058 CARD32 hue16, sat16, val16 ;
01059 int vd_len = var_domain?strlen(var_domain):0 ;
01060
01061 tmp = safemalloc( vd_len + 1+ strlen(name )+32+1 ) ;
01062
01063 if( var_domain && var_domain[0] != '\0' )
01064 {
01065 if( var_domain[vd_len-1] != '.' )
01066 {
01067 sprintf( tmp, "%s.", var_domain );
01068 ++vd_len ;
01069 }else
01070 strcpy( tmp, var_domain );
01071 }
01072
01073
01074 #ifdef HAVE_AFTERBASE
01075 if( state->verbose > 1 )
01076 show_progress("defining synonim [%s] for color value #%8.8X.", name, argb);
01077 register_custom_color( name, argb );
01078 #endif
01079 sprintf( tmp+vd_len, "%s.alpha", name );
01080 asxml_var_insert( tmp, ARGB32_ALPHA8(argb) );
01081 sprintf( tmp+vd_len, "%s.red", name );
01082 asxml_var_insert( tmp, ARGB32_RED8(argb) );
01083 sprintf( tmp+vd_len, "%s.green", name );
01084 asxml_var_insert( tmp, ARGB32_GREEN8(argb) );
01085 sprintf( tmp+vd_len, "%s.blue", name );
01086 asxml_var_insert( tmp, ARGB32_BLUE8(argb) );
01087
01088 hue16 = rgb2hsv( ARGB32_RED16(argb), ARGB32_GREEN16(argb), ARGB32_BLUE16(argb), &sat16, &val16 );
01089
01090 sprintf( tmp+vd_len, "%s.hue", name );
01091 asxml_var_insert( tmp, hue162degrees( hue16 ) );
01092 sprintf( tmp+vd_len, "%s.saturation", name );
01093 asxml_var_insert( tmp, val162percent( sat16 ) );
01094 sprintf( tmp+vd_len, "%s.value", name );
01095 asxml_var_insert( tmp, val162percent( val16 ) );
01096 free( tmp );
01097 }
01098 }
01099 return NULL;
01100 }
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112 static ASImage *
01113 handle_asxml_tag_printf( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm)
01114 {
01115 xml_elem_t* ptr ;
01116 const char* format = NULL;
01117 const char* var = NULL;
01118 int val = 0 ;
01119 Bool use_val = False ;
01120 int arg_count = 0, i;
01121 LOCAL_DEBUG_OUT("doc = %p, parm = %p", doc, parm );
01122 for (ptr = parm ; ptr ; ptr = ptr->next)
01123 {
01124 if (!strcmp(ptr->tag, "format")) format = ptr->parm;
01125 else if (!strcmp(ptr->tag, "var")) { var = ptr->parm; use_val = False; }
01126 else if (!strcmp(ptr->tag, "val")) { val = (int)parse_math(ptr->parm, NULL, 0); use_val = True; }
01127 }
01128
01129 if( format != NULL )
01130 {
01131 char *interpreted_format = interpret_ctrl_codes( mystrdup(format) );
01132
01133 for( i = 0 ; format[i] != '\0' ; ++i )
01134 if( format[i] == '%' )
01135 {
01136 if( format[i+1] != '%' )
01137 ++arg_count ;
01138 else
01139 ++i ;
01140 }
01141
01142 if( use_val && arg_count == 1)
01143 printf( interpreted_format, val );
01144 else if( var != NULL && arg_count == 1 )
01145 printf( interpreted_format, asxml_var_get(var) );
01146 else if( arg_count == 0 )
01147 fputs( interpreted_format, stdout );
01148 free( interpreted_format );
01149 }
01150
01151 return NULL;
01152 }
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164 static ASImage *
01165 handle_asxml_tag_set( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm)
01166 {
01167 xml_elem_t* ptr ;
01168 const char* var_domain = NULL ;
01169 const char* var = NULL;
01170 int val = 0 ;
01171 LOCAL_DEBUG_OUT("doc = %p, parm = %p", doc, parm );
01172 for (ptr = parm ; ptr ; ptr = ptr->next)
01173 {
01174 if (!strcmp(ptr->tag, "var")) var = ptr->parm;
01175 else if (!strcmp(ptr->tag, "domain")) var_domain = ptr->parm;
01176 else if (!strcmp(ptr->tag, "val")) val = (int)parse_math(ptr->parm, NULL, 0);
01177 }
01178
01179 if( var != NULL )
01180 {
01181 char *tmp = (char*)var ;
01182 if( var_domain && var_domain[0] != '\0' )
01183 {
01184 int vd_len = strlen(var_domain);
01185 tmp = safemalloc( vd_len + 1 + strlen(var) + 1 );
01186 sprintf( tmp, ( var_domain[vd_len-1] != '.' )?"%s.%s":"%s%s", var_domain, var );
01187 }
01188 asxml_var_insert( tmp, val );
01189 if( tmp != var )
01190 free( tmp );
01191 }
01192
01193 return NULL;
01194 }
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 static ASImage *
01212 handle_asxml_tag_if( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm)
01213 {
01214 xml_elem_t* ptr ;
01215 int val1 = 0, val2 = 0 ;
01216 const char *op = NULL ;
01217 int res = 0 ;
01218 ASImage *im = NULL, *imtmp = NULL ;
01219 LOCAL_DEBUG_OUT("doc = %p, parm = %p", doc, parm );
01220
01221 for (ptr = parm ; ptr ; ptr = ptr->next)
01222 {
01223 if (!strcmp(ptr->tag, "op")) op = ptr->parm;
01224 else if (!strcmp(ptr->tag, "val1")) val1 = (int)parse_math(ptr->parm, NULL, 0);
01225 else if (!strcmp(ptr->tag, "val2")) val2 = (int)parse_math(ptr->parm, NULL, 0);
01226 }
01227
01228 if( op != NULL )
01229 {
01230 if ( strcmp(op, "gt") == 0 ) res = (val1 > val2);
01231 else if( strcmp(op, "lt") == 0 ) res = (val1 < val2);
01232 else if( strcmp(op, "ge") == 0 ) res = (val1 >= val2);
01233 else if( strcmp(op, "le") == 0 ) res = (val1 <= val2);
01234 else if( strcmp(op, "eq") == 0 ) res = (val1 == val2);
01235 else if( strcmp(op, "ne") == 0 ) res = (val1 != val2);
01236 }
01237
01238 if( doc->tag[0] == 'u' )
01239 res = !res ;
01240
01241 ptr = NULL ;
01242 for (ptr = doc->child ; ptr ; ptr = ptr->next)
01243 {
01244 if( strcmp(ptr->tag, res?"then":"else" ) )
01245 {
01246 ptr = ptr->child ;
01247 break;
01248 }
01249 if( res && ptr->next == NULL )
01250 ptr = doc->child ;
01251 }
01252
01253 while( ptr )
01254 {
01255 imtmp = build_image_from_xml(state->asv, state->imman, state->fontman, ptr, NULL, state->flags, state->verbose, state->display_win);
01256 if( im && imtmp ) safe_asimage_destroy( im );
01257 if( imtmp ) im = imtmp ;
01258 ptr = ptr->next ;
01259 }
01260 return im ;
01261 }
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295 static ASImage *
01296 handle_asxml_tag_gradient( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, int width, int height)
01297 {
01298 ASImage *result = NULL ;
01299 xml_elem_t* ptr ;
01300 double angle = 0;
01301 char* color_str = NULL;
01302 char* offset_str = NULL;
01303 LOCAL_DEBUG_OUT("doc = %p, parm = %p, width = %d, height = %d", doc, parm, width, height );
01304 for (ptr = parm ; ptr ; ptr = ptr->next) {
01305 if (!strcmp(ptr->tag, "angle")) angle = strtod(ptr->parm, NULL);
01306 else if (!strcmp(ptr->tag, "colors")) color_str = ptr->parm;
01307 else if (!strcmp(ptr->tag, "offsets")) offset_str = ptr->parm;
01308 }
01309 if ( color_str)
01310 {
01311 ASGradient gradient;
01312 int reverse = 0, npoints1 = 0, npoints2 = 0;
01313 char* p;
01314 angle = fmod(angle, 2 * PI);
01315 if (angle > 2 * PI * 15 / 16 || angle < 2 * PI * 1 / 16) {
01316 gradient.type = GRADIENT_Left2Right;
01317 } else if (angle < 2 * PI * 3 / 16) {
01318 gradient.type = GRADIENT_TopLeft2BottomRight;
01319 } else if (angle < 2 * PI * 5 / 16) {
01320 gradient.type = GRADIENT_Top2Bottom;
01321 } else if (angle < 2 * PI * 7 / 16) {
01322 gradient.type = GRADIENT_BottomLeft2TopRight; reverse = 1;
01323 } else if (angle < 2 * PI * 9 / 16) {
01324 gradient.type = GRADIENT_Left2Right; reverse = 1;
01325 } else if (angle < 2 * PI * 11 / 16) {
01326 gradient.type = GRADIENT_TopLeft2BottomRight; reverse = 1;
01327 } else if (angle < 2 * PI * 13 / 16) {
01328 gradient.type = GRADIENT_Top2Bottom; reverse = 1;
01329 } else {
01330 gradient.type = GRADIENT_BottomLeft2TopRight;
01331 }
01332 for (p = color_str ; isspace((int)*p) ; p++);
01333 for (npoints1 = 0 ; *p ; npoints1++) {
01334 if (*p) for ( ; *p && !isspace((int)*p) ; p++);
01335 for ( ; isspace((int)*p) ; p++);
01336 }
01337 if (offset_str) {
01338 for (p = offset_str ; isspace((int)*p) ; p++);
01339 for (npoints2 = 0 ; *p ; npoints2++) {
01340 if (*p) for ( ; *p && !isspace((int)*p) ; p++);
01341 for ( ; isspace((int)*p) ; p++);
01342 }
01343 }
01344 gradient.npoints = max( npoints1, npoints2 );
01345 if (npoints1 > 1) {
01346 int i;
01347 gradient.color = safecalloc(gradient.npoints, sizeof(ARGB32));
01348 gradient.offset = NEW_ARRAY(double, gradient.npoints);
01349 for (p = color_str ; isspace((int)*p) ; p++);
01350 for (npoints1 = 0 ; *p ; ) {
01351 char* pb = p, ch;
01352 if (*p) for ( ; *p && !isspace((int)*p) ; p++);
01353 for ( ; isspace((int)*p) ; p++);
01354 ch = *p; *p = '\0';
01355 if (parse_argb_color(pb, gradient.color + npoints1) != pb)
01356 {
01357 npoints1++;
01358 }else
01359 show_warning( "failed to parse color [%s] - defaulting to black", pb );
01360 *p = ch;
01361 }
01362 if (offset_str) {
01363 for (p = offset_str ; isspace((int)*p) ; p++);
01364 for (npoints2 = 0 ; *p ; ) {
01365 char* pb = p, ch;
01366 if (*p) for ( ; *p && !isspace((int)*p) ; p++);
01367 ch = *p; *p = '\0';
01368 gradient.offset[npoints2] = strtod(pb, &pb);
01369 if (pb == p) npoints2++;
01370 *p = ch;
01371 for ( ; isspace((int)*p) ; p++);
01372 }
01373 } else {
01374 for (npoints2 = 0 ; npoints2 < gradient.npoints ; npoints2++)
01375 gradient.offset[npoints2] = (double)npoints2 / (gradient.npoints - 1);
01376 }
01377 if (reverse) {
01378 for (i = 0 ; i < gradient.npoints / 2 ; i++) {
01379 int i2 = gradient.npoints - 1 - i;
01380 ARGB32 c = gradient.color[i];
01381 double o = gradient.offset[i];
01382 gradient.color[i] = gradient.color[i2];
01383 gradient.color[i2] = c;
01384 gradient.offset[i] = gradient.offset[i2];
01385 gradient.offset[i2] = o;
01386 }
01387 for (i = 0 ; i < gradient.npoints ; i++) {
01388 gradient.offset[i] = 1.0 - gradient.offset[i];
01389 }
01390 }
01391 if (state->verbose > 1) {
01392 show_progress("Generating [%dx%d] gradient with angle [%f] and npoints [%d/%d].", width, height, angle, npoints1, npoints2);
01393 for (i = 0 ; i < gradient.npoints ; i++) {
01394 show_progress(" Point [%d] has color [#%08x] and offset [%f].", i, (unsigned int)gradient.color[i], gradient.offset[i]);
01395 }
01396 }
01397 result = make_gradient(state->asv, &gradient, width, height, SCL_DO_ALL, ASA_ASImage, 0, ASIMAGE_QUALITY_DEFAULT);
01398 if( gradient.color )
01399 free( gradient.color );
01400 if( gradient.offset )
01401 free( gradient.offset );
01402 }
01403 }
01404 return result;
01405 }
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431 static ASImage *
01432 handle_asxml_tag_solid( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, int width, int height)
01433 {
01434 ASImage *result = NULL ;
01435 xml_elem_t* ptr;
01436 Bool opacity_set = False ;
01437 int opacity = 100 ;
01438 ARGB32 color = ARGB32_White;
01439 CARD32 a, r, g, b ;
01440 LOCAL_DEBUG_OUT("doc = %p, parm = %p, width = %d, height = %d", doc, parm, width, height );
01441 for (ptr = parm ; ptr ; ptr = ptr->next) {
01442 if (!strcmp(ptr->tag, "color")) parse_argb_color(ptr->parm, &color);
01443 else if (!strcmp(ptr->tag, "opacity")) { opacity = atol(ptr->parm); opacity_set = True ; }
01444 }
01445 if( state->verbose > 1 )
01446 show_progress("Creating solid color [#%08x] image [%dx%d].", (unsigned int)color, width, height);
01447 result = create_asimage(width, height, ASIMAGE_QUALITY_TOP);
01448 if( opacity < 0 ) opacity = 0 ;
01449 else if( opacity > 100 ) opacity = 100 ;
01450 a = opacity_set? (0x000000FF * (CARD32)opacity)/100: ARGB32_ALPHA8(color);
01451 r = ARGB32_RED8(color);
01452 g = ARGB32_GREEN8(color);
01453 b = ARGB32_BLUE8(color);
01454 color = MAKE_ARGB32(a,r,g,b);
01455 if (result)
01456 fill_asimage(state->asv, result, 0, 0, width, height, color);
01457
01458 return result;
01459 }
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498 static ASImage *
01499 handle_asxml_tag_save( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp)
01500 {
01501 ASImage *result = NULL ;
01502 xml_elem_t* ptr ;
01503 const char* dst = NULL;
01504 const char* ext = NULL;
01505 const char* compress = NULL ;
01506 const char* opacity = NULL ;
01507 int delay = 0 ;
01508 int replace = 1;
01509
01510 int autoext = 0;
01511 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p", doc, parm, imtmp );
01512 for (ptr = parm ; ptr ; ptr = ptr->next) {
01513 if (!strcmp(ptr->tag, "dst")) dst = ptr->parm;
01514 else if (!strcmp(ptr->tag, "format")) ext = ptr->parm;
01515 else if (!strncmp(ptr->tag, "compress", 8)) compress = ptr->parm;
01516 else if (!strcmp(ptr->tag, "opacity")) opacity = ptr->parm;
01517 else if (!strcmp(ptr->tag, "delay")) delay = atoi(ptr->parm);
01518 else if (!strcmp(ptr->tag, "replace")) replace = atoi(ptr->parm);
01519 }
01520 if (dst && !ext) {
01521 ext = strrchr(dst, '.');
01522 if (ext) ext++;
01523 autoext = 1;
01524 }
01525
01526 result = imtmp;
01527
01528 if ( autoext && ext )
01529 show_warning("No format given. File extension [%s] used as format.", ext);
01530 if( state->verbose > 1 )
01531 show_progress("reSaving image to file [%s].", dst?dst:"stdout");
01532 if (result && get_flags( state->flags, ASIM_XML_ENABLE_SAVE) )
01533 {
01534 if( state->verbose > 1 )
01535 show_progress("Saving image to file [%s].", dst?dst:"stdout");
01536 if( !save_asimage_to_file(dst, result, ext, compress, opacity, delay, replace))
01537 show_error("Unable to save image into file [%s].", dst?dst:"stdout");
01538 }
01539
01540 return result;
01541 }
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 static ASImage *
01557 handle_asxml_tag_background( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp)
01558 {
01559 ASImage *result = NULL ;
01560 xml_elem_t* ptr ;
01561 ARGB32 argb = ARGB32_Black;
01562 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p", doc, parm, imtmp );
01563 for (ptr = parm ; ptr ; ptr = ptr->next) {
01564 if (!strcmp(ptr->tag, "color")) parse_argb_color( ptr->parm, &argb );
01565 }
01566 if (imtmp) {
01567 result = clone_asimage( imtmp, SCL_DO_ALL );
01568 result->back_color = argb ;
01569 }
01570 if( state->verbose > 1 )
01571 show_progress( "Setting back_color for image %p to 0x%8.8X", result, argb );
01572 return result;
01573 }
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593 static ASImage *
01594 handle_asxml_tag_blur( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp)
01595 {
01596 ASImage *result = NULL ;
01597 xml_elem_t* ptr ;
01598 int horz = 0, vert = 0;
01599 int filter = SCL_DO_ALL;
01600 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p", doc, parm, imtmp );
01601 for (ptr = parm ; ptr ; ptr = ptr->next)
01602 {
01603 if (!strcmp(ptr->tag, "horz")) horz = atoi(ptr->parm);
01604 else if (!strcmp(ptr->tag, "vert")) vert = atoi(ptr->parm);
01605 else if (!strcmp(ptr->tag, "channels"))
01606 {
01607 int i = 0 ;
01608 char *str = &(ptr->parm[0]) ;
01609 filter = 0 ;
01610 while( str[i] != '\0' )
01611 {
01612 if( str[i] == 'a' )
01613 filter |= SCL_DO_ALPHA ;
01614 else if( str[i] == 'r' )
01615 filter |= SCL_DO_RED ;
01616 else if( str[i] == 'g' )
01617 filter |= SCL_DO_GREEN ;
01618 else if( str[i] == 'b' )
01619 filter |= SCL_DO_BLUE ;
01620 ++i ;
01621 }
01622 }
01623 }
01624 result = blur_asimage_gauss(state->asv, imtmp, horz, vert, filter, ASA_ASImage, 0, ASIMAGE_QUALITY_DEFAULT);
01625 if( state->verbose > 1 )
01626 show_progress("Blurrer image with radii %d, %d.", horz, vert);
01627 return result;
01628 }
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663 static ASImage *
01664 handle_asxml_tag_bevel( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
01665 {
01666 ASImage *result = NULL ;
01667 xml_elem_t* ptr ;
01668 char* color_str = NULL;
01669 char* border_str = NULL;
01670 int solid = 1, outline = 0 ;
01671 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
01672 for (ptr = parm ; ptr ; ptr = ptr->next) {
01673 if (!strcmp(ptr->tag, "colors")) color_str = ptr->parm;
01674 else if (!strcmp(ptr->tag, "border")) border_str = ptr->parm;
01675 else if (!strcmp(ptr->tag, "solid")) solid = atoi(ptr->parm);
01676 else if (!strcmp(ptr->tag, "outline")) outline = atoi(ptr->parm);
01677 }
01678 if (imtmp)
01679 {
01680 ASImageBevel bevel;
01681 ASImageLayer layer;
01682 memset( &bevel, 0x00, sizeof(ASImageBevel) );
01683 if( solid )
01684 bevel.type = BEVEL_SOLID_INLINE;
01685 bevel.hi_color = 0xffdddddd;
01686 bevel.lo_color = 0xff555555;
01687 if( outline )
01688 bevel.top_outline = bevel.left_outline = bevel.right_outline = bevel.bottom_outline = 10;
01689 else
01690 bevel.top_inline = bevel.left_inline = bevel.right_inline = bevel.bottom_inline = 10;
01691 if (color_str) {
01692 char* p = color_str;
01693 while (isspace((int)*p)) p++;
01694 p = (char*)parse_argb_color(p, &bevel.hi_color);
01695 while (isspace((int)*p)) p++;
01696 parse_argb_color(p, &bevel.lo_color);
01697 }
01698 if (border_str) {
01699 char* p = (char*)border_str;
01700 if( outline )
01701 {
01702 bevel.left_outline = (unsigned short)parse_math(p, &p, width);
01703 bevel.top_outline = (unsigned short)parse_math(p, &p, height);
01704 bevel.right_outline = (unsigned short)parse_math(p, &p, width);
01705 bevel.bottom_outline = (unsigned short)parse_math(p, &p, height);
01706 }else
01707 {
01708 bevel.left_inline = (unsigned short)parse_math(p, &p, width);
01709 bevel.top_inline = (unsigned short)parse_math(p, &p, height);
01710 bevel.right_inline = (unsigned short)parse_math(p, &p, width);
01711 bevel.bottom_inline = (unsigned short)parse_math(p, &p, height);
01712 }
01713 }
01714 bevel.hihi_color = bevel.hi_color;
01715 bevel.hilo_color = bevel.hi_color;
01716 bevel.lolo_color = bevel.lo_color;
01717 if( state->verbose > 1 )
01718 show_progress("Generating bevel with offsets [%d %d %d %d] and colors [#%08x #%08x].", bevel.left_inline, bevel.top_inline, bevel.right_inline, bevel.bottom_inline, (unsigned int)bevel.hi_color, (unsigned int)bevel.lo_color);
01719 init_image_layers( &layer, 1 );
01720 layer.im = imtmp;
01721 if( width <= bevel.left_outline+bevel.right_outline )
01722 layer.clip_width = 1;
01723 else
01724 layer.clip_width = width-(bevel.left_outline+bevel.right_outline);
01725 if( height <= bevel.top_outline+bevel.bottom_outline )
01726 layer.clip_height = 1;
01727 else
01728 layer.clip_height = height-(bevel.top_outline+bevel.bottom_outline);
01729 layer.bevel = &bevel;
01730 result = merge_layers(state->asv, &layer, 1,
01731 width, height, ASA_ASImage, 0, ASIMAGE_QUALITY_DEFAULT);
01732 }
01733 return result;
01734 }
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757 static ASImage *
01758 handle_asxml_tag_mirror( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
01759 {
01760 ASImage *result = NULL ;
01761 xml_elem_t* ptr ;
01762 int dir = 0;
01763 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
01764 for (ptr = parm ; ptr ; ptr = ptr->next) {
01765 if (!strcmp(ptr->tag, "dir")) dir = !mystrcasecmp(ptr->parm, "vertical");
01766 }
01767 result = mirror_asimage(state->asv, imtmp, 0, 0, width, height, dir,
01768 ASA_ASImage,
01769 0, ASIMAGE_QUALITY_DEFAULT);
01770 if( state->verbose > 1 )
01771 show_progress("Mirroring image [%sally].", dir ? "horizont" : "vertic");
01772 return result;
01773 }
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796 static ASImage *
01797 handle_asxml_tag_rotate( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
01798 {
01799 ASImage *result = NULL ;
01800 xml_elem_t* ptr ;
01801 double angle = 0;
01802 int dir = 0;
01803 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
01804 for (ptr = parm ; ptr ; ptr = ptr->next)
01805 if (!strcmp(ptr->tag, "angle")) angle = strtod(ptr->parm, NULL);
01806
01807 angle = fmod(angle, 2 * PI);
01808 if (angle > 2 * PI * 7 / 8 || angle < 2 * PI * 1 / 8)
01809 dir = 0;
01810 else if (angle < 2 * PI * 3 / 8)
01811 dir = FLIP_VERTICAL;
01812 else if (angle < 2 * PI * 5 / 8)
01813 dir = FLIP_UPSIDEDOWN;
01814 else
01815 dir = FLIP_VERTICAL | FLIP_UPSIDEDOWN;
01816 if (dir)
01817 {
01818 if( get_flags(dir, FLIP_VERTICAL))
01819 {
01820 int tmp = width ;
01821 width = height ;
01822 height = tmp ;
01823 }
01824 result = flip_asimage(state->asv, imtmp, 0, 0, width, height, dir, ASA_ASImage, 0, ASIMAGE_QUALITY_DEFAULT);
01825 if( state->verbose > 1 )
01826 show_progress("Rotating image [%f degrees].", angle);
01827 } else
01828 result = imtmp;
01829
01830 return result;
01831 }
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866 static ASImage *
01867 handle_asxml_tag_scale( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
01868 {
01869 ASImage *result = NULL ;
01870 xml_elem_t* ptr;
01871 int src_x = 0, src_y = 0 ;
01872 int src_width = 0, src_height = 0 ;
01873 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
01874 for (ptr = parm ; ptr ; ptr = ptr->next)
01875 {
01876 if (!strcmp(ptr->tag, "src_x")) src_x = (int)parse_math(ptr->parm, NULL, width);
01877 else if (!strcmp(ptr->tag, "src_y")) src_y = (int)parse_math(ptr->parm, NULL, width);
01878 else if (!strcmp(ptr->tag, "src_width")) src_width = (int)parse_math(ptr->parm, NULL, width);
01879 else if (!strcmp(ptr->tag, "src_height")) src_height = (int)parse_math(ptr->parm, NULL, width);
01880 }
01881 if( state->verbose > 1 )
01882 show_progress("Scaling image to [%dx%d].", width, height);
01883 result = scale_asimage2( state->asv, imtmp,
01884 src_x, src_y, src_width, src_height,
01885 width, height,
01886 ASA_ASImage, 100, ASIMAGE_QUALITY_DEFAULT);
01887 return result;
01888 }
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926 static ASImage *
01927 handle_asxml_tag_slice( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
01928 {
01929 ASImage *result = NULL ;
01930 xml_elem_t* ptr;
01931 int x_start = 0, x_end = 0 ;
01932 int y_start = 0, y_end = 0 ;
01933 Bool scale = False ;
01934 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
01935 for (ptr = parm ; ptr ; ptr = ptr->next)
01936 {
01937 if (!strcmp(ptr->tag, "x_start")) x_start = (int)parse_math(ptr->parm, NULL, width);
01938 else if (!strcmp(ptr->tag, "x_end")) x_end = (int)parse_math(ptr->parm, NULL, width);
01939 else if (!strcmp(ptr->tag, "y_start")) y_start = (int)parse_math(ptr->parm, NULL, height);
01940 else if (!strcmp(ptr->tag, "y_end")) y_end = (int)parse_math(ptr->parm, NULL, height);
01941 else if (!strcmp(ptr->tag, "scale")) scale = (ptr->parm[0] == '1');
01942 }
01943
01944 if( state->verbose > 1 )
01945 show_progress("Slicing image to [%dx%d].", width, height);
01946 result = slice_asimage2( state->asv, imtmp, x_start, x_end, y_start, y_end, width, height,
01947 scale, ASA_ASImage, 100, ASIMAGE_QUALITY_DEFAULT);
01948 return result;
01949 }
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976 static ASImage *
01977 handle_asxml_tag_pixelize( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
01978 {
01979 ASImage *result = NULL ;
01980 xml_elem_t* ptr;
01981 int clip_x = 0, clip_y = 0 ;
01982 int pixel_width = 1, pixel_height = 1 ;
01983 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
01984 for (ptr = parm ; ptr ; ptr = ptr->next)
01985 {
01986 if (!strcmp(ptr->tag, "clip_x")) clip_x = (int)parse_math(ptr->parm, NULL, width);
01987 else if (!strcmp(ptr->tag, "clip_y")) clip_y = (int)parse_math(ptr->parm, NULL, height);
01988 else if (!strcmp(ptr->tag, "pixel_width")) pixel_width = (int)parse_math(ptr->parm, NULL, width);
01989 else if (!strcmp(ptr->tag, "pixel_height")) pixel_height = (int)parse_math(ptr->parm, NULL, height);
01990 }
01991
01992 if( state->verbose > 1 )
01993 show_progress("Pixelizing image to [%dx%d] using pixel size %dx%d.",
01994 width, height, pixel_width, pixel_height);
01995 result = pixelize_asimage (state->asv, imtmp, clip_x, clip_y, width, height,
01996 pixel_width, pixel_height,
01997 ASA_ASImage, 100, ASIMAGE_QUALITY_DEFAULT);
01998 return result;
01999 }
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025 static ASImage *
02026 handle_asxml_tag_color2alpha( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
02027 {
02028 ASImage *result = NULL ;
02029 xml_elem_t* ptr;
02030 int clip_x = 0, clip_y = 0 ;
02031 ARGB32 color;
02032 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
02033 for (ptr = parm ; ptr ; ptr = ptr->next)
02034 {
02035 if (!strcmp(ptr->tag, "clip_x")) clip_x = (int)parse_math(ptr->parm, NULL, width);
02036 else if (!strcmp(ptr->tag, "clip_y")) clip_y = (int)parse_math(ptr->parm, NULL, height);
02037 else if (!strcmp(ptr->tag, "color")) parse_argb_color(ptr->parm, &color);
02038 }
02039
02040 if( state->verbose > 1 )
02041 show_progress("color2alpha image to [%dx%d] using color #%8.8X.", width, height, color);
02042 result = color2alpha_asimage (state->asv, imtmp, clip_x, clip_y, width, height,
02043 color,
02044 ASA_ASImage, 100, ASIMAGE_QUALITY_DEFAULT);
02045 return result;
02046 }
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072 static ASImage *
02073 handle_asxml_tag_crop( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
02074 {
02075 ASImage *result = NULL ;
02076 xml_elem_t* ptr;
02077 ARGB32 tint = 0 ;
02078 int srcx = 0, srcy = 0;
02079 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
02080 for (ptr = parm ; ptr ; ptr = ptr->next) {
02081 if (!strcmp(ptr->tag, "srcx")) srcx = (int)parse_math(ptr->parm, NULL, width);
02082 else if (!strcmp(ptr->tag, "srcy")) srcy = (int)parse_math(ptr->parm, NULL, height);
02083 else if (!strcmp(ptr->tag, "tint")) parse_argb_color(ptr->parm, &tint);
02084 }
02085 if( state->verbose > 1 )
02086 show_progress("Cropping image to [%dx%d].", width, height);
02087 result = tile_asimage(state->asv, imtmp, srcx, srcy, width, height, tint, ASA_ASImage, 100, ASIMAGE_QUALITY_TOP);
02088 return result;
02089 }
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124 static ASImage *
02125 handle_asxml_tag_tile( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
02126 {
02127 ASImage *result = NULL ;
02128 xml_elem_t* ptr;
02129 int xorig = 0, yorig = 0;
02130 ARGB32 tint = 0 ;
02131 char *complement_str = NULL ;
02132 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
02133 for (ptr = parm ; ptr ; ptr = ptr->next) {
02134 if (!strcmp(ptr->tag, "x_origin")) xorig = (int)parse_math(ptr->parm, NULL, width);
02135 else if (!strcmp(ptr->tag, "y_origin")) yorig = (int)parse_math(ptr->parm, NULL, height);
02136 else if (!strcmp(ptr->tag, "tint")) parse_argb_color(ptr->parm, &tint);
02137 else if (!strcmp(ptr->tag, "complement")) complement_str = ptr->parm;
02138 }
02139 if( complement_str )
02140 {
02141 register char *ptr = complement_str ;
02142 CARD32 a = ARGB32_ALPHA8(tint),
02143 r = ARGB32_RED8(tint),
02144 g = ARGB32_GREEN8(tint),
02145 b = ARGB32_BLUE8(tint) ;
02146 while( *ptr )
02147 {
02148 if( *ptr == 'a' ) a = ~a ;
02149 else if( *ptr == 'r' ) r = ~r ;
02150 else if( *ptr == 'g' ) g = ~g ;
02151 else if( *ptr == 'b' ) b = ~b ;
02152 ++ptr ;
02153 }
02154
02155 tint = MAKE_ARGB32(a, r, g, b );
02156 }
02157 if( state->verbose > 1 )
02158 show_progress("Tiling image to [%dx%d].", width, height);
02159 result = tile_asimage(state->asv, imtmp, xorig, yorig, width, height, tint, ASA_ASImage, 100, ASIMAGE_QUALITY_TOP);
02160 return result;
02161 }
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218 static ASImage *
02219 handle_asxml_tag_hsv( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
02220 {
02221 ASImage *result = NULL ;
02222 xml_elem_t* ptr;
02223 int affected_hue = 0, affected_radius = 360 ;
02224 int hue_offset = 0, saturation_offset = 0, value_offset = 0 ;
02225 int xorig = 0, yorig = 0;
02226 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
02227 for (ptr = parm ; ptr ; ptr = ptr->next)
02228 {
02229 if (!strcmp(ptr->tag, "x_origin")) xorig = (int)parse_math(ptr->parm, NULL, width);
02230 else if (!strcmp(ptr->tag, "y_origin")) yorig = (int)parse_math(ptr->parm, NULL, height);
02231 else if (!strcmp(ptr->tag, "affected_hue"))
02232 {
02233 if( isdigit( (int)ptr->parm[0] ) )
02234 affected_hue = (int)parse_math(ptr->parm, NULL, 360);
02235 else
02236 {
02237 ARGB32 color = 0;
02238 if( parse_argb_color( ptr->parm, &color ) != ptr->parm )
02239 {
02240 affected_hue = rgb2hue( ARGB32_RED16(color),
02241 ARGB32_GREEN16(color),
02242 ARGB32_BLUE16(color));
02243 affected_hue = hue162degrees( affected_hue );
02244 }
02245 }
02246 }
02247 else if (!strcmp(ptr->tag, "affected_radius")) affected_radius = (int)parse_math(ptr->parm, NULL, 360);
02248 else if (!strcmp(ptr->tag, "hue_offset")) hue_offset = (int)parse_math(ptr->parm, NULL, 360);
02249 else if (!strcmp(ptr->tag, "saturation_offset"))saturation_offset = (int)parse_math(ptr->parm, NULL, 100);
02250 else if (!strcmp(ptr->tag, "value_offset")) value_offset = (int)parse_math(ptr->parm, NULL, 100);
02251 }
02252 if( hue_offset == -1 && saturation_offset == -1 )
02253 {
02254 hue_offset = 0 ;
02255 saturation_offset = -99 ;
02256 }
02257 if (hue_offset!=0 || saturation_offset != 0 || value_offset != 0 )
02258 {
02259 result = adjust_asimage_hsv(state->asv, imtmp, xorig, yorig, width, height,
02260 affected_hue, affected_radius,
02261 hue_offset, saturation_offset, value_offset,
02262 ASA_ASImage, 100, ASIMAGE_QUALITY_TOP);
02263 }
02264 if( state->verbose > 1 )
02265 show_progress("adjusted HSV of the image by [%d,%d,%d] affected hues are %+d-%+d.result = %p", hue_offset, saturation_offset, value_offset, affected_hue-affected_radius, affected_hue+affected_radius, result);
02266 return result;
02267 }
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294 static ASImage *
02295 handle_asxml_tag_pad( ASImageXMLState *state, xml_elem_t* doc, xml_elem_t* parm, ASImage *imtmp, int width, int height)
02296 {
02297 ASImage *result = NULL ;
02298 xml_elem_t* ptr;
02299 ARGB32 color = ARGB32_Black;
02300 int left = 0, top = 0, right = 0, bottom = 0;
02301 LOCAL_DEBUG_OUT("doc = %p, parm = %p, imtmp = %p, width = %d, height = %d", doc, parm, imtmp, width, height );
02302 for (ptr = parm ; ptr ; ptr = ptr->next) {
02303 if (!strcmp(ptr->tag, "left")) left = (int)parse_math(ptr->parm, NULL, width);
02304 else if (!strcmp(ptr->tag, "top")) top = (int)parse_math(ptr->parm, NULL, height);
02305 else if (!strcmp(ptr->tag, "right")) right = (int)parse_math(ptr->parm, NULL, width);
02306 else if (!strcmp(ptr->tag, "bottom")) bottom = (int)parse_math(ptr->parm, NULL, height);
02307 else if (!strcmp(ptr->tag, "color")) parse_argb_color(ptr->parm, &color);
02308 }
02309 if( state->verbose > 1 )
02310 show_progress("Padding image to [%dx%d%+d%+d].", width+left+right, height+top+bottom, left, top);
02311 if (left > 0 || top > 0 || right > 0 || bottom > 0 )
02312 result = pad_asimage(state->asv, imtmp, left, top, width+left+right, height+top+bottom,
02313 color, ASA_ASImage, 100, ASIMAGE_QUALITY_DEFAULT);
02314 return result;
02315 }
02316
02317 #define REPLACE_STRING(str,val) do {if(str)free(str);(str) = (val);}while(0)
02318
02319
02320 ASImage*
02321 build_image_from_xml( ASVisual *asv, ASImageManager *imman, ASFontManager *fontman, xml_elem_t* doc, xml_elem_t** rparm, ASFlagType flags, int verbose, Window display_win)
02322 {
02323 xml_elem_t* ptr;
02324 char* id = NULL;
02325 ASImage* result = NULL;
02326 ASImageXMLState state ;
02327
02328 if( IsCDATA(doc) ) return NULL ;
02329
02330 memset( &state, 0x00, sizeof(state));
02331 state.flags = flags ;
02332 state.asv = asv ;
02333 state.imman = imman ;
02334 state.fontman = fontman ;
02335 state.verbose = verbose ;
02336 state.display_win = display_win ;
02337
02338 if( doc )
02339 {
02340 xml_elem_t* parm = xml_parse_parm(doc->parm, NULL);
02341 xml_elem_t* ptr ;
02342 char* refid = NULL;
02343 char* width_str = NULL;
02344 char* height_str = NULL;
02345 ASImage *refimg = NULL ;
02346 int width = 0, height = 0 ;
02347 LOCAL_DEBUG_OUT("parm = %p", parm);
02348
02349 for (ptr = parm ; ptr ; ptr = ptr->next)
02350 {
02351 if (ptr->tag[0] == 'i' && ptr->tag[1] == 'd' && ptr->tag[2] == '\0')
02352 REPLACE_STRING(id,mystrdup(ptr->parm));
02353 else if (strcmp(ptr->tag, "refid") == 0 ) refid = ptr->parm ;
02354 else if (strcmp(ptr->tag, "width") == 0 ) width_str = ptr->parm ;
02355 else if (strcmp(ptr->tag, "height") == 0 ) height_str = ptr->parm ;
02356 }
02357
02358 if( id )
02359 if( (result = fetch_asimage( imman, id)) != NULL )
02360 {
02361 free( id );
02362 xml_elem_delete(NULL, parm);
02363 return result ;
02364 }
02365
02366 if( refid )
02367 refimg = fetch_asimage( imman, refid);
02368
02369 if (!strcmp(doc->tag, "composite"))
02370 result = handle_asxml_tag_composite( &state, doc, parm );
02371 else if (!strcmp(doc->tag, "text"))
02372 result = handle_asxml_tag_text( &state, doc, parm );
02373 else if (!strcmp(doc->tag, "img"))
02374 {
02375 translate_tag_size( width_str, height_str, NULL, refimg, &width, &height );
02376 result = handle_asxml_tag_img( &state, doc, parm, width, height );
02377 }else if (!strcmp(doc->tag, "recall"))
02378 result = handle_asxml_tag_recall( &state, doc, parm );
02379 else if (!strcmp(doc->tag, "release"))
02380 result = handle_asxml_tag_release( &state, doc, parm );
02381 else if (!strcmp(doc->tag, "color"))
02382 result = handle_asxml_tag_color( &state, doc, parm );
02383 else if (!strcmp(doc->tag, "printf"))
02384 result = handle_asxml_tag_printf( &state, doc, parm );
02385 else if (!strcmp(doc->tag, "set"))
02386 result = handle_asxml_tag_set( &state, doc, parm );
02387 else if (!strcmp(doc->tag, "if") || !strcmp(doc->tag, "unless") )
02388 result = handle_asxml_tag_if( &state, doc, parm );
02389 else if ( !strcmp(doc->tag, "gradient") )
02390 {
02391 translate_tag_size( width_str, height_str, NULL, refimg, &width, &height );
02392 if( width > 0 && height > 0 )
02393 result = handle_asxml_tag_gradient( &state, doc, parm, width, height );
02394 }else if (!strcmp(doc->tag, "solid"))
02395 {
02396 translate_tag_size( width_str, height_str, NULL, refimg, &width, &height );
02397 if( width > 0 && height > 0 )
02398 result = handle_asxml_tag_solid( &state, doc, parm, width, height);
02399 }else
02400 {
02401 ASImage *imtmp = NULL ;
02402
02403 for (ptr = doc->child ; ptr && !imtmp ; ptr = ptr->next)
02404 imtmp = build_image_from_xml(asv, imman, fontman, ptr, NULL, flags, verbose, display_win);
02405
02406 if( imtmp )
02407 {
02408 if (imtmp && !strcmp(doc->tag, "save"))
02409 result = handle_asxml_tag_save( &state, doc, parm, imtmp );
02410 else if (imtmp && !strcmp(doc->tag, "background"))
02411 result = handle_asxml_tag_background( &state, doc, parm, imtmp );
02412 else if (imtmp && !strcmp(doc->tag, "blur"))
02413 result = handle_asxml_tag_blur( &state, doc, parm, imtmp );
02414 else
02415 {
02416 translate_tag_size( width_str, height_str, imtmp, refimg, &width, &height );
02417
02418 if ( width > 0 && height > 0 )
02419 {
02420 #define HANDLE_SIZED_TAG(ttag) \
02421 else if( !strcmp(doc->tag, #ttag) ) result = handle_asxml_tag_##ttag( &state, doc, parm, imtmp, width, height )
02422 if (0){}
02423 HANDLE_SIZED_TAG(bevel);
02424 HANDLE_SIZED_TAG(mirror);
02425 HANDLE_SIZED_TAG(rotate);
02426 HANDLE_SIZED_TAG(scale);
02427 HANDLE_SIZED_TAG(slice);
02428 HANDLE_SIZED_TAG(crop);
02429 HANDLE_SIZED_TAG(tile);
02430 HANDLE_SIZED_TAG(hsv);
02431 HANDLE_SIZED_TAG(pad);
02432 HANDLE_SIZED_TAG(pixelize);
02433 HANDLE_SIZED_TAG(color2alpha);
02434 #undef HANDLE_SIZED_TAG
02435 }
02436 }
02437
02438 if( result != imtmp )
02439 safe_asimage_destroy(imtmp);
02440 }
02441 }
02442
02443 if( refimg )
02444 release_asimage( refimg );
02445
02446 if (rparm) *rparm = parm;
02447 else xml_elem_delete(NULL, parm);
02448 }
02449 LOCAL_DEBUG_OUT("result = %p, id = \"%s\"", result, id?id:"(null)" );
02450
02451
02452
02453
02454 if (!result && doc )
02455 {
02456 xml_elem_t* tparm = NULL;
02457 for (ptr = doc->child ; ptr && !result ; ptr = ptr->next)
02458 {
02459 xml_elem_t* sparm = NULL;
02460 result = build_image_from_xml(asv, imman, fontman, ptr, &sparm, flags, verbose, display_win);
02461 if (result)
02462 {
02463 if (tparm) xml_elem_delete(NULL, tparm);
02464 tparm = sparm;
02465 }else
02466 if (sparm) xml_elem_delete(NULL, sparm);
02467
02468 }
02469 if (rparm)
02470 {
02471 if( *rparm ) xml_elem_delete(NULL, *rparm); *rparm = tparm;
02472 }else
02473 xml_elem_delete(NULL, tparm);
02474 }
02475
02476 LOCAL_DEBUG_OUT("result = %p", result );
02477 result = commit_xml_image_built( &state, id, result );
02478 if( id )
02479 free( id );
02480 LOCAL_DEBUG_OUT("result = %p", result );
02481 if( result )
02482 {
02483 LOCAL_DEBUG_OUT("result's size = %dx%d", result->width, result->height );
02484 }
02485 return result;
02486 }
02487
02488
02489
02490