summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjkoan <jkoan@gmx.de>2020-06-03 12:35:53 +0200
committerjkoan <jkoan@gmx.de>2020-10-14 13:25:23 +0200
commit77b00a635ddbd3fd8af2ebd228adf9e30c406715 (patch)
treee3401dcfc8e5a7363a13c4382c427a063dee56b6
parent55d64dd5476a9f8cca0db1c93f345ae1defccab3 (diff)
downloadnavit-77b00a635ddbd3fd8af2ebd228adf9e30c406715.tar.gz
graphics:svg_debug:Add initial version of svg_debug
Some TODOs still remaining, but its working good so far
-rwxr-xr-xCMakeLists.txt6
-rw-r--r--navit/graphics/svg_debug/CMakeLists.txt2
-rw-r--r--navit/graphics/svg_debug/graphics_svg_debug.c699
-rw-r--r--navit/navit_shipped.xml15
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).