diff options
Diffstat (limited to 'navit')
33 files changed, 576 insertions, 411 deletions
diff --git a/navit/CMakeLists.txt b/navit/CMakeLists.txt index d0d57e230..daf8abe8d 100644 --- a/navit/CMakeLists.txt +++ b/navit/CMakeLists.txt @@ -107,12 +107,11 @@ if (DEFINED NAVIT_COMPILE_FLAGS) set_target_properties(${NAVIT_LIBNAME} PROPERTIES COMPILE_FLAGS "${NAVIT_COMPILE_FLAGS}") endif() -# Subversion revision ADD_CUSTOM_TARGET( - version + git_version ${CMAKE_COMMAND} -D SRC=${CMAKE_CURRENT_SOURCE_DIR}/version.h.in -D DST=${CMAKE_CURRENT_BINARY_DIR}/version.h - -D NAME=SVN_VERSION + -D NAME="GIT_VERSION" -P ${PROJECT_SOURCE_DIR}/cmake/version.cmake ) @@ -153,7 +152,7 @@ else() add_custom_target( navit_config_xml ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/navit.xml) endif() -ADD_DEPENDENCIES(${NAVIT_LIBNAME} version) +ADD_DEPENDENCIES(${NAVIT_LIBNAME} git_version) if (USE_LIBGNUINTL AND NOT HAVE_GLIB) ADD_DEPENDENCIES(support_glib support_gettext_intl) endif() diff --git a/navit/android/AndroidManifest.xml.cmake b/navit/android/AndroidManifest.xml.cmake index c70ab66aa..9267f65a3 100644 --- a/navit/android/AndroidManifest.xml.cmake +++ b/navit/android/AndroidManifest.xml.cmake @@ -5,7 +5,7 @@ android:versionCode="@ANDROID_VERSION_INT@" android:versionName="@ANDROID_VERSION_NAME@-@ANDROID_VERSION_INT@" android:installLocation="auto"> - <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="@ANDROID_API_VERSION@"/> + <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="@ANDROID_API_VERSION@"/> <uses-feature android:name="android.hardware.location.network" android:required="false"/> <uses-feature android:name="android.hardware.touchscreen" android:required="false"/> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:resizeable="true" android:anyDensity="true"/> @@ -20,8 +20,7 @@ android:name=".NavitAppConfig"> <activity android:name="Navit" android:label="@string/app_name" - android:theme="@android:style/Theme.NoTitleBar" - android:configChanges="locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale"> + android:configChanges="locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/navit/android/AndroidManifest.xml.in b/navit/android/AndroidManifest.xml.in index 09e8410ff..5a43ee277 100644 --- a/navit/android/AndroidManifest.xml.in +++ b/navit/android/AndroidManifest.xml.in @@ -10,8 +10,7 @@ android:name=".NavitAppConfig"> <activity android:name="Navit" android:label="@string/app_name" - android:theme="@android:style/Theme.NoTitleBar" - android:configChanges="locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale"> + android:configChanges="locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> @@ -27,7 +26,7 @@ <activity android:name=".NavitAddressResultListActivity"></activity> <activity android:name=".FileBrowserActivity"></activity> </application> - <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="8"/> + <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19"/> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:resizeable="true" android:anyDensity="true"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> diff --git a/navit/android/src/org/navitproject/navit/NavitGraphics.java b/navit/android/src/org/navitproject/navit/NavitGraphics.java index fc4944240..5817f4773 100644 --- a/navit/android/src/org/navitproject/navit/NavitGraphics.java +++ b/navit/android/src/org/navitproject/navit/NavitGraphics.java @@ -161,24 +161,16 @@ public class NavitGraphics canvas.drawBitmap(draw_bitmap, pos_x, pos_y, null); if (overlay_disabled == 0) { - //Log.e("NavitGraphics", "view -> onDraw 1"); // assume we ARE in map view mode! in_map = true; - - Object overlays_array[]; - overlays_array = overlays.toArray(); - for (Object overlay : overlays_array) + for (NavitGraphics overlay : overlays) { - //Log.e("NavitGraphics","view -> onDraw 2"); - - NavitGraphics overlay_graphics = (NavitGraphics) overlay; - if (overlay_graphics.overlay_disabled == 0) + if (overlay.overlay_disabled == 0) { - //Log.e("NavitGraphics","view -> onDraw 3"); - Rect r=overlay_graphics.get_rect(); - canvas.drawBitmap(overlay_graphics.draw_bitmap, r.left, r.top, null); + Rect r=overlay.get_rect(); + canvas.drawBitmap(overlay.draw_bitmap, r.left, r.top, null); } - } + } } else { @@ -196,7 +188,7 @@ public class NavitGraphics } } } - + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { @@ -694,7 +686,7 @@ public class NavitGraphics } public NavitGraphics(final Activity activity, NavitGraphics parent, int x, int y, int w, int h, - int alpha, int wraparound, int use_camera) + int wraparound, int use_camera) { if (parent == null) { @@ -1015,7 +1007,7 @@ public class NavitGraphics } } - protected void overlay_resize(int x, int y, int w, int h, int alpha, int wraparound) + protected void overlay_resize(int x, int y, int w, int h, int wraparound) { //Log.e("NavitGraphics","overlay_resize"); draw_bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); diff --git a/navit/color.h b/navit/color.h index f086eab84..dee10a187 100644 --- a/navit/color.h +++ b/navit/color.h @@ -24,6 +24,7 @@ struct color { int r,g,b,a; }; +#define COLOR_BITDEPTH 16 #define COLOR_WHITE_ 0xffff,0xffff,0xffff,0xffff #define COLOR_BLACK_ 0x0000,0x0000,0x0000,0xffff #define COLOR_BACKGROUND_ 0xffff, 0xefef, 0xb7b7, 0xffff diff --git a/navit/font/freetype/font_freetype.c b/navit/font/freetype/font_freetype.c index 131bd87e8..f4359fb90 100644 --- a/navit/font/freetype/font_freetype.c +++ b/navit/font/freetype/font_freetype.c @@ -53,6 +53,9 @@ #endif #endif +#define COLOR_BITDEPTH_OUTPUT 8 +#define COL_SHIFT (COLOR_BITDEPTH-COLOR_BITDEPTH_OUTPUT) + struct font_freetype_font { int size; #if USE_CACHING @@ -552,19 +555,19 @@ font_freetype_glyph_get_shadow(struct font_freetype_glyph *g, bg=0x00; break; case 8: - fg=foreground->a>>8; - bg=background->a>>8; + fg=foreground->a>>COL_SHIFT; + bg=background->a>>COL_SHIFT; break; case 24: case 32: - fg=((foreground->a>>8)<<24)| - ((foreground->r>>8)<<16)| - ((foreground->g>>8)<<8)| - ((foreground->b>>8)<<0); - bg=((background->a>>8)<<24)| - ((background->r>>8)<<16)| - ((background->g>>8)<<8)| - ((background->b>>8)<<0); + fg=((foreground->a>>COL_SHIFT)<<24)| + ((foreground->r>>COL_SHIFT)<<16)| + ((foreground->g>>COL_SHIFT)<<8)| + ((foreground->b>>COL_SHIFT)<<0); + bg=((background->a>>COL_SHIFT)<<24)| + ((background->r>>COL_SHIFT)<<16)| + ((background->g>>COL_SHIFT)<<8)| + ((background->b>>COL_SHIFT)<<0); break; default: return 0; @@ -710,14 +713,14 @@ font_freetype_glyph_get_glyph(struct font_freetype_glyph *g, unsigned char v,vi,*pm, *ps; switch (depth) { case 8: - tr=transparent->a>>8; + tr=transparent->a>>COL_SHIFT; break; case 24: case 32: - tr=((transparent->a>>8)<<24)| - ((transparent->r>>8)<<16)| - ((transparent->g>>8)<<8)| - ((transparent->b>>8)<<0); + tr=((transparent->a>>COL_SHIFT)<<24)| + ((transparent->r>>COL_SHIFT)<<16)| + ((transparent->g>>COL_SHIFT)<<8)| + ((transparent->b>>COL_SHIFT)<<0); break; default: return 0; @@ -747,9 +750,9 @@ font_freetype_glyph_get_glyph(struct font_freetype_glyph *g, v=*pm; if (v) { vi=255-v; - ps[0]=(((fg->r*v+bg->r*vi)/255)>>8); - ps[1]=(((fg->g*v+bg->g*vi)/255)>>8); - ps[2]=(((fg->b*v+bg->b*vi)/255)>>8); + ps[0]=(((fg->r*v+bg->r*vi)/255)>>COL_SHIFT); + ps[1]=(((fg->g*v+bg->g*vi)/255)>>COL_SHIFT); + ps[2]=(((fg->b*v+bg->b*vi)/255)>>COL_SHIFT); } else { ps[0]=tr >> 16; ps[1]=tr >> 8; @@ -765,10 +768,10 @@ font_freetype_glyph_get_glyph(struct font_freetype_glyph *g, if (v) { vi=255-v; ((unsigned int *)ps)[0]= - ((((fg->a*v+bg->a*vi)/255)>>8)<<24)| - ((((fg->r*v+bg->r*vi)/255)>>8)<<16)| - ((((fg->g*v+bg->g*vi)/255)>>8)<<8)| - ((((fg->b*v+bg->b*vi)/255)>>8)<<0); + ((((fg->a*v+bg->a*vi)/255)>>COL_SHIFT)<<24)| + ((((fg->r*v+bg->r*vi)/255)>>COL_SHIFT)<<16)| + ((((fg->g*v+bg->g*vi)/255)>>COL_SHIFT)<<8)| + ((((fg->b*v+bg->b*vi)/255)>>COL_SHIFT)<<0); } else ((unsigned int *)ps)[0]=tr; ps+=4; diff --git a/navit/graphics.c b/navit/graphics.c index 64611acdc..44993b3e3 100644 --- a/navit/graphics.c +++ b/navit/graphics.c @@ -58,6 +58,15 @@ //# Comment: //# Authors: Martin Schaller (04/2008) //############################################################################################################## +/** + * @brief graphics object + * A graphics object serves as the target for drawing operations. + * It encapsulates various settings, and a drawing target, such as an image buffer or a window. + * Currently, in Navit, there is always one main graphics object, which is used to draw the + * map, and optionally additional graphics objects for overlays. + * @see graphics_overlay_new() + * @see struct graphics_gc + */ struct graphics { struct graphics* parent; @@ -272,19 +281,31 @@ int graphics_get_attr(struct graphics *this_, enum attr_type type, struct attr * } /** - * FIXME - * @param <> - * @returns <> + * @brief Create a new graphics overlay. + * An overlay is a graphics object that is independent of the main graphics object. When + * drawing everything to a window, the overlay will be shown on top of the main graphics + * object. Navit uses overlays for OSD elements and for the vehicle on the map. + * This allows updating OSD elements and the vehicle without redrawing the map. + * + * @param parent parent graphics context (should be the main graphics context as returned by + * graphics_new) + * @param p drawing position for the overlay + * @param w width of overlay + * @param h height of overlay + * @param wraparound use wraparound (0/1). If set, position, width and height "wrap around": + * negative position coordinates wrap around the window, negative width/height specify + * difference to window width/height. + * @returns new overlay * @author Martin Schaller (04/2008) */ -struct graphics * graphics_overlay_new(struct graphics *parent, struct point *p, int w, int h, int alpha, int wraparound) +struct graphics * graphics_overlay_new(struct graphics *parent, struct point *p, int w, int h, int wraparound) { struct graphics *this_; struct point_rect pr; if (!parent->meth.overlay_new) return NULL; this_=g_new0(struct graphics, 1); - this_->priv=parent->meth.overlay_new(parent->priv, &this_->meth, p, w, h, alpha, wraparound); + this_->priv=parent->meth.overlay_new(parent->priv, &this_->meth, p, w, h, wraparound); this_->image_cache_hash = parent->image_cache_hash; this_->parent = parent; pr.lu.x=0; @@ -301,23 +322,22 @@ struct graphics * graphics_overlay_new(struct graphics *parent, struct point *p, } /** - * @brief Alters the size, position, alpha and wraparound for an overlay + * @brief Alters the size, position and wraparound for an overlay * * @param this_ The overlay's graphics struct * @param p The new position of the overlay * @param w The new width of the overlay * @param h The new height of the overlay - * @param alpha The new alpha of the overlay * @param wraparound The new wraparound of the overlay */ void -graphics_overlay_resize(struct graphics *this_, struct point *p, int w, int h, int alpha, int wraparound) +graphics_overlay_resize(struct graphics *this_, struct point *p, int w, int h, int wraparound) { if (! this_->meth.overlay_resize) { return; } - this_->meth.overlay_resize(this_->priv, p, w, h, alpha, wraparound); + this_->meth.overlay_resize(this_->priv, p, w, h, wraparound); } static void @@ -467,9 +487,9 @@ void graphics_font_destroy_all(struct graphics *gra) } /** - * FIXME - * @param <> - * @returns <> + * Create a new graphics context. + * @param gra associated graphics object for the new context + * @returns new graphics context * @author Martin Schaller (04/2008) */ struct graphics_gc * graphics_gc_new(struct graphics *gra) @@ -483,9 +503,8 @@ struct graphics_gc * graphics_gc_new(struct graphics *gra) } /** - * FIXME - * @param <> - * @returns <> + * Destroy a graphics context, freeing associated resources. + * @param gc context to destroy * @author Martin Schaller (04/2008) */ void graphics_gc_destroy(struct graphics_gc *gc) @@ -530,9 +549,9 @@ graphics_convert_color(struct graphics *gra, struct color *in, struct color *out } /** - * FIXME - * @param <> - * @returns <> + * Set foreground color. + * @param gc graphics context to set color for + * @param c color to set * @author Martin Schaller (04/2008) */ void graphics_gc_set_foreground(struct graphics_gc *gc, struct color *c) @@ -849,9 +868,9 @@ void graphics_image_free(struct graphics *gra, struct graphics_image *img) } /** - * FIXME - * @param <> - * @returns <> + * Report the beginning or the end of a set of drawing operations. + * @param this_ graphics object that is being drawn to + * @param mode specify beginning or end of drawing * @author Martin Schaller (04/2008) */ void graphics_draw_mode(struct graphics *this_, enum draw_mode_num mode) diff --git a/navit/graphics.h b/navit/graphics.h index f1e782f0b..810355f2d 100644 --- a/navit/graphics.h +++ b/navit/graphics.h @@ -73,13 +73,13 @@ struct graphics_methods { struct graphics_font_priv *(*font_new)(struct graphics_priv *gr, struct graphics_font_methods *meth, char *font, int size, int flags); struct graphics_gc_priv *(*gc_new)(struct graphics_priv *gr, struct graphics_gc_methods *meth); void (*background_gc)(struct graphics_priv *gr, struct graphics_gc_priv *gc); - struct graphics_priv *(*overlay_new)(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound); + struct graphics_priv *(*overlay_new)(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound); struct graphics_image_priv *(*image_new)(struct graphics_priv *gr, struct graphics_image_methods *meth, char *path, int *w, int *h, struct point *hot, int rotation); void *(*get_data)(struct graphics_priv *gr, const char *type); void (*image_free)(struct graphics_priv *gr, struct graphics_image_priv *priv); void (*get_text_bbox)(struct graphics_priv *gr, struct graphics_font_priv *font, char *text, int dx, int dy, struct point *ret, int estimate); void (*overlay_disable)(struct graphics_priv *gr, int disable); - void (*overlay_resize)(struct graphics_priv *gr, struct point *p, int w, int h, int alpha, int wraparound); + void (*overlay_resize)(struct graphics_priv *gr, struct point *p, int w, int h, int wraparound); int (*set_attr)(struct graphics_priv *gr, struct attr *attr); }; @@ -101,6 +101,11 @@ struct graphics_gc_methods { void (*gc_set_background)(struct graphics_gc_priv *gc, struct color *c); }; +/** + * @brief graphics context + * A graphics context encapsulates a set of drawing parameters, such as + * linewidth and drawing color. + */ struct graphics_gc { struct graphics_gc_priv *priv; struct graphics_gc_methods meth; @@ -150,8 +155,8 @@ int graphics_set_attr(struct graphics *gra, struct attr *attr); void graphics_set_rect(struct graphics *gra, struct point_rect *pr); struct graphics *graphics_new(struct attr *parent, struct attr **attrs); int graphics_get_attr(struct graphics *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter); -struct graphics *graphics_overlay_new(struct graphics *parent, struct point *p, int w, int h, int alpha, int wraparound); -void graphics_overlay_resize(struct graphics *this_, struct point *p, int w, int h, int alpha, int wraparound); +struct graphics *graphics_overlay_new(struct graphics *parent, struct point *p, int w, int h, int wraparound); +void graphics_overlay_resize(struct graphics *this_, struct point *p, int w, int h, int wraparound); void graphics_init(struct graphics *this_); void *graphics_get_data(struct graphics *this_, const char *type); void graphics_add_callback(struct graphics *this_, struct callback *cb); diff --git a/navit/graphics/android/graphics_android.c b/navit/graphics/android/graphics_android.c index 362e3d9d0..a543252ce 100644 --- a/navit/graphics/android/graphics_android.c +++ b/navit/graphics/android/graphics_android.c @@ -414,7 +414,7 @@ draw_mode(struct graphics_priv *gra, enum draw_mode_num mode) (*jnienv)->CallVoidMethod(jnienv, gra->NavitGraphics, gra->NavitGraphics_draw_mode, (int)mode); } -static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound); +static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound); static void * get_data(struct graphics_priv *this, const char *type) @@ -451,9 +451,9 @@ static void overlay_disable(struct graphics_priv *gra, int disable) (*jnienv)->CallVoidMethod(jnienv, gra->NavitGraphics, gra->NavitGraphics_overlay_disable, disable); } -static void overlay_resize(struct graphics_priv *gra, struct point *pnt, int w, int h, int alpha, int wraparound) +static void overlay_resize(struct graphics_priv *gra, struct point *pnt, int w, int h, int wraparound) { - (*jnienv)->CallVoidMethod(jnienv, gra->NavitGraphics, gra->NavitGraphics_overlay_resize, pnt ? pnt->x:0 , pnt ? pnt->y:0, w, h, alpha, wraparound); + (*jnienv)->CallVoidMethod(jnienv, gra->NavitGraphics, gra->NavitGraphics_overlay_resize, pnt ? pnt->x:0 , pnt ? pnt->y:0, w, h, wraparound); } static int @@ -550,7 +550,7 @@ set_activity(jobject graphics) } static int -graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, struct point *pnt, int w, int h, int alpha, int wraparound, int use_camera) +graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, struct point *pnt, int w, int h, int wraparound, int use_camera) { struct callback *cb; jmethodID cid, Context_getPackageName; @@ -603,13 +603,13 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s if (!find_class_global("org/navitproject/navit/NavitGraphics", &ret->NavitGraphicsClass)) return 0; dbg(lvl_debug,"at 3\n"); - cid = (*jnienv)->GetMethodID(jnienv, ret->NavitGraphicsClass, "<init>", "(Landroid/app/Activity;Lorg/navitproject/navit/NavitGraphics;IIIIIII)V"); + cid = (*jnienv)->GetMethodID(jnienv, ret->NavitGraphicsClass, "<init>", "(Landroid/app/Activity;Lorg/navitproject/navit/NavitGraphics;IIIIII)V"); if (cid == NULL) { dbg(lvl_error,"no method found\n"); return 0; /* exception thrown */ } dbg(lvl_debug,"at 4 android_activity=%p\n",android_activity); - ret->NavitGraphics=(*jnienv)->NewObject(jnienv, ret->NavitGraphicsClass, cid, android_activity, parent ? parent->NavitGraphics : NULL, pnt ? pnt->x:0 , pnt ? pnt->y:0, w, h, alpha, wraparound, use_camera); + ret->NavitGraphics=(*jnienv)->NewObject(jnienv, ret->NavitGraphicsClass, cid, android_activity, parent ? parent->NavitGraphics : NULL, pnt ? pnt->x:0 , pnt ? pnt->y:0, w, h, wraparound, use_camera); dbg(lvl_debug,"result=%p\n",ret->NavitGraphics); if (ret->NavitGraphics) ret->NavitGraphics = (*jnienv)->NewGlobalRef(jnienv, ret->NavitGraphics); @@ -675,7 +675,7 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s return 0; if (!find_method(ret->NavitGraphicsClass, "overlay_disable", "(I)V", &ret->NavitGraphics_overlay_disable)) return 0; - if (!find_method(ret->NavitGraphicsClass, "overlay_resize", "(IIIIII)V", &ret->NavitGraphics_overlay_resize)) + if (!find_method(ret->NavitGraphicsClass, "overlay_resize", "(IIIII)V", &ret->NavitGraphics_overlay_resize)) return 0; if (!find_method(ret->NavitGraphicsClass, "SetCamera", "(I)V", &ret->NavitGraphics_SetCamera)) return 0; @@ -745,7 +745,7 @@ graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct at command_add_table(attr->u.callback_list, commands, sizeof(commands)/sizeof(struct command_table), ret); } image_cache_hash = g_hash_table_new(g_str_hash, g_str_equal); - if (graphics_android_init(ret, NULL, NULL, 0, 0, 0, 0, use_camera)) { + if (graphics_android_init(ret, NULL, NULL, 0, 0, 0, use_camera)) { dbg(lvl_debug,"returning %p\n",ret); return ret; } else { @@ -755,11 +755,11 @@ graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct at } static struct graphics_priv * -overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound) +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound) { struct graphics_priv *ret=g_new0(struct graphics_priv, 1); *meth=graphics_methods; - if (graphics_android_init(ret, gr, p, w, h, alpha, wraparound, 0)) { + if (graphics_android_init(ret, gr, p, w, h, wraparound, 0)) { dbg(lvl_debug,"returning %p\n",ret); return ret; } else { diff --git a/navit/graphics/cocoa/graphics_cocoa.m b/navit/graphics/cocoa/graphics_cocoa.m index e9aec60cb..154ea6901 100644 --- a/navit/graphics/cocoa/graphics_cocoa.m +++ b/navit/graphics/cocoa/graphics_cocoa.m @@ -556,7 +556,7 @@ background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc) } static struct graphics_priv * -overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound); +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound); static struct graphics_image_priv * @@ -649,7 +649,7 @@ static struct graphics_methods graphics_methods = { static struct graphics_priv * -overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound) +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound) { struct graphics_priv *ret=g_new0(struct graphics_priv, 1); *meth=graphics_methods; diff --git a/navit/graphics/gd/graphics_gd.c b/navit/graphics/gd/graphics_gd.c index 06d63ac2f..b4991f30a 100644 --- a/navit/graphics/gd/graphics_gd.c +++ b/navit/graphics/gd/graphics_gd.c @@ -195,7 +195,7 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm (char *filename) struct graphics_priv { gdImagePtr im; - int w,h,flags,alpha,overlay,shmkey,shmsize,shmoffset; + int w,h,flags,overlay,shmkey,shmsize,shmoffset; void *shm; struct shmem_header *shm_header; struct point p; @@ -547,7 +547,7 @@ draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) } } -static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha); +static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound); static void add_overlays(struct graphics_priv *overlay, gdImagePtr im) @@ -633,7 +633,7 @@ overlay_disable(struct graphics_priv *gr, int disable) } static void -overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, int alpha, int wraparound) +overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, int wraparound) { dbg(lvl_debug,"enter\n"); } @@ -816,7 +816,7 @@ static struct graphics_methods graphics_methods = { }; static struct graphics_priv * -overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha) +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound) { struct font_priv * (*font_freetype_new)(void *meth); struct graphics_priv *ret; @@ -831,7 +831,6 @@ overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct poin ret->p=*p; ret->w=w; ret->h=h; - ret->alpha=alpha; ret->overlay=1; ret->flags=1; ret->im=gdImageCreateTrueColor(ret->w,ret->h); diff --git a/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c b/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c index 21fcee88f..332673529 100644 --- a/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c +++ b/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c @@ -22,8 +22,10 @@ #include <stdlib.h> #include <signal.h> #include <sys/time.h> +#include <math.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> +#include <cairo.h> #include <locale.h> /* For WIN32 */ #if !defined(GDK_Book) || !defined(GDK_Calendar) #include <X11/XF86keysym.h> @@ -62,11 +64,8 @@ struct graphics_priv { GtkWidget *widget; GtkWidget *win; struct window window; - GdkDrawable *drawable; - GdkColormap *colormap; + cairo_t *cairo; struct point p; - struct point pclean; - int cleanup; int width; int height; int win_w; @@ -74,13 +73,11 @@ struct graphics_priv { int visible; int overlay_disabled; int overlay_autodisabled; - int a; int wraparound; struct graphics_priv *parent; struct graphics_priv *overlays; struct graphics_priv *next; struct graphics_gc_priv *background_gc; - enum draw_mode_num mode; struct callback_list *cbl; struct font_freetype_methods freetype_methods; struct navit *nav; @@ -94,10 +91,12 @@ struct graphics_priv { struct graphics_gc_priv { - GdkGC *gc; - GdkPixmap *pixmap; struct graphics_priv *gr; struct color c; + double linewidth; + double *dashes; + int ndashes; + double offset; }; struct graphics_image_priv { @@ -129,50 +128,41 @@ graphics_destroy(struct graphics_priv *gr) static void gc_destroy(struct graphics_gc_priv *gc) { - g_object_unref(gc->gc); g_free(gc); } static void gc_set_linewidth(struct graphics_gc_priv *gc, int w) { - gdk_gc_set_line_attributes(gc->gc, w, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); + gc->linewidth = w; } static void gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n) { - gdk_gc_set_dashes(gc->gc, offset, (gint8 *)dash_list, n); - gdk_gc_set_line_attributes(gc->gc, w, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND); -} - -static void -gc_set_color(struct graphics_gc_priv *gc, struct color *c, int fg) -{ - GdkColor gdkc; - gdkc.pixel=0; - gdkc.red=c->r; - gdkc.green=c->g; - gdkc.blue=c->b; - gdk_colormap_alloc_color(gc->gr->colormap, &gdkc, FALSE, TRUE); - gdk_colormap_query_color(gc->gr->colormap, gdkc.pixel, &gdkc); - gc->c=*c; - if (fg) { - gdk_gc_set_foreground(gc->gc, &gdkc); - } else - gdk_gc_set_background(gc->gc, &gdkc); + int i; + g_free(gc->dashes); + gc->ndashes=n; + gc->offset=offset; + if(n) { + gc->dashes=g_malloc_n(n, sizeof(double)); + for (i=0; i<n; i++) { + gc->dashes[i]=dash_list[i]; + } + } else { + gc->dashes=NULL; + } } static void gc_set_foreground(struct graphics_gc_priv *gc, struct color *c) { - gc_set_color(gc, c, 1); + gc->c=*c; } static void gc_set_background(struct graphics_gc_priv *gc, struct color *c) { - gc_set_color(gc, c, 0); } static struct graphics_gc_methods gc_methods = { @@ -188,8 +178,17 @@ static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics struct graphics_gc_priv *gc=g_new(struct graphics_gc_priv, 1); *meth=gc_methods; - gc->gc=gdk_gc_new(gr->widget->window); gc->gr=gr; + + gc->linewidth=1; + gc->c.r=0; + gc->c.g=0; + gc->c.b=0; + gc->c.a=0; + gc->dashes=NULL; + gc->ndashes=0; + gc->offset=0; + return gc; } @@ -278,37 +277,83 @@ image_free(struct graphics_priv *gr, struct graphics_image_priv *priv) } static void +set_drawing_color(cairo_t *cairo, struct color c) +{ + double col_max = 1<<COLOR_BITDEPTH; + cairo_set_source_rgba(cairo, c.r/col_max, c.g/col_max, c.b/col_max, c.a/col_max); +} + +static void +set_stroke_params_from_gc(cairo_t *cairo, struct graphics_gc_priv *gc) +{ + set_drawing_color(cairo, gc->c); + cairo_set_dash(cairo, gc->dashes, gc->ndashes, gc->offset); + cairo_set_line_width(cairo, gc->linewidth); +} + +static void draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count) { - gdk_draw_lines(gr->drawable, gc->gc, (GdkPoint *)p, count); + int i; + if (!count) + return; + cairo_move_to(gr->cairo, p[0].x, p[0].y); + for (i=1; i<count; i++) { + cairo_line_to(gr->cairo, p[i].x, p[i].y); + } + set_stroke_params_from_gc(gr->cairo, gc); + cairo_stroke(gr->cairo); } static void draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count) { - gdk_draw_polygon(gr->drawable, gc->gc, TRUE, (GdkPoint *)p, count); + int i; + set_drawing_color(gr->cairo, gc->c); + cairo_move_to(gr->cairo, p[0].x, p[0].y); + for (i=1; i<count; i++) { + cairo_line_to(gr->cairo, p[i].x, p[i].y); + } + cairo_fill(gr->cairo); } static void draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h) { - gdk_draw_rectangle(gr->drawable, gc->gc, TRUE, p->x, p->y, w, h); + cairo_save(gr->cairo); + // Use OPERATOR_SOURCE to overwrite old contents even when drawing with transparency. + // Necessary for OSD drawing. + cairo_set_operator(gr->cairo, CAIRO_OPERATOR_SOURCE); + cairo_rectangle(gr->cairo, p->x, p->y, w, h); + set_drawing_color(gr->cairo, gc->c); + cairo_fill(gr->cairo); + cairo_restore(gr->cairo); } static void draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r) { - gdk_draw_arc(gr->drawable, gc->gc, FALSE, p->x-r/2, p->y-r/2, r, r, 0, 64*360); + cairo_arc (gr->cairo, p->x, p->y, r/2, 0.0, 2*M_PI); + set_stroke_params_from_gc(gr->cairo, gc); + cairo_stroke(gr->cairo); } static void -display_text_draw(struct font_freetype_text *text, struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, int color, struct point *p) +draw_rgb_image_buffer(cairo_t *cairo, int buffer_width, int buffer_height, int draw_pos_x, int draw_pos_y, int stride, unsigned char *buffer) +{ + cairo_surface_t *buffer_surface = cairo_image_surface_create_for_data( + buffer, CAIRO_FORMAT_ARGB32, buffer_width, buffer_height, stride); + cairo_set_source_surface(cairo, buffer_surface, draw_pos_x, draw_pos_y); + cairo_paint(cairo); + cairo_surface_destroy(buffer_surface); +} + +static void +display_text_draw(struct font_freetype_text *text, struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct point *p) { int i,x,y,stride; struct font_freetype_glyph *g, **gp; - unsigned char *shadow,*glyph; struct color transparent={0x0,0x0,0x0,0x0}; - struct color white={0xffff,0xffff,0xffff,0xffff}; gp=text->glyph; i=text->glyph_count; @@ -318,19 +363,12 @@ display_text_draw(struct font_freetype_text *text, struct graphics_priv *gr, str { g=*gp++; if (g->w && g->h && bg ) { - stride=g->w+2; + unsigned char *shadow; + stride=cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, g->w+2); shadow=g_malloc(stride*(g->h+2)); - if (gr->freetype_methods.get_shadow(g, shadow, 8, stride, &white, &transparent)) - gdk_draw_gray_image(gr->drawable, bg->gc, ((x+g->x)>>6)-1, ((y+g->y)>>6)-1, g->w+2, g->h+2, GDK_RGB_DITHER_NONE, shadow, stride); + gr->freetype_methods.get_shadow(g, shadow, 32, stride, &bg->c, &transparent); + draw_rgb_image_buffer(gr->cairo, g->w+2, g->h+2, ((x+g->x)>>6)-1, ((y+g->y)>>6)-1, stride, shadow); g_free(shadow); - if (color) { - stride*=3; - shadow=g_malloc(stride*(g->h+2)); - gr->freetype_methods.get_shadow(g, shadow, 24, stride, &bg->c, &transparent); - gdk_draw_rgb_image(gr->drawable, fg->gc, ((x+g->x)>>6)-1, ((y+g->y)>>6)-1, g->w+2, g->h+2, GDK_RGB_DITHER_NONE, shadow, stride); - g_free(shadow); - } - } x+=g->dx; y+=g->dy; @@ -343,21 +381,12 @@ display_text_draw(struct font_freetype_text *text, struct graphics_priv *gr, str { g=*gp++; if (g->w && g->h) { - if (color) { - stride=g->w; - if (bg) { - glyph=g_malloc(stride*g->h); - gr->freetype_methods.get_glyph(g, glyph, 8, stride, &fg->c, &bg->c, &transparent); - gdk_draw_gray_image(gr->drawable, bg->gc, (x+g->x)>>6, (y+g->y)>>6, g->w, g->h, GDK_RGB_DITHER_NONE, glyph, g->w); - g_free(glyph); - } - stride*=3; - glyph=g_malloc(stride*g->h); - gr->freetype_methods.get_glyph(g, glyph, 24, stride, &fg->c, bg?&bg->c:&transparent, &transparent); - gdk_draw_rgb_image(gr->drawable, fg->gc, (x+g->x)>>6, (y+g->y)>>6, g->w, g->h, GDK_RGB_DITHER_NONE, glyph, stride); - g_free(glyph); - } else - gdk_draw_gray_image(gr->drawable, fg->gc, (x+g->x)>>6, (y+g->y)>>6, g->w, g->h, GDK_RGB_DITHER_NONE, g->pixmap, g->w); + unsigned char *glyph; + stride=cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, g->w); + glyph=g_malloc(stride*g->h); + gr->freetype_methods.get_glyph(g, glyph, 32, stride, &fg->c, bg?&bg->c:&transparent, &transparent); + draw_rgb_image_buffer(gr->cairo, g->w, g->h, (x+g->x)>>6, (y+g->y)>>6, stride, glyph); + g_free(glyph); } x+=g->dx; y+=g->dy; @@ -368,7 +397,6 @@ 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; - int color=0; if (! font) { @@ -388,35 +416,36 @@ draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics #endif if (bg && !bg->c.a) bg=NULL; - if (bg) { - if (COLOR_IS_BLACK(fg->c) && COLOR_IS_WHITE(bg->c)) { - gdk_gc_set_function(fg->gc, GDK_AND_INVERT); - gdk_gc_set_function(bg->gc, GDK_OR); - } else if (COLOR_IS_WHITE(fg->c) && COLOR_IS_BLACK(bg->c)) { - gdk_gc_set_function(fg->gc, GDK_OR); - gdk_gc_set_function(bg->gc, GDK_AND_INVERT); - } else { - gdk_gc_set_function(fg->gc, GDK_OR); - gdk_gc_set_function(bg->gc, GDK_AND_INVERT); - color=1; - } - } else { - gdk_gc_set_function(fg->gc, GDK_OR); - color=1; - } t=gr->freetype_methods.text_new(text, (struct font_freetype_font *)font, dx, dy); - display_text_draw(t, gr, fg, bg, color, p); + display_text_draw(t, gr, fg, bg, p); gr->freetype_methods.text_destroy(t); - gdk_gc_set_function(fg->gc, GDK_COPY); - if (bg) - gdk_gc_set_function(bg->gc, GDK_COPY); } static void draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img) { - gdk_draw_pixbuf(gr->drawable, fg->gc, img->pixbuf, 0, 0, p->x, p->y, - img->w, img->h, GDK_RGB_DITHER_NONE, 0, 0); + gdk_cairo_set_source_pixbuf(gr->cairo, img->pixbuf, p->x, p->y); + cairo_paint(gr->cairo); +} + +static unsigned char* +create_buffer_with_stride_if_required(unsigned char *input_buffer, int w, int h, size_t bytes_per_pixel, size_t output_stride) +{ + int line; + size_t input_offset, output_offset; + unsigned char *out_buf; + size_t input_stride = w*bytes_per_pixel; + if (input_stride == output_stride) { + return NULL; + } + + out_buf = g_malloc(h*output_stride); + for (line = 0; line < h; line++) { + input_offset = line*input_stride; + output_offset = line*output_stride; + memcpy(out_buf+output_offset, input_buffer+input_offset, input_stride); + } + return out_buf; } #ifdef HAVE_IMLIB2 @@ -424,15 +453,11 @@ static void draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, struct graphics_image_priv *img) { int w,h; - static struct graphics_priv *imlib_gr; + DATA32 *intermediate_buffer; + unsigned char* intermediate_buffer_aligned; + Imlib_Image intermediate_image; + size_t stride; dbg(lvl_debug,"draw_image_warp data=%p\n", img); - if (imlib_gr != gr) { - imlib_context_set_display(gdk_x11_drawable_get_xdisplay(gr->widget->window)); - imlib_context_set_colormap(gdk_x11_colormap_get_xcolormap(gtk_widget_get_colormap(gr->widget))); - imlib_context_set_visual(gdk_x11_visual_get_xvisual(gtk_widget_get_visual(gr->widget))); - imlib_context_set_drawable(gdk_x11_drawable_get_xid(gr->drawable)); - imlib_gr=gr; - } w = img->w; h = img->h; if (!img->image) { @@ -463,37 +488,51 @@ draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct po dbg(lvl_error,"implement me\n"); } - } else - imlib_context_set_image(img->image); + } + + intermediate_buffer = g_malloc0(gr->width*gr->height*4); + intermediate_image = imlib_create_image_using_data(gr->width, gr->height, intermediate_buffer); + imlib_context_set_image(intermediate_image); + imlib_image_set_has_alpha(1); + if (count == 3) { /* 0 1 2 */ - imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, p[1].y-p[0].y, p[2].x-p[0].x, p[2].y-p[0].y); + imlib_blend_image_onto_image_skewed(img->image, 1, 0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, p[1].y-p[0].y, p[2].x-p[0].x, p[2].y-p[0].y); } if (count == 2) { - /* 0 + /* 0 1 */ - imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, 0, 0, p[1].y-p[0].y); + imlib_blend_image_onto_image_skewed(img->image, 1, 0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, 0, 0, p[1].y-p[0].y); } if (count == 1) { - /* - 0 + /* + 0 */ - imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x-w/2, p[0].y-h/2, w, 0, 0, h); + imlib_blend_image_onto_image_skewed(img->image, 1, 0, 0, w, h, p[0].x-w/2, p[0].y-h/2, w, 0, 0, h); } + + stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, gr->width); + intermediate_buffer_aligned = create_buffer_with_stride_if_required( + (unsigned char* )intermediate_buffer, gr->width, gr->height, sizeof(DATA32), stride); + cairo_surface_t *buffer_surface = cairo_image_surface_create_for_data( + intermediate_buffer_aligned ? intermediate_buffer_aligned : (unsigned char*)intermediate_buffer, + CAIRO_FORMAT_ARGB32, gr->width, gr->height, stride); + cairo_set_source_surface(gr->cairo, buffer_surface, 0, 0); + cairo_paint(gr->cairo); + + cairo_surface_destroy(buffer_surface); + imlib_free_image(); + g_free(intermediate_buffer); + g_free(intermediate_buffer_aligned); } #endif static void -overlay_rect(struct graphics_priv *parent, struct graphics_priv *overlay, int clean, GdkRectangle *r) +overlay_rect(struct graphics_priv *parent, struct graphics_priv *overlay, GdkRectangle *r) { - if (clean) { - r->x=overlay->pclean.x; - r->y=overlay->pclean.y; - } else { - r->x=overlay->p.x; - r->y=overlay->p.y; - } + r->x=overlay->p.x; + r->y=overlay->p.y; r->width=overlay->width; r->height=overlay->height; if (!overlay->wraparound) @@ -509,65 +548,24 @@ overlay_rect(struct graphics_priv *parent, struct graphics_priv *overlay, int cl } static void -overlay_draw(struct graphics_priv *parent, struct graphics_priv *overlay, GdkRectangle *re, GdkPixmap *pixmap, GdkGC *gc) +overlay_draw(struct graphics_priv *parent, struct graphics_priv *overlay, GdkRectangle *re, cairo_t *cairo) { - GdkPixbuf *pixbuf,*pixbuf2; - guchar *pixels1, *pixels2, *p1, *p2, r=0, g=0, b=0, a=0; - int x,y; - int rowstride1,rowstride2; - int n_channels1,n_channels2; - GdkRectangle or,ir; - struct graphics_gc_priv *bg=overlay->background_gc; - if (bg) { - r=bg->c.r>>8; - g=bg->c.g>>8; - b=bg->c.b>>8; - a=bg->c.a>>8; - } - + GdkRectangle or, ir; if (parent->overlay_disabled || overlay->overlay_disabled || overlay->overlay_autodisabled) return; - dbg(lvl_debug,"r->x=%d r->y=%d r->width=%d r->height=%d\n", re->x, re->y, re->width, re->height); - overlay_rect(parent, overlay, 0, &or); - dbg(lvl_debug,"or.x=%d or.y=%d or.width=%d or.height=%d\n", or.x, or.y, or.width, or.height); + overlay_rect(parent, overlay, &or); if (! gdk_rectangle_intersect(re, &or, &ir)) return; or.x-=re->x; or.y-=re->y; - pixbuf=gdk_pixbuf_get_from_drawable(NULL, overlay->drawable, NULL, 0, 0, 0, 0, or.width, or.height); - pixbuf2=gdk_pixbuf_new(gdk_pixbuf_get_colorspace(pixbuf), TRUE, gdk_pixbuf_get_bits_per_sample(pixbuf), - or.width, or.height); - rowstride1 = gdk_pixbuf_get_rowstride (pixbuf); - rowstride2 = gdk_pixbuf_get_rowstride (pixbuf2); - pixels1=gdk_pixbuf_get_pixels (pixbuf); - pixels2=gdk_pixbuf_get_pixels (pixbuf2); - n_channels1 = gdk_pixbuf_get_n_channels (pixbuf); - n_channels2 = gdk_pixbuf_get_n_channels (pixbuf2); - for (y = 0 ; y < or.height ; y++) { - for (x = 0 ; x < or.width ; x++) { - p1 = pixels1 + y * rowstride1 + x * n_channels1; - p2 = pixels2 + y * rowstride2 + x * n_channels2; - p2[0]=p1[0]; - p2[1]=p1[1]; - p2[2]=p1[2]; - if (bg && p1[0] == r && p1[1] == g && p1[2] == b) - p2[3]=a; - else - p2[3]=overlay->a; - } - } - gdk_draw_pixbuf(pixmap, gc, pixbuf2, 0, 0, or.x, or.y, or.width, or.height, GDK_RGB_DITHER_NONE, 0, 0); - g_object_unref(pixbuf); - g_object_unref(pixbuf2); + cairo_surface_t *overlay_surface = cairo_get_target(overlay->cairo); + cairo_set_source_surface(cairo, overlay_surface, or.x, or.y); + cairo_paint(cairo); } static void draw_drag(struct graphics_priv *gr, struct point *p) { - if (!gr->cleanup) { - gr->pclean=gr->p; - gr->cleanup=1; - } if (p) gr->p=*p; else { @@ -584,56 +582,13 @@ background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc) } static void -gtk_drawing_area_draw(struct graphics_priv *gr, GdkRectangle *r) -{ - GdkPixmap *pixmap; - GtkWidget *widget=gr->widget; - GdkGC *gc=widget->style->fg_gc[GTK_WIDGET_STATE(widget)]; - struct graphics_priv *overlay; - - if (! gr->drawable) - return; - pixmap = gdk_pixmap_new(widget->window, r->width, r->height, -1); - if ((gr->p.x || gr->p.y) && gr->background_gc) - gdk_draw_rectangle(pixmap, gr->background_gc->gc, TRUE, 0, 0, r->width, r->height); - gdk_draw_drawable(pixmap, gc, gr->drawable, r->x, r->y, gr->p.x, gr->p.y, r->width, r->height); - overlay=gr->overlays; - while (overlay) { - overlay_draw(gr,overlay,r,pixmap,gc); - overlay=overlay->next; - } - gdk_draw_drawable(widget->window, gc, pixmap, 0, 0, r->x, r->y, r->width, r->height); - g_object_unref(pixmap); -} - -static void draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) { - GdkRectangle r; - struct graphics_priv *overlay; if (mode == draw_mode_end) { - if (gr->parent) { - if (gr->cleanup) { - overlay_rect(gr->parent, gr, 1, &r); - gtk_drawing_area_draw(gr->parent, &r); - gr->cleanup=0; - } - overlay_rect(gr->parent, gr, 0, &r); - gtk_drawing_area_draw(gr->parent, &r); - } else { - r.x=0; - r.y=0; - r.width=gr->width; - r.height=gr->height; - gtk_drawing_area_draw(gr, &r); - overlay=gr->overlays; - while (overlay) { - overlay->cleanup=0; - overlay=overlay->next; - } - } + // Just invalidate the whole window. We could only the invalidate the area of + // graphics_priv, but that is probably not significantly faster. + gdk_window_invalidate_rect(gr->widget->window, NULL, TRUE); } - gr->mode=mode; } /* Events */ @@ -644,15 +599,17 @@ configure(GtkWidget * widget, GdkEventConfigure * event, gpointer user_data) struct graphics_priv *gra=user_data; if (! gra->visible) return TRUE; - if (gra->drawable != NULL) { - g_object_unref(gra->drawable); - } #ifndef _WIN32 dbg(lvl_debug,"window=%lu\n", GDK_WINDOW_XID(widget->window)); #endif gra->width=widget->allocation.width; gra->height=widget->allocation.height; - gra->drawable = gdk_pixmap_new(widget->window, gra->width, gra->height, -1); + cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, gra->width, gra->height); + if (gra->cairo) + cairo_destroy(gra->cairo); + gra->cairo = cairo_create(surface); + cairo_surface_destroy(surface); + cairo_set_antialias (gra->cairo, CAIRO_ANTIALIAS_GOOD); callback_list_call_attr_2(gra->cbl, attr_resize, GINT_TO_POINTER(gra->width), GINT_TO_POINTER(gra->height)); return TRUE; } @@ -661,11 +618,28 @@ static gint expose(GtkWidget * widget, GdkEventExpose * event, gpointer user_data) { struct graphics_priv *gra=user_data; + struct graphics_gc_priv *background_gc=gra->background_gc; + struct graphics_priv *overlay; gra->visible=1; - if (! gra->drawable) + if (! gra->cairo) configure(widget, NULL, user_data); - gtk_drawing_area_draw(gra, &event->area); + + cairo_t *cairo=gdk_cairo_create(widget->window); + if (gra->p.x || gra->p.y) { + set_drawing_color(cairo, background_gc->c); + cairo_paint(cairo); + } + cairo_set_source_surface(cairo, cairo_get_target(gra->cairo), gra->p.x, gra->p.y); + cairo_paint(cairo); + + overlay = gra->overlays; + while (overlay) { + overlay_draw(gra,overlay,&event->area,cairo); + overlay=overlay->next; + } + + cairo_destroy(cairo); return FALSE; } @@ -865,14 +839,14 @@ overlay_disable(struct graphics_priv *gr, int disabled) gr->overlay_disabled=disabled; if (gr->parent) { GdkRectangle r; - overlay_rect(gr->parent, gr, 0, &r); - gtk_drawing_area_draw(gr->parent, &r); + overlay_rect(gr->parent, gr, &r); + gdk_window_invalidate_rect(gr->parent->widget->window, &r, TRUE); } } } static void -overlay_resize(struct graphics_priv *this, struct point *p, int w, int h, int alpha, int wraparound) +overlay_resize(struct graphics_priv *this, struct point *p, int w, int h, int wraparound) { //do not dereference parent for non overlay osds if(!this->parent) { @@ -905,14 +879,13 @@ overlay_resize(struct graphics_priv *this, struct point *p, int w, int h, int al changed = 1; } - this->a = alpha >> 8; this->wraparound = wraparound; if (changed) { - // Set the drawables to the right sizes - g_object_unref(this->drawable); - - this->drawable=gdk_pixmap_new(this->parent->widget->window, w2, h2, -1); + cairo_destroy(this->cairo); + cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w2, h2); + this->cairo=cairo_create(surface); + cairo_surface_destroy(surface); if ((w == 0) || (h == 0)) { this->overlay_autodisabled = 1; @@ -964,11 +937,10 @@ set_attr(struct graphics_priv *gr, struct attr *attr) } static struct graphics_priv * -overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound) +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound) { int w2,h2; struct graphics_priv *this=graphics_gtk_drawing_area_new_helper(meth); - this->colormap=gr->colormap; this->widget=gr->widget; this->p=*p; this->width=w; @@ -989,7 +961,9 @@ overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct poin w2 = w; } - this->drawable=gdk_pixmap_new(gr->widget->window, w2, h2, -1); + cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w2, h2); + this->cairo=cairo_create(surface); + cairo_surface_destroy(surface); if ((w == 0) || (h == 0)) { this->overlay_autodisabled = 1; @@ -998,7 +972,6 @@ overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct poin } this->next=gr->overlays; - this->a=alpha >> 8; this->wraparound=wraparound; gr->overlays=this; return this; @@ -1140,7 +1113,6 @@ graphics_gtk_drawing_area_new(struct navit *nav, struct graphics_methods *meth, else this->window_title=g_strdup("Navit"); this->cbl=cbl; - this->colormap=gdk_colormap_new(gdk_visual_get_system(),FALSE); gtk_widget_set_events(draw, GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_POINTER_MOTION_MASK|GDK_KEY_PRESS_MASK); g_signal_connect(G_OBJECT(draw), "expose_event", G_CALLBACK(expose), this); g_signal_connect(G_OBJECT(draw), "configure_event", G_CALLBACK(configure), this); diff --git a/navit/graphics/null/graphics_null.c b/navit/graphics/null/graphics_null.c index 22909f7b0..e3d617af2 100644 --- a/navit/graphics/null/graphics_null.c +++ b/navit/graphics/null/graphics_null.c @@ -164,7 +164,7 @@ draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) { } -static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound); +static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound); static void resize_callback(int w, int h) @@ -211,7 +211,7 @@ static void overlay_disable(struct graphics_priv *gr, int disable) { } -static void overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, int alpha, int wraparound) +static void overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, int wraparound) { } @@ -239,7 +239,7 @@ static struct graphics_methods graphics_methods = { }; static struct graphics_priv * -overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound) +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound) { *meth=graphics_methods; return &graphics_priv; diff --git a/navit/graphics/opengl/graphics_opengl.c b/navit/graphics/opengl/graphics_opengl.c index 5d65d1cd7..742dcae51 100644 --- a/navit/graphics/opengl/graphics_opengl.c +++ b/navit/graphics/opengl/graphics_opengl.c @@ -1235,7 +1235,7 @@ draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) static struct graphics_priv *overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, - int alpha, int wraparound); + int wraparound); static int graphics_opengl_fullscreen(struct window *w, int on) @@ -1369,7 +1369,7 @@ overlay_disable(struct graphics_priv *gr, int disable) static void overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, - int alpha, int wraparound) + int wraparound) { int changed = 0; int w2, h2; @@ -1462,7 +1462,7 @@ graphics_opengl_new_helper(struct graphics_methods *meth) static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, - struct point *p, int w, int h, int alpha, int wraparound) + struct point *p, int w, int h, int wraparound) { struct graphics_priv *this = graphics_opengl_new_helper(meth); this->p = *p; diff --git a/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp b/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp index 21ff837d6..20ac0c296 100644 --- a/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp +++ b/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp @@ -529,7 +529,7 @@ static void draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) //# Comment: //# Authors: Martin Schaller (04/2008) //############################################################################################################## -static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h,int alpha, int wraparound); +static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h,int wraparound); static int argc=1; static char *argv[]={NULL,NULL,NULL}; @@ -704,7 +704,7 @@ static struct graphics_methods graphics_methods = { //# Comment: //# Authors: Martin Schaller (04/2008) //############################################################################################################## -static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h,int alpha,int wraparound) +static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h,int wraparound) { *meth=graphics_methods; struct graphics_priv *ret=g_new0(struct graphics_priv, 1); diff --git a/navit/graphics/sdl/graphics_sdl.c b/navit/graphics/sdl/graphics_sdl.c index 95a6a7040..b01af5c3f 100644 --- a/navit/graphics/sdl/graphics_sdl.c +++ b/navit/graphics/sdl/graphics_sdl.c @@ -840,7 +840,7 @@ static void overlay_disable(struct graphics_priv *gr, int disable) } static struct graphics_priv * -overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound); +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound); static int window_fullscreen(struct window *win, int on) { @@ -912,7 +912,7 @@ static struct graphics_methods graphics_methods = { }; static struct graphics_priv * -overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h,int alpha, int wraparound) +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h,int wraparound) { struct graphics_priv *ov; Uint32 rmask, gmask, bmask, amask; diff --git a/navit/graphics/win32/graphics_win32.c b/navit/graphics/win32/graphics_win32.c index 671983505..124832a38 100644 --- a/navit/graphics/win32/graphics_win32.c +++ b/navit/graphics/win32/graphics_win32.c @@ -1477,9 +1477,9 @@ static void draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, st static struct graphics_priv * graphics_win32_new_helper(struct graphics_methods *meth); -static void overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, int alpha, int wraparound) +static void overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, int wraparound) { - dbg(lvl_debug, "resize overlay: %x, x: %d, y: %d, w: %d, h: %d, alpha: %x, wraparound: %d\n", gr, p->x, p->y, w, h, alpha, wraparound); + dbg(lvl_debug, "resize overlay: %x, x: %d, y: %d, w: %d, h: %d, wraparound: %d\n", gr, p->x, p->y, w, h, wraparound); if ( gr->width != w || gr->height != h ) { @@ -1494,10 +1494,10 @@ static void overlay_resize(struct graphics_priv *gr, struct point *p, int w, int static struct graphics_priv * - overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound) + overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound) { struct graphics_priv *this=graphics_win32_new_helper(meth); - dbg(lvl_debug, "overlay: %x, x: %d, y: %d, w: %d, h: %d, alpha: %x, wraparound: %d\n", this, p->x, p->y, w, h, alpha, wraparound); + dbg(lvl_debug, "overlay: %x, x: %d, y: %d, w: %d, h: %d, wraparound: %d\n", this, p->x, p->y, w, h, wraparound); this->width = w; this->height = h; this->parent = gr; diff --git a/navit/map/binfile/binfile.c b/navit/map/binfile/binfile.c index 5d2cf172e..4ca4c6bf5 100644 --- a/navit/map/binfile/binfile.c +++ b/navit/map/binfile/binfile.c @@ -2129,7 +2129,6 @@ binmap_search_new(struct map_priv *map, struct item *item, struct attr *search, town = map_rect_get_item_byid_binfile(map_rec, map->last_searched_town_id_hi, map->last_searched_town_id_lo); if (town) msp->mr = binmap_search_street_by_place(map, town, &c, &msp->ms, &msp->boundaries); - map_rect_destroy_binfile(map_rec); if (msp->boundaries) dbg(lvl_debug, "using map town boundaries\n"); if (!msp->boundaries && town) @@ -2138,6 +2137,7 @@ binmap_search_new(struct map_priv *map, struct item *item, struct attr *search, if (msp->boundaries) dbg(lvl_debug, "using estimated boundaries\n"); } + map_rect_destroy_binfile(map_rec); /* start searching in area around the street segment even if town boundaries are available */ msp->mr=binmap_search_housenumber_by_estimate(map, &c, &msp->ms); msp->mode = 2; diff --git a/navit/maptool/boundaries.c b/navit/maptool/boundaries.c index 480f5d65e..9d39b724f 100644 --- a/navit/maptool/boundaries.c +++ b/navit/maptool/boundaries.c @@ -83,6 +83,8 @@ process_boundaries_setup(FILE *boundaries, struct relations *relations) int has_subrelations=0; int has_outer_ways=0; + processed_relations++; + if(!iso) iso=osm_tag_value(ib, "iso3166-1:alpha2"); @@ -352,8 +354,9 @@ process_boundaries(FILE *boundaries, FILE *ways) } void -free_boundaries(GList *l) +free_boundaries(GList *bl) { + GList *l=bl; while (l) { struct boundary *boundary=l->data; GList *s=boundary->segments; @@ -378,5 +381,5 @@ free_boundaries(GList *l) g_free(boundary); l=g_list_next(l); } - g_list_free(l); + g_list_free(bl); } diff --git a/navit/maptool/maptool.c b/navit/maptool/maptool.c index 3fc47b680..765d6abf7 100644 --- a/navit/maptool/maptool.c +++ b/navit/maptool/maptool.c @@ -72,16 +72,76 @@ int overlap=1; int bytes_read; static long start_brk; -static struct timeval start_tv; +#ifdef _WIN32 +#define timespec timeval +#endif +static struct timespec start_ts; + +/* + Asynchronous signal safe lltoa function (note: no trailing \0 char!) +*/ +int assafe_lltoa(long long n, int maxlen, char *buf) +{ + int i; + int out_length; + + if(maxlen<1) + return 0; + + if(n<0) { + n=-n; + buf[0]='-'; + maxlen--; + buf++; + } else if(n==0) { + buf[0]='0'; + return 1; + } + + for(i=0; n>0 && i<maxlen; i++) { + buf[i]='0'+(n%10); + n/=10; + } + out_length=i; + for(i=0;i<out_length/2;i++) { + char c=buf[i]; + buf[i]=buf[out_length-i-1]; + buf[out_length-i-1]=c; + } + return out_length; +} + +/* + Asynchronous signal safe string copy to buffer function (note: no trailing \0 char!) +*/ +int assafe_strcp2buf(char *str, int maxlen, char *buf) +{ + int i; + for(i=0;str[i] && i<maxlen;i++) + buf[i]=str[i]; + return i; +} static void progress_time(void) { - struct timeval tv; + struct timespec ts; int seconds; - gettimeofday(&tv, NULL); - seconds=tv.tv_sec-start_tv.tv_sec; - fprintf(stderr," %d:%02d",seconds/60,seconds%60); + const int buflen=20; + char buf[buflen]; + int pos=1; + buf[0]=' '; +#ifdef _WIN32 + gettimeofday(&ts, NULL); +#else + clock_gettime(CLOCK_REALTIME, &ts); +#endif + seconds=ts.tv_sec-start_ts.tv_sec; + pos+=assafe_lltoa(seconds/60, buflen-pos, buf+pos); + seconds%=60; + pos+=assafe_strcp2buf(seconds>9?":":":0", buflen-pos, buf+pos); + pos+=assafe_lltoa(seconds, buflen-pos, buf+pos); + write(2,buf,pos); } static void @@ -89,24 +149,58 @@ progress_memory(void) { #ifdef HAVE_SBRK long mem=(long)sbrk(0)-start_brk; - fprintf(stderr," %ld MB",mem/1024/1024); + const int buflen=20; + char buf[buflen]; + int pos=1; + buf[0]=' '; + pos+=assafe_lltoa(mem/1024/1024, buflen-pos, buf+pos); + pos+=assafe_strcp2buf(" MB", buflen-pos, buf+pos); + write(2,buf,pos); #endif } void -sig_alrm(int sig) +sig_alrm_do(int sig) { + const int buflen=1024; + char buf[buflen]; + int pos=0; #ifndef _WIN32 - signal(SIGALRM, sig_alrm); + signal(SIGALRM, sig_alrm_do); alarm(30); #endif - fprintf(stderr,"PROGRESS%d: Processed %d nodes (%d out) %d ways %d relations %d tiles", phase, processed_nodes, processed_nodes_out, processed_ways, processed_relations, processed_tiles); + pos+=assafe_strcp2buf("PROGRESS", buflen-pos, buf+pos); + pos+=assafe_lltoa(phase, buflen-pos, buf+pos); + pos+=assafe_strcp2buf(": Processed ", buflen-pos, buf+pos); + pos+=assafe_lltoa(processed_nodes, buflen-pos, buf+pos); + pos+=assafe_strcp2buf(" nodes (", buflen-pos, buf+pos); + pos+=assafe_lltoa(processed_nodes_out, buflen-pos, buf+pos); + pos+=assafe_strcp2buf(" out) ", buflen-pos, buf+pos); + pos+=assafe_lltoa(processed_ways, buflen-pos, buf+pos); + pos+=assafe_strcp2buf(" ways ", buflen-pos, buf+pos); + pos+=assafe_lltoa(processed_relations, buflen-pos, buf+pos); + pos+=assafe_strcp2buf(" relations ", buflen-pos, buf+pos); + pos+=assafe_lltoa(processed_tiles, buflen-pos, buf+pos); + pos+=assafe_strcp2buf(" tiles", buflen-pos, buf+pos); + write(2,buf,pos); progress_time(); progress_memory(); - fprintf(stderr,"\n"); +#ifndef _WIN32 + write(2,"\r\n",2); +#else + write(2,"\n",1); +#endif +} + +void +sig_alrm(int sig) +{ + fflush(stderr); + sig_alrm_do(sig); } + void sig_alrm_end(void) { @@ -444,6 +538,7 @@ start_phase(struct maptool_params *p, char *str) phase++; if (p->start <= phase && p->end >= phase) { fprintf(stderr,"PROGRESS: Phase %d: %s",phase,str); + fflush(stderr); progress_time(); progress_memory(); fprintf(stderr,"\n"); @@ -711,7 +806,10 @@ maptool_assemble_map(struct maptool_params *p, char *suffix, char **filenames, c zip_set_compression_level(zip_info, p->compression_level); if (p->md5file) zip_set_md5(zip_info, 1); - zip_open(zip_info, p->result, zipdir, zipindex); + if(!zip_open(zip_info, p->result, zipdir, zipindex)) { + fprintf(stderr,"Fatal: Could not write output file.\n"); + exit(1); + } if (p->url) { map_information_attrs[1].type=attr_url; map_information_attrs[1].u.str=p->url; @@ -845,8 +943,11 @@ int main(int argc, char **argv) #ifdef HAVE_SBRK start_brk=(long)sbrk(0); #endif - gettimeofday(&start_tv, NULL); - +#ifdef _WIN32 + gettimeofday(&start_ts,NULL); +#else + clock_gettime(CLOCK_REALTIME, &start_ts); +#endif while (1) { int parse_result=parse_option(&p, argv, argc, &option_index); if (!parse_result) { diff --git a/navit/maptool/maptool.h b/navit/maptool/maptool.h index d8813b49f..7fde891dd 100644 --- a/navit/maptool/maptool.h +++ b/navit/maptool/maptool.h @@ -412,7 +412,7 @@ void zip_set_maxnamelen(struct zip_info *info, int max); int zip_get_maxnamelen(struct zip_info *info); int zip_add_member(struct zip_info *info); int zip_set_timestamp(struct zip_info *info, char *timestamp); -void zip_open(struct zip_info *info, char *out, char *dir, char *index); +int zip_open(struct zip_info *info, char *out, char *dir, char *index); FILE *zip_get_index(struct zip_info *info); int zip_get_zipnum(struct zip_info *info); void zip_set_zipnum(struct zip_info *info, int num); diff --git a/navit/maptool/osm.c b/navit/maptool/osm.c index 804321d4e..d8063c3a7 100644 --- a/navit/maptool/osm.c +++ b/navit/maptool/osm.c @@ -2062,10 +2062,13 @@ osm_process_towns(FILE *in, FILE *boundaries, FILE *ways, char *suffix) struct attr attrs[11]; FILE *towns_poly; - profile(0,NULL); + processed_nodes=processed_nodes_out=processed_ways=processed_relations=processed_tiles=0; + bytes_read=0; + sig_alrm(0); + bl=process_boundaries(boundaries, ways); - profile(1,"processed boundaries\n"); + fprintf(stderr, "Processed boundaries\n"); town_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); while ((ib=read_item(in))) { @@ -2077,13 +2080,15 @@ osm_process_towns(FILE *in, FILE *boundaries, FILE *ways, char *suffix) } fseek(in, 0, SEEK_SET); - profile(1, "Finished town table rebuild\n"); + fprintf(stderr, "Finished town table rebuild\n"); while ((ib=read_item(in))) { struct coord *c=(struct coord *)(ib+1); struct country_table *result=NULL; char *is_in=item_bin_get_attr(ib, attr_osm_is_in, NULL); int i; + + processed_nodes++; memset(attrs, 0, sizeof(attrs)); result=osm_process_town_by_boundary(bl, ib, c, attrs); @@ -2145,7 +2150,10 @@ osm_process_towns(FILE *in, FILE *boundaries, FILE *ways, char *suffix) g_hash_table_destroy(town_hash); free_boundaries(bl); - profile(0, "Finished processing towns\n"); + sig_alrm(0); + sig_alrm_end(); + + fprintf(stderr, "Finished processing towns\n"); } void diff --git a/navit/maptool/osm_o5m.c b/navit/maptool/osm_o5m.c index e5949000c..1ca3b1c3c 100644 --- a/navit/maptool/osm_o5m.c +++ b/navit/maptool/osm_o5m.c @@ -335,7 +335,17 @@ map_collect_data_osm_o5m(FILE *in, struct maptool_osm *osm) break; default: fprintf(stderr,"Unknown tag 0x%x\n",c); - return 0; + /* Fall through */ + case 0xdc: /* File timestamp: silently ignore it */ + len=get_uval(&o.buffer_start); + if (o.buffer_start > o.buffer_end) { + return 0; + } + if (buffer_end(&o, len)) { + return 0; + } + o.buffer_start+=len; + break; } } return 0; diff --git a/navit/maptool/tile.c b/navit/maptool/tile.c index cee2671dc..68b837bc0 100644 --- a/navit/maptool/tile.c +++ b/navit/maptool/tile.c @@ -576,6 +576,7 @@ write_tilesdir(struct tile_info *info, struct zip_info *zip_info, FILE *out) } len--; } + g_list_free(tiles_list); if (info->suffix[0] && info->write) { struct item_bin *item_bin=init_item(type_submap); item_bin_add_coord_rect(item_bin, &world_bbox); diff --git a/navit/maptool/zip.c b/navit/maptool/zip.c index 3d58d191e..b75f1e3e7 100644 --- a/navit/maptool/zip.c +++ b/navit/maptool/zip.c @@ -428,12 +428,25 @@ zip_set_timestamp(struct zip_info *info, char *timestamp) return 0; } -void +int zip_open(struct zip_info *info, char *out, char *dir, char *index) { info->res2=fopen(out,"wb+"); + if(!info->res2) { + fprintf(stderr,"Could not open output zip file %s\n", out); + return 0; + } info->dir=fopen(dir,"wb+"); + if(!info->dir) { + fprintf(stderr,"Could not open zip directory %s\n", dir); + return 0; + } info->index=fopen(index,"wb+"); + if(!info->index) { + fprintf(stderr,"Could not open index %s\n", index); + return 0; + } + return 1; } FILE * diff --git a/navit/navigation.c b/navit/navigation.c index d00e6b243..173d4eeb5 100644 --- a/navit/navigation.c +++ b/navit/navigation.c @@ -24,7 +24,7 @@ * (#519) * */ - + /* KNOWN ISSUES * * @@ -111,7 +111,7 @@ static int min_turn_limit = 25; * robotaxi: * suggested limits derived from 'simple turn rules' in bugfix/enhancement #1095: * 25-45-110-165. - * taken over from here: 25 (straight limit) and 165 (u-turn-limit used for very strong turn) + * taken over from here: 25 (straight limit) and 165 (u-turn-limit used for very strong turn) */ /** Minimum absolute delta for a turn of "normal" strength (which is always just announced as "turn left/right" even when strength is required). @@ -369,7 +369,7 @@ static void navigation_flush(struct navigation *this_); * @param angle1 The first angle * @param angle2 The second angle * @return The difference between the angles, see description - */ + */ static int angle_delta(int angle1, int angle2) { @@ -710,9 +710,9 @@ navigation_get_attr(struct navigation *this_, enum attr_type type, struct attr * mr=map_rect_new(this_->map, NULL); while ((item=map_rect_get_item(mr))) { if (item->type != type_nav_none && item->type != type_nav_position) { - if (type == attr_item_type) + if (type == attr_item_type) attr->u.item_type=item->type; - else { + else { if (!item_attr_get(item, type, attr)) item=NULL; } @@ -787,7 +787,7 @@ navigation_new(struct attr *parent, struct attr **attrs) if ((attr=attr_search(attrs, NULL, attr_flags))) { ret->flags = attr->u.num; } - return ret; + return ret; } int @@ -854,7 +854,7 @@ road_angle(struct coord *c1, struct coord *c2, int dir) } static const char -*get_count_str(int n) +*get_count_str(int n) { switch (n) { case 0: @@ -872,13 +872,13 @@ static const char return _("fifth"); case 6: return _("sixth"); - default: + default: return NULL; } } static const char -*get_exit_count_str(int n) +*get_exit_count_str(int n) { switch (n) { case 0: @@ -896,7 +896,7 @@ static const char return _("fifth exit"); case 6: return _("sixth exit"); - default: + default: return NULL; } } @@ -940,7 +940,7 @@ distance_set_last() { static int i=0; if (i == 0) { - while (distances[i] > 0) + while (distances[i] > 0) i++; } return distances[i-1]; @@ -970,7 +970,7 @@ round_distance_reduced( int dist ) break; i++; } - dbg(lvl_debug,"converted %d to %d with factor %d\n",dist,distances[m],factor); + dbg(lvl_debug,"converted %d to %d with factor %d\n",dist,distances[m],factor); return distances[m] * factor; } @@ -980,10 +980,10 @@ round_distance_reduced( int dist ) * Considers the configuration of 'imperial' units and 'vocabulary_distances'. * 'imperial' if set distinguishes the distance statement between miles and feet. Maximum distance in feet is 500. * 'vocabulary_distances' if set constrains the distance values to a set of simple pronounceable numbers. -* +* * @param nav The navigation object. * @param dist Distance in meters. -* @param type The type of announcement precision. +* @param type The type of announcement precision. * @param is_length 1 for length statement, 0 for distance statement. * @return String with length/distance statement. */ @@ -991,7 +991,7 @@ static char * get_distance_str(struct navigation *nav, int dist_meters, enum attr_type type, int is_length) { int imperial=0,vocabulary=1; /* default configuration */ - + /* Get configuration */ struct attr attr; if (navit_get_attr(nav->navit, attr_imperial, &attr, NULL)) @@ -1044,7 +1044,7 @@ get_distance_str(struct navigation *nav, int dist_meters, enum attr_type type, i return g_strdup_printf(_("in %d.%d miles"), dist_miles, rem); } - if (is_length) + if (is_length) return g_strdup_printf(navit_nls_ngettext("one mile","%d miles", dist_miles), dist_miles); else return g_strdup_printf(navit_nls_ngettext("in one mile","in %d miles", dist_miles), dist_miles); @@ -1137,19 +1137,19 @@ navigation_way_init(struct navigation_way *w) w->name_systematic=map_convert_string(realitem->map,attr.u.str); else w->name_systematic=NULL; - + if (w->dir < 0) { if (item_coord_get(realitem, cbuf, 2) != 2) { dbg(lvl_warning,"Using calculate_angle() with a less-than-two-coords-item?\n"); map_rect_destroy(mr); return; } - + while (item_coord_get(realitem, &c, 1)) { cbuf[0] = cbuf[1]; cbuf[1] = c; } - + } else { if (item_coord_get(realitem, cbuf, 2) != 2) { dbg(lvl_warning,"Using calculate_angle() with a less-than-two-coords-item?\n"); @@ -1488,10 +1488,10 @@ navigation_itm_ways_clear(struct navigation_itm *itm) * and the next navigation item are excluded. * * @param itm The item that should be updated - * @param graph_map The route graph's map that these items are on + * @param graph_map The route graph's map that these items are on */ static void -navigation_itm_ways_update(struct navigation_itm *itm, struct map *graph_map) +navigation_itm_ways_update(struct navigation_itm *itm, struct map *graph_map) { struct map_selection coord_sel; struct map_rect *g_rect; /* Contains a map rectangle from the route graph's map */ @@ -1508,9 +1508,9 @@ navigation_itm_ways_update(struct navigation_itm *itm, struct map *graph_map) coord_sel.u.c_rect.lu = itm->start; coord_sel.u.c_rect.rl = itm->start; /* the selection's order is ignored */ - + g_rect = map_rect_new(graph_map, &coord_sel); - + i = map_rect_get_item(g_rect); if (!i || i->type != type_rg_point) { /* probably offroad? */ map_rect_destroy(g_rect); @@ -1518,22 +1518,22 @@ navigation_itm_ways_update(struct navigation_itm *itm, struct map *graph_map) } w = NULL; - + while (1) { i = map_rect_get_item(g_rect); if (!i) { break; } - + if (i->type != type_rg_segment) { continue; } - + if (!item_attr_get(i,attr_street_item,&sitem_attr)) { dbg(lvl_warning, "Got no street item for route graph item in entering_straight()\n"); continue; - } + } if (!item_attr_get(i,attr_direction,&direction_attr)) { continue; @@ -1569,7 +1569,7 @@ navigation_itm_ways_update(struct navigation_itm *itm, struct map *graph_map) } map_rect_destroy(g_rect); - + itm->way.next = w; } @@ -1609,7 +1609,7 @@ navigation_destroy_itms_cmds(struct navigation *this_, struct navigation_itm *en g_free(cmd->maneuver); g_free(cmd); } - + map_convert_free(itm->way.name); map_convert_free(itm->way.name_systematic); map_convert_free(itm->way.exit_ref); @@ -1620,7 +1620,7 @@ navigation_destroy_itms_cmds(struct navigation *this_, struct navigation_itm *en } if (! this_->first) this_->last=NULL; - if (! this_->first && end) + if (! this_->first && end) dbg(lvl_error,"end wrong\n"); dbg(lvl_info,"ret this_->first=%p this_->cmd_first=%p\n",this_->first, this_->cmd_first); } @@ -1690,7 +1690,7 @@ navigation_itm_new(struct navigation *this_, struct item *routeitem) ret->way.item=*streetitem; item_hash_insert(this_->hash, streetitem, ret); - mr=map_rect_new(streetitem->map, NULL); + mr=map_rect_new(streetitem->map, NULL); struct map *tmap = streetitem->map; @@ -1746,7 +1746,7 @@ navigation_itm_new(struct navigation *this_, struct item *routeitem) } } } - + navigation_itm_update(ret, routeitem); @@ -1868,7 +1868,7 @@ navigation_itm_new(struct navigation *this_, struct item *routeitem) } /** - * @brief Counts how many times a driver could turn right/left + * @brief Counts how many times a driver could turn right/left * * This function counts how many times the driver theoretically could * turn right/left between two navigation items, not counting the final @@ -1902,7 +1902,7 @@ count_possible_turns(struct navigation *nav, struct navigation_itm *from, struct if (angle_delta(curr->prev->angle_end, w->angle2) > 0) { count++; break; - } + } } } w = w->next; @@ -3172,7 +3172,7 @@ navigation_item_destination(struct navigation *nav, struct navigation_command *c ret=g_strdup_printf(_("%sinto %s%s%s|neuter form"), prefix, name1, sep, name2); break; } - + } else /* TRANSLATORS: gives the name of the next road to turn into (into the E17) */ ret=g_strdup_printf(_("%sinto the %s"),prefix,name_systematic); @@ -3273,6 +3273,7 @@ show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigat int skip_roads = 0; int count_roundabout; struct navigation_itm *cur; + struct navigation_way *candidate_way; int tellstreetname = 0; char *at = NULL; /* Motorway junction name */ char *direction = NULL; /* The direction-dependent part of the maneuver */ @@ -3327,11 +3328,46 @@ show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigat count_roundabout = 0; while (cur && (cur->way.flags & AF_ROUNDABOUT)) { - if (cur->next->way.next && is_way_allowed(nav,cur->next->way.next,3)) - /* If the next segment has no exit or the exit isn't allowed, don't count it */ - count_roundabout++; + candidate_way=cur->next->way.next; + while (candidate_way) + { + if (candidate_way && is_way_allowed(nav,candidate_way,3)) + /* If the next segment has no exit or the exit isn't allowed, don't count it */ + { + count_roundabout++; + /* As soon as we have an allowed one on this node, + * stop further counting for this node. + */ + break; + } + candidate_way=candidate_way->next; + } cur = cur->prev; } + + /*try to figure out if the entry node has a usable exit as well + * + * this will fail for left-hand driving areas + */ + if (cur && cur->next) + { + candidate_way=cur->next->way.next; + while (candidate_way) + { + if (candidate_way && is_way_allowed(nav,candidate_way,3) + /*&& (angle_delta(cur->angle_end,candidate_way->angle2) > 0) && ( angle_delta(candidate_way->angle2,cur->next->way.angle2) < 0 )*/) + /*for right-hand traffic, exits should be to the right anyway to allow smooth turns, so leave this out until we find a counterexample :)*/ + { + count_roundabout++; + /* As soon as we have an allowed one on this node, + * stop further counting for this node. + */ + break; + } + candidate_way=candidate_way->next; + } + } + switch (level) { case level_follow: @@ -3410,7 +3446,7 @@ show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigat char *exit_announce=NULL; /* interchange or exit announcement shall be a long distance information only. - But if so, exit_label shall not be announced in case it is a substring + But if so, exit_label shall not be announced in case it is a substring of destination info to avoid redundancy and not let the sentence become too long. Otherwise, if there is no additional destination info, just say it at level_meters. */ if ((level == level_soon) || ((level == level_meters) && (!street_destination_announce && !destination)) || (type != attr_navigation_speech)) { @@ -3674,10 +3710,7 @@ show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct n } -////////////////////////////////////// level = navigation_get_announce_level_cmd(nav, itm, cmd, distance-cmd->length); -////////////////////////////////////// - //level=navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length); if (level > level_soon) { /* suppress the 'follow the road..' announcement, if the next 'soon' announcement is just a few meters away, so just quit */ @@ -3797,11 +3830,11 @@ navigation_update(struct navigation *this_, struct route *route, struct attr *at return; dbg(lvl_debug,"enter %d\n", mode); - if (attr->u.num == route_status_no_destination || attr->u.num == route_status_not_found || attr->u.num == route_status_path_done_new) + if (attr->u.num == route_status_no_destination || attr->u.num == route_status_not_found || attr->u.num == route_status_path_done_new) navigation_flush(this_); if (attr->u.num != route_status_path_done_new && attr->u.num != route_status_path_done_incremental) return; - + if (! this_->route) return; map=route_get_map(this_->route); @@ -3844,7 +3877,7 @@ navigation_update(struct navigation *this_, struct route *route, struct attr *at navigation_itm_new(this_, ritem); } dbg(lvl_info,"turn_around=%d\n", this_->turn_around); - if (first) + if (first) navigation_destroy_itms_cmds(this_, NULL); else { if (! ritem) { @@ -3907,7 +3940,7 @@ navigation_get_map(struct navigation *this_) data.u.str=""; description.type=attr_description; description.u.str="Navigation"; - + attrs[0]=&type; attrs[1]=&navigation; attrs[2]=&data; @@ -4047,7 +4080,7 @@ navigation_map_item_attr_get(void *priv_data, enum attr_type attr_type, struct a return 0; case attr_street_name_systematic: attr->u.str=itm->way.name_systematic; - this_->attr_next=attr_street_destination; + this_->attr_next=attr_street_destination; if (attr->u.str){ return 1;} return 0; @@ -4152,7 +4185,7 @@ navigation_map_item_attr_get(void *priv_data, enum attr_type attr_type, struct a maneuver->delta); return 1; } - + default: this_->attr_next=attr_none; return 0; @@ -4251,7 +4284,7 @@ navigation_map_get_item(struct map_rect_priv *priv) priv->cmd_itm=priv->cmd_itm_next; if (!priv->cmd) return NULL; - if (!priv->show_all && priv->itm->prev != NULL) + if (!priv->show_all && priv->itm->prev != NULL) priv->itm=priv->cmd->itm; priv->itm_next=priv->itm->next; if (priv->itm->prev) @@ -4321,7 +4354,7 @@ navigation_map_get_item_byid(struct map_rect_priv *priv, int id_hi, int id_lo) struct item *ret; navigation_map_rect_init(priv); while ((ret=navigation_map_get_item(priv))) { - if (ret->id_hi == id_hi && ret->id_lo == id_lo) + if (ret->id_hi == id_hi && ret->id_lo == id_lo) return ret; } return NULL; diff --git a/navit/navit_shipped.xml b/navit/navit_shipped.xml index e6945ea4a..983ad373c 100644 --- a/navit/navit_shipped.xml +++ b/navit/navit_shipped.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?><!-- For configuration options used in this file, please read - http://wiki.navit-project.org/index.php/Configuring_Navit - Do not edit /usr/share/navit/navit.xml : changes would be lost - on upgrade. Rather copy it to ~/.navit/. + http://wiki.navit-project.org/index.php/Configuration + Do not edit /usr/share/navit/navit.xml or /etc/navit/navit.xml : + changes would be lost on upgrade. Rather copy it to ~/.navit/. --> <!DOCTYPE config SYSTEM "navit.dtd"> @@ -353,7 +353,7 @@ Waypoint</text></img> <route destination_distance="50"/> <navigation> - <announce type="street_0,street_1_city,street_parking_lane" level0="25" level1="100" level2="200" unit="m"/> + <announce type="street_0,street_1_city,street_parking_lane,living_street,street_service" level0="25" level1="100" level2="200" unit="m"/> <announce type="street_2_city,street_3_city,street_4_city,ramp" level0="50" level1="200" level2="500" unit="m"/> <announce type="highway_city,street_1_land,street_2_land,street_3_land,street_4_land" level0="100" level1="400" level2="1000" unit="m"/> <announce type="street_n_lanes,highway_land" level0="300" level1="1000" level2="2000" unit="m"/> diff --git a/navit/osd.c b/navit/osd.c index 4d5527b86..dd87392fb 100644 --- a/navit/osd.c +++ b/navit/osd.c @@ -158,7 +158,7 @@ osd_std_click(struct osd_item *this, struct navit *nav, int pressed, int button, void osd_std_resize(struct osd_item *item) { - graphics_overlay_resize(item->gr, &item->p, item->w, item->h, 65535, 1); + graphics_overlay_resize(item->gr, &item->p, item->w, item->h, 1); } /** @@ -373,7 +373,7 @@ osd_set_std_graphic(struct navit *nav, struct osd_item *item, struct osd_priv *p navit_gr = navit_get_graphics(nav); osd_std_calculate_sizes(item, navit_get_width(nav), navit_get_height(nav)); - item->gr = graphics_overlay_new(navit_gr, &item->p, item->w, item->h, 65535, 1); + item->gr = graphics_overlay_new(navit_gr, &item->p, item->w, item->h, 1); item->graphic_bg = graphics_gc_new(item->gr); graphics_gc_set_foreground(item->graphic_bg, &item->color_bg); diff --git a/navit/speech/cmdline/speech_cmdline.c b/navit/speech/cmdline/speech_cmdline.c index 08a1abe03..49252f346 100644 --- a/navit/speech/cmdline/speech_cmdline.c +++ b/navit/speech/cmdline/speech_cmdline.c @@ -236,6 +236,10 @@ speechd_new(struct speech_methods *meth, struct attr **attrs, struct attr *paren this->flags=attr->u.num; if (this->sample_dir && this->sample_suffix) { void *handle=file_opendir(this->sample_dir); + if (!handle) { + dbg(lvl_error,"Cannot read sample directory contents: %s", this->sample_dir); + return NULL; + } char *name; int suffix_len=strlen(this->sample_suffix); while((name=file_readdir(handle))) { diff --git a/navit/start_real.c b/navit/start_real.c index e002cf93d..16e0d5edb 100644 --- a/navit/start_real.c +++ b/navit/start_real.c @@ -51,7 +51,7 @@ #include <winbase.h> #endif -char *version=PACKAGE_VERSION" "SVN_VERSION""NAVIT_VARIANT; +char *version=PACKAGE_VERSION"+git:"GIT_VERSION""NAVIT_VARIANT; int main_argc; char * const* main_argv; diff --git a/navit/vehicle.c b/navit/vehicle.c index be8bd1bdd..a280fb024 100644 --- a/navit/vehicle.c +++ b/navit/vehicle.c @@ -339,7 +339,7 @@ vehicle_set_cursor(struct vehicle *this_, struct cursor *cursor, int overwrite) if (cursor && this_->gra && this_->cursor) { this_->cursor_pnt.x+=(this_->cursor->w - cursor->w)/2; this_->cursor_pnt.y+=(this_->cursor->h - cursor->h)/2; - graphics_overlay_resize(this_->gra, &this_->cursor_pnt, cursor->w, cursor->h, 65535, 0); + graphics_overlay_resize(this_->gra, &this_->cursor_pnt, cursor->w, cursor->h, 0); } if (cursor) { @@ -382,7 +382,7 @@ vehicle_draw(struct vehicle *this_, struct graphics *gra, struct point *pnt, int this_->cursor_pnt.y-=this_->cursor->h/2; if (!this_->gra) { struct color c; - this_->gra=graphics_overlay_new(gra, &this_->cursor_pnt, this_->cursor->w, this_->cursor->h, 65535, 0); + this_->gra=graphics_overlay_new(gra, &this_->cursor_pnt, this_->cursor->w, this_->cursor->h, 0); if (this_->gra) { graphics_init(this_->gra); this_->bg=graphics_gc_new(this_->gra); diff --git a/navit/vehicle/gpsd/vehicle_gpsd.c b/navit/vehicle/gpsd/vehicle_gpsd.c index 4526e159f..f7f5616f9 100644 --- a/navit/vehicle/gpsd/vehicle_gpsd.c +++ b/navit/vehicle/gpsd/vehicle_gpsd.c @@ -130,7 +130,11 @@ vehicle_gpsd_callback(struct gps_data_t *data, const char *buf, size_t len, #else for( i=0;i<data->satellites;i++) { #endif +#if GPSD_API_MAJOR_VERSION >= 6 + if (data->skyview[i].ss > 0) +#else if (data->ss[i] > 0) +#endif sats_signal++; } } diff --git a/navit/version.h.in b/navit/version.h.in index cc58ebe24..3c39d0e1f 100644 --- a/navit/version.h.in +++ b/navit/version.h.in @@ -1,2 +1,2 @@ -#cmakedefine SVN_VERSION "@SVN_VERSION@" +#cmakedefine GIT_VERSION "@GIT_VERSION@" #cmakedefine NAVIT_VARIANT "@NAVIT_VARIANT@" |