From 2fa4ecf284b709748745c8f8aa80c1481e9db491 Mon Sep 17 00:00:00 2001 From: martin-s Date: Wed, 5 Nov 2008 08:07:11 +0000 Subject: [PATCH] Add:graphics_gd:New graphics system git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@1644 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- navit/configure.in | 27 ++ navit/navit/graphics/Makefile.am | 3 + navit/navit/graphics/gd/Makefile.am | 9 + navit/navit/graphics/gd/graphics_gd.c | 526 ++++++++++++++++++++++++++++++++++ 4 files changed, 565 insertions(+) create mode 100644 navit/navit/graphics/gd/Makefile.am create mode 100644 navit/navit/graphics/gd/graphics_gd.c diff --git a/navit/configure.in b/navit/configure.in index 61e6ecc..cb7b993 100644 --- a/navit/configure.in +++ b/navit/configure.in @@ -12,6 +12,7 @@ binding_python=yes; binding_python_reason=default gui_gtk=no; gui_gtk_reason=default gui_win32=no; gui_win32_reason=default gui_internal=yes; gui_internal_reason=default +graphics_gd=no; graphics_gd_reason=default graphics_gtk_drawing_area=no; graphics_gtk_drawing_area_reason=default graphics_qt_qpainter=yes; graphics_qt_qpainter_reason=default graphics_opengl=yes; graphics_opengl_reason=default @@ -651,6 +652,30 @@ if test "x$support_libc" = "xyes"; then fi ## graphics +# gd +AC_ARG_ENABLE(graphics-gd, [ --enable-graphics-gd enable graphics type gd], graphics_gd=$enableval;graphics_gd_reason="configure parameter") +if test "x${graphics_gd}" = "xyes" ; then + if test -z "$GDLIB_CONFIG"; then + AC_PATH_PROG([GDLIB_CONFIG], [gdlib-config], []) + fi + AC_MSG_CHECKING([for gdlib with $GDLIB_CONFIG]) + if test ! -x "$GDLIB_CONFIG"; then + if test "x${GDLIB_CONFIG}" = "x" ; then + graphics_gd_reason="$GDLIB_CONFIG not executable" + else + graphics_gd_reason="gdlib-config missing" + fi + graphics_gd=no + AC_MSG_RESULT([no]) + else + GD_CFLAGS="-I`$GDLIB_CONFIG --includedir`" + GD_LIBS="-L`$GDLIB_CONFIG --libdir` -lgd `$GDLIB_CONFIG --libs`" + AC_SUBST(GD_CFLAGS) + AC_SUBST(GD_LIBS) + AC_MSG_RESULT([yes]) + fi +fi +AM_CONDITIONAL(GRAPHICS_GD, test "x${graphics_gd}" = "xyes") # gtk_drawing_area AC_ARG_ENABLE(graphics-gtk-drawing-area, [ --disable-graphics-gtk-drawing-area disable graphics type gtk_drawing_area], graphics_gtk_drawing_area=$enableval;graphics_gtk_drawing_area_reason="configure parameter") AM_CONDITIONAL(GRAPHICS_GTK_DRAWING_AREA, [test "x${graphics_gtk_drawing_area}" = "xyes"]) @@ -742,6 +767,7 @@ navit/fib-1.1/Makefile navit/font/Makefile navit/font/freetype/Makefile navit/graphics/Makefile +navit/graphics/gd/Makefile navit/graphics/gtk_drawing_area/Makefile navit/graphics/directfb/Makefile navit/graphics/cogl/Makefile @@ -859,6 +885,7 @@ echo " gtk_drawing_area: $graphics_gtk_drawing_area ($graphics_gtk_drawing_are echo " qt_qpainter: $graphics_qt_qpainter ($graphics_qt_qpainter_reason)" echo " win32: $graphics_win32 ($graphics_win32_reason)" echo " OpenGL: $graphics_opengl ($graphics_opengl_reason)" +echo " gd: $graphics_gd ($graphics_gd_reason)" echo "GUI types:" echo " gtk: $gui_gtk ($gui_gtk_reason)" diff --git a/navit/navit/graphics/Makefile.am b/navit/navit/graphics/Makefile.am index 10d4bb9..b2298d2 100644 --- a/navit/navit/graphics/Makefile.am +++ b/navit/navit/graphics/Makefile.am @@ -20,3 +20,6 @@ endif if GRAPHICS_WIN32 SUBDIRS+=win32 endif +if GRAPHICS_GD + SUBDIRS+=gd +endif diff --git a/navit/navit/graphics/gd/Makefile.am b/navit/navit/graphics/gd/Makefile.am new file mode 100644 index 0000000..239af87 --- /dev/null +++ b/navit/navit/graphics/gd/Makefile.am @@ -0,0 +1,9 @@ +include $(top_srcdir)/Makefile.inc +AM_CPPFLAGS = @NAVIT_CFLAGS@ @GD_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=graphics_gd +libgraphics_gd_la_LDFLAGS = @GD_LIBS@ +if PLUGINS +modulegraphics_LTLIBRARIES = libgraphics_gd.la +else +noinst_LTLIBRARIES = libgraphics_gd.la +endif +libgraphics_gd_la_SOURCES = graphics_gd.c diff --git a/navit/navit/graphics/gd/graphics_gd.c b/navit/navit/graphics/gd/graphics_gd.c new file mode 100644 index 0000000..730b6f0 --- /dev/null +++ b/navit/navit/graphics/gd/graphics_gd.c @@ -0,0 +1,526 @@ +/** + * Navit, a modular navigation system. + * Copyright (C) 2005-2008 Navit Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include "config.h" +#include "point.h" +#include "graphics.h" +#include "color.h" +#include "plugin.h" +#include "callback.h" +#include "navit.h" +#include "debug.h" +#include "navit/font/freetype/font_freetype.h" + +#define NAVIT_GD_XPM_TRANSPARENCY_HACK + +#ifdef NAVIT_GD_XPM_TRANSPARENCY_HACK +#include + +BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm (char *filename) +{ + XpmInfo info; + XpmImage image; + int i, j, k, number; + char buf[5]; + gdImagePtr im = 0; + int *pointer; + int red = 0, green = 0, blue = 0, alpha = 0; + int *colors; + int ret; + + ret = XpmReadFileToXpmImage (filename, &image, &info); + if (ret != XpmSuccess) + return 0; + + if (!(im = gdImageCreate (image.width, image.height))) + return 0; + + number = image.ncolors; + if (overflow2(sizeof (int), number)) { + return 0; + } + colors = (int *) gdMalloc (sizeof (int) * number); + if (colors == NULL) + return (0); + for (i = 0; i < number; i++) + { + alpha = 0; + switch (strlen (image.colorTable[i].c_color)) + { + case 4: + if (!strcasecmp(image.colorTable[i].c_color,"none")) { + red = 0; + green = 0; + blue = 0; + alpha = 127; + } else { + buf[1] = '\0'; + buf[0] = image.colorTable[i].c_color[1]; + red = strtol (buf, NULL, 16); + + buf[0] = image.colorTable[i].c_color[3]; + green = strtol (buf, NULL, 16); + + buf[0] = image.colorTable[i].c_color[5]; + blue = strtol (buf, NULL, 16); + } + break; + case 7: + buf[2] = '\0'; + buf[0] = image.colorTable[i].c_color[1]; + buf[1] = image.colorTable[i].c_color[2]; + red = strtol (buf, NULL, 16); + + buf[0] = image.colorTable[i].c_color[3]; + buf[1] = image.colorTable[i].c_color[4]; + green = strtol (buf, NULL, 16); + + buf[0] = image.colorTable[i].c_color[5]; + buf[1] = image.colorTable[i].c_color[6]; + blue = strtol (buf, NULL, 16); + break; + case 10: + buf[3] = '\0'; + buf[0] = image.colorTable[i].c_color[1]; + buf[1] = image.colorTable[i].c_color[2]; + buf[2] = image.colorTable[i].c_color[3]; + red = strtol (buf, NULL, 16); + red /= 64; + + buf[0] = image.colorTable[i].c_color[4]; + buf[1] = image.colorTable[i].c_color[5]; + buf[2] = image.colorTable[i].c_color[6]; + green = strtol (buf, NULL, 16); + green /= 64; + + buf[0] = image.colorTable[i].c_color[7]; + buf[1] = image.colorTable[i].c_color[8]; + buf[2] = image.colorTable[i].c_color[9]; + blue = strtol (buf, NULL, 16); + blue /= 64; + break; + case 13: + buf[4] = '\0'; + buf[0] = image.colorTable[i].c_color[1]; + buf[1] = image.colorTable[i].c_color[2]; + buf[2] = image.colorTable[i].c_color[3]; + buf[3] = image.colorTable[i].c_color[4]; + red = strtol (buf, NULL, 16); + red /= 256; + + buf[0] = image.colorTable[i].c_color[5]; + buf[1] = image.colorTable[i].c_color[6]; + buf[2] = image.colorTable[i].c_color[7]; + buf[3] = image.colorTable[i].c_color[8]; + green = strtol (buf, NULL, 16); + green /= 256; + + buf[0] = image.colorTable[i].c_color[9]; + buf[1] = image.colorTable[i].c_color[10]; + buf[2] = image.colorTable[i].c_color[11]; + buf[3] = image.colorTable[i].c_color[12]; + blue = strtol (buf, NULL, 16); + blue /= 256; + break; + } + + + colors[i] = gdImageColorResolveAlpha(im, red, green, blue, alpha); + if (colors[i] == -1) + fprintf (stderr, "ARRRGH\n"); + } + + pointer = (int *) image.data; + for (i = 0; i < image.height; i++) + { + for (j = 0; j < image.width; j++) + { + k = *pointer++; + gdImageSetPixel (im, j, i, colors[k]); + } + } + gdFree (colors); + return (im); +} +#endif + + +struct graphics_priv { + gdImagePtr im; + int w,h; + struct callback *cb; + struct callback_list *cbl; + struct navit *nav; + struct graphics_gc_priv *background; + struct font_freetype_methods freetype_methods; +}; + +struct graphics_gc_priv { + struct graphics_priv *gr; + int color; + int bgcolor; + int width; + unsigned char *dash_list; + int dash_count; + int dash_list_len; +}; + +struct graphics_image_priv { + gdImagePtr im; +}; + + +static void +graphics_destroy(struct graphics_priv *gr) +{ + g_free(gr); +} + +static void +gc_destroy(struct graphics_gc_priv *gc) +{ + if (gc->color != -1) + gdImageColorDeallocate(gc->gr->im, gc->color); + if (gc->bgcolor != -1) + gdImageColorDeallocate(gc->gr->im, gc->bgcolor); + g_free(gc->dash_list); + g_free(gc); +} + +static void +gc_set_linewidth(struct graphics_gc_priv *gc, int w) +{ + gc->width=w; +} + +static void +gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n) +{ + int i,count=0; + g_free(gc->dash_list); + gc->dash_list=g_new(unsigned char, n); + for (i = 0 ; i < n ; i++) { + gc->dash_list[i]=dash_list[i]; + count+=dash_list[i]; + } + gc->dash_list_len=n; + gc->dash_count=count; +} + +static void +gc_set_foreground(struct graphics_gc_priv *gc, struct color *c) +{ + gc->color=gdImageColorAllocate(gc->gr->im, c->r>>8, c->g>>8, c->b>>8); +} + +static void +gc_set_background(struct graphics_gc_priv *gc, struct color *c) +{ + gc->bgcolor=gdImageColorAllocate(gc->gr->im, c->r>>8, c->g>>8, c->b>>8); +} + +static struct graphics_gc_methods gc_methods = { + gc_destroy, + gc_set_linewidth, + gc_set_dashes, + gc_set_foreground, + gc_set_background +}; + +static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth) +{ + struct graphics_gc_priv *ret=g_new0(struct graphics_gc_priv, 1); + ret->gr=gr; + ret->width=1; + ret->color=-1; + ret->bgcolor=-1; + *meth=gc_methods; + return ret; +} + + +static struct graphics_image_priv * +image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, struct point *hot) +{ + FILE *file; + struct graphics_image_priv *ret=NULL; + gdImagePtr im=NULL; + int len; + + if (! name) + return NULL; + len=strlen(name); + if (len < 4) + return NULL; + file=fopen(name,"r"); + if (file) { + if (!strcmp(name+len-4,".png")) + im=gdImageCreateFromPng(file); + else if (!strcmp(name+len-4,".xpm")) + im=gdImageCreateFromXpm(name); + fclose(file); + } + if (im) { + ret=g_new0(struct graphics_image_priv, 1); + ret->im=im; + *w=im->sx; + *h=im->sy; + hot->x=im->sx/2; + hot->y=im->sy/2; + } + return ret; +} + +static void +draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count) +{ + int color[gc->dash_count],cc; + int i,j,k=0; + + if (gc->dash_count) { + cc=gc->color; + for (i = 0 ; i < gc->dash_list_len ; i++) { + for (j = 0 ; j < gc->dash_list[i] ; j++) { + color[k++]=cc; + } + if (cc == gdTransparent) + cc=gc->color; + else + cc=gdTransparent; + } + } + gdImageSetStyle(gr->im, color, gc->dash_count); + gdImageSetThickness(gr->im, gc->width); + gdImageOpenPolygon(gr->im, (gdPointPtr) p, count, gc->dash_count ? gdStyled : gc->color); +} + +static void +draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count) +{ + + gdImageFilledPolygon(gr->im, (gdPointPtr) p, count, gc->color); +} + +static void +draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h) +{ +#if 0 + gdImageFilledRectangle(gr->im, p->x, p->y, p->x+w, p->y+h, gc->color); +#endif +} + +static void +draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r) +{ + gdImageSetStyle(gr->im, NULL, 0); + gdImageSetThickness(gr->im, gc->width); + gdImageArc(gr->im, p->x, p->y, r, r, 0, 360, gc->color); +} + + +static void +draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy) +{ + struct font_freetype_text *t; + struct font_freetype_glyph *g, **gp; + gdImagePtr im; + int i,x,y,w,h; + t=gr->freetype_methods.text_new(text, (struct font_freetype_font *)font, dx, dy); + struct color transparent = {0x0, 0x0, 0x0, 0x7f7f}; + struct color white = {0xffff, 0xffff, 0xffff, 0x0}; + struct color black = {0x0, 0x0, 0x0, 0x0}; + + x=p->x << 6; + y=p->y << 6; + gp=t->glyph; + i=t->glyph_count; + while (i-- > 0) + { + g=*gp++; + w=g->w; + h=g->h; + if (w && h) { + im=gdImageCreateTrueColor(w+2, h+2); + gr->freetype_methods.get_shadow(g,(unsigned char *)(im->tpixels),32,0,&white,&transparent); + gdImageCopy(gr->im, im, ((x+g->x)>>6)-1, ((y+g->y)>>6)-1, 0, 0, w+2, h+2); + gdImageDestroy(im); + } + x+=g->dx; + y+=g->dy; + } + x=p->x << 6; + y=p->y << 6; + gp=t->glyph; + i=t->glyph_count; + while (i-- > 0) + { + g=*gp++; + w=g->w; + h=g->h; + if (w && h) { + im=gdImageCreateTrueColor(w, h); + gr->freetype_methods.get_glyph(g,(unsigned char *)(im->tpixels),32,0,&black,&white,&transparent); + gdImageCopy(gr->im, im, (x+g->x)>>6, (y+g->y)>>6, 0, 0, w, h); + gdImageDestroy(im); + } + x+=g->dx; + y+=g->dy; + } + gr->freetype_methods.text_destroy(t); +} + +static void +draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img) +{ + gdImageCopy(gr->im, img->im, p->x, p->y, 0, 0, img->im->sx, img->im->sy); +} + +static void +draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data) +{ +} + +static void +draw_restore(struct graphics_priv *gr, struct point *p, int w, int h) +{ +} + +static void +background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc) +{ + gr->background=gc; +} + +static void +draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) +{ + FILE *pngout; + dbg(0,"enter\n"); + if (mode == draw_mode_begin && gr->background) { + gdImageFilledRectangle(gr->im, 0, 0, gr->w, gr->h, gr->background->color); + } + if (mode == draw_mode_end) { + pngout=fopen("test.png", "wb"); + gdImagePng(gr->im, pngout); + fclose(pngout); + } +} + +static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h); + +int dummy; + +static void * +get_data(struct graphics_priv *this, char *type) +{ + return &dummy; +} + + +static void +image_free(struct graphics_priv *gr, struct graphics_image_priv *priv) +{ + gdImageDestroy(priv->im); + g_free(priv); +} + +static void +overlay_disable(struct graphics_priv *gr, int disable) +{ + dbg(0,"enter\n"); +} + + + +static struct graphics_methods graphics_methods = { + graphics_destroy, + draw_mode, + draw_lines, + draw_polygon, + draw_rectangle, + draw_circle, + draw_text, + draw_image, + draw_image_warp, + draw_restore, + NULL, + NULL, + gc_new, + background_gc, + overlay_new, + image_new, + get_data, + image_free, + NULL, + overlay_disable, +}; + +static struct graphics_priv * +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h) +{ + *meth=graphics_methods; + return NULL; +} + +static void +emit_callback(struct graphics_priv *priv) +{ + callback_list_call_attr_2(priv->cbl, attr_resize, (void *)priv->w, (void *)priv->h); +} + + +static struct graphics_priv * +graphics_gd_new(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl) +{ + struct font_priv * (*font_freetype_new)(void *meth); + struct graphics_priv *ret; + struct attr *attr; + font_freetype_new=plugin_get_font_type("freetype"); + if (!font_freetype_new) + return NULL; + *meth=graphics_methods; + ret=g_new(struct graphics_priv, 1); + font_freetype_new(&ret->freetype_methods); + meth->font_new=(struct graphics_font_priv *(*)(struct graphics_priv *, struct graphics_font_methods *, char *, int, int))ret->freetype_methods.font_new; + meth->get_text_bbox=ret->freetype_methods.get_text_bbox; + ret->cb=callback_new_attr_1(callback_cast(emit_callback), attr_navit, ret); + navit_add_callback(nav, ret->cb); + ret->cbl=cbl; + ret->nav=nav; + attr=attr_search(attrs, NULL, attr_w); + if (attr) + ret->w=attr->u.num; + else + ret->w=800; + attr=attr_search(attrs, NULL, attr_h); + if (attr) + ret->h=attr->u.num; + else + ret->h=600; + ret->im=gdImageCreateTrueColor(ret->w,ret->h); + return ret; +} + +void +plugin_init(void) +{ + plugin_register_graphics_type("gd", graphics_gd_new); +} -- 2.7.4