You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
5.6 KiB
185 lines
5.6 KiB
/***************************************************************************
|
|
* gtk_gfx.c
|
|
*
|
|
* Copyright 2010 Steffen Pohle
|
|
* steffen@gulpe.de
|
|
****************************************************************************/
|
|
|
|
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
|
|
#include "map.h"
|
|
#include "gtk_port.h"
|
|
#include "memoryleak.h"
|
|
#include "system.h"
|
|
|
|
iPoint gfx_screensize;
|
|
struct image *gfx_doublebuffer = NULL;
|
|
|
|
/************************************************************************
|
|
* functions for starting and finishing the drawing process
|
|
*/
|
|
void gfx_flip () {
|
|
gc = gdk_gc_new (map_da->window);
|
|
gdk_gc_get_values (gc, &gcvalues);
|
|
gdk_draw_drawable (map_da->window, gc, gfx_doublebuffer->pixmap, 0, 0, 0, 0, gfx_screensize.x, gfx_screensize.y);
|
|
gdk_gc_unref (gc);
|
|
};
|
|
|
|
|
|
void gfx_resize (int width, int height) {
|
|
if (width != gfx_screensize.x || height != gfx_screensize.y) {
|
|
if (height == 0) height = 1;
|
|
if (width == 0) width = 1;
|
|
|
|
gfx_screensize.x = width;
|
|
gfx_screensize.y = height;
|
|
if (gfx_doublebuffer) gfx_img_free (gfx_doublebuffer);
|
|
gfx_doublebuffer = gfx_img_alloc (width, height);
|
|
}
|
|
};
|
|
|
|
|
|
int gfx_color_alloc (struct color *c, unsigned short int r, unsigned short int g, unsigned short int b) {
|
|
c->r = r;
|
|
c->b = b;
|
|
c->g = g;
|
|
|
|
if (c->alloc && colormap != NULL) {
|
|
gdk_colormap_free_colors (colormap, &c->c, 1);
|
|
c->alloc = 0;
|
|
}
|
|
|
|
if (colormap != NULL) {
|
|
c->alloc = 1;
|
|
c->c.red = r;
|
|
c->c.blue = b;
|
|
c->c.green = g;
|
|
gdk_colormap_alloc_color (colormap, &c->c, TRUE, TRUE);
|
|
}
|
|
else c->alloc = 0;
|
|
|
|
return 1;
|
|
};
|
|
|
|
|
|
/***************************************************************************
|
|
* img functions
|
|
*/
|
|
struct image *gfx_img_alloc (int w, int h) {
|
|
struct image *img = (struct image*) ml_malloc (sizeof (struct image));
|
|
d_printf ("img_gfx_alloc: %d,%d", w, h);
|
|
|
|
img->pixmap = gdk_pixmap_new (map_da->window, w, h, -1);
|
|
img->gc = gdk_gc_new (img->pixmap);
|
|
img->width = w;
|
|
img->height = h;
|
|
|
|
return img;
|
|
};
|
|
|
|
|
|
void gfx_img_free (struct image *img) {
|
|
gdk_gc_unref (img->gc);
|
|
g_object_unref (img->pixmap);
|
|
ml_free (img);
|
|
};
|
|
|
|
|
|
void gfx_clear (struct image *img, struct color *c) {
|
|
if (img == NULL) img = gfx_doublebuffer;
|
|
gdk_gc_set_foreground (img->gc,&c->c);
|
|
gdk_draw_rectangle (img->pixmap, img->gc, TRUE, 0, 0, img->width, img->height);
|
|
};
|
|
|
|
|
|
void gfx_draw_img (struct image *dimg, int dx, int dy, int dw, int dh, struct image *simg, int sx, int sy) {
|
|
if (dimg == NULL) dimg = gfx_doublebuffer;
|
|
if (simg == NULL || simg->pixmap == NULL || dimg == NULL || dimg->pixmap == NULL) {
|
|
d_printf ("WARN: gfx_img_draw_img drawing on NULL or from NULL image");
|
|
d_print_backtrace ();
|
|
return;
|
|
}
|
|
|
|
/* check for boundrys, do clipping */
|
|
if (sx + dw > simg->width) dw = simg->width - sx;
|
|
if (dx + dw > dimg->width) dw = dimg->width - dx;
|
|
if (sy + dh > simg->height) dh = simg->height - sy;
|
|
if (dh + dh > gfx_screensize.y) dh = dimg->height - dy;
|
|
if (dw <= 0 || dh <= 0) return;
|
|
|
|
/* draw the pixmap onto the screen */
|
|
gdk_draw_drawable (dimg->pixmap, dimg->gc, simg->pixmap, sx, sy, dx, dy, dw, dh);
|
|
};
|
|
|
|
|
|
void gfx_draw_line (struct image *dimg, int x1, int y1, int x2, int y2, struct line_style style) {
|
|
if (dimg == NULL) dimg = gfx_doublebuffer;
|
|
gdk_gc_set_foreground (dimg->gc,&style.c.c);
|
|
gdk_gc_set_line_attributes (dimg->gc, style.width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
|
|
gdk_draw_line(dimg->pixmap, dimg->gc, x1, y1, x2, y2);
|
|
};
|
|
|
|
|
|
void gfx_draw_text (struct image *dimg, int x, int y, char *text, struct color *c) {
|
|
if (dimg == NULL) dimg = gfx_doublebuffer;
|
|
PangoLayout *layout = gtk_widget_create_pango_layout(map_da, NULL);
|
|
pango_layout_set_text(layout, text, -1);
|
|
|
|
gdk_gc_set_foreground (dimg->gc, &color[COLOR_white][2].c);
|
|
gdk_draw_layout(dimg->pixmap, dimg->gc, x-1, y-1, layout);
|
|
gdk_draw_layout(dimg->pixmap, dimg->gc, x-1, y+1, layout);
|
|
gdk_draw_layout(dimg->pixmap, dimg->gc, x+1, y-1, layout);
|
|
gdk_draw_layout(dimg->pixmap, dimg->gc, x+1, y+1, layout);
|
|
|
|
gdk_gc_set_foreground (dimg->gc, &c->c);
|
|
gdk_draw_layout(dimg->pixmap, dimg->gc, x, y, layout);
|
|
g_object_unref(layout);
|
|
};
|
|
|
|
|
|
void gfx_draw_polygon (struct image *dimg, iPoint *p, int pcnt, struct line_style style, struct color *c) {
|
|
static GdkPoint *polygon = NULL;
|
|
static int polygon_cnt = 0;
|
|
int i;
|
|
|
|
if (dimg == NULL) dimg = gfx_doublebuffer;
|
|
if (polygon_cnt < pcnt) {
|
|
polygon_cnt = pcnt;
|
|
if (polygon != NULL)
|
|
polygon = (GdkPoint *) ml_realloc (polygon, sizeof (GdkPoint) * polygon_cnt);
|
|
else
|
|
polygon = (GdkPoint *) ml_malloc (sizeof (GdkPoint) * polygon_cnt);
|
|
}
|
|
|
|
for (i = 0; i < pcnt; i++) {
|
|
polygon[i].x = p[i].x;
|
|
polygon[i].y = p[i].y;
|
|
}
|
|
|
|
gdk_gc_set_foreground (dimg->gc, &c->c);
|
|
gdk_draw_polygon (dimg->pixmap, dimg->gc, TRUE, polygon, pcnt);
|
|
};
|
|
|
|
|
|
void gfx_draw_rect (struct image *dimg, int x1, int y1, int x2, int y2, struct color *c) {
|
|
if (dimg == NULL) dimg = gfx_doublebuffer;
|
|
gdk_gc_set_foreground (dimg->gc, &c->c);
|
|
gdk_draw_rectangle (dimg->pixmap, dimg->gc, TRUE, x1, y1, x2-x1, y2-y1);
|
|
};
|
|
|