diff options
author | jkoan <jkoan@gmx.de> | 2020-06-03 12:35:53 +0200 |
---|---|---|
committer | jkoan <jkoan@gmx.de> | 2020-10-14 13:25:23 +0200 |
commit | 77b00a635ddbd3fd8af2ebd228adf9e30c406715 (patch) | |
tree | e3401dcfc8e5a7363a13c4382c427a063dee56b6 | |
parent | 55d64dd5476a9f8cca0db1c93f345ae1defccab3 (diff) | |
download | navit-77b00a635ddbd3fd8af2ebd228adf9e30c406715.tar.gz |
graphics:svg_debug:Add initial version of svg_debug
Some TODOs still remaining, but its working good so far
-rwxr-xr-x | CMakeLists.txt | 6 | ||||
-rw-r--r-- | navit/graphics/svg_debug/CMakeLists.txt | 2 | ||||
-rw-r--r-- | navit/graphics/svg_debug/graphics_svg_debug.c | 699 | ||||
-rw-r--r-- | navit/navit_shipped.xml | 15 |
4 files changed, 721 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f392e1f92..8eb772104 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,6 +103,7 @@ add_module(graphics/sdl "Required library not found" FALSE) add_module(graphics/egl "Required library not found" FALSE) add_module(graphics/qt_qpainter "Qt libraries not found" FALSE) add_module(graphics/qt5 "Qt5 libraries not found" FALSE) +add_module(graphics/svg_debug "native Glib not found" FALSE) add_module(gui/qml "Qt Declarative not found" FALSE) add_module(gui/qt5_qml "Qt5 Declarative not found" FALSE) add_module(gui/gtk "GTK libs not found" FALSE) @@ -317,7 +318,10 @@ if (NOT HAVE_WORDEXP) endif() if (NOT GLIB2_FOUND) set_with_reason(support/ezxml "Glib not found" TRUE) -endif() +else(NOT GLIB2_FOUND) + set_with_reason(graphics/svg_debug "Glib found" TRUE) +endif(NOT GLIB2_FOUND) + if(FREETYPE_FOUND) pkg_check_modules(FRIBIDI fribidi) diff --git a/navit/graphics/svg_debug/CMakeLists.txt b/navit/graphics/svg_debug/CMakeLists.txt new file mode 100644 index 000000000..2bc202c1e --- /dev/null +++ b/navit/graphics/svg_debug/CMakeLists.txt @@ -0,0 +1,2 @@ +module_add_library(graphics_svg_debug graphics_svg_debug.c) + diff --git a/navit/graphics/svg_debug/graphics_svg_debug.c b/navit/graphics/svg_debug/graphics_svg_debug.c new file mode 100644 index 000000000..1829454fb --- /dev/null +++ b/navit/graphics/svg_debug/graphics_svg_debug.c @@ -0,0 +1,699 @@ +/* + * Navit, a modular navigation system. + * Copyright (C) 2020 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. + */ +/** + * This Plugin can act as a Plugin + * + */ +#include "color.h" +#include <glib.h> +#include "config.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <glib.h> +#include <gio/gio.h> +#include <pthread.h> +#include <poll.h> +#include <signal.h> + +#include "config.h" +#include "debug.h" +#include "point.h" +#include "graphics.h" + +#include "plugin.h" +#include "window.h" +#include "navit.h" +#include "keys.h" +#include "item.h" +#include "attr.h" +#include "item.h" +#include "attr.h" +#include "point.h" +#include "graphics.h" +#include "color.h" +#include "navit.h" +#include "event.h" +#include "debug.h" +#include "callback.h" +#include "util.h" + +struct graphics_priv{ + + unsigned int frame; + int width; + int height; + int fullscreen; + struct color bg_color; + FILE *outfile; + const char *outputdir; + void *proxy_priv; + struct graphics_methods *proxy_graphics_methods; + struct navit *nav; + struct callback_list *cbl; +}; + +struct graphics_font_priv { + int size; + char *font; + struct graphics_font graphics_font_proxy; +}; + +struct graphics_gc_priv { + struct graphics_priv *gr; + int dashed[4]; + int is_dashed; + struct color fg; + struct color bg; + int linewidth; + struct graphics_image_priv *img; + struct graphics_gc_priv *graphics_gc_priv_proxy; + struct graphics_gc_methods *graphics_gc_methods_proxy; +}; + +struct graphics_image_priv { + int w,h; + char *data; + struct graphics_image_priv *graphics_image_priv_proxy; + struct graphics_image_methods *graphics_image_methods; +}; + +static void svg_debug_graphics_destroy(struct graphics_priv *gr) { + // TODO +} + +static void svg_debug_font_destroy(struct graphics_font_priv *this); +void svg_debug_get_text_bbox(struct graphics_priv *gr, struct graphics_font_priv *font, char *text, int dx, int dy, + struct point *ret, int estimate); + +static struct graphics_font_methods font_methods = { + .font_destroy = svg_debug_font_destroy, +}; + +static void resize_callback_do(struct graphics_priv *gr, int w, int h) { + dbg(lvl_debug,"resize_callback w:%i h:%i",w,h) + gr->width=w; + gr->height=h; +} + +static void svg_debug_font_destroy(struct graphics_font_priv *this) { + dbg(lvl_debug, "enter font_destroy" ); + if(this->graphics_font_proxy.meth.font_destroy){ + this->graphics_font_proxy.meth.font_destroy(this->graphics_font_proxy.priv); + } +} + +static struct graphics_font_priv *svg_debug_font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, char *font, + int size, int flags) { + struct graphics_font_priv *priv = g_new(struct graphics_font_priv, 1); + + *meth=font_methods; + + priv->size=size/10; + if(gr->proxy_graphics_methods->font_new){ + priv->graphics_font_proxy.priv=gr->proxy_graphics_methods->font_new(gr->proxy_priv, &priv->graphics_font_proxy.meth, font, size, flags); + } else { + return priv; + } + if(priv->graphics_font_proxy.priv){ + return priv; + } + return NULL; +} +void svg_debug_get_text_bbox(struct graphics_priv *gr, struct graphics_font_priv *font, char *text, int dx, int dy, + struct point *ret, int estimate){ + if(gr->proxy_graphics_methods->get_text_bbox){ + gr->proxy_graphics_methods->get_text_bbox(gr->proxy_priv,font->graphics_font_proxy.priv,text,dx,dy,ret,estimate); + } +} + +static void svg_debug_gc_destroy(struct graphics_gc_priv *gc) { + g_free(gc); +} + +static void svg_debug_gc_set_linewidth(struct graphics_gc_priv *gc, int w) { + gc->linewidth=w; + if(gc->graphics_gc_methods_proxy->gc_set_linewidth){ + gc->graphics_gc_methods_proxy->gc_set_linewidth(gc->graphics_gc_priv_proxy,w); + } + +} + +static void svg_debug_gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n) { + if(n <= 4){ + for (int i = 0; i < 4; ++i) { + gc->dashed[i]=dash_list[i]; + } + } + gc->is_dashed=TRUE; + if(gc->graphics_gc_methods_proxy->gc_set_dashes){ + gc->graphics_gc_methods_proxy->gc_set_dashes(gc->graphics_gc_priv_proxy,w,offset,dash_list,n); + } +} + +static void svg_debug_gc_set_foreground(struct graphics_gc_priv *gc, struct color *c) { + gc->fg.r = c->r/256; + gc->fg.g = c->g/256; + gc->fg.b = c->b/256; + gc->fg.a = c->a/256; + if(gc->graphics_gc_methods_proxy->gc_set_foreground){ + gc->graphics_gc_methods_proxy->gc_set_foreground(gc->graphics_gc_priv_proxy,c); + } +} + +static void svg_debug_gc_set_background(struct graphics_gc_priv *gc, struct color *c) { + gc->bg.r = c->r/256; + gc->bg.g = c->g/256; + gc->bg.b = c->b/256; + gc->bg.a = c->a/256; + if(gc->graphics_gc_methods_proxy->gc_set_foreground){ + gc->graphics_gc_methods_proxy->gc_set_foreground(gc->graphics_gc_priv_proxy,c); + } +} + +static void svg_debug_gc_set_texture(struct graphics_gc_priv *gc, struct graphics_image_priv *img){ + gc->img=img; +} + +static struct graphics_gc_methods gc_methods = { + .gc_destroy = svg_debug_gc_destroy, + .gc_set_linewidth = svg_debug_gc_set_linewidth, + .gc_set_dashes = svg_debug_gc_set_dashes, + .gc_set_foreground = svg_debug_gc_set_foreground, + .gc_set_background = svg_debug_gc_set_background, + .gc_set_texture = svg_debug_gc_set_texture, +}; + +static struct graphics_gc_priv *svg_debug_gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth) { + struct graphics_gc_priv *gc=g_new0(struct graphics_gc_priv, 1); + struct graphics_gc_priv *graphics_gc_priv_proxy = g_new0(struct graphics_gc_priv, 1); + struct graphics_gc_methods *graphics_gc_methods_proxy=g_new0(struct graphics_gc_methods, 1); + *meth=gc_methods; + gc->gr=gr; + gc->is_dashed=FALSE; + gc->linewidth=1; + + if(gr->proxy_graphics_methods->gc_new){ + gr->proxy_graphics_methods->gc_new(gr->proxy_priv,graphics_gc_methods_proxy); + } + gc->graphics_gc_methods_proxy=graphics_gc_methods_proxy; + gc->graphics_gc_priv_proxy=graphics_gc_priv_proxy; + return gc; +} + +void svg_debug_image_destroy(struct graphics_image_priv *img); +void svg_debug_image_destroy(struct graphics_image_priv *img) { + g_free(img->graphics_image_methods); + g_free(img->graphics_image_priv_proxy); + g_free(img->data); + if(img->graphics_image_methods->image_destroy){ + img->graphics_image_methods->image_destroy(img->graphics_image_priv_proxy); + } + g_free(img); +} + +static struct graphics_image_methods image_methods = { + .image_destroy = svg_debug_image_destroy, +}; + +static struct graphics_image_priv *svg_debug_image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *path, + int *w, int *h, struct point *hot, int rotation) { + struct graphics_image_priv *image_priv; + struct graphics_image_methods *graphics_image_methods; + char *base64_data_url; + char *base64_encoded_image; + char *image_mime_type; + char fileext[3] = ""; + char *contents; + gsize img_size; + image_priv = g_new0(struct graphics_image_priv, 1); + graphics_image_methods = g_new0(struct graphics_image_methods, 1); + *meth=image_methods; + const char *data_url_template= "data:%s;base64,%s"; + + if(g_file_get_contents(path,&contents,&img_size,NULL)){ + dbg(lvl_debug,"image_new loaded %s",path); + + strtolower(fileext,&path[(strlen(path)-3)]); + if(strcmp(fileext, "png")){ + image_mime_type="image/png"; + } else if (strcmp(fileext, "jpg")) { + image_mime_type="image/jpeg"; + } else if (strcmp(fileext, "gif")) { + image_mime_type="image/gif"; + } else { + image_mime_type="application/octet-stream"; + } + base64_encoded_image=g_base64_encode((guchar*)contents,img_size); + + base64_data_url=g_malloc0(strlen(base64_encoded_image)+strlen(data_url_template)+strlen(image_mime_type)+1); + sprintf(base64_data_url,data_url_template,image_mime_type,base64_encoded_image); + g_free(base64_encoded_image); + //g_free() + + image_priv->data=base64_data_url; + g_free(contents); + image_priv->h=*h; + image_priv->w=*w; + } else { + dbg(lvl_error,"image_new failed to load %s",path); + image_priv->data="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="; + image_priv->h=1; + image_priv->w=1; + } + if(gr->proxy_graphics_methods->image_new){ + image_priv->graphics_image_priv_proxy= + gr->proxy_graphics_methods->image_new( + gr->proxy_priv,graphics_image_methods,path,w,h,hot,rotation + ); + image_priv->graphics_image_methods=graphics_image_methods; + } + if(image_priv->graphics_image_priv_proxy){ + return image_priv; + } + return NULL; +} + +static void svg_debug_draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count) { + const char *line_template_start = "<polyline points=\""; + const char *coord_template = "%i,%i "; + const char *dashed_template_start = "\" stroke-dasharray=\""; + const char *dashed_dasharray = "%i "; + const char *dashed_template_end = ""; + const char *line_template_end = "\" style=\"fill:none;stroke:rgb(%i,%i,%i);stroke-width:%i\" />\n"; + + fprintf(gr->outfile,line_template_start,""); + for (int i = 0; i < count; i++) { + fprintf(gr->outfile,coord_template,p[i].x,p[i].y); + } + + if (gc->is_dashed) { + fprintf(gr->outfile,dashed_template_start,""); + for (int i = 0; i < 4; i++) { + fprintf(gr->outfile,dashed_dasharray,gc->dashed[i]); + } + fprintf(gr->outfile,dashed_template_end,""); + } + + fprintf(gr->outfile,line_template_end,gc->fg.r,gc->fg.g,gc->fg.b,gc->linewidth); + + if(gr->proxy_graphics_methods->draw_lines){ + gr->proxy_graphics_methods->draw_lines(gr->proxy_priv,gc->graphics_gc_priv_proxy,p,count); + } + +} + +static void svg_debug_draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count) { + const char *coord_template="%i,%i "; + const char *polygon_template_start="<polygon points=\"%s"; + const char *polygon_template_end = "\" style=\"fill:rgb(%i,%i,%i)\" />\n"; + fprintf(gr->outfile,polygon_template_start,""); + for (int i = 0; i < count; i++) { + fprintf(gr->outfile,coord_template,p[i].x,p[i].y); + } + fprintf(gr->outfile,polygon_template_end,gc->fg.r,gc->fg.g,gc->fg.b); + + if(gr->proxy_graphics_methods->draw_polygon){ + gr->proxy_graphics_methods->draw_polygon(gr->proxy_priv,gc->graphics_gc_priv_proxy,p,count); + } + +} + +static void svg_debug_draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h) { + const char *rectangle_template = "<rect x=\"%i\" y=\"%i\" width=\"%i\" height=\"%i\" style=\"fill:rgb(%i,%i,%i)\"></rect>\n"; + fprintf(gr->outfile,rectangle_template,p->x,p->y,w,h,gc->fg.r,gc->fg.g,gc->fg.b); + + if(gr->proxy_graphics_methods->draw_rectangle){ + gr->proxy_graphics_methods->draw_rectangle(gr->proxy_priv,gc->graphics_gc_priv_proxy,p,w,h); + } +} + +static void svg_debug_draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r) { + const char *circle_template = "<circle cx=\"%i\" cy=\"%i\" r=\"%i\" fill=\"rgb(%i,%i,%i)\" />\n"; + fprintf(gr->outfile,circle_template,p->x,p->y,r/2,gc->fg.r,gc->fg.g,gc->fg.b); + + if(gr->proxy_graphics_methods->draw_circle){ + gr->proxy_graphics_methods->draw_circle(gr->proxy_priv,gc->graphics_gc_priv_proxy,p,r); + } + + +} + + +static void svg_debug_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) { + const char *image_template = "<text x=\"%i\" y=\"%i\" fill=\"rgb(%i,%i,%i)\" style=\"font-size: %ipt;\">%s</text>\n"; + if (dx == 0x10000 || dy == 0) { + fprintf(gr->outfile,image_template,p->x,p->y,fg->fg.r,fg->fg.g,fg->fg.b,font? font->size : 0 ,text); + } + if(gr->proxy_graphics_methods->draw_text && font){ + gr->proxy_graphics_methods->draw_text(gr->proxy_priv,fg->graphics_gc_priv_proxy,bg->graphics_gc_priv_proxy,font->graphics_font_proxy.priv,text,p,dx,dy); + } +} + +static void svg_debug_draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, + struct graphics_image_priv *img) { + // Write already encoded image to file + const char *image_template = "<image x=\"%i\" y=\"%i\" width=\"%i\" height=\"%i\" xlink:href=\"%s\"></image>\n"; + fprintf(gr->outfile,image_template,p->x,p->y,img->w,img->h,img->data); + if(gr->proxy_graphics_methods->draw_image){ + gr->proxy_graphics_methods->draw_image(gr->proxy_priv,fg,p,img->graphics_image_priv_proxy); + } +} + +static void svg_debug_draw_drag(struct graphics_priv *gr, struct point *p) { + if(gr->proxy_graphics_methods->draw_drag){ + gr->proxy_graphics_methods->draw_drag(gr->proxy_priv,p); + } +} + +static void svg_debug_background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc) { + if(gr->proxy_graphics_methods->background_gc){ + gr->proxy_graphics_methods->background_gc(gr->proxy_priv,gc->graphics_gc_priv_proxy); + } +} + +static void svg_debug_draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) { + const char *svg_start_template = "<svg height=\"%i\" width=\"%i\" xmlns= \"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n"; + const char *svg_end_template = "</svg>\n"; + char filename[255]; + switch (mode) { + case draw_mode_begin: + if(gr->outfile){ + fprintf(gr->outfile,svg_end_template,""); + fclose(gr->outfile); + gr->frame+=1; + } + sprintf(filename, "%s/svg_debug_frame_%u.svg", gr->outputdir, gr->frame); + gr->outfile = fopen(filename, "w"); + fprintf(gr->outfile,svg_start_template,gr->height,gr->width); + break; + case draw_mode_end: + fprintf(gr->outfile,svg_end_template,""); + fclose(gr->outfile); + gr->frame+=1; + sprintf(filename, "%s/svg_debug_after_frame_%u.svg", gr->outputdir, gr->frame); + gr->outfile = fopen(filename, "w"); + fprintf(gr->outfile,svg_start_template,gr->height,gr->width); + // we need a additional file for drawings without previous begin? + break; + default: + break; + } + if(gr->proxy_graphics_methods->draw_mode){ + gr->proxy_graphics_methods->draw_mode(gr->proxy_priv,mode); + } +} + +static void graphics_svg_debug_overlay_draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) { + // TODO + // https://stackoverflow.com/questions/5451135/embed-svg-in-svg + // more or less like in draw_mode but with different format string + // probably overlay_num so main svg can import it +} + +static struct graphics_priv * graphics_svg_debug_overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, + int w, int h, int wraparound); + +static int graphics_svg_debug_fullscreen(struct window *win, int on) { + struct graphics_priv *graphics_priv = (struct graphics_priv*)win->priv; + struct window *proxy_win; + if(!graphics_priv->proxy_graphics_methods->get_data){ + return 0; + } + proxy_win=graphics_priv->proxy_graphics_methods->get_data(graphics_priv->proxy_priv,"window"); + if(proxy_win){ + return proxy_win->fullscreen(proxy_win,on); + } + return 0; +} + +static gboolean graphics_svg_debug_idle(void *data) { + struct graphics_priv *gr = (struct graphics_priv *)data; + static int first_run=TRUE; + if (first_run){ + callback_list_call_attr_2(gr->cbl, attr_resize, GINT_TO_POINTER(gr->width), GINT_TO_POINTER(gr->height)); + first_run=FALSE; + } + return TRUE; +} + +static void graphics_svg_debug_disable_suspend(struct window *w) { + struct graphics_priv *graphics_priv = (struct graphics_priv*)w->priv; + struct window *proxy_win; + if(!graphics_priv->proxy_graphics_methods->get_data){ + return; + } + proxy_win=graphics_priv->proxy_graphics_methods->get_data(graphics_priv->proxy_priv,"window"); + if(proxy_win){ + proxy_win->disable_suspend(proxy_win); + } + return; +} + +static void *svg_debug_get_data(struct graphics_priv *this, char const *type) { + if (strcmp(type, "window") == 0) { + struct window *win; + win = g_new0(struct window, 1); + win->priv = this; + win->fullscreen = graphics_svg_debug_fullscreen; + win->disable_suspend = graphics_svg_debug_disable_suspend; + return win; + } + if(this->proxy_graphics_methods->get_data){ + // FIXME: This will leak the proxied graphics_priv... But it works for now + return this->proxy_graphics_methods->get_data(this->proxy_priv,type); + } + return NULL; +} + +static void svg_debug_image_free(struct graphics_priv *gr, struct graphics_image_priv *priv) { + if(gr->proxy_graphics_methods->image_free){ + gr->proxy_graphics_methods->image_free(gr->proxy_priv,priv->graphics_image_priv_proxy); + } +} + + +static void graphics_svg_debug_overlay_disable(struct graphics_priv *gr, int disable) { + // TODO +} + +static void graphics_svg_debug_overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, int wraparound) { + // TODO +} + +static struct graphics_methods graphics_methods = { + .graphics_destroy = svg_debug_graphics_destroy, + .draw_mode = svg_debug_draw_mode, + .draw_lines = svg_debug_draw_lines, + .draw_polygon = svg_debug_draw_polygon, + .draw_rectangle = svg_debug_draw_rectangle, + .draw_circle = svg_debug_draw_circle, + .draw_text = svg_debug_draw_text, + // FIXME: Text size calculation is hard, because the svg is + // interpreted by the viewer, so we don't know its size + + .draw_image = svg_debug_draw_image, + .draw_image_warp = NULL, + .draw_drag = svg_debug_draw_drag, + .font_new = svg_debug_font_new, + .gc_new = svg_debug_gc_new, + .background_gc = svg_debug_background_gc, + .overlay_new = NULL, //graphics_svg_debug_overlay_new, // TODO + .image_new = svg_debug_image_new, + .get_data = svg_debug_get_data, + .image_free = svg_debug_image_free, + .get_text_bbox = svg_debug_get_text_bbox, + .overlay_disable = NULL, // graphics_svg_debug_overlay_disable, // TODO + .overlay_resize = NULL, // graphics_svg_debug_overlay_resize, // TODO + .set_attr = NULL, // TODO add proxy + .show_native_keyboard = NULL, // TODO add proxy + .hide_native_keyboard = NULL, // TODO add proxy + .get_dpi = NULL, // TODO add proxy + .draw_polygon_with_holes = NULL, // TODO add proxy + +}; + +static struct graphics_priv *graphics_svg_debug_overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, + int w, int h, int wraparound) { + struct graphics_priv *this=g_new0(struct graphics_priv, 1); + *meth=graphics_methods; + meth->draw_mode=graphics_svg_debug_overlay_draw_mode; + + // TODO + + return this; +} + +static struct graphics_priv *graphics_svg_debug_new(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, + struct callback_list *cbl) { + struct graphics_priv *this=g_new0(struct graphics_priv, 1); + struct graphics_methods *proxy_graphics_methods=g_new0(struct graphics_methods, 1); + struct attr *attr; + void *proxy_priv = NULL; + struct graphics_priv * (*proxy_gra)(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, + struct callback_list *cbl); + + *meth=graphics_methods; + + // Save Parameters for later + this->nav = nav; + this->cbl = cbl; + + // Read configuration + this->width = 32; + if ((attr = attr_search(attrs, NULL, attr_w))) + this->width = attr->u.num; + this->height = 32; + if ((attr = attr_search(attrs, NULL, attr_h))) + this->height = attr->u.num; + + this->outputdir = g_get_tmp_dir(); + if ((attr = attr_search(attrs, NULL, attr_outputdir))) + this->outputdir = attr->u.str; + + // Get prlugin to proxy + proxy_gra=NULL; + if ((attr = attr_search(attrs, NULL, attr_name))) { + if(attr->u.str[0] != '\0'){ + proxy_gra=plugin_get_category_graphics(attr->u.str); + } + if (proxy_gra) { + // Call proxy plugin + proxy_priv=(*proxy_gra)(nav,proxy_graphics_methods,attrs,cbl); + } else { + dbg(lvl_error,"Failed to load graphics plugin %s.", attr->u.str); + return NULL; + } + } else { + if (! event_request_system("glib","graphics_sdl_new")) { + dbg(lvl_error,"event_request_system failed"); + g_free(this); + return NULL; + } + } + + // Save proxy to call it later + this->proxy_priv=proxy_priv; + this->proxy_graphics_methods=proxy_graphics_methods; + this->frame=0; + + // If something tries to write before calling draw_mode with start for the first time + this->outfile=fopen("/dev/null","w"); + + //callbacks = cbl; + g_timeout_add(G_PRIORITY_DEFAULT+10, graphics_svg_debug_idle, this); + + if(!proxy_gra){ + dbg(lvl_debug,"No Proxied plugin, so do not set functions to NULL")// see comment below + callback_list_call_attr_2(cbl, attr_resize, GINT_TO_POINTER(this->width), GINT_TO_POINTER(this->height)); + return this; + } + + // The rest of this function makes sure that svg_debug only supports what the + // proxied graphics plugin supports as well + // for example some graphics plugins don't support circles, but svg_debug does. + // if navit core sees that we support circles we would see it inside the svg, but not + // in the proxied graphics + // + // get_data and draw_mode may not been set to null because they need to exist + if(!this->proxy_graphics_methods->graphics_destroy){ + meth->graphics_destroy=NULL; + } + if(!this->proxy_graphics_methods->draw_lines){ + meth->draw_lines=NULL; + } + if(!this->proxy_graphics_methods->draw_polygon){ + meth->draw_polygon=NULL; + } + if(!this->proxy_graphics_methods->draw_rectangle){ + meth->draw_rectangle=NULL; + } + if(!this->proxy_graphics_methods->draw_circle){ + meth->draw_circle=NULL; + } + if(!this->proxy_graphics_methods->draw_text){ + meth->draw_text=NULL; + } + if(!this->proxy_graphics_methods->draw_image){ + meth->draw_image=NULL; + } + if(!this->proxy_graphics_methods->draw_image_warp){ + meth->draw_image_warp=NULL; + } + if(!this->proxy_graphics_methods->draw_drag){ + meth->draw_drag=NULL; + } + if(!this->proxy_graphics_methods->font_new){ + meth->font_new=NULL; + } + if(!this->proxy_graphics_methods->gc_new){ + meth->gc_new=NULL; + } + if(!this->proxy_graphics_methods->background_gc){ + meth->background_gc=NULL; + } + if(!this->proxy_graphics_methods->overlay_new){ + meth->overlay_new=NULL; + } + if(!this->proxy_graphics_methods->image_new){ + meth->image_new=NULL; + } + if(!this->proxy_graphics_methods->image_free){ + meth->image_free=NULL; + } + if(!this->proxy_graphics_methods->get_text_bbox){ + meth->get_text_bbox=NULL; + } + if(!this->proxy_graphics_methods->overlay_disable){ + meth->overlay_disable=NULL; + } + if(!this->proxy_graphics_methods->overlay_resize){ + meth->overlay_resize=NULL; + } + if(!this->proxy_graphics_methods->set_attr){ + meth->set_attr=NULL; + } + if(!this->proxy_graphics_methods->show_native_keyboard){ + meth->show_native_keyboard=NULL; + } + if(!this->proxy_graphics_methods->hide_native_keyboard){ + meth->hide_native_keyboard=NULL; + } + if(!this->proxy_graphics_methods->get_dpi){ + meth->get_dpi=NULL; + } + if(!this->proxy_graphics_methods->draw_polygon_with_holes){ + meth->draw_polygon_with_holes=NULL; + } + + // Add resize callback so we get called when window is resized so we can adjust the svg size + struct callback *callback = callback_new_attr_1(callback_cast(resize_callback_do), attr_resize, this); + callback_list_add(cbl, callback); + return this; +} + + + +void plugin_init(void) { + dbg(lvl_error,"enter svg_debug plugin_init") + plugin_register_category_graphics("svg_debug", graphics_svg_debug_new); + //plugin_register_category_event("svg_debug", event_svg_debug_new); +} diff --git a/navit/navit_shipped.xml b/navit/navit_shipped.xml index 5473349c7..5c2c404dc 100644 --- a/navit/navit_shipped.xml +++ b/navit/navit_shipped.xml @@ -37,6 +37,21 @@ <navit center="11.5666 48.1333" zoom="256" tracking="1" orientation="-1" recent_dest="250" drag_bitmap="0" default_layout="Car"> <!-- Use one of gtk_drawing_area, qt_qpainter or sdl. On windows systems, use win32 --> <graphics type="gtk_drawing_area"/> + + <!-- + To debug the graphics plugin in question it is possible to proxy it with svg_debug + This way every frame will be written as a svg file. In addition to this the real graphics plugin will + be called. To configure this, set type to svg_debug and the name attribute to the proxied plugin. + Parameters are past to the proxied plugin as well. But resize callbacks currently only passed to the proxied + plugin, and not handled by svg_debug, so resizing the window will not update the width and height of the resulting + scg file. But all calls will still be recorded and written to the file, so you will see those drawing when opening + the svg in an editor like inkscape. + Example: + --> + <!-- + <graphics type="svg_debug" name="sdl2" window_title="Alternative attributes as passed to proxied plugin" w="1000" h="1000" /> + --> + <!-- The following line let you select which graphical user interface you'd like to use. Options include internal (optimized for touch screen devices), gtk (useful for desktop computers). |