2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
31 #include "navit/font/freetype/font_freetype.h"
33 #define NAVIT_GD_XPM_TRANSPARENCY_HACK
35 #ifdef NAVIT_GD_XPM_TRANSPARENCY_HACK
38 static void emit_callback(struct graphics_priv *priv);
40 BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm (char *filename)
48 int red = 0, green = 0, blue = 0, alpha = 0;
52 ret = XpmReadFileToXpmImage (filename, &image, &info);
53 if (ret != XpmSuccess)
56 if (!(im = gdImageCreate (image.width, image.height)))
59 number = image.ncolors;
60 if (overflow2(sizeof (int), number)) {
63 colors = (int *) gdMalloc (sizeof (int) * number);
66 for (i = 0; i < number; i++)
69 switch (strlen (image.colorTable[i].c_color))
72 if (!strcasecmp(image.colorTable[i].c_color,"none")) {
79 buf[0] = image.colorTable[i].c_color[1];
80 red = strtol (buf, NULL, 16);
82 buf[0] = image.colorTable[i].c_color[3];
83 green = strtol (buf, NULL, 16);
85 buf[0] = image.colorTable[i].c_color[5];
86 blue = strtol (buf, NULL, 16);
91 buf[0] = image.colorTable[i].c_color[1];
92 buf[1] = image.colorTable[i].c_color[2];
93 red = strtol (buf, NULL, 16);
95 buf[0] = image.colorTable[i].c_color[3];
96 buf[1] = image.colorTable[i].c_color[4];
97 green = strtol (buf, NULL, 16);
99 buf[0] = image.colorTable[i].c_color[5];
100 buf[1] = image.colorTable[i].c_color[6];
101 blue = strtol (buf, NULL, 16);
105 buf[0] = image.colorTable[i].c_color[1];
106 buf[1] = image.colorTable[i].c_color[2];
107 buf[2] = image.colorTable[i].c_color[3];
108 red = strtol (buf, NULL, 16);
111 buf[0] = image.colorTable[i].c_color[4];
112 buf[1] = image.colorTable[i].c_color[5];
113 buf[2] = image.colorTable[i].c_color[6];
114 green = strtol (buf, NULL, 16);
117 buf[0] = image.colorTable[i].c_color[7];
118 buf[1] = image.colorTable[i].c_color[8];
119 buf[2] = image.colorTable[i].c_color[9];
120 blue = strtol (buf, NULL, 16);
125 buf[0] = image.colorTable[i].c_color[1];
126 buf[1] = image.colorTable[i].c_color[2];
127 buf[2] = image.colorTable[i].c_color[3];
128 buf[3] = image.colorTable[i].c_color[4];
129 red = strtol (buf, NULL, 16);
132 buf[0] = image.colorTable[i].c_color[5];
133 buf[1] = image.colorTable[i].c_color[6];
134 buf[2] = image.colorTable[i].c_color[7];
135 buf[3] = image.colorTable[i].c_color[8];
136 green = strtol (buf, NULL, 16);
139 buf[0] = image.colorTable[i].c_color[9];
140 buf[1] = image.colorTable[i].c_color[10];
141 buf[2] = image.colorTable[i].c_color[11];
142 buf[3] = image.colorTable[i].c_color[12];
143 blue = strtol (buf, NULL, 16);
149 colors[i] = gdImageColorResolveAlpha(im, red, green, blue, alpha);
151 fprintf (stderr, "ARRRGH\n");
154 pointer = (int *) image.data;
155 for (i = 0; i < image.height; i++)
157 for (j = 0; j < image.width; j++)
160 gdImageSetPixel (im, j, i, colors[k]);
169 struct graphics_priv {
171 int w,h,flags,alpha,overlay;
174 struct callback_list *cbl;
176 struct graphics_gc_priv *background;
177 struct font_freetype_methods freetype_methods;
178 struct window window;
179 struct graphics_data_image image;
180 struct graphics_priv *next,*overlays;
183 struct graphics_gc_priv {
184 struct graphics_priv *gr;
188 unsigned char *dash_list;
193 struct graphics_image_priv {
199 graphics_destroy(struct graphics_priv *gr)
205 gc_destroy(struct graphics_gc_priv *gc)
208 gdImageColorDeallocate(gc->gr->im, gc->color);
209 if (gc->bgcolor != -1)
210 gdImageColorDeallocate(gc->gr->im, gc->bgcolor);
211 g_free(gc->dash_list);
216 gc_set_linewidth(struct graphics_gc_priv *gc, int w)
222 gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n)
225 g_free(gc->dash_list);
226 gc->dash_list=g_new(unsigned char, n);
227 for (i = 0 ; i < n ; i++) {
228 gc->dash_list[i]=dash_list[i];
232 gc->dash_count=count;
236 gc_set_foreground(struct graphics_gc_priv *gc, struct color *c)
238 gc->color=gdImageColorAllocate(gc->gr->im, c->r>>8, c->g>>8, c->b>>8);
242 gc_set_background(struct graphics_gc_priv *gc, struct color *c)
244 gc->bgcolor=gdImageColorAllocate(gc->gr->im, c->r>>8, c->g>>8, c->b>>8);
247 static struct graphics_gc_methods gc_methods = {
255 static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth)
257 struct graphics_gc_priv *ret=g_new0(struct graphics_gc_priv, 1);
267 static struct graphics_image_priv *
268 image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, struct point *hot, int rotation)
271 struct graphics_image_priv *ret=NULL;
280 file=fopen(name,"r");
282 if (!strcmp(name+len-4,".png"))
283 im=gdImageCreateFromPng(file);
284 else if (!strcmp(name+len-4,".xpm"))
285 im=gdImageCreateFromXpm(name);
289 ret=g_new0(struct graphics_image_priv, 1);
300 draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
302 int color[gc->dash_count],cc;
305 if (gc->dash_count) {
307 for (i = 0 ; i < gc->dash_list_len ; i++) {
308 for (j = 0 ; j < gc->dash_list[i] ; j++) {
311 if (cc == gdTransparent)
316 gdImageSetStyle(gr->im, color, gc->dash_count);
318 gdImageSetThickness(gr->im, gc->width);
319 gdImageOpenPolygon(gr->im, (gdPointPtr) p, count, gc->dash_count ? gdStyled : gc->color);
323 draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
326 gdImageFilledPolygon(gr->im, (gdPointPtr) p, count, gc->color);
330 draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h)
332 gdImageFilledRectangle(gr->im, p->x, p->y, p->x+w, p->y+h, gc->color);
336 draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r)
338 gdImageSetThickness(gr->im, gc->width);
339 gdImageArc(gr->im, p->x, p->y, r, r, 0, 360, gc->color);
344 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)
346 struct font_freetype_text *t;
347 struct font_freetype_glyph *g, **gp;
350 t=gr->freetype_methods.text_new(text, (struct font_freetype_font *)font, dx, dy);
351 struct color transparent = {0x0, 0x0, 0x0, 0x7f7f};
352 struct color white = {0xffff, 0xffff, 0xffff, 0x0};
353 struct color black = {0x0, 0x0, 0x0, 0x0};
365 im=gdImageCreateTrueColor(w+2, h+2);
366 gr->freetype_methods.get_shadow(g,(unsigned char *)(im->tpixels),32,0,&white,&transparent);
367 gdImageCopy(gr->im, im, ((x+g->x)>>6)-1, ((y+g->y)>>6)-1, 0, 0, w+2, h+2);
383 im=gdImageCreateTrueColor(w, h);
384 gr->freetype_methods.get_glyph(g,(unsigned char *)(im->tpixels),32,0,&black,&white,&transparent);
385 gdImageCopy(gr->im, im, (x+g->x)>>6, (y+g->y)>>6, 0, 0, w, h);
391 gr->freetype_methods.text_destroy(t);
395 draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img)
397 gdImageCopy(gr->im, img->im, p->x, p->y, 0, 0, img->im->sx, img->im->sy);
401 draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data)
406 draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
411 draw_drag(struct graphics_priv *gr, struct point *p)
423 background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc)
429 draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
433 if (mode == draw_mode_begin && gr->background) {
434 gdImageFilledRectangle(gr->im, 0, 0, gr->w, gr->h, gr->background->color);
437 if (mode == draw_mode_end && !(gr->flags & 1)) {
438 rename("test.png","test.png.old");
439 pngout=fopen("test.png", "wb");
440 gdImagePng(gr->im, pngout);
445 static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha);
448 get_data(struct graphics_priv *this, char *type)
452 gdImagePtr im = this->im;
453 dbg(1,"type=%s\n",type);
454 if (!strcmp(type,"window"))
455 return &this->window;
456 if (!strcmp(type,"image_png")) {
457 if (this->overlays) {
458 struct graphics_priv *overlay=this->overlays;
459 im=gdImageCreateTrueColor(this->w,this->h);
460 gdImageCopy(im, this->im, 0, 0, 0, 0, this->w, this->h);
462 gdImageCopy(im, overlay->im, overlay->p.x, overlay->p.y, 0, 0, overlay->w, overlay->h);
463 overlay=overlay->next;
466 if (this->image.data)
467 gdFree(this->image.data);
468 this->image.data=gdImagePngPtr(im, &this->image.size);
473 if (sscanf(type,"click_%d_%d_%d",&p.x,&p.y,&b) == 3) {
474 dbg(1,"click %d %d %d\n",p.x,p.y,b);
475 callback_list_call_attr_3(this->cbl, attr_button, (void *)b, (void *)1, (void *)&p);
477 if (sscanf(type,"move_%d_%d",&p.x,&p.y) == 2) {
478 dbg(1,"move %d %d\n",p.x,p.y);
479 callback_list_call_attr_1(this->cbl, attr_motion, (void *)&p);
486 image_free(struct graphics_priv *gr, struct graphics_image_priv *priv)
488 gdImageDestroy(priv->im);
493 overlay_disable(struct graphics_priv *gr, int disable)
499 overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, int alpha, int wraparound)
506 set_attr_do(struct graphics_priv *gr, struct attr *attr, int init)
508 switch (attr->type) {
510 if (gr->w != attr->u.num) {
514 gdImageDestroy(gr->im);
515 gr->im=gdImageCreateTrueColor(gr->w,gr->h);
521 if (gr->h != attr->u.num) {
525 gdImageDestroy(gr->im);
526 gr->im=gdImageCreateTrueColor(gr->w,gr->h);
532 gr->flags=attr->u.num;
542 set_attr(struct graphics_priv *gr, struct attr *attr)
544 return set_attr_do(gr, attr, 0);
547 static struct graphics_methods graphics_methods = {
572 static struct graphics_priv *
573 overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha)
575 struct font_priv * (*font_freetype_new)(void *meth);
576 struct graphics_priv *ret;
579 ret=g_new0(struct graphics_priv, 1);
580 *meth=graphics_methods;
581 font_freetype_new=plugin_get_font_type("freetype");
582 if (!font_freetype_new)
584 font_freetype_new(&ret->freetype_methods);
591 ret->im=gdImageCreateTrueColor(ret->w,ret->h);
592 ret->next=gr->overlays;
599 emit_callback(struct graphics_priv *priv)
601 callback_list_call_attr_2(priv->cbl, attr_resize, (void *)priv->w, (void *)priv->h);
605 static struct graphics_priv *
606 graphics_gd_new(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl)
608 struct font_priv * (*font_freetype_new)(void *meth);
609 struct graphics_priv *ret;
611 event_request_system("glib","graphics_gd_new");
612 font_freetype_new=plugin_get_font_type("freetype");
613 if (!font_freetype_new)
615 *meth=graphics_methods;
616 ret=g_new0(struct graphics_priv, 1);
617 font_freetype_new(&ret->freetype_methods);
618 meth->font_new=(struct graphics_font_priv *(*)(struct graphics_priv *, struct graphics_font_methods *, char *, int, int))ret->freetype_methods.font_new;
619 meth->get_text_bbox=ret->freetype_methods.get_text_bbox;
620 ret->cb=callback_new_attr_1(callback_cast(emit_callback), attr_navit, ret);
621 navit_add_callback(nav, ret->cb);
627 set_attr_do(ret, *attrs, 1);
631 ret->im=gdImageCreateTrueColor(ret->w,ret->h);
638 plugin_register_graphics_type("gd", graphics_gd_new);