void x_tile_destroy() { int i; if (tmp_img) { gdk_image_destroy(tmp_img); tmp_img = NULL; } if (tile_pixmap) { gdk_pixmap_unref(tile_pixmap); tile_pixmap = NULL; } if (tmp_pixbuf) { gdk_pixbuf_unref(tmp_pixbuf); tmp_pixbuf = NULL; } if (tile_pixbuf) { gdk_pixbuf_unref(tile_pixbuf); tile_pixbuf = NULL; } if (tile_transp) { for(i = 0; i < total_tiles_used; i++) free(tile_transp[i].data); free(tile_transp); tile_transp = NULL; } if (tile_image) { gdk_image_destroy(tile_image); tile_image = NULL; } #ifdef GTK_PROXY free(GTK_glyph2tile); GTK_glyph2tile = (short *)0; #endif }
Renderer* GtkOvgGlue::createRenderHandler() { GNASH_REPORT_FUNCTION; if (!_drawing_area) { log_error("No area to draw in!"); return 0; } GdkVisual* wvisual = gdk_drawable_get_visual(_drawing_area->window); GdkImage* tmpimage = gdk_image_new (GDK_IMAGE_FASTEST, wvisual, 1, 1); // const GdkVisual* visual = tmpimage->visual; gdk_image_destroy(tmpimage); _renderer.reset(reinterpret_cast<renderer::openvg::Renderer_ovg *> (renderer::openvg::create_handler(0))); if (!_renderer) { boost::format fmt = boost::format( _("Could not create OPENVG renderer")); throw GnashException(fmt.str()); } return reinterpret_cast<Renderer *>(_renderer.get()); }
Renderer* GtkAggGlue::createRenderHandler() { GdkVisual* wvisual = gdk_drawable_get_visual(_drawing_area->window); GdkImage* tmpimage = gdk_image_new (GDK_IMAGE_FASTEST, wvisual, 1, 1); const GdkVisual* visual = tmpimage->visual; // FIXME: we use bpp instead of depth, because depth doesn't appear to // include the padding byte(s) the GdkImage actually has. const char *pixelformat = agg_detect_pixel_format( visual->red_shift, visual->red_prec, visual->green_shift, visual->green_prec, visual->blue_shift, visual->blue_prec, tmpimage->bpp * 8); gdk_image_destroy(tmpimage); _agg_renderer = create_Renderer_agg(pixelformat); if (! _agg_renderer) { boost::format fmt = boost::format( _("Could not create AGG renderer with pixelformat %s") ) % pixelformat; throw GnashException(fmt.str()); } return _agg_renderer; }
void GtkAggGlue::setRenderHandlerSize(int width, int height) { assert(width > 0); assert(height > 0); assert(_agg_renderer != NULL); if (_offscreenbuf && _offscreenbuf->width == width && _offscreenbuf->height == height) { return; } if (_offscreenbuf) { gdk_image_destroy(_offscreenbuf); } GdkVisual* visual = gdk_drawable_get_visual(_drawing_area->window); _offscreenbuf = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height); static_cast<Renderer_agg_base *>(_agg_renderer)->init_buffer( (unsigned char*) _offscreenbuf->mem, _offscreenbuf->bpl * _offscreenbuf->height, _offscreenbuf->width, _offscreenbuf->height, _offscreenbuf->bpl); }
static GdkPixmap * scale_pixmap (GdkWindow *window, GdkPixmap *pixmap, gdouble scale_x, gdouble scale_y) { GdkGC *gc; GdkColormap *colormap; GdkColorContext *cc; GdkVisual *visual; GdkImage *image; GdkPixmap *new_pixmap; gint x, y, width, height, new_width, new_height; if(!pixmap) return NULL; if(!window) return NULL; gc = gdk_gc_new(pixmap); colormap = gdk_colormap_get_system (); visual = gdk_visual_get_system (); cc = gdk_color_context_new(visual, colormap); gdk_window_get_size(pixmap, &width, &height); if(scale_x == 1.0 && scale_y == 1.0){ new_pixmap = gdk_pixmap_new(window, width, height, -1); gdk_draw_pixmap(new_pixmap, gc, pixmap, 0, 0, 0, 0, width, height); return new_pixmap; } new_width = roundint(width * scale_x); new_height = roundint(height * scale_y); new_pixmap = gdk_pixmap_new(window, new_width, new_height, -1); image = gdk_image_get(pixmap, 0, 0, width, height); for(x = 0; x < new_width; x++){ for(y = 0; y < new_height; y++){ GdkColor color; gint px, py; px = MIN(roundint(x / scale_x), width - 1); py = MIN(roundint(y / scale_y), height - 1); color.pixel = gdk_image_get_pixel(image, px, py); gdk_color_context_query_color(cc, &color); gdk_gc_set_foreground(gc, &color); gdk_draw_point(new_pixmap, gc, x, y); } } gdk_image_destroy(image); gdk_color_context_free(cc); return new_pixmap; }
GtkOvgGlue::~GtkOvgGlue() { GNASH_REPORT_FUNCTION; #ifdef ENABLE_EGL_OFFSCREEN if (_offscreenbuf) { gdk_image_destroy(_offscreenbuf); } #endif }
static void psdrawpixmap (GtkPlotPC *pc, GdkPixmap *pixmap, GdkBitmap *mask, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height, gdouble scale_x, gdouble scale_y) { FILE *psout = GTK_PLOT_PS(pc)->psfile; GdkColormap *colormap; colormap = gdk_colormap_get_system (); fprintf(psout, "gsave\n"); if(pixmap){ GdkImage *image; gint x, y; image = gdk_image_get(pixmap, xsrc, ysrc, width, height); if(mask) gtk_plot_pc_clip_mask(pc, xdest, ydest, mask); fprintf(psout, "%d %g translate\n", xdest, ydest + height * scale_y); fprintf(psout, "%g %g scale\n",width * scale_x, height * scale_y); fprintf(psout, "%d %d 8 [%d 0 0 %d 0 %d]\n",width, height, width, height, height); fprintf(psout, "/scanline %d 3 mul string def\n", width); fprintf(psout, "{ currentfile scanline readhexstring pop } false 3\n"); fprintf(psout, "colorimage\n"); for(y = 0; y < height; y++){ for(x = 0; x < width; x++){ GdkColor color; gchar string[7]; color.pixel = gdk_image_get_pixel(image, x, y); gdk_colormap_query_color(colormap, color.pixel, &color); color_to_hex(color, string); fprintf(psout,"%s",string); if(fmod(x + 1, 13) == 0) fprintf(psout, "\n"); } fprintf(psout,"\n"); } gdk_image_destroy(image); if(mask) gtk_plot_pc_clip_mask(pc, xdest, ydest, NULL); } fprintf(psout, "grestore\n"); }
void WinDraw_Cleanup(void) { if (splash_pixmap) { gdk_pixmap_unref(splash_pixmap); splash_pixmap = 0; } if (pixmap) { gdk_pixmap_unref(pixmap); pixmap = 0; } if (scaled_screen) { gdk_image_destroy(scaled_screen); scaled_screen = 0; } if (surface) { gdk_image_destroy(surface); surface = 0; ScrBuf = 0; } gdk_window_get_position(window->window, &winx, &winy); }
void video_setsize( int width, int height ) { video_buffer_width = width; video_buffer_height = height; if( video_buffer_1 ) { free( video_buffer_1 ); } if( image_1 ) { gdk_image_destroy( image_1 ); } if( video_buffer_2 ) { free( video_buffer_2 ); } if( image_2 ) { gdk_image_destroy( image_2 ); } gtk_widget_set_usize( GTK_WIDGET( nes_gtk_window ), width, height ); /* Buffer allocation. */ video_buffer_1 = (unsigned char*) malloc( width * height * 8 ); image_1 = gdk_image_new( GDK_IMAGE_FASTEST, visual, width, height ); video_buffer_2 = (unsigned char*) malloc( width * height * 8 ); image_2 = gdk_image_new( GDK_IMAGE_FASTEST, visual, width, height ); cur_image = image_1; cur_video_buffer = video_buffer_1; }
static void load_scenario (char *fname) { char *tmp, *fn; GdkColor bgcolor; GdkImage *tmpimage; tmp = g_strconcat ( "same-gnome/", fname, NULL); fn = gnome_unconditional_pixmap_file ( tmp ); g_free( tmp ); if (!g_file_exists (fn)) { printf (_("Could not find the \'%s\' theme for SameGnome\n"), fn); exit (1); } if (scenario) g_free (scenario); scenario = g_strdup(fname); configure_sync (fname); if (image) gdk_imlib_destroy_image (image); image = gdk_imlib_load_image (fn); gdk_imlib_render (image, image->rgb_width, image->rgb_height); stones = gdk_imlib_move_image (image); mask = gdk_imlib_move_mask (image); tmpimage = gdk_image_get(stones, 0, 0, 1, 1); bgcolor.pixel = gdk_image_get_pixel(tmpimage, 0, 0); gdk_window_set_background (draw_area->window, &bgcolor); gdk_image_destroy(tmpimage); g_free( fn ); nstones = image->rgb_width / STONE_SIZE; /* ncolors = image->rgb_height / STONE_SIZE; */ ncolors = 3; gtk_widget_draw (draw_area, NULL); }
void GtkOvgGlue::setRenderHandlerSize(int width, int height) { GNASH_REPORT_FUNCTION; assert(width > 0); assert(height > 0); assert(_renderer != NULL); #ifdef ENABLE_EGL_OFFSCREEN if (_offscreenbuf && _offscreenbuf->width == width && _offscreenbuf->height == height) { return; } if (_offscreenbuf) { gdk_image_destroy(_offscreenbuf); } GdkVisual* visual = gdk_drawable_get_visual(_drawing_area->window); _offscreenbuf = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height); #endif #if 1 // if (_renderer) { // vgScale(width, height); // } #else // Attach the window to the low level device long xid = GDK_WINDOW_XID(gtk_widget_get_window(_drawing_area)); _device->attachWindow(static_cast<renderer::GnashDevice::native_window_t> (xid)); vgLoadIdentity(); // Allow drawing everywhere by default InvalidatedRanges ranges; ranges.setWorld(); _renderer->set_invalidated_regions(ranges); renderer::EGLDevice *egl = (renderer::EGLDevice*)_device.get(); egl->swapBuffers(); #endif }
void *pl_fbdev_set_mode(int w, int h, int bpp) { if (w <= 0 || h <= 0) return pl_fbdev_buf; if (image) gdk_image_destroy(image); image = gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(), w, h ); pl_fbdev_buf = (void *) image->mem; gtk_image_set_from_image (GTK_IMAGE(drawing), image, NULL); gtk_window_resize (GTK_WINDOW (actor), w, h); hildon_animation_actor_set_scale (actor, (gdouble)D_WIDTH / (gdouble)w, (gdouble)D_HEIGHT / (gdouble)h ); return pl_fbdev_buf; }
static void *font_gtk_get_glyph(unsigned char *str) { agsurface_t *dst; int h, w, l; BYTE *conv; GdkPixmap *pix_gdk; GdkGC *gc_gdk; GdkImage *img_gdk; GdkColor col_gdk; /* convert string code from sjis to euc (or LANG) */ conv = sjis2lang(str); l = strlen(conv); w = gdk_text_width(fontset, conv, l); if (w == 0) { free(conv); return NULL; } #ifdef GTKV12 h = gdk_text_height(fontset, conv, l); #else h = font_ascent + fontset->ascent; #endif if (w > GLYPH_PIXMAP_WIDTH) w = GLYPH_PIXMAP_WIDTH; if (h > GLYPH_PIXMAP_HEIGHT) h = GLYPH_PIXMAP_HEIGHT; pix_gdk = gdk_pixmap_new(mainwin->window, w, h, gdk_depth); gc_gdk = gdk_gc_new(pix_gdk); /* color */ col_gdk.pixel = 0; gdk_gc_set_foreground(gc_gdk, &col_gdk); // gdk_gc_set_background(gc_gdk, &col_gdk); gdk_draw_rectangle(pix_gdk, gc_gdk, TRUE, 0, 0, w, h); col_gdk.pixel = 1; gdk_gc_set_foreground(gc_gdk, &col_gdk); gdk_draw_text(pix_gdk, fontset, gc_gdk, 0, fontset->ascent, conv, l); gdk_gc_destroy(gc_gdk); img_gdk = gdk_image_get(&((GdkWindowPrivate *)pix_gdk)->window, 0, 0, w, h); gdk_pixmap_unref(pix_gdk); dst = g_new(agsurface_t, 1); dst->width = w; dst->height = h; dst->bytes_per_pixel = (img_gdk->bpp+1)/8; /* むーん */ dst->bytes_per_line = img_gdk->bpl; dst->pixel = img_gdk->mem; image_get_glyph(dst, &img_glyph); if (this->antialiase_on) { aa_make(img_glyph.pixel, w, dst->height, img_glyph.bytes_per_line); } img_glyph.width = w; img_glyph.height = h; g_free(dst); g_free(conv); gdk_image_destroy(img_gdk); return &img_glyph; }
/* subfunction of gtk_plot_gdk_draw_string(). */ static gint drawstring(GtkPlotPC *pc, GdkBitmap *dest, GdkGC *gc, GdkColor *black, GdkColor *white, gint dx, gint dy, GtkPSFont *psfont, GdkFont *font, GdkFont *latin_font, GdkWChar wc) { GdkBitmap *tmp; GdkFont *dfont; GdkImage *image; gint w, h, a, d, x, y, d2; guint32 pixel; if (psfont->i18n_latinfamily && psfont->vertical && (0 > wc || wc > 0x7f)) { /* vertical-writing CJK postscript fonts. */ dfont = font; w = gdk_char_width_wc(dfont, wc); a = dfont->ascent; d = dfont->descent; h = a + d; d2 = w * d / h; tmp = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, w, h, 1); gdk_gc_set_foreground(gc, white); gdk_draw_rectangle(tmp, gc, TRUE, 0, 0, -1, -1); gdk_gc_set_foreground(gc, black); gdk_draw_text_wc(tmp, dfont, gc, 0, a, &wc, 1); image = gdk_image_get(tmp, 0, 0, w, h); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { pixel = gdk_image_get_pixel(image, x, y); if (pixel == black->pixel) gdk_draw_point(dest, gc, dx + y, dy + d2 - x); } } gdk_image_destroy(image); gdk_pixmap_unref(tmp); return h; } else { /* horizontal writing */ if (psfont->i18n_latinfamily && 0 <= wc && wc <= 0x7f) dfont = latin_font; else dfont = font; gdk_draw_text_wc(dest, dfont, gc, dx, dy, &wc, 1); w = gdk_char_width_wc(dfont, wc); return w; } }
GtkAggGlue::~GtkAggGlue() { if (_offscreenbuf) { gdk_image_destroy(_offscreenbuf); } }
GdkImage *gdkimage_from_pikeimage(struct object *img, int fast, GdkImage *i) { GdkColormap *col=gdk_colormap_get_system(); GdkVisual *vis=gdk_visual_get_system(); struct image *img_data; INT_TYPE x,y; TIMER_INIT("Getting extents"); img_data=(struct image*)get_storage(img, image_program); /* 1a: create the actual image... */ x = img_data->xsize; y = img_data->ysize; if (x==0 || y==0) Pike_error("Size of image must be > 0x0\n"); if (i) { if ((i->width!=x) || (i->height!=y)) { gdk_image_destroy((void *)i); i=NULL; } } if (!i) { PFTIME("Create"); i=(void *)gdk_image_new(fast,vis,x,y); } if (!i) Pike_error("Failed to create gdkimage\n"); /* 1b: do the work.. */ if (vis->type==GDK_VISUAL_TRUE_COLOR || vis->type==GDK_VISUAL_STATIC_GRAY) /* no colormap.. */ { int pad=0; int native_byteorder; PFTIME("Convert"); if (vis->type==GDK_VISUAL_STATIC_GRAY) pgtk2_encode_grey(img_data,i->mem,i->bpp,i->bpl); else { if (i->bpl!=(i->bpp*x)) switch(i->bpl & 3) { case 0: pad = 4; break; case 1: pad = 1; break; case 2: pad = 2; break; case 3: pad = 1; break; } else pad=0; pgtk2_encode_truecolor_masks(img_data,i->bpp*8,pad*8, (i->byte_order!=1),vis->red_mask, vis->green_mask,vis->blue_mask, i->mem, i->bpl*y); } } else { static int colors_allocated=0; static struct object *pike_cmap; /* I hate this... colormaps, here we come.. */ /* This is rather complicated, but: 1/ build an array of the colors in the colormap 2/ use that array to build a pike X-image colormap. 3/ call Image.X.encode_pseudocolor( img, bpp, lpad, depth, colormp ) 4/ copy the actual data to the image.. */ if (!colors_allocated) { #define COLORMAP_SIZE 256 char allocated[COLORMAP_SIZE]; int j,i,r,g,b; PFTIME("Creating colormap"); colors_allocated=1; MEMSET(allocated,0,sizeof(allocated)); for (r=0; r<3; r++) for (g=0; g<4; g++) for (b=0; b<3; b++) { GdkColor color; color.red = (guint16)(r * (65535/2.0)); color.green = (guint16)(g * (65535/3.0)); color.blue = (guint16)(b * (65535/2.0)); color.pixel = 0; if (gdk_color_alloc(col,&color)) if (color.pixel<COLORMAP_SIZE) allocated[color.pixel]=1; } for (r=0; r<6; r++) for (g=0; g<7; g++) for (b=0; b<6; b++) { GdkColor color; color.red=(guint16)(r*(65535/5.0)); color.green=(guint16)(g*(65535/6.0)); color.blue=(guint16)(b*(65535/5.0)); color.pixel=0; if (gdk_color_alloc(col,&color)) if (color.pixel<COLORMAP_SIZE) allocated[color.pixel]=1; } for (i=0; i<COLORMAP_SIZE; i++) { if (allocated[i]) { push_int(col->colors[i].red>>8); push_int(col->colors[i].green>>8); push_int(col->colors[i].blue>>8); f_aggregate(3); } else push_int(0); } f_aggregate(256); /* now on stack: the array with colors. */ pgtk2_get_image_module(); pgtk2_index_stack("colortable"); /* on stack: array function */ Pike_sp[0]=Pike_sp[-1]; Pike_sp[-1]=Pike_sp[-2]; Pike_sp[-2]=Pike_sp[0]; /* on stack: function array */ PFTIME("Creating colormap obj"); apply_svalue(Pike_sp-2,1); /* on stack: function cmap */ get_all_args("internal",1,"%o",&pike_cmap); pike_cmap->refs+=100; /* lets keep this one.. :-) */ push_int(8); push_int(8); push_int(8); apply(pike_cmap,"rigid",3); pop_stack(); apply(pike_cmap,"ordered",0); pop_stack(); pop_stack(); }
static void gtk_plot_gdk_draw_string (GtkPlotPC *pc, gint tx, gint ty, gint angle, const GdkColor *fg, const GdkColor *bg, gboolean transparent, gint border, gint border_space, gint border_width, gint shadow_width, const gchar *font_name, gint font_height, GtkJustification just, const gchar *text) { GdkBitmap *text_bitmap; GdkPixmap *text_pixmap; GdkBitmap *text_mask; GdkImage *image; GdkGC *gc, *bitmap_gc; GdkColormap *colormap; GdkColor white, black, mask_color; GList *family = NULL; gint y0; gint old_width, old_height; gboolean bold, italic; gint fontsize; gint ascent, descent; gint numf; gint xp = 0, yp = 0; gint width, height; gint x, y; gint i; GdkFont *font, *latin_font, *dfont; GtkPSFont *psfont, *base_psfont, *latin_psfont; gchar subs[2], insert_char; GdkWChar *aux, *wtext, *lastchar = NULL, *xaux; gchar num[4]; if(!GTK_PLOT_GDK(pc)->drawable) return; if(!GTK_PLOT_GDK(pc)->window) return; if(!GTK_PLOT_GDK(pc)->gc) return; if(!text || strlen(text) == 0) return; colormap = gdk_colormap_get_system (); gc = GTK_PLOT_GDK(pc)->gc; if(!gc) return; gtk_plot_text_get_size(text, angle, font_name, font_height, &width, &height, &ascent, &descent); if(height == 0 || width == 0) return; old_width = width; old_height = height; if(angle == 90 || angle == 270) { old_width = height; old_height = width; } gtk_psfont_get_families(&family, &numf); font = gtk_psfont_get_gdkfont(font_name, font_height); base_psfont = psfont = gtk_psfont_get_font(font_name); italic = psfont->italic; bold = psfont->bold; fontsize = font_height; x = 0; y0 = y = ascent; if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } else { latin_psfont = NULL; latin_font = NULL; } i = strlen(text) + 2; aux = wtext = g_malloc0(sizeof(GdkWChar) * i); gdk_mbstowcs(wtext, text, i - 1); /* initializing text bitmap - ajd */ text_bitmap = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, old_width, old_height, 1); bitmap_gc = gdk_gc_new(text_bitmap); gdk_color_white (colormap, &white); gdk_gc_set_foreground(bitmap_gc, &white); gdk_draw_rectangle(text_bitmap, bitmap_gc, TRUE, 0, 0, -1, -1); gdk_color_black (colormap, &black); gdk_gc_set_foreground(bitmap_gc, &black); while(aux && *aux != '\0' && *aux != '\n'){ if(*aux == '\\'){ aux++; switch(*aux){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '9': psfont = gtk_psfont_find_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } aux++; break; case '8': case 'g': psfont = gtk_psfont_find_by_family("Symbol", italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } aux++; break; case 'B': bold = TRUE; psfont = gtk_psfont_find_by_family(psfont->family, italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'x': xaux = aux + 1; for (i=0; i<3; i++){ if (xaux[i] >= '0' && xaux[i] <= '9') num[i] = xaux[i]; else break; } if (i < 3){ aux++; break; } num[3] = '\0'; insert_char = (gchar)atoi(num); subs[0] = insert_char; subs[1] = '\0'; /* \xNNN is always outputted with latin fonts. */ dfont = (psfont->i18n_latinfamily != NULL) ? latin_font : font; gdk_draw_string (text_bitmap, dfont, bitmap_gc, x, y, subs); x += gdk_char_width(font, insert_char); aux += 4; lastchar = aux - 1; break; case 'i': italic = TRUE; psfont = gtk_psfont_find_by_family(psfont->family, italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'S': case '^': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); y -= font->ascent; if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 's': case '_': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); y += font->descent; if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case '+': fontsize += 3; gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case '-': fontsize -= 3; gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'N': psfont = base_psfont; gdk_font_unref(font); fontsize = font_height; font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); y = y0; italic = psfont->italic; bold = psfont->bold; if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'b': if (lastchar) { gtk_psfont_get_char_size(psfont, font, latin_font, *lastchar, &i, NULL, NULL); x -= i; if (lastchar == wtext) lastchar = NULL; else lastchar--; } else { gtk_psfont_get_char_size(psfont, font, latin_font, 'X', &i, NULL, NULL); x -= i; } aux++; break; default: if(aux && *aux != '\0' && *aux !='\n'){ x += drawstring(pc, text_bitmap, bitmap_gc, &black, &white, x, y, psfont, font, latin_font, *aux); lastchar = aux; aux++; } break; } } else { if(aux && *aux != '\0' && *aux !='\n'){ x += drawstring(pc, text_bitmap, bitmap_gc, &black, &white, x, y, psfont, font, latin_font, *aux); lastchar = aux; aux++; } } } g_free(wtext); /* initializing clip mask bitmap - ajd */ text_mask = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, width, height, 1); mask_color = white; mask_color.pixel = 0; gdk_gc_set_foreground(bitmap_gc, &mask_color); gdk_draw_rectangle(text_mask, bitmap_gc, TRUE, 0, 0, -1, -1); mask_color = black; mask_color.pixel = 1; gdk_gc_set_foreground(bitmap_gc, &mask_color); /* performing text rotation and saving it onto clip mask bitmap - ajd */ image = gdk_image_get(text_bitmap, 0, 0, old_width, old_height); for(y = 0; y < old_height; y++) for(x = 0; x < old_width; x++) { if( black.pixel == gdk_image_get_pixel(image, x, y) ){ switch(angle){ case 0: xp = x; yp = y; break; case 90: xp = y; yp = old_width - x; break; case 180: xp = old_width - x; yp = old_height - y; break; case 270: xp = old_height - y; yp = x; break; } gdk_draw_point(text_mask, bitmap_gc, xp, yp); } } gdk_image_destroy(image); /* initializing text pixmap - ajd */ text_pixmap = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, width, height, -1); gdk_gc_set_foreground(gc, (GdkColor *) bg); gdk_draw_rectangle(text_pixmap, gc, TRUE, 0, 0, -1, -1); gdk_gc_set_foreground(gc, (GdkColor *) fg); /* copying clip mask bitmap onto text pixmap - ajd */ gdk_gc_set_clip_mask(gc, text_mask); gdk_gc_set_clip_origin(gc, 0, 0); gdk_draw_rectangle(text_pixmap, gc, TRUE, 0, 0, -1, -1); gdk_gc_set_clip_mask(gc, NULL); gtk_plot_text_get_area(text, angle, just, font_name, font_height, &x, &y, &width, &height); tx += x; ty += y; if(transparent){ gdk_gc_set_clip_mask (gc, text_mask); gdk_gc_set_clip_origin (gc, tx, ty); } else { gdk_gc_set_foreground(gc, (GdkColor *) bg); gtk_plot_pc_draw_rectangle(pc, TRUE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); } gdk_draw_pixmap(GTK_PLOT_GDK(pc)->drawable, gc, text_pixmap, 0, 0, tx, ty, -1, -1); gdk_gc_set_clip_mask(gc, NULL); gdk_pixmap_unref(text_pixmap); gdk_bitmap_unref(text_mask); gdk_font_unref(font); if (latin_font) gdk_font_unref(latin_font); gdk_gc_unref(bitmap_gc); gdk_pixmap_unref(text_bitmap); /* border */ gdk_gc_set_foreground(gc, (GdkColor *) fg); gtk_plot_pc_set_dash(pc, 0, NULL, 0); gtk_plot_pc_set_lineattr(pc, border_width, 0, 0, 0); switch(border){ case GTK_PLOT_BORDER_SHADOW: gtk_plot_pc_draw_rectangle(pc, TRUE, tx - border_space + shadow_width, ty + height + border_space, width + 2 * border_space, shadow_width); gtk_plot_pc_draw_rectangle(pc, TRUE, tx + width + border_space, ty - border_space + shadow_width, shadow_width, height + 2 * border_space); case GTK_PLOT_BORDER_LINE: gtk_plot_pc_draw_rectangle(pc, FALSE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); case GTK_PLOT_BORDER_NONE: default: break; } return; }
static GdkBitmap * scale_bitmap (GdkWindow *window, GdkBitmap *bitmap, gdouble scale_x, gdouble scale_y) { GdkGC *gc; GdkVisual *visual = NULL; GdkImage *image = NULL, *new_image = NULL; GdkBitmap *new_bitmap = NULL; gint x, y, width, height, new_width, new_height; GdkColor color; if(!bitmap) return NULL; if(!window) return NULL; gc = gdk_gc_new(bitmap); gdk_window_get_size(bitmap, &width, &height); if(scale_x == 1.0 && scale_y == 1.0){ new_bitmap = gdk_pixmap_new(window, width, height, 1); color.pixel = 0; gdk_gc_set_foreground(gc, &color); gdk_draw_rectangle(new_bitmap, gc, TRUE, 0, 0, width, height); color.pixel = 1; gdk_gc_set_foreground(gc, &color); gdk_draw_pixmap(new_bitmap, gc, bitmap, 0, 0, 0, 0, width, height); gdk_gc_unref(gc); return new_bitmap; } new_width = roundint(width * scale_x); new_height = roundint(height * scale_y); /* make a client side image of the bitmap, and * scale the data into a another client side image */ visual = gdk_window_get_visual (bitmap); if(!visual) return NULL; new_image = gdk_image_new(GDK_IMAGE_FASTEST,visual,new_width,new_height); if(!new_image) return NULL; new_bitmap = gdk_pixmap_new(window, new_width, new_height, 1); image = gdk_drawable_get_image(bitmap, 0, 0, width, height); color.pixel = 0; gdk_gc_set_foreground(gc, &color); gdk_draw_rectangle(new_bitmap, gc, TRUE, 0, 0, width, height); color.pixel = 1; gdk_gc_set_foreground(gc, &color); for(x = 0; x < new_width; x++){ for(y = 0; y < new_height; y++){ gint px, py; gulong pixel; px = MIN(roundint(x / scale_x), width - 1); py = MIN(roundint(y / scale_y), height - 1); pixel = gdk_image_get_pixel(image, px, py); gdk_image_put_pixel(new_image, x, y, pixel); } } /* draw the image into a new pixmap */ gdk_draw_image(new_bitmap,gc,new_image,0,0,0,0,new_width,new_height); gdk_image_destroy(image); gdk_image_destroy(new_image); gdk_gc_unref(gc); return new_bitmap; }
static void psclipmask(GtkPlotPC *pc, gdouble x, gdouble y, const GdkBitmap *mask) { FILE *psout = GTK_PLOT_PS(pc)->psfile; gint width, height; gint px, py; gint npoints = 0; gint i; GtkPlotVector *points; GdkImage *image; if(!mask){ fprintf(psout,"grestore\n"); return; } gdk_window_get_size((GdkWindow *)mask, &width, &height); image = gdk_image_get((GdkWindow *)mask, 0, 0, width, height); points = (GtkPlotVector *)g_malloc(width*height*sizeof(GtkPlotVector)); for(px = 0; px < width; px++){ for(py = 0; py < height; py++){ if(gdk_image_get_pixel(image, px, py)){ points[npoints].x = px; points[npoints].y = py; npoints++; break; } } } for(py = points[npoints-1].y; py < height; py++){ for(px = width - 1; px >= 0; px--){ if(gdk_image_get_pixel(image, px, py)){ points[npoints].x = px; points[npoints].y = py; npoints++; break; } } } for(px = points[npoints-1].x; px >= 0; px--){ for(py = height - 1; py >= 0; py--){ if(gdk_image_get_pixel(image, px, py)){ points[npoints].x = px; points[npoints].y = py; npoints++; break; } } } for(py = points[npoints-1].y; py >= 0; py--){ for(px = 0; px < width; px++){ if(gdk_image_get_pixel(image, px, py)){ points[npoints].x = px; points[npoints].y = py; npoints++; break; } } } fprintf(psout,"gsave\n"); fprintf(psout,"n\n"); fprintf(psout,"%g %g m\n", x + points[0].x, y + points[0].y); for(i = 1; i < npoints; i++) fprintf(psout,"%g %g l\n", x + points[i].x, y + points[i].y); fprintf(psout,"cp\n"); fprintf(psout,"clip\n"); g_free(points); gdk_image_destroy(image); }
void WinDraw_ChangeSize(void) { DWORD oldx = WindowX, oldy = WindowY; int dif; Mouse_ChangePos(); switch (Config.WinStrech) { case 0: WindowX = TextDotX; WindowY = TextDotY; break; case 1: WindowX = 768; WindowY = 512; break; case 2: if (TextDotX <= 384) WindowX = TextDotX * 2; else WindowX = TextDotX; if (TextDotY <= 256) WindowY = TextDotY * 2; else WindowY = TextDotY; break; case 3: if (TextDotX <= 384) WindowX = TextDotX * 2; else WindowX = TextDotX; if (TextDotY <= 256) WindowY = TextDotY * 2; else WindowY = TextDotY; dif = WindowX - WindowY; if ((dif > -32) && (dif < 32)) { // 正方形に近い画面なら、としておこう WindowX = (int)(WindowX * 1.25); } break; } if ((WindowX > 768) || (WindowX <= 0)) { if (oldx) WindowX = oldx; else WindowX = oldx = 768; } if ((WindowY > 512) || (WindowY <= 0)) { if (oldy) WindowY = oldy; else WindowY = oldy = 512; } surface_rect.width = TextDotX; surface_rect.height = TextDotY; if ((oldx == WindowX) && (oldy == WindowY)) return; if ((TextDotX == WindowX) && (TextDotY == WindowY)) screen_mode = 0; else { screen_mode = 1; if (scaled_screen) gdk_image_destroy(scaled_screen); scaled_screen = gdk_image_new(GDK_IMAGE_FASTEST, surface->visual, WindowX, WindowY); } if (surface) { bzero(ScrBuf, FULLSCREEN_WIDTH * FULLSCREEN_HEIGHT * 2); #if 1 gdk_draw_rectangle(pixmap, window->style->black_gc, TRUE, 0, 0, FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT); #else gdk_draw_rectangle(pixmap, window->style->black_gc, TRUE, oldx, 0, FULLSCREEN_WIDTH - oldx, FULLSCREEN_HEIGHT); gdk_draw_rectangle(pixmap, window->style->black_gc, TRUE, 0, oldy, FULLSCREEN_WIDTH - oldx, FULLSCREEN_HEIGHT - oldy); #endif } WinDraw_InitWindowSize((WORD)WindowX, (WORD)WindowY); gtk_widget_set_usize(drawarea, winw, winh); gtk_widget_set_uposition(window, winx, winy); StatBar_Show(Config.WindowFDDStat); Mouse_ChangePos(); }
wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight, int newx, int newy ) { wxCHECK_MSG( Ok(), wxNullBitmap, wxT("invalid bitmap") ); if (newy==M_BMPDATA->m_width && newy==M_BMPDATA->m_height) return *this; int width = wxMax(newx, 1); int height = wxMax(newy, 1); width = wxMin(width, clipwidth); height = wxMin(height, clipheight); wxBitmap bmp; #ifdef __WXGTK20__ if (HasPixbuf()) { bmp.SetWidth(width); bmp.SetHeight(height); bmp.SetDepth(GetDepth()); bmp.SetPixbuf(gdk_pixbuf_new(GDK_COLORSPACE_RGB, gdk_pixbuf_get_has_alpha(GetPixbuf()), 8, width, height)); gdk_pixbuf_scale(GetPixbuf(), bmp.GetPixbuf(), 0, 0, width, height, clipx, clipy, (double)newx/GetWidth(), (double)newy/GetHeight(), GDK_INTERP_BILINEAR); } else #endif // __WXGTK20__ { GdkImage *img = (GdkImage*) NULL; if (GetPixmap()) img = gdk_image_get( GetPixmap(), 0, 0, GetWidth(), GetHeight() ); else if (GetBitmap()) img = gdk_image_get( GetBitmap(), 0, 0, GetWidth(), GetHeight() ); else wxFAIL_MSG( wxT("Ill-formed bitmap") ); wxCHECK_MSG( img, wxNullBitmap, wxT("couldn't create image") ); int bpp = -1; GdkGC *gc = NULL; GdkPixmap *dstpix = NULL; if (GetPixmap()) { GdkVisual *visual = gdk_window_get_visual( GetPixmap() ); if (visual == NULL) visual = wxTheApp->GetGdkVisual(); bpp = visual->depth; bmp = wxBitmap(width,height,bpp); dstpix = bmp.GetPixmap(); gc = gdk_gc_new( dstpix ); } char *dst = NULL; long dstbyteperline = 0; if (GetBitmap()) { bpp = 1; dstbyteperline = width/8*M_BMPDATA->m_bpp; if (width*M_BMPDATA->m_bpp % 8 != 0) dstbyteperline++; dst = (char*) malloc(dstbyteperline*height); } // be careful to use the right scaling factor float scx = (float)M_BMPDATA->m_width/(float)newx; float scy = (float)M_BMPDATA->m_height/(float)newy; // prepare accel-tables int *tablex = (int *)calloc(width,sizeof(int)); int *tabley = (int *)calloc(height,sizeof(int)); // accel table filled with clipped values for (int x = 0; x < width; x++) tablex[x] = (int) (scx * (x+clipx)); for (int y = 0; y < height; y++) tabley[y] = (int) (scy * (y+clipy)); // Main rescaling routine starts here for (int h = 0; h < height; h++) { char outbyte = 0; int old_x = -1; guint32 old_pixval = 0; for (int w = 0; w < width; w++) { guint32 pixval; int x = tablex[w]; if (x == old_x) pixval = old_pixval; else { pixval = gdk_image_get_pixel( img, x, tabley[h] ); old_pixval = pixval; old_x = x; } if (bpp == 1) { if (!pixval) { char bit=1; char shift = bit << w % 8; outbyte |= shift; } if ((w+1)%8==0) { dst[h*dstbyteperline+w/8] = outbyte; outbyte = 0; } } else { GdkColor col; col.pixel = pixval; gdk_gc_set_foreground( gc, &col ); gdk_draw_point( dstpix, gc, w, h); } } // do not forget the last byte if ((bpp == 1) && (width % 8 != 0)) dst[h*dstbyteperline+width/8] = outbyte; } gdk_image_destroy( img ); if (gc) gdk_gc_unref( gc ); if (bpp == 1) { bmp = wxBitmap( (const char *)dst, width, height, 1 ); free( dst ); } if (GetMask()) { dstbyteperline = width/8; if (width % 8 != 0) dstbyteperline++; dst = (char*) malloc(dstbyteperline*height); img = gdk_image_get( GetMask()->GetBitmap(), 0, 0, GetWidth(), GetHeight() ); for (int h = 0; h < height; h++) { char outbyte = 0; int old_x = -1; guint32 old_pixval = 0; for (int w = 0; w < width; w++) { guint32 pixval; int x = tablex[w]; if (x == old_x) pixval = old_pixval; else { pixval = gdk_image_get_pixel( img, x, tabley[h] ); old_pixval = pixval; old_x = x; } if (pixval) { char bit=1; char shift = bit << w % 8; outbyte |= shift; } if ((w+1)%8 == 0) { dst[h*dstbyteperline+w/8] = outbyte; outbyte = 0; } } // do not forget the last byte if (width % 8 != 0) dst[h*dstbyteperline+width/8] = outbyte; } wxMask* mask = new wxMask; mask->m_bitmap = gdk_bitmap_create_from_data( wxGetRootWindow()->window, (gchar *) dst, width, height ); bmp.SetMask(mask); free( dst ); gdk_image_destroy( img ); } free( tablex ); free( tabley ); } return bmp; }
/* this is called for a mode change: */ int _tme_gtk_screen_mode_change(struct tme_fb_connection *conn_fb) { struct tme_gtk_display *display; struct tme_gtk_screen *screen; struct tme_fb_connection *conn_fb_other; struct tme_fb_xlat fb_xlat_q; const struct tme_fb_xlat *fb_xlat_a; int scale; unsigned long fb_area, avail_area, percentage; gint width, height; gint height_extra; const void *map_g_old; const void *map_r_old; const void *map_b_old; const tme_uint32_t *map_pixel_old; tme_uint32_t map_pixel_count_old; tme_uint32_t colorset; GdkImage *gdkimage; GdkVisual *visual; tme_uint32_t color_count, color_i; tme_uint32_t color_count_distinct; tme_uint32_t color_j; struct tme_fb_color *colors_tme; GdkColor *colors_gdk; gboolean *success; gboolean warned_color_alloc; /* recover our data structures: */ display = conn_fb->tme_fb_connection.tme_connection_element->tme_element_private; conn_fb_other = (struct tme_fb_connection *) conn_fb->tme_fb_connection.tme_connection_other; /* lock our mutex: */ tme_mutex_lock(&display->tme_gtk_display_mutex); /* find the screen that this framebuffer connection references: */ for (screen = display->tme_gtk_display_screens; (screen != NULL && screen->tme_gtk_screen_fb != conn_fb); screen = screen->tme_gtk_screen_next); assert (screen != NULL); /* if the user hasn't specified a scaling, pick one: */ scale = screen->tme_gtk_screen_fb_scale; if (scale < 0) { /* calulate the areas, in square pixels, of the emulated framebuffer and the host's screen: */ fb_area = (conn_fb_other->tme_fb_connection_width * conn_fb_other->tme_fb_connection_height); avail_area = (gdk_screen_width() * gdk_screen_height()); /* see what percentage of the host's screen would be taken up by an unscaled emulated framebuffer: */ percentage = (fb_area * 100) / avail_area; /* if this is at least 70%, halve the emulated framebuffer, else if this is 30% or less, double the emulated framebuffer: */ if (percentage >= 70) { scale = TME_FB_XLAT_SCALE_HALF; } else if (percentage <= 30) { scale = TME_FB_XLAT_SCALE_DOUBLE; } else { scale = TME_FB_XLAT_SCALE_NONE; } screen->tme_gtk_screen_fb_scale = -scale; } /* get the system's default visual: */ visual = gdk_visual_get_system(); /* get the required dimensions for the GdkImage: */ width = ((conn_fb_other->tme_fb_connection_width * scale) / TME_FB_XLAT_SCALE_NONE); height = ((conn_fb_other->tme_fb_connection_height * scale) / TME_FB_XLAT_SCALE_NONE); /* NB: we need to allocate an extra scanline's worth (or, if we're doubling, an extra two scanlines' worth) of image, because the framebuffer translation functions can sometimes overtranslate (see the explanation of TME_FB_XLAT_RUN in fb-xlat-auto.sh): */ height_extra = (scale == TME_FB_XLAT_SCALE_DOUBLE ? 2 : 1); /* if the previous gdkimage isn't the right size: */ gdkimage = screen->tme_gtk_screen_gdkimage; if (gdkimage->width != width || gdkimage->height != (height + height_extra)) { /* allocate a new gdkimage: */ gdkimage = gdk_image_new(GDK_IMAGE_FASTEST, visual, width, height + height_extra); /* set the new image on the image widget: */ gtk_image_set(GTK_IMAGE(screen->tme_gtk_screen_gtkimage), gdkimage, NULL); /* destroy the previous gdkimage and remember the new one: */ gdk_image_destroy(screen->tme_gtk_screen_gdkimage); screen->tme_gtk_screen_gdkimage = gdkimage; } /* remember all previously allocated maps and colors, but otherwise remove them from our framebuffer structure: */ map_g_old = conn_fb->tme_fb_connection_map_g; map_r_old = conn_fb->tme_fb_connection_map_r; map_b_old = conn_fb->tme_fb_connection_map_b; map_pixel_old = conn_fb->tme_fb_connection_map_pixel; map_pixel_count_old = conn_fb->tme_fb_connection_map_pixel_count; conn_fb->tme_fb_connection_map_g = NULL; conn_fb->tme_fb_connection_map_r = NULL; conn_fb->tme_fb_connection_map_b = NULL; conn_fb->tme_fb_connection_map_pixel = NULL; conn_fb->tme_fb_connection_map_pixel_count = 0; /* update our framebuffer connection: */ conn_fb->tme_fb_connection_width = width; conn_fb->tme_fb_connection_height = height; conn_fb->tme_fb_connection_depth = gdkimage->depth; conn_fb->tme_fb_connection_bits_per_pixel = _tme_gtk_gdkimage_bipp(gdkimage); conn_fb->tme_fb_connection_skipx = 0; conn_fb->tme_fb_connection_scanline_pad = _tme_gtk_gdkimage_scanline_pad(gdkimage); conn_fb->tme_fb_connection_order = (gdkimage->byte_order == GDK_LSB_FIRST ? TME_ENDIAN_LITTLE : TME_ENDIAN_BIG); conn_fb->tme_fb_connection_buffer = gdkimage->mem; switch (visual->type) { case GDK_VISUAL_STATIC_GRAY: case GDK_VISUAL_GRAYSCALE: conn_fb->tme_fb_connection_class = TME_FB_XLAT_CLASS_MONOCHROME; break; default: assert(FALSE); /* FALLTHROUGH */ case GDK_VISUAL_STATIC_COLOR: case GDK_VISUAL_PSEUDO_COLOR: case GDK_VISUAL_DIRECT_COLOR: case GDK_VISUAL_TRUE_COLOR: conn_fb->tme_fb_connection_class = TME_FB_XLAT_CLASS_COLOR; break; } switch (visual->type) { case GDK_VISUAL_DIRECT_COLOR: /* we set the primary maps to anything non-NULL, to indicate that primaries are index mapped: */ conn_fb->tme_fb_connection_map_g = conn_fb; conn_fb->tme_fb_connection_map_r = conn_fb; conn_fb->tme_fb_connection_map_b = conn_fb; /* FALLTHROUGH */ case GDK_VISUAL_TRUE_COLOR: conn_fb->tme_fb_connection_mask_g = visual->green_mask; conn_fb->tme_fb_connection_mask_r = visual->red_mask; conn_fb->tme_fb_connection_mask_b = visual->blue_mask; break; default: conn_fb->tme_fb_connection_mask_g = 0; conn_fb->tme_fb_connection_mask_r = 0; conn_fb->tme_fb_connection_mask_b = 0; break; } /* get the needed colors: */ colorset = tme_fb_xlat_colors_get(conn_fb_other, scale, conn_fb, &colors_tme); color_count = conn_fb->tme_fb_connection_map_pixel_count; /* if we need to allocate colors, but the colorset is not tied to the source framebuffer characteristics, and is identical to the currently allocated colorset, we can reuse the previously allocated maps and colors: */ if (color_count > 0 && colorset != TME_FB_COLORSET_NONE && colorset == screen->tme_gtk_screen_colorset) { /* free the requested color array: */ tme_free(colors_tme); /* restore the previously allocated maps and colors: */ conn_fb->tme_fb_connection_map_g = map_g_old; conn_fb->tme_fb_connection_map_r = map_r_old; conn_fb->tme_fb_connection_map_b = map_b_old; conn_fb->tme_fb_connection_map_pixel = map_pixel_old; conn_fb->tme_fb_connection_map_pixel_count = map_pixel_count_old; } /* otherwise, we may need to free and/or allocate colors: */ else { /* save the colorset signature: */ screen->tme_gtk_screen_colorset = colorset; /* free any previously allocated maps and colors: */ if (map_g_old != NULL) { tme_free((void *) map_g_old); } if (map_r_old != NULL) { tme_free((void *) map_r_old); } if (map_b_old != NULL) { tme_free((void *) map_b_old); } if (map_pixel_old != NULL) { /* recreate the array of GdkColor: */ colors_gdk = tme_new(GdkColor, map_pixel_count_old); color_i = 0; do { colors_gdk[color_i].pixel = map_pixel_old[color_i]; } while (++color_i < map_pixel_count_old); /* free the colors: */ gdk_colormap_free_colors(gdk_colormap_get_system(), colors_gdk, map_pixel_count_old); tme_free(colors_gdk); tme_free((void *) map_pixel_old); } /* if we need to allocate colors: */ if (color_count > 0) { /* make the GdkColor array, and count the number of distinct colors: */ colors_gdk = tme_new(GdkColor, color_count * 2); color_count_distinct = 0; for (color_i = 0; color_i < color_count; color_i++) { color_j = colors_tme[color_i].tme_fb_color_pixel; colors_gdk[color_j].green = colors_tme[color_i].tme_fb_color_value_g; colors_gdk[color_j].red = colors_tme[color_i].tme_fb_color_value_r; colors_gdk[color_j].blue = colors_tme[color_i].tme_fb_color_value_b; if (color_j >= color_count_distinct) { color_count_distinct = color_j + 1; } } success = tme_new(gboolean, color_count_distinct); /* allocate exact matches for as many colors as possible: */ gdk_colormap_alloc_colors(gdk_colormap_get_system(), colors_gdk, color_count_distinct, FALSE, FALSE, success); /* allocate read-only best matches for any colors we failed to allocate exactly: */ warned_color_alloc = FALSE; for (color_i = 0; color_i < color_count; color_i++) { color_j = colors_tme[color_i].tme_fb_color_pixel; if (!success[color_j]) { if (!gdk_colormap_alloc_color(gdk_colormap_get_system(), &colors_gdk[color_j], FALSE, TRUE)) { if (!warned_color_alloc) { warned_color_alloc = TRUE; tme_log(&display->tme_gtk_display_element->tme_element_log_handle, 0, ENOMEM, (&display->tme_gtk_display_element->tme_element_log_handle, _("could not allocate all colors"))); } } } colors_tme[color_i].tme_fb_color_pixel = colors_gdk[color_j].pixel; } /* free the arrays used with gdk_colormap_alloc_colors(): */ tme_free(success); tme_free(colors_gdk); /* set the needed colors: */ tme_fb_xlat_colors_set(conn_fb_other, scale, conn_fb, colors_tme); } } /* compose the framebuffer translation question: */ fb_xlat_q.tme_fb_xlat_width = conn_fb_other->tme_fb_connection_width; fb_xlat_q.tme_fb_xlat_height = conn_fb_other->tme_fb_connection_height; fb_xlat_q.tme_fb_xlat_scale = (unsigned int) scale; fb_xlat_q.tme_fb_xlat_src_depth = conn_fb_other->tme_fb_connection_depth; fb_xlat_q.tme_fb_xlat_src_bits_per_pixel = conn_fb_other->tme_fb_connection_bits_per_pixel; fb_xlat_q.tme_fb_xlat_src_skipx = conn_fb_other->tme_fb_connection_skipx; fb_xlat_q.tme_fb_xlat_src_scanline_pad = conn_fb_other->tme_fb_connection_scanline_pad; fb_xlat_q.tme_fb_xlat_src_order = conn_fb_other->tme_fb_connection_order; fb_xlat_q.tme_fb_xlat_src_class = conn_fb_other->tme_fb_connection_class; fb_xlat_q.tme_fb_xlat_src_map = (conn_fb_other->tme_fb_connection_map_g != NULL ? TME_FB_XLAT_MAP_INDEX : TME_FB_XLAT_MAP_LINEAR); fb_xlat_q.tme_fb_xlat_src_map_bits = conn_fb_other->tme_fb_connection_map_bits; fb_xlat_q.tme_fb_xlat_src_mask_g = conn_fb_other->tme_fb_connection_mask_g; fb_xlat_q.tme_fb_xlat_src_mask_r = conn_fb_other->tme_fb_connection_mask_r; fb_xlat_q.tme_fb_xlat_src_mask_b = conn_fb_other->tme_fb_connection_mask_b; fb_xlat_q.tme_fb_xlat_dst_depth = conn_fb->tme_fb_connection_depth; fb_xlat_q.tme_fb_xlat_dst_bits_per_pixel = conn_fb->tme_fb_connection_bits_per_pixel; fb_xlat_q.tme_fb_xlat_dst_skipx = conn_fb->tme_fb_connection_skipx; fb_xlat_q.tme_fb_xlat_dst_scanline_pad = conn_fb->tme_fb_connection_scanline_pad; fb_xlat_q.tme_fb_xlat_dst_order = conn_fb->tme_fb_connection_order; fb_xlat_q.tme_fb_xlat_dst_map = (conn_fb->tme_fb_connection_map_g != NULL ? TME_FB_XLAT_MAP_INDEX : TME_FB_XLAT_MAP_LINEAR); fb_xlat_q.tme_fb_xlat_dst_mask_g = conn_fb->tme_fb_connection_mask_g; fb_xlat_q.tme_fb_xlat_dst_mask_r = conn_fb->tme_fb_connection_mask_r; fb_xlat_q.tme_fb_xlat_dst_mask_b = conn_fb->tme_fb_connection_mask_b; /* ask the framebuffer translation question: */ fb_xlat_a = tme_fb_xlat_best(&fb_xlat_q); /* if this translation isn't optimal, log a note: */ if (!tme_fb_xlat_is_optimal(fb_xlat_a)) { tme_log(&display->tme_gtk_display_element->tme_element_log_handle, 0, TME_OK, (&display->tme_gtk_display_element->tme_element_log_handle, _("no optimal framebuffer translation function available"))); } /* save the translation function: */ screen->tme_gtk_screen_fb_xlat = fb_xlat_a->tme_fb_xlat_func; /* force the next translation to do a complete redraw: */ screen->tme_gtk_screen_full_redraw = TRUE; /* unlock our mutex: */ tme_mutex_unlock(&display->tme_gtk_display_mutex); /* done: */ return (TME_OK); }