/* * Proview Open Source Process Control. * Copyright (C) 2005-2012 SSAB EMEA AB. * * This file is part of Proview. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Proview. If not, see <http://www.gnu.org/licenses/> * * Linking Proview statically or dynamically with other modules is * making a combined work based on Proview. Thus, the terms and * conditions of the GNU General Public License cover the whole * combination. * * In addition, as a special exception, the copyright holders of * Proview give you permission to, from the build function in the * Proview Configurator, combine Proview with modules generated by the * Proview PLC Editor to a PLC program, regardless of the license * terms of these modules. You may copy and distribute the resulting * combined work under the terms of your choice, provided that every * copy of the combined work is accompanied by a complete copy of * the source code of Proview (the version used to produce the * combined work), being distributed under the terms of the GNU * General Public License plus this exception. **/ #include "glow_std.h" #include <iostream> #include <float.h> #include <math.h> #include <stdlib.h> #if defined OS_POSIX #include <sys/types.h> #include <sys/stat.h> #endif #include "glow_transform.h" #include "glow_growimage.h" #include "glow_grownode.h" #include "glow_growctx.h" #include "glow_draw.h" //#if defined IMLIB static int rgb_tone( unsigned char *x0, unsigned char *y0, unsigned char *z0, int tone); static int rgb_shift( unsigned char *x0, unsigned char *y0, unsigned char *z0, int shift); //#endif extern "C" { #include "co_dcli.h" } GrowImage::GrowImage( GrowCtx *glow_ctx, const char *name, double x, double y, const char *imagefile, glow_mDisplayLevel display_lev) : ll(glow_ctx,x,y), ur(glow_ctx,x+1,y+1), hot(0), pzero(glow_ctx), stored_pos(glow_ctx), highlight(0), inverse(0), user_data(NULL), dynamic(0), dynamicsize(0), image(0), original_image(0), pixmap(0), nav_pixmap(0), clip_mask(0), nav_clip_mask(0), ctx(glow_ctx), display_level(display_lev), color_tone(glow_eDrawTone_No), color_lightness(0), color_intensity(0), color_shift(0), color_inverse(0), current_color_tone(glow_eDrawTone_No), current_color_lightness(0), current_color_intensity(0), current_color_shift(0), current_color_inverse(0), current_direction(0), current_nav_color_tone(glow_eDrawTone_No), current_nav_color_lightness(0), current_nav_color_intensity(0), current_nav_color_shift(0), current_nav_color_inverse(0), current_nav_direction(0), flip_vertical(false), flip_horizontal(false), current_flip_vertical(false), current_flip_horizontal(false), rotation(0), current_rotation(0), fixposition(0) { strcpy( n_name, name); strcpy( image_filename, ""); strcpy( filename, ""); strcpy( last_group, ""); imlib = ((GlowDraw *)ctx->gdraw)->imlib; if ( imagefile) insert_image( imagefile); pzero.nav_zoom(); if ( ctx->grid_on) { double x_grid, y_grid; ctx->find_grid( ll.x, ll.y, &x_grid, &y_grid); ll.posit( x_grid, y_grid); // ctx->find_grid( ur.x, ur.y, &x_grid, &y_grid); if ( !pixmap) ur.posit( ll.x + 1, ll.y + 1); else ur.posit( ll.x + double( current_width) / ctx->mw.zoom_factor_x, ll.y + double( current_height) / ctx->mw.zoom_factor_y); } draw( &ctx->mw, (GlowTransform *)NULL, highlight, hot, NULL, NULL); get_node_borders(); } void GrowImage::copy_from( const GrowImage& im) { memcpy( this, &im, sizeof(im)); image = 0; pixmap = 0; nav_pixmap = 0; clip_mask = 0; nav_clip_mask = 0; if ( strcmp( image_filename, "") != 0) insert_image( image_filename); } GrowImage::~GrowImage() { ctx->object_deleted( this); if ( !ctx->nodraw) { erase( &ctx->mw); erase( &ctx->navw); ctx->draw( &ctx->mw, x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->navw, x_left * ctx->navw.zoom_factor_x - ctx->navw.offset_x - 1, y_low * ctx->navw.zoom_factor_y - ctx->navw.offset_y - 1, x_right * ctx->navw.zoom_factor_x - ctx->navw.offset_x + 1, y_high * ctx->navw.zoom_factor_y - ctx->navw.offset_y + 1); if ( hot) ctx->gdraw->set_cursor( &ctx->mw, glow_eDrawCursor_Normal); } #if defined IMLIB if ( original_image) ctx->gdraw->image_free( original_image); if ( image) ctx->gdraw->image_free( image); if ( pixmap) ctx->gdraw->pixmap_free( pixmap); #endif } int GrowImage::insert_image( const char *imagefile) { int found = 0; char imagename[80]; char *s; struct stat info; int sts; if ( imagefile != image_filename) strcpy( image_filename, imagefile); // Find file if ( strncmp( image_filename, "jpwr/", 5) == 0) { if ( (s = strchr( &image_filename[5], '/'))) strcpy( imagename, s+1); else strcpy( imagename, image_filename); } else strcpy( imagename, image_filename); strcpy( filename, imagename); if ( check_file( filename)) found = 1; if ( !found) { // Add some search path for ( int i = 0; i < ((GrowCtx *)ctx)->path_cnt; i++) { strcpy( filename, ((GrowCtx *)ctx)->path[i]); strcat( filename, imagename); dcli_translate_filename( filename, filename); if ( check_file( filename)) { found = 1; break; } } if ( !found) return 0; } sts = stat( filename, &info); if ( sts == -1) return 0; date = info.st_ctime; ctx->gdraw->image_load( filename, &original_image, &image); if ( !original_image) return 0; current_width = int( ctx->mw.zoom_factor_x / ctx->mw.base_zoom_factor * ctx->gdraw->image_get_width( image)); current_height = int( ctx->mw.zoom_factor_y / ctx->mw.base_zoom_factor * ctx->gdraw->image_get_height( image)); current_color_tone = color_tone; current_color_lightness = color_lightness; current_color_intensity = color_intensity; current_color_shift = color_shift; current_color_inverse = color_inverse; set_image_color( image, NULL); ctx->gdraw->image_scale( current_width, current_height, original_image, &image, &pixmap, &clip_mask); ctx->gdraw->image_render( current_width, current_height, original_image, &image, &pixmap, &clip_mask); ur.posit( ll.x + double( current_width) / ctx->mw.zoom_factor_x, ll.y + double( current_height) / ctx->mw.zoom_factor_y); get_node_borders(); return 1; } int GrowImage::update() { struct stat info; int sts; sts = stat( filename, &info); if ( sts == -1) return 0; if ( date == info.st_ctime) return 0; ctx->gdraw->image_load( filename, &original_image, &image); if ( !original_image) return 0; date = info.st_ctime; set_image_color( image, NULL); ctx->gdraw->image_scale( current_width, current_height, original_image, &image, &pixmap, &clip_mask); ctx->gdraw->image_render( current_width, current_height, original_image, &image, &pixmap, &clip_mask); draw(); return 1; } void GrowImage::zoom() { ll.zoom(); ur.zoom(); } void GrowImage::nav_zoom() { ll.nav_zoom(); ur.nav_zoom(); } void GrowImage::traverse( int x, int y) { ll.traverse( x, y); ur.traverse( x, y); } void GrowImage::move( double delta_x, double delta_y, int grid) { if ( fixposition) return; ctx->set_defered_redraw(); ctx->draw( &ctx->mw, x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); if ( grid) { double x_grid, y_grid; /* Move to closest grid point */ erase( &ctx->mw); erase( &ctx->navw); ctx->find_grid( x_left + delta_x / ctx->mw.zoom_factor_x, y_low + delta_y / ctx->mw.zoom_factor_y, &x_grid, &y_grid); trf.move( x_grid - x_left, y_grid - y_low); get_node_borders(); } else { double dx, dy; erase( &ctx->mw); erase( &ctx->navw); dx = delta_x / ctx->mw.zoom_factor_x; dy = delta_y / ctx->mw.zoom_factor_y; trf.move( dx, dy); x_right += dx; x_left += dx; y_high += dy; y_low += dy; } ctx->draw( &ctx->mw, x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->navw, x_left * ctx->navw.zoom_factor_x - ctx->navw.offset_x - 1, y_low * ctx->navw.zoom_factor_y - ctx->navw.offset_y - 1, x_right * ctx->navw.zoom_factor_x - ctx->navw.offset_x + 1, y_high * ctx->navw.zoom_factor_y - ctx->navw.offset_y + 1); ctx->redraw_defered(); } void GrowImage::move_noerase( int delta_x, int delta_y, int grid) { if ( fixposition) return; if ( grid) { double x_grid, y_grid; /* Move to closest grid point */ ctx->find_grid( x_left + double( delta_x) / ctx->mw.zoom_factor_x, y_low + double( delta_y) / ctx->mw.zoom_factor_y, &x_grid, &y_grid); trf.move( x_grid - x_left, y_grid - y_low); get_node_borders(); } else { double dx, dy; dx = double( delta_x) / ctx->mw.zoom_factor_x; dy = double( delta_y) / ctx->mw.zoom_factor_y; trf.move( dx, dy); x_right += dx; x_left += dx; y_high += dy; y_low += dy; } ctx->draw( &ctx->mw, x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->navw, x_left * ctx->navw.zoom_factor_x - ctx->navw.offset_x - 1, y_low * ctx->navw.zoom_factor_y - ctx->navw.offset_y - 1, x_right * ctx->navw.zoom_factor_x - ctx->navw.offset_x + 1, y_high * ctx->navw.zoom_factor_y - ctx->navw.offset_y + 1); } int GrowImage::local_event_handler( glow_eEvent event, double x, double y) { double ll_x, ur_x, ll_y, ur_y; ll_x = min( ll.x, ur.x); ur_x = max( ll.x, ur.x); ll_y = min( ll.y, ur.y); ur_y = max( ll.y, ur.y); if ( ll_x <= x && x <= ur_x && ll_y <= y && y <= ur_y) { // cout << "Event handler: Hit in image" << endl; return 1; } else return 0; } int GrowImage::event_handler( GlowWind *w, glow_eEvent event, double fx, double fy) { double x, y; trf.reverse( fx, fy, &x, &y); return local_event_handler( event, x, y); } int GrowImage::event_handler( GlowWind *w, glow_eEvent event, int x, int y, double fx, double fy) { int sts; double rx, ry; // Convert koordinates to local koordinates trf.reverse( fx, fy, &rx, &ry); sts = 0; if ( event == ctx->event_move_node) { sts = local_event_handler( event, rx, ry); if ( sts) { /* Register node for potential movement */ ctx->move_insert( this); } return sts; } switch ( event) { case glow_eEvent_CursorMotion: { int redraw = 0; if ( ctx->hot_mode == glow_eHotMode_TraceAction) sts = 0; else if ( ctx->hot_found) sts = 0; else { sts = local_event_handler( event, rx, ry); if ( sts) ctx->hot_found = 1; } if ( sts && !hot && !(ctx->node_movement_active || ctx->node_movement_paste_active)) { ctx->gdraw->set_cursor( w, glow_eDrawCursor_CrossHair); hot = 1; redraw = 1; } if ( !sts && hot) { if ( !ctx->hot_found) ctx->gdraw->set_cursor( w, glow_eDrawCursor_Normal); erase( w); redraw = 1; hot = 0; } if ( redraw) { ctx->draw( w, x_left * w->zoom_factor_x - w->offset_x - DRAW_MP, y_low * w->zoom_factor_y - w->offset_y - DRAW_MP, x_right * w->zoom_factor_x - w->offset_x + DRAW_MP, y_high * w->zoom_factor_y - w->offset_y + DRAW_MP); // ((GlowImage *)this)->draw( (void *)&pzero, highlight, hot, NULL); } break; } default: sts = local_event_handler( event, rx, ry); } if ( sts) ctx->register_callback_object( glow_eObjectType_Node, this); return sts; } void GrowImage::save( ofstream& fp, glow_eSaveMode mode) { char *s; fp << int(glow_eSave_GrowImage) << endl; fp << int(glow_eSave_GrowImage_n_name) << FSPACE << n_name << endl; fp << int(glow_eSave_GrowImage_image_filename) << FSPACE << image_filename << endl; fp << int(glow_eSave_GrowImage_x_right) << FSPACE << x_right << endl; fp << int(glow_eSave_GrowImage_x_left) << FSPACE << x_left << endl; fp << int(glow_eSave_GrowImage_y_high) << FSPACE << y_high << endl; fp << int(glow_eSave_GrowImage_y_low) << FSPACE << y_low << endl; fp << int(glow_eSave_GrowImage_dynamicsize) << FSPACE << dynamicsize << endl; fp << int(glow_eSave_GrowImage_dynamic) << endl; if( dynamic) { fp << "\""; for ( s = dynamic; *s; s++) { if ( *s == '"') fp << "\\"; fp << *s; } fp << "\"" << endl; } fp << int(glow_eSave_GrowImage_trf) << endl; trf.save( fp, mode); fp << int(glow_eSave_GrowImage_display_level) << FSPACE << int(display_level) << endl; fp << int(glow_eSave_GrowImage_ll) << endl; ll.save( fp, mode); fp << int(glow_eSave_GrowImage_ur) << endl; ur.save( fp, mode); fp << int(glow_eSave_GrowImage_color_tone) << FSPACE << int(color_tone) << endl; fp << int(glow_eSave_GrowImage_color_lightness) << FSPACE << color_lightness << endl; fp << int(glow_eSave_GrowImage_color_intensity) << FSPACE << color_intensity << endl; fp << int(glow_eSave_GrowImage_color_shift) << FSPACE << color_shift << endl; fp << int(glow_eSave_GrowImage_fixposition) << FSPACE << fixposition << endl; fp << int(glow_eSave_End) << endl; } void GrowImage::open( ifstream& fp) { int type; int end_found = 0; char dummy[40]; int tmp; int j; char c; for (;;) { if ( !fp.good()) { fp.clear(); fp.getline( dummy, sizeof(dummy)); printf( "** Read error GrowImage: \"%d %s\"\n", type, dummy); } fp >> type; switch( type) { case glow_eSave_GrowImage: break; case glow_eSave_GrowImage_n_name: fp.get(); fp.getline( n_name, sizeof(n_name)); break; case glow_eSave_GrowImage_image_filename: fp.get(); fp.getline( image_filename, sizeof(image_filename)); break; case glow_eSave_GrowImage_x_right: fp >> x_right; break; case glow_eSave_GrowImage_x_left: fp >> x_left; break; case glow_eSave_GrowImage_y_high: fp >> y_high; break; case glow_eSave_GrowImage_y_low: fp >> y_low; break; case glow_eSave_GrowImage_dynamicsize: fp >> dynamicsize; break; case glow_eSave_GrowImage_dynamic: fp.getline( dummy, sizeof(dummy)); if ( dynamicsize) { dynamic = (char *) calloc( 1, dynamicsize); fp.get(); for ( j = 0; j < dynamicsize; j++) { if ((c = fp.get()) == '"') { if ( dynamic[j-1] == '\\') j--; else { dynamic[j] = 0; break; } } dynamic[j] = c; } fp.getline( dummy, sizeof(dummy)); } break; case glow_eSave_GrowImage_trf: trf.open( fp); break; case glow_eSave_GrowImage_display_level: fp >> tmp; display_level = (glow_mDisplayLevel)tmp; break; case glow_eSave_GrowImage_ll: ll.open( fp); break; case glow_eSave_GrowImage_ur: ur.open( fp); break; case glow_eSave_GrowImage_color_tone: fp >> tmp; color_tone = (glow_eDrawTone)tmp; break; case glow_eSave_GrowImage_color_lightness: fp >> color_lightness; break; case glow_eSave_GrowImage_color_intensity: fp >> color_intensity; break; case glow_eSave_GrowImage_color_shift: fp >> color_shift; break; case glow_eSave_GrowImage_fixposition: fp >> fixposition; break; case glow_eSave_End: end_found = 1; break; default: cout << "GrowImage:open syntax error" << endl; fp.getline( dummy, sizeof(dummy)); } if ( end_found) break; } if ( strcmp( image_filename, "") != 0) insert_image( image_filename); } void GrowImage::draw( GlowWind *w, int ll_x, int ll_y, int ur_x, int ur_y) { int tmp; if ( ll_x > ur_x) { /* Shift */ tmp = ll_x; ll_x = ur_x; ur_x = tmp; } if ( ll_y > ur_y) { /* Shift */ tmp = ll_y; ll_y = ur_y; ur_y = tmp; } if ( x_right * w->zoom_factor_x - w->offset_x + 1 >= ll_x && x_left * w->zoom_factor_x - w->offset_x <= ur_x && y_high * w->zoom_factor_y - w->offset_y + 1 >= ll_y && y_low * w->zoom_factor_y - w->offset_y <= ur_y) { draw( w, (GlowTransform *)NULL, highlight, hot, NULL, NULL); } } void GrowImage::draw( GlowWind *w, int *ll_x, int *ll_y, int *ur_x, int *ur_y) { int tmp; int obj_ur_x = int( x_right * w->zoom_factor_x) - w->offset_x; int obj_ll_x = int( x_left * w->zoom_factor_x) - w->offset_x; int obj_ur_y = int( y_high * w->zoom_factor_y) - w->offset_y; int obj_ll_y = int( y_low * w->zoom_factor_y) - w->offset_y; if ( *ll_x > *ur_x) { /* Shift */ tmp = *ll_x; *ll_x = *ur_x; *ur_x = tmp; } if ( *ll_y > *ur_y) { /* Shift */ tmp = *ll_y; *ll_y = *ur_y; *ur_y = tmp; } if ( obj_ur_x >= *ll_x && obj_ll_x <= *ur_x && obj_ur_y >= *ll_y && obj_ll_y <= *ur_y) { draw( w, (GlowTransform *)NULL, highlight, hot, NULL, NULL); // Increase the redraw area if ( obj_ur_x > *ur_x) *ur_x = obj_ur_x; if ( obj_ur_y > *ur_y) *ur_y = obj_ur_y; if ( obj_ll_x < *ll_x) *ll_x = obj_ll_x; if ( obj_ll_y < *ll_y) *ll_y = obj_ll_y; } } void GrowImage::set_highlight( int on) { erase( &ctx->mw); erase( &ctx->navw); highlight = on; draw(); } void GrowImage::select_region_insert( double ll_x, double ll_y, double ur_x, double ur_y, glow_eSelectPolicy select_policy) { if ( select_policy == glow_eSelectPolicy_Surround ) { if ( x_left > ll_x && x_right < ur_x && y_high < ur_y && y_low > ll_y) ctx->select_insert( this); } else { if ( x_right > ll_x && x_left < ur_x && y_low < ur_y && y_high > ll_y) ctx->select_insert( this); } } void GrowImage::set_dynamic( char *code, int size) { if ( !dynamic) { dynamic = (char *) calloc( 1, size+1); dynamicsize = size+1; } else if ( dynamicsize < size+1) { free( dynamic); dynamic = (char *) calloc( 1, size+1); dynamicsize = size+1; } strncpy( dynamic, code, size+1); } void GrowImage::exec_dynamic() { if ( dynamicsize && strcmp( dynamic, "") != 0) ((GrowCtx *)ctx)->dynamic_cb( this, dynamic, glow_eDynamicType_Object); } void GrowImage::set_position( double x, double y) { double old_x_left, old_x_right, old_y_low, old_y_high; if ( trf.a13 == x && trf.a23 == y) return; old_x_left = x_left; old_x_right = x_right; old_y_low = y_low; old_y_high = y_high; erase( &ctx->mw); erase( &ctx->navw); trf.posit( x, y); get_node_borders(); ctx->draw( &ctx->mw, old_x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, old_y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, old_x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, old_y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->mw, x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->navw, x_left * ctx->navw.zoom_factor_x - ctx->navw.offset_x - 1, y_low * ctx->navw.zoom_factor_y - ctx->navw.offset_y - 1, x_right * ctx->navw.zoom_factor_x - ctx->navw.offset_x + 1, y_high * ctx->navw.zoom_factor_y - ctx->navw.offset_y + 1); } void GrowImage::set_scale( double scale_x, double scale_y, double x0, double y0, glow_eScaleType type) { double old_x_left, old_x_right, old_y_low, old_y_high; if ( trf.s_a11 && trf.s_a22 && fabs( scale_x - trf.a11 / trf.s_a11) < FLT_EPSILON && fabs( scale_y - trf.a22 / trf.s_a22) < FLT_EPSILON) return; switch( type) { case glow_eScaleType_LowerLeft: x0 = x_left; y0 = y_low; break; case glow_eScaleType_LowerRight: x0 = x_right; y0 = y_low; break; case glow_eScaleType_UpperRight: x0 = x_right; y0 = y_high; break; case glow_eScaleType_UpperLeft: x0 = x_left; y0 = y_high; break; case glow_eScaleType_FixPoint: break; case glow_eScaleType_Center: x0 = (x_left + x_right) / 2; y0 = (y_low + y_high) /2; break; default: ; } old_x_left = x_left; old_x_right = x_right; old_y_low = y_low; old_y_high = y_high; erase( &ctx->mw); erase( &ctx->navw); trf.scale_from_stored( scale_x, scale_y, x0, y0); get_node_borders(); switch( type) { case glow_eScaleType_LowerLeft: x_left = old_x_left; y_low = old_y_low; break; case glow_eScaleType_LowerRight: x_right = old_x_right; y_low = old_y_low; break; case glow_eScaleType_UpperRight: x_right = old_x_right; y_high = old_y_high; break; case glow_eScaleType_UpperLeft: x_left = old_x_left; y_high = old_y_high; break; case glow_eScaleType_FixPoint: break; case glow_eScaleType_Center: x0 = (x_left + x_right) / 2; y0 = (y_low + y_high) /2; break; default: ; } ctx->draw( &ctx->mw, old_x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, old_y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, old_x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, old_y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->mw, x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->navw, x_left * ctx->navw.zoom_factor_x - ctx->navw.offset_x - 1, y_low * ctx->navw.zoom_factor_y - ctx->navw.offset_y - 1, x_right * ctx->navw.zoom_factor_x - ctx->navw.offset_x + 1, y_high * ctx->navw.zoom_factor_y - ctx->navw.offset_y + 1); } void GrowImage::set_rotation( double angle, double x0, double y0, glow_eRotationPoint type) { double old_x_left, old_x_right, old_y_low, old_y_high; if ( fabs( angle - trf.rotation + trf.s_rotation) < FLT_EPSILON) return; switch( type) { case glow_eRotationPoint_LowerLeft: x0 = x_left; y0 = y_low; break; case glow_eRotationPoint_LowerRight: x0 = x_right; y0 = y_low; break; case glow_eRotationPoint_UpperRight: x0 = x_right; y0 = y_high; break; case glow_eRotationPoint_UpperLeft: x0 = x_left; y0 = y_high; break; case glow_eRotationPoint_Center: x0 = (x_left + x_right) / 2; y0 = (y_high + y_low) / 2; break; default: ; } old_x_left = x_left; old_x_right = x_right; old_y_low = y_low; old_y_high = y_high; erase( &ctx->mw); erase( &ctx->navw); trf.rotate_from_stored( angle, x0, y0); get_node_borders(); ctx->draw( &ctx->mw, old_x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, old_y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, old_x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, old_y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->mw, x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->navw, x_left * ctx->navw.zoom_factor_x - ctx->navw.offset_x - 1, y_low * ctx->navw.zoom_factor_y - ctx->navw.offset_y - 1, x_right * ctx->navw.zoom_factor_x - ctx->navw.offset_x + 1, y_high * ctx->navw.zoom_factor_y - ctx->navw.offset_y + 1); } void GrowImage::draw( GlowWind *w, GlowTransform *t, int highlight, int hot, void *node, void *colornode) { if ( !(display_level & ctx->display_level)) return; if ( w == &ctx->navw) { if ( ctx->no_nav) return; hot = 0; } int x1, y1, x2, y2, ll_x, ll_y, ur_x, ur_y; if (!t) { x1 = int( trf.x( ll.x, ll.y) * w->zoom_factor_x) - w->offset_x; y1 = int( trf.y( ll.x, ll.y) * w->zoom_factor_y) - w->offset_y; x2 = int( trf.x( ur.x, ur.y) * w->zoom_factor_x) - w->offset_x; y2 = int( trf.y( ur.x, ur.y) * w->zoom_factor_y) - w->offset_y; } else { x1 = int( trf.x( t, ll.x, ll.y) * w->zoom_factor_x) - w->offset_x; y1 = int( trf.y( t, ll.x, ll.y) * w->zoom_factor_y) - w->offset_y; x2 = int( trf.x( t, ur.x, ur.y) * w->zoom_factor_x) - w->offset_x; y2 = int( trf.y( t, ur.x, ur.y) * w->zoom_factor_y) - w->offset_y; } ll_x = min( x1, x2); ur_x = max( x1, x2); ll_y = min( y1, y2); ur_y = max( y1, y2); if ( ll_x == ur_x || ll_y == ur_y) return; double rot; if ( t) rot = (trf.rot( t) / 360 - floor( trf.rot( t) / 360)) * 360; else rot = (trf.rot() / 360 - floor( trf.rot() / 360)) * 360; rotation = int((rot + 45) / 90) * 90; if ( w == &ctx->navw) { ctx->gdraw->fill_rect( w, ll_x, ll_y, ur_x - ll_x, ur_y - ll_y, glow_eDrawType_LineGray); } else { if ( pixmap || image) { int sts = 0; int flip_vert, flip_horiz; glow_tImImage om = original_image; glow_tImImage old_image = image; if ( colornode) { flip_vert = (( ((GrowNode *)node)->flip_vertical && !flip_vertical) || ( !((GrowNode *)node)->flip_vertical && flip_vertical)); flip_horiz = (( ((GrowNode *)node)->flip_horizontal && !flip_horizontal) || ( !((GrowNode *)node)->flip_horizontal && flip_horizontal)); } else { flip_vert = flip_vertical; flip_horiz = flip_horizontal; } if ( ur_x - ll_x != current_width || ur_y - ll_y != current_height) { ctx->gdraw->image_scale( ur_x - ll_x, ur_y - ll_y, om, &image, &pixmap, &clip_mask); current_width = ctx->gdraw->image_get_width( image); current_height = ctx->gdraw->image_get_height( image); sts = 1; om = 0; if ( rotation != current_rotation) current_rotation = 0; } if ( rotation != current_rotation) { ctx->gdraw->image_rotate( &image, rotation, current_rotation); current_rotation = rotation; om = 0; sts = 1; } if ( (colornode && !(current_color_tone == ((GrowNode *)node)->color_tone && current_color_lightness == ((GrowNode *)node)->color_lightness && current_color_intensity == ((GrowNode *)node)->color_intensity && current_color_shift == ((GrowNode *)node)->color_shift && current_color_inverse == ((GrowNode *)node)->color_inverse)) || ( !colornode && !(current_color_tone == color_tone && current_color_lightness == color_lightness && current_color_intensity == color_intensity && current_color_shift == color_shift && current_color_inverse == color_inverse)) || ( image != old_image && ((colornode && (glow_eDrawTone_No != ((GrowNode *)node)->color_tone || ((GrowNode *)node)->color_lightness || ((GrowNode *)node)->color_intensity || ((GrowNode *)node)->color_shift || ((GrowNode *)node)->color_inverse)) || ( !colornode && (glow_eDrawTone_No == color_tone || color_lightness || color_intensity || color_shift || color_inverse))))) { set_image_color( om, colornode); if ( ctx->gdraw->image_get_width( image) != current_width || ctx->gdraw->image_get_height( image) != current_height) { ctx->gdraw->image_scale( ur_x - ll_x, ur_y - ll_y, 0, &image, &pixmap, &clip_mask); current_width = ctx->gdraw->image_get_width( image); current_height = ctx->gdraw->image_get_height( image); } om = 0; sts = 1; } if ( flip_vert != current_flip_vertical) { ctx->gdraw->image_flip_vertical( &image); current_flip_vertical = flip_vert; sts = 1; } if ( flip_horiz != current_flip_horizontal) { ctx->gdraw->image_flip_horizontal( &image); current_flip_horizontal = flip_horiz; sts = 1; } if ( sts) { ctx->gdraw->image_render( ur_x - ll_x, ur_y - ll_y, om, &image, &pixmap, &clip_mask); om = 0; current_width = ctx->gdraw->image_get_width( image); current_height = ctx->gdraw->image_get_height( image); if ( colornode) { current_color_tone = ((GrowNode *)colornode)->color_tone; current_color_lightness = ((GrowNode *)colornode)->color_lightness; current_color_intensity = ((GrowNode *)colornode)->color_intensity; current_color_shift = ((GrowNode *)colornode)->color_shift; current_color_inverse = ((GrowNode *)colornode)->color_inverse; } else { current_color_tone = color_tone; current_color_lightness = color_lightness; current_color_intensity = color_intensity; current_color_shift = color_shift; current_color_inverse = color_inverse; } } ctx->gdraw->image( w, ll_x, ll_y, ur_x - ll_x, ur_y - ll_y, image, pixmap, clip_mask); } else ctx->gdraw->fill_rect( w, ll_x, ll_y, ur_x - ll_x, ur_y - ll_y, glow_eDrawType_LineGray); if ( highlight) { ctx->gdraw->rect( w, ll_x, ll_y, ur_x - ll_x - 1, ur_y - ll_y - 1, glow_eDrawType_LineRed, 0, 0); } else if ( hot /* && !((GrowCtx *)ctx)->enable_bg_pixmap */) ctx->gdraw->rect( w, ll_x, ll_y, ur_x - ll_x - 1, ur_y - ll_y - 1, glow_eDrawType_LineGray, 0, 0); } } void GrowImage::erase( GlowWind *w, GlowTransform *t, int hot, void *node) { if ( !(display_level & ctx->display_level)) return; if ( w == &ctx->navw) { if ( ctx->no_nav) return; hot = 0; } int x1, y1, x2, y2, ll_x, ll_y, ur_x, ur_y; if (!t) { x1 = int( trf.x( ll.x, ll.y) * w->zoom_factor_x) - w->offset_x; y1 = int( trf.y( ll.x, ll.y) * w->zoom_factor_y) - w->offset_y; x2 = int( trf.x( ur.x, ur.y) * w->zoom_factor_x) - w->offset_x; y2 = int( trf.y( ur.x, ur.y) * w->zoom_factor_y) - w->offset_y; } else { x1 = int( trf.x( t, ll.x, ll.y) * w->zoom_factor_x) - w->offset_x; y1 = int( trf.y( t, ll.x, ll.y) * w->zoom_factor_y) - w->offset_y; x2 = int( trf.x( t, ur.x, ur.y) * w->zoom_factor_x) - w->offset_x; y2 = int( trf.y( t, ur.x, ur.y) * w->zoom_factor_y) - w->offset_y; } ll_x = min( x1, x2); ur_x = max( x1, x2); ll_y = min( y1, y2); ur_y = max( y1, y2); w->set_draw_buffer_only(); if ( ctx->enable_bg_pixmap) ctx->gdraw->draw_background( w, ll_x, ll_y, ur_x - ll_x, ur_y - ll_y); else ctx->gdraw->fill_rect( w, ll_x, ll_y, ur_x - ll_x, ur_y - ll_y, glow_eDrawType_LineErase); w->reset_draw_buffer_only(); } void GrowImage::draw() { ctx->draw( &ctx->mw, x_left * ctx->mw.zoom_factor_x - ctx->mw.offset_x - DRAW_MP, y_low * ctx->mw.zoom_factor_y - ctx->mw.offset_y - DRAW_MP, x_right * ctx->mw.zoom_factor_x - ctx->mw.offset_x + DRAW_MP, y_high * ctx->mw.zoom_factor_y - ctx->mw.offset_y + DRAW_MP); ctx->draw( &ctx->navw, x_left * ctx->navw.zoom_factor_x - ctx->navw.offset_x - 1, y_low * ctx->navw.zoom_factor_y - ctx->navw.offset_y - 1, x_right * ctx->navw.zoom_factor_x - ctx->navw.offset_x + 1, y_high * ctx->navw.zoom_factor_y - ctx->navw.offset_y + 1); } void GrowImage::get_borders( GlowTransform *t, double *x_right, double *x_left, double *y_high, double *y_low) { double ll_x, ur_x, ll_y, ur_y, x1, x2, y1, y2; if ( t) { x1 = trf.x( t, ll.x, ll.y); x2 = trf.x( t, ur.x, ur.y); y1 = trf.y( t, ll.x, ll.y); y2 = trf.y( t, ur.x, ur.y); } else { x1 = trf.x( ll.x, ll.y); x2 = trf.x( ur.x, ur.y); y1 = trf.y( ll.x, ll.y); y2 = trf.y( ur.x, ur.y); } ll_x = min( x1, x2); ur_x = max( x1, x2); ll_y = min( y1, y2); ur_y = max( y1, y2); if ( display_level != glow_mDisplayLevel_1) return; if ( ll_x < *x_left) *x_left = ll_x; if ( ur_x > *x_right) *x_right = ur_x; if ( ll_y < *y_low) *y_low = ll_y; if ( ur_y > *y_high) *y_high = ur_y; } void GrowImage::set_transform( GlowTransform *t) { trf = *t * trf; get_node_borders(); } void GrowImage::align( double x, double y, glow_eAlignDirection direction) { double dx, dy; if ( fixposition) return; erase( &ctx->mw); erase( &ctx->navw); ctx->set_defered_redraw(); draw(); switch ( direction) { case glow_eAlignDirection_CenterVert: dx = x - (x_right + x_left) / 2; dy = 0; break; case glow_eAlignDirection_CenterHoriz: dx = 0; dy = y - (y_high + y_low) / 2; break; case glow_eAlignDirection_CenterCenter: dx = x - (x_right + x_left) / 2; dy = y - (y_high + y_low) / 2; break; case glow_eAlignDirection_Right: dx = x - x_right; dy = 0; break; case glow_eAlignDirection_Left: dx = x - x_left; dy = 0; break; case glow_eAlignDirection_Up: dx = 0; dy = y - y_high; break; case glow_eAlignDirection_Down: dx = 0; dy = y - y_low; break; } trf.move( dx, dy); x_right += dx; x_left += dx; y_high += dy; y_low += dy; draw(); ctx->redraw_defered(); } void GrowImage::export_javabean( GlowTransform *t, void *node, glow_eExportPass pass, int *shape_cnt, int node_cnt, int in_nc, ofstream &fp) { if ( !(display_level & ctx->display_level)) return; double x1, y1, x2, y2, ll_x, ll_y, ur_x, ur_y; double rot; int transparent = 0; if (!t) { x1 = trf.x( ll.x, ll.y) * ctx->mw.zoom_factor_x - ctx->mw.offset_x; y1 = trf.y( ll.x, ll.y) * ctx->mw.zoom_factor_y - ctx->mw.offset_y; x2 = trf.x( ur.x, ur.y) * ctx->mw.zoom_factor_x - ctx->mw.offset_x; y2 = trf.y( ur.x, ur.y) * ctx->mw.zoom_factor_y - ctx->mw.offset_y; rot = trf.rot(); } else { x1 = trf.x( t, ll.x, ll.y) * ctx->mw.zoom_factor_x - ctx->mw.offset_x; y1 = trf.y( t, ll.x, ll.y) * ctx->mw.zoom_factor_y - ctx->mw.offset_y; x2 = trf.x( t, ur.x, ur.y) * ctx->mw.zoom_factor_x - ctx->mw.offset_x; y2 = trf.y( t, ur.x, ur.y) * ctx->mw.zoom_factor_y - ctx->mw.offset_y; rot = trf.rot(t); } ll_x = min( x1, x2); ur_x = max( x1, x2); ll_y = min( y1, y2); ur_y = max( y1, y2); if ( clip_mask) transparent = 1; ctx->export_jbean->image( ll_x, ll_y, ur_x, ur_y, image_filename, transparent, color_tone, color_lightness, color_intensity, color_shift, rot, pass, shape_cnt, node_cnt, in_nc, fp); } int GrowImage::set_image_color( glow_tImImage om, void *n) { GrowNode *node = (GrowNode *) n; if ( node) { c_color_lightness = node->color_lightness; c_color_tone = node->color_tone; c_color_inverse = node->color_inverse; c_color_shift = node->color_shift; c_color_intensity = node->color_intensity; } else { c_color_lightness = color_lightness; c_color_tone = color_tone; c_color_inverse = color_inverse; c_color_shift = color_shift; c_color_intensity = color_intensity; } if ( c_color_intensity > 0) factor_intens = 1 + 0.1 * c_color_intensity; else factor_intens = 1 + 0.1 * c_color_intensity; if ( c_color_lightness > 0) factor_light = 1 - 0.1 * c_color_lightness; else factor_light = 1 + 0.1 * c_color_lightness; if ( !(c_color_tone == glow_eDrawTone_No || c_color_tone >= glow_eDrawTone__) || c_color_shift || c_color_intensity || c_color_lightness || c_color_inverse) { ctx->gdraw->image_pixel_iter( om, &image, pixel_cb, this); } return 1; } void GrowImage::pixel_cb( void *data, unsigned char *rgb) { GrowImage *o = (GrowImage *)data; int m; int value; if ( !(o->c_color_tone == glow_eDrawTone_No || o->c_color_tone >= glow_eDrawTone__)) { rgb_tone( rgb, rgb+1, rgb+2, o->c_color_tone); } if ( o->c_color_shift) { rgb_shift( rgb, rgb+1, rgb+2, o->c_color_shift); } for ( int i = 0; i < 3; i++) { if ( o->c_color_intensity) { value = int( o->factor_intens * *rgb) - o->c_color_intensity * 25; if ( value > 255) *rgb = 255; else if ( value < 0) *rgb = 0; else *rgb = value; } if ( o->c_color_lightness) { if ( o->c_color_lightness > 0) { value = int( o->factor_light * *rgb) + o->c_color_lightness * 25; if ( value < 0) *rgb = 0; else *rgb = value; } else { value = int( o->factor_light * *rgb); if ( value > 255) *rgb = 255; else *rgb = value; } } if ( o->c_color_inverse) { // *rgb = 255 - *rgb; if ( i % 3 == 0) { m = ((int)(*rgb) + *(rgb+1) + *(rgb+2)) / 3; value = 255 - m + ((int)*rgb - m); if ( value < 0) value = 0; if ( value > 255) value = 255; *rgb = (unsigned char) value; value = 255 - m + ((int)*(rgb+1) - m); if ( value < 0) value = 0; if ( value > 255) value = 255; *(rgb+1) = (unsigned char) value; value = 255 - m + ((int)*(rgb+2) - m); if ( value < 0) value = 0; if ( value > 255) value = 255; *(rgb+2) = (unsigned char) value; } } rgb++; } } //#if defined IMLIB static int rgb_tone( unsigned char *x0, unsigned char *y0, unsigned char *z0, int tone) { int a1, b2; int tmp, m; float ka1, kb1; int ka2, kb2; m = ((int)*x0 + *y0 + *z0) / 3; ka1 = 0.6; /* 0.6 */ ka2 = 120; /* 130 */ kb1 = 0.4; kb2 = 0; if ( m > 75) a1 = (int)(m * ka1) + ka2; else a1 = (int)(m * 1.5); if ( a1 > 255) a1 = 255; b2 = int(kb1 * m) + kb2; if ( b2 < 0) b2 = 0; switch ( tone) { case glow_eDrawTone_Gray: *x0 = m; *y0 = m; *z0 = m; break; case glow_eDrawTone_YellowGreen: *x0 = a1; *y0 = a1; *z0 = b2; break; case glow_eDrawTone_Yellow: tmp = int( 1.2 * a1); if (tmp <= 255) *x0 = tmp; else *x0 = 255; *y0 = (unsigned char)(0.9 * a1); *z0 = b2; break; case glow_eDrawTone_Orange: tmp = (int)(1.2 * a1); if (tmp <= 255) *x0 = (unsigned char)tmp; else *x0 = 255; *y0 = (unsigned char)(0.6 * a1); *z0 = b2; break; case glow_eDrawTone_Red: *x0 = a1; *y0 = b2; *z0 = b2; break; case glow_eDrawTone_Magenta: *x0 = a1; *y0 = b2; *z0 = a1; break; case glow_eDrawTone_Blue: *x0 = b2; *y0 = b2; *z0 = a1; break; case glow_eDrawTone_Seablue: *x0 = b2; *y0 = a1; *z0 = a1; break; case glow_eDrawTone_Green: *x0 = b2; *y0 = a1; *z0 = b2; break; case glow_eDrawTone_DarkGray: *x0 = (unsigned char)(m / 1.3); *y0 = (unsigned char)(m / 1.3); *z0 = (unsigned char)(m / 1.3); break; } return 1; } //#endif //#if defined IMLIB static int rgb_shift( unsigned char *x0, unsigned char *y0, unsigned char *z0, int shift) { unsigned char x, y, z; int d; int step; shift = -shift; shift %= 8; if ( shift < 0) shift += 8; x = *x0; y = *y0; z = *z0; for( ;;) { if ( x == y && y == z) break; if ( x > y && y >= z && x > z) { d = x - z; step = 6 * d / 10 * shift; // printf("Section 1, d: %d, step: %d, lap: %d\n", d, step, 6 * d); if ( step <= z + d - y) { y += step; break; } step -= z + d - y; y = z + d; if ( step <= d) { x -= step; break; } x -= d; step -= d; if ( step <= d) { z += step; break; } z += d; step -= d; if ( step <= d) { y -= step; break; } y -= d; step -= d; if ( step <= d) { x += step; break; } x += d; step -= d; if ( step <= d) { z -= step; break; } z -= d; step -= d; if ( step <= d) { y += step; break; } y += d; printf( "Error, shift larger than one lap\n"); break; } else if ( x > z && y >= x && y > z) { d = y - z; step = 6 * d / 10 * shift; // printf("Section 2, d: %d, step: %d\n", d, step); if ( step <= x - z) { x -= step; break; } step -= x - z; x = z; if ( step <= d) { z += step; break; } z += d; step -= d; if ( step <= d) { y -= step; break; } y -= d; step -= d; if ( step <= d) { x += step; break; } x += d; step -= d; if ( step <= d) { z -= step; break; } z -= d; step -= d; if ( step <= d) { y += step; break; } y += d; step -= d; if ( step <= d) { x -= step; break; } x -= d; printf( "Error, shift larger than one lap\n"); break; } else if ( y > z && z >= x && y > x) { d = y - x; step = 6 * d / 10 * shift; // printf("Section 3, d: %d, step: %d\n", d, step); if ( step <= x + d - z) { z += step; break; } step -= x + d - z; z = x + d; if ( step <= d) { y -= step; break; } y -= d; step -= d; if ( step <= d) { x += step; break; } x += d; step -= d; if ( step <= d) { z -= step; break; } z -= d; step -= d; if ( step <= d) { y += step; break; } y += d; step -= d; if ( step <= d) { x -= step; break; } x -= d; step -= d; if ( step <= d) { z += step; break; } z += d; printf( "Error, shift larger than one lap\n"); break; } else if ( z >= y && y > x && z >= y) { d = z - x; step = 6 * d / 10 * shift; // printf("Section 4, d: %d, step: %d\n", d, step); if ( step <= y - x) { y -= step; break; } step -= y - x; y = x; if ( step <= d) { x += step; break; } x += d; step -= d; if ( step <= d) { z -= step; break; } z -= d; step -= d; if ( step <= d) { y += step; break; } y += d; step -= d; if ( step <= d) { x -= step; break; } x -= d; step -= d; if ( step <= d) { z += step; break; } z += d; step -= d; if ( step <= d) { y -= step; break; } y -= d; printf( "Error, shift larger than one lap\n"); break; } else if ( z > x && x >= y && z > y) { d = z - y; step = 6 * d / 10 * shift; // printf("Section 5, d: %d, step: %d\n", d, step); if ( step <= y + d - x) { x += step; break; } step -= y + d - x; x = y + d; if ( step <= d) { z -= step; break; } z -= d; step -= d; if ( step <= d) { y += step; break; } y += d; step -= d; if ( step <= d) { x -= step; break; } x -= d; step -= d; if ( step <= d) { z += step; break; } z += d; step -= d; if ( step <= d) { y -= step; break; } y -= d; step -= d; if ( step <= d) { x += step; break; } x += d; printf( "Error, shift larger than one lap\n"); break; } else /* if ( x >= z && z > y && x > y) */ { d = x - y; step = 6 * d / 8 * shift; // printf("Section 6, d: %d, step: %d\n", d, step); if ( d < 0) printf( "d: %d ( %d, %d, %d)\n", d, x, y, z); if ( step <= z - y) { z -= step; break; } step -= z - y; z = y; if ( step <= d) { y += step; break; } y += d; step -= d; if ( step <= d) { x -= step; break; } x -= d; step -= d; if ( step <= d) { z += step; break; } z += d; step -= d; if ( step <= d) { y -= step; break; } y -= d; step -= d; if ( step <= d) { x += step; break; } x += d; step -= d; if ( step <= d) { z -= step; break; } z -= d; printf( "Error, shift larger than one lap\n"); break; } } *x0 = x; *y0 = y; *z0 = z; return 1; } //#endif int grow_image_to_pixmap( GrowCtx *ctx, char *imagefile, int width, int height, glow_tPixmap *pixmap, glow_tImImage *image, int *w, int *h) { int found = 0; char imagename[80]; pwr_tFileName filename; char *s; // Find file if ( strncmp( imagefile, "jpwr/", 5) == 0) { if ( (s = strchr( &imagefile[5], '/'))) strcpy( imagename, s+1); else strcpy( imagename, imagefile); } else strcpy( imagename, imagefile); strcpy( filename, imagename); if ( check_file( filename)) found = 1; if ( !found) { // Add some search path for ( int i = 0; i < ((GrowCtx *)ctx)->path_cnt; i++) { strcpy( filename, ((GrowCtx *)ctx)->path[i]); strcat( filename, imagename); dcli_translate_filename( filename, filename); if ( check_file( filename)) { found = 1; break; } } if ( !found) return 0; } ctx->gdraw->image_load( filename, image, 0); if ( !*image) return 0; if ( width == 0 || height == 0) { width = ctx->gdraw->image_get_width( *image); height = ctx->gdraw->image_get_height( *image); } else { ctx->gdraw->image_scale( width, height, 0, image, pixmap, 0); } ctx->gdraw->image_render( width, height, 0, image, pixmap, 0); *w = width; *h = height; return 1; } void GrowImage::flip( double x0, double y0, glow_eFlipDirection dir) { switch ( dir) { case glow_eFlipDirection_Horizontal: trf.store(); set_scale( 1, -1, x0, y0, glow_eScaleType_FixPoint); flip_horizontal = !flip_horizontal; break; case glow_eFlipDirection_Vertical: trf.store(); set_scale( -1, 1, x0, y0, glow_eScaleType_FixPoint); flip_vertical = !flip_vertical; break; } }