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
}
Beispiel #2
0
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());
}
Beispiel #3
0
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;
}
Beispiel #4
0
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); 
}
Beispiel #5
0
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;
}
Beispiel #6
0
GtkOvgGlue::~GtkOvgGlue()
{
    GNASH_REPORT_FUNCTION;

#ifdef ENABLE_EGL_OFFSCREEN
    if (_offscreenbuf) {
        gdk_image_destroy(_offscreenbuf);
    }
#endif    

}
Beispiel #7
0
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");
}
Beispiel #8
0
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);
}
Beispiel #9
0
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;
}
Beispiel #10
0
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);
}
Beispiel #11
0
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    
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
/* 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;
  }
}
Beispiel #15
0
GtkAggGlue::~GtkAggGlue()
{
    if (_offscreenbuf) {
        gdk_image_destroy(_offscreenbuf);
    }
}
Beispiel #16
0
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();
    }
Beispiel #17
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
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);
}
Beispiel #20
0
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();
}
Beispiel #21
0
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; 
}
Beispiel #22
0
/* 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);
}